Merge remote-tracking branches 'asoc/topic/wm8753', 'asoc/topic/wm8770', 'asoc/topic...
authorMark Brown <broonie@kernel.org>
Wed, 28 Mar 2018 02:31:34 +0000 (10:31 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 28 Mar 2018 02:31:34 +0000 (10:31 +0800)
2082 files changed:
.gitignore
Documentation/ABI/testing/sysfs-ata
Documentation/ABI/testing/sysfs-block-device [new file with mode: 0644]
Documentation/ABI/testing/sysfs-class-scsi_host
Documentation/ABI/testing/sysfs-devices-platform-dock [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-system-cpu
Documentation/ABI/testing/sysfs-platform-dptf [new file with mode: 0644]
Documentation/PCI/pci.txt
Documentation/accelerators/ocxl.rst
Documentation/atomic_bitops.txt
Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt [new file with mode: 0644]
Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
Documentation/devicetree/bindings/dma/mv-xor-v2.txt
Documentation/devicetree/bindings/eeprom/at24.txt
Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt
Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
Documentation/devicetree/bindings/misc/arm-charlcd.txt [deleted file]
Documentation/devicetree/bindings/net/dsa/marvell.txt
Documentation/devicetree/bindings/net/renesas,ravb.txt
Documentation/devicetree/bindings/power/mti,mips-cpc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power/wakeup-source.txt
Documentation/devicetree/bindings/sound/ak4458.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/ak5558.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/da7219.txt
Documentation/devicetree/bindings/sound/dmic.txt
Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt [deleted file]
Documentation/devicetree/bindings/sound/max98090.txt
Documentation/devicetree/bindings/sound/maxim,max9759.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
Documentation/devicetree/bindings/sound/pcm1789.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
Documentation/devicetree/bindings/sound/rockchip,rk3288-hdmi-analog.txt
Documentation/devicetree/bindings/sound/rohm,bd28623.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/rt5651.txt
Documentation/devicetree/bindings/sound/rt5665.txt
Documentation/devicetree/bindings/sound/samsung,odroid.txt
Documentation/devicetree/bindings/sound/samsung,tm2-audio.txt
Documentation/devicetree/bindings/sound/samsung-i2s.txt
Documentation/devicetree/bindings/sound/sgtl5000.txt
Documentation/devicetree/bindings/sound/snow.txt
Documentation/devicetree/bindings/sound/st,stm32-sai.txt
Documentation/devicetree/bindings/sound/tda7419.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/uniphier,aio.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8524.txt
Documentation/devicetree/bindings/thermal/imx-thermal.txt
Documentation/devicetree/bindings/usb/dwc2.txt
Documentation/devicetree/bindings/usb/renesas_usb3.txt
Documentation/devicetree/bindings/usb/renesas_usbhs.txt
Documentation/devicetree/bindings/usb/usb-xhci.txt
Documentation/features/sched/membarrier-sync-core/arch-support.txt [new file with mode: 0644]
Documentation/gpu/tve200.rst
Documentation/i2c/busses/i2c-i801
Documentation/ia64/serial.txt
Documentation/locking/mutex-design.txt
Documentation/media/dmx.h.rst.exceptions
Documentation/media/uapi/dvb/dmx-qbuf.rst
Documentation/networking/segmentation-offloads.txt
Documentation/sphinx/kerneldoc.py
Documentation/virtual/kvm/api.txt
Documentation/virtual/kvm/cpuid.txt
Documentation/virtual/kvm/msr.txt
Documentation/x86/intel_rdt_ui.txt
Documentation/x86/topology.txt
MAINTAINERS
Makefile
arch/alpha/include/asm/cmpxchg.h
arch/alpha/include/asm/xchg.h
arch/arc/Kconfig
arch/arc/boot/dts/axs101.dts
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/boot/dts/haps_hs_idu.dts
arch/arc/boot/dts/nsim_700.dts
arch/arc/boot/dts/nsim_hs.dts
arch/arc/boot/dts/nsim_hs_idu.dts
arch/arc/boot/dts/nsimosci.dts
arch/arc/boot/dts/nsimosci_hs.dts
arch/arc/boot/dts/nsimosci_hs_idu.dts
arch/arc/include/asm/bug.h
arch/arc/include/asm/entry-arcv2.h
arch/arc/kernel/mcip.c
arch/arc/kernel/setup.c
arch/arc/kernel/smp.c
arch/arc/kernel/unwind.c
arch/arc/mm/cache.c
arch/arm/boot/dts/bcm11351.dtsi
arch/arm/boot/dts/bcm21664.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/bcm2836.dtsi
arch/arm/boot/dts/bcm2837.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/bcm958625hr.dts
arch/arm/boot/dts/gemini-dlink-dns-313.dts
arch/arm/boot/dts/imx6dl-icore-rqs.dts
arch/arm/boot/dts/logicpd-som-lv.dtsi
arch/arm/boot/dts/logicpd-torpedo-som.dtsi
arch/arm/boot/dts/omap5-uevm.dts
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk322x.dtsi
arch/arm/boot/dts/rk3288-phycore-som.dtsi
arch/arm/boot/dts/zx296702.dtsi
arch/arm/configs/omap2plus_defconfig
arch/arm/kernel/time.c
arch/arm/kvm/hyp/Makefile
arch/arm/kvm/hyp/banked-sr.c
arch/arm/mach-clps711x/board-dt.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-omap1/clock.c
arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/pm.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/tsx09-common.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/plat-orion/common.c
arch/arm64/boot/dts/amlogic/meson-axg.dtsi
arch/arm64/boot/dts/amlogic/meson-gx.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
arch/arm64/boot/dts/mediatek/mt8173.dtsi
arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3368.dtsi
arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/hugetlb.h
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/include/asm/mmu_context.h
arch/arm64/include/asm/pgalloc.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/stacktrace.h
arch/arm64/include/asm/uaccess.h
arch/arm64/kernel/armv8_deprecated.c
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/efi.c
arch/arm64/kernel/hibernate.c
arch/arm64/kernel/perf_event.c
arch/arm64/kernel/process.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/stacktrace.c
arch/arm64/kernel/sys_compat.c
arch/arm64/kernel/time.c
arch/arm64/kernel/traps.c
arch/arm64/kvm/guest.c
arch/arm64/kvm/hyp/switch.c
arch/arm64/mm/dump.c
arch/arm64/mm/fault.c
arch/arm64/mm/hugetlbpage.c
arch/arm64/mm/kasan_init.c
arch/arm64/mm/mmu.c
arch/arm64/mm/pageattr.c
arch/arm64/mm/proc.S
arch/arm64/net/bpf_jit_comp.c
arch/cris/include/arch-v10/arch/bug.h
arch/h8300/include/asm/byteorder.h
arch/ia64/include/asm/atomic.h
arch/ia64/include/asm/bug.h
arch/ia64/kernel/Makefile
arch/ia64/kernel/err_inject.c
arch/ia64/scripts/unwcheck.py
arch/m68k/include/asm/bug.h
arch/microblaze/Kconfig
arch/microblaze/Kconfig.platform
arch/microblaze/include/asm/setup.h
arch/microblaze/lib/fastcopy.S
arch/microblaze/mm/init.c
arch/mips/ath25/board.c
arch/mips/boot/Makefile
arch/mips/cavium-octeon/octeon-irq.c
arch/mips/include/asm/compat.h
arch/mips/kernel/mips-cpc.c
arch/mips/kernel/setup.c
arch/mips/kernel/smp-bmips.c
arch/mips/lantiq/Kconfig
arch/mips/lantiq/xway/sysctrl.c
arch/mips/loongson64/Kconfig
arch/mips/ralink/mt7621.c
arch/mips/ralink/reset.c
arch/parisc/include/asm/cacheflush.h
arch/parisc/include/asm/processor.h
arch/parisc/kernel/cache.c
arch/parisc/kernel/head.S
arch/parisc/kernel/pacache.S
arch/parisc/kernel/smp.c
arch/parisc/kernel/time.c
arch/parisc/mm/init.c
arch/powerpc/boot/Makefile
arch/powerpc/include/asm/book3s/32/pgtable.h
arch/powerpc/include/asm/book3s/64/hash-4k.h
arch/powerpc/include/asm/book3s/64/hash-64k.h
arch/powerpc/include/asm/book3s/64/hash.h
arch/powerpc/include/asm/book3s/64/pgalloc.h
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/include/asm/firmware.h
arch/powerpc/include/asm/hw_irq.h
arch/powerpc/include/asm/kexec.h
arch/powerpc/include/asm/nohash/32/pgtable.h
arch/powerpc/include/asm/nohash/64/pgtable.h
arch/powerpc/include/asm/topology.h
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_xive.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/mm/drmem.c
arch/powerpc/mm/hash64_4k.c
arch/powerpc/mm/hash64_64k.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/hugetlbpage-hash64.c
arch/powerpc/mm/init-common.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable-radix.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/tlb_hash64.c
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/net/bpf_jit_comp64.c
arch/powerpc/platforms/powernv/opal-imc.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/setup.c
arch/powerpc/platforms/powernv/vas-window.c
arch/powerpc/platforms/pseries/hotplug-cpu.c
arch/powerpc/platforms/pseries/ras.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/xive/spapr.c
arch/riscv/Kconfig
arch/riscv/include/asm/barrier.h
arch/riscv/kernel/entry.S
arch/riscv/kernel/head.S
arch/riscv/kernel/setup.c
arch/s390/include/asm/mmu_context.h
arch/s390/kernel/entry.S
arch/s390/kernel/nospec-branch.c
arch/s390/kvm/intercept.c
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/kvm-s390.h
arch/s390/kvm/priv.c
arch/s390/kvm/vsie.c
arch/sh/boot/dts/Makefile
arch/sparc/Kconfig
arch/sparc/include/asm/bug.h
arch/sparc/mm/tlb.c
arch/x86/.gitignore
arch/x86/Kconfig
arch/x86/Kconfig.cpu
arch/x86/Makefile
arch/x86/boot/compressed/eboot.c
arch/x86/boot/compressed/misc.c
arch/x86/crypto/sha512-mb/sha512_mb_mgr_init_avx2.c
arch/x86/entry/calling.h
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/entry/entry_64_compat.S
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/vdso/vdso32/vclock_gettime.c
arch/x86/entry/vsyscall/vsyscall_64.c
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/ds.c
arch/x86/events/intel/lbr.c
arch/x86/events/intel/p6.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/events/perf_event.h
arch/x86/ia32/sys_ia32.c
arch/x86/include/asm/acpi.h
arch/x86/include/asm/apm.h
arch/x86/include/asm/asm-prototypes.h
arch/x86/include/asm/barrier.h
arch/x86/include/asm/bitops.h
arch/x86/include/asm/bug.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/efi.h
arch/x86/include/asm/io.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/microcode.h
arch/x86/include/asm/mmu_context.h
arch/x86/include/asm/nospec-branch.h
arch/x86/include/asm/page_64.h
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/percpu.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/pgtable_32.h
arch/x86/include/asm/pgtable_64.h
arch/x86/include/asm/pgtable_types.h
arch/x86/include/asm/platform_sst_audio.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/refcount.h
arch/x86/include/asm/rmwcc.h
arch/x86/include/asm/sections.h
arch/x86/include/asm/smp.h
arch/x86/include/asm/sys_ia32.h
arch/x86/include/asm/tlbflush.h
arch/x86/include/asm/vmx.h
arch/x86/include/uapi/asm/hyperv.h
arch/x86/include/uapi/asm/kvm_para.h
arch/x86/include/uapi/asm/mce.h
arch/x86/kernel/amd_nb.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/vector.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/asm-offsets_32.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/centaur.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cyrix.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/intel_rdt.c
arch/x86/kernel/cpu/intel_rdt_rdtgroup.c
arch/x86/kernel/cpu/mcheck/mce-internal.h
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/microcode/amd.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/microcode/intel.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/cpu/proc.c
arch/x86/kernel/head_32.S
arch/x86/kernel/head_64.S
arch/x86/kernel/idt.c
arch/x86/kernel/ioport.c
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/kvm.c
arch/x86/kernel/machine_kexec_64.c
arch/x86/kernel/module.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/pci-nommu.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/signal_compat.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/traps.c
arch/x86/kernel/unwind_orc.c
arch/x86/kernel/vm86_32.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/kvm/cpuid.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/lib/Makefile
arch/x86/lib/cpu.c
arch/x86/lib/error-inject.c
arch/x86/lib/retpoline.S
arch/x86/mm/cpu_entry_area.c
arch/x86/mm/fault.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/kmmio.c
arch/x86/mm/mem_encrypt_boot.S
arch/x86/mm/pgtable.c
arch/x86/mm/pgtable_32.c
arch/x86/mm/pti.c
arch/x86/mm/tlb.c
arch/x86/net/bpf_jit_comp.c
arch/x86/oprofile/nmi_int.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/intel-mid/intel-mid.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/realmode/rm/trampoline_64.S
arch/x86/tools/relocs.c
arch/x86/um/asm/barrier.h
arch/x86/xen/enlighten_pv.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/smp.c
arch/x86/xen/suspend.c
arch/xtensa/kernel/pci-dma.c
arch/xtensa/mm/init.c
block/blk-cgroup.c
block/blk-core.c
block/blk-mq.c
block/genhd.c
block/ioctl.c
block/kyber-iosched.c
block/mq-deadline.c
block/partition-generic.c
block/sed-opal.c
certs/blacklist_nohashes.c
crypto/asymmetric_keys/pkcs7_trust.c
crypto/asymmetric_keys/pkcs7_verify.c
crypto/asymmetric_keys/public_key.c
crypto/asymmetric_keys/restrict.c
crypto/sha3_generic.c
drivers/acpi/acpi_watchdog.c
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/ec.c
drivers/acpi/nfit/core.c
drivers/acpi/numa.c
drivers/acpi/property.c
drivers/acpi/spcr.c
drivers/android/binder.c
drivers/ata/ahci.c
drivers/ata/libahci.c
drivers/ata/libahci_platform.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/sata_rcar.c
drivers/auxdisplay/img-ascii-lcd.c
drivers/auxdisplay/panel.c
drivers/base/core.c
drivers/base/power/wakeirq.c
drivers/base/property.c
drivers/block/amiflop.c
drivers/block/ataflop.c
drivers/block/brd.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/nbd.c
drivers/block/pktcdvd.c
drivers/block/swim.c
drivers/block/xen-blkfront.c
drivers/block/z2ram.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_bcm.c
drivers/bus/ti-sysc.c
drivers/char/hw_random/via-rng.c
drivers/char/tpm/st33zp24/st33zp24.c
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm2-cmd.c
drivers/char/tpm/tpm_i2c_infineon.c
drivers/char/tpm/tpm_i2c_nuvoton.c
drivers/char/tpm/tpm_tis_core.c
drivers/clk/bcm/clk-bcm2835.c
drivers/clk/clk-aspeed.c
drivers/clk/clk.c
drivers/clk/hisilicon/clk-hi3660-stub.c
drivers/clk/imx/clk-imx51-imx53.c
drivers/clk/qcom/apcs-msm8916.c
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/ti/clk-33xx.c
drivers/clk/ti/clk-43xx.c
drivers/clk/ti/clkctrl.c
drivers/clocksource/Kconfig
drivers/clocksource/arc_timer.c
drivers/clocksource/fsl_ftm_timer.c
drivers/clocksource/mips-gic-timer.c
drivers/clocksource/timer-sun5i.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/longhaul.c
drivers/cpufreq/p4-clockmod.c
drivers/cpufreq/powernow-k7.c
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpufreq/scpi-cpufreq.c
drivers/cpufreq/speedstep-centrino.c
drivers/cpufreq/speedstep-lib.c
drivers/crypto/caam/ctrl.c
drivers/crypto/ccp/psp-dev.c
drivers/crypto/padlock-aes.c
drivers/crypto/s5p-sss.c
drivers/crypto/sunxi-ss/sun4i-ss-prng.c
drivers/crypto/talitos.c
drivers/dax/super.c
drivers/dma/mv_xor_v2.c
drivers/dma/sh/rcar-dmac.c
drivers/dma/stm32-dmamux.c
drivers/edac/amd64_edac.c
drivers/edac/sb_edac.c
drivers/extcon/extcon-axp288.c
drivers/extcon/extcon-intel-int3496.c
drivers/firmware/dcdbas.c
drivers/firmware/efi/libstub/tpm.c
drivers/gpio/gpio-rcar.c
drivers/gpio/gpiolib-of.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
drivers/gpu/drm/amd/amdgpu/atombios_encoders.h
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/amdgpu/si.c
drivers/gpu/drm/amd/amdgpu/si_dpm.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_stream.h
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c
drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
drivers/gpu/drm/amd/display/include/signal_types.h
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/ast/ast_tables.h
drivers/gpu/drm/cirrus/cirrus_mode.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_framebuffer.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/drm_probe_helper.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_rotator.h [deleted file]
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/regs-fimc.h
drivers/gpu/drm/exynos/regs-hdmi.h
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/kvmgt.c
drivers/gpu/drm/i915/gvt/mmio_context.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/gvt/scheduler.h
drivers/gpu/drm/i915/gvt/trace.h
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_oa_cflgt3.c
drivers/gpu/drm/i915/i915_oa_cnl.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_pmu.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_sysfs.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_breadcrumbs.c
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_hangcheck.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/imx/ipuv3-crtc.c
drivers/gpu/drm/imx/ipuv3-plane.c
drivers/gpu/drm/meson/meson_crtc.c
drivers/gpu/drm/meson/meson_drv.h
drivers/gpu/drm/meson/meson_plane.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/scheduler/gpu_scheduler.c
drivers/gpu/drm/sun4i/sun4i_crtc.c
drivers/gpu/drm/sun4i/sun4i_dotclock.c
drivers/gpu/drm/sun4i/sun4i_drv.c
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
drivers/gpu/drm/sun4i/sun4i_rgb.c
drivers/gpu/drm/sun4i/sun4i_tcon.c
drivers/gpu/drm/sun4i/sun4i_tcon.h
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/dsi.c
drivers/gpu/drm/tegra/plane.c
drivers/gpu/drm/udl/udl_fb.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/gpu/drm/virtio/virtgpu_ioctl.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/ipu-v3/ipu-common.c
drivers/gpu/ipu-v3/ipu-cpmem.c
drivers/gpu/ipu-v3/ipu-csi.c
drivers/gpu/ipu-v3/ipu-pre.c
drivers/gpu/ipu-v3/ipu-prg.c
drivers/hid/hid-ids.h
drivers/hid/hid-quirks.c
drivers/hv/ring_buffer.c
drivers/hwmon/coretemp.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/k10temp.c
drivers/hwmon/k8temp.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-bcm2835.c
drivers/i2c/busses/i2c-designware-master.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-octeon-core.c
drivers/i2c/busses/i2c-octeon-core.h
drivers/i2c/busses/i2c-sirf.c
drivers/ide/ide-probe.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/aspeed_adc.c
drivers/iio/adc/meson_saradc.c
drivers/iio/adc/stm32-adc.c
drivers/iio/adc/stm32-dfsdm-adc.c
drivers/iio/adc/stm32-dfsdm-core.c
drivers/iio/chemical/ccs811.c
drivers/iio/imu/adis_trigger.c
drivers/iio/industrialio-buffer.c
drivers/iio/pressure/st_pressure_core.c
drivers/iio/proximity/Kconfig
drivers/infiniband/core/addr.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/core_priv.h
drivers/infiniband/core/cq.c
drivers/infiniband/core/device.c
drivers/infiniband/core/rdma_core.c
drivers/infiniband/core/restrack.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_ioctl.c
drivers/infiniband/core/uverbs_ioctl_merge.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/uverbs_std_types.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/bnxt_re/bnxt_re.h
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/bnxt_re/qplib_fp.h
drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/roce_hsi.h
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/cq.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/mlx5/srq.c
drivers/infiniband/hw/qedr/qedr_iw_cm.c
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
drivers/infiniband/sw/rdmavt/mr.c
drivers/infiniband/ulp/ipoib/ipoib_fs.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/mouse/synaptics.c
drivers/input/touchscreen/mms114.c
drivers/iommu/intel-svm.c
drivers/irqchip/irq-bcm7038-l1.c
drivers/irqchip/irq-bcm7120-l2.c
drivers/irqchip/irq-brcmstb-l2.c
drivers/irqchip/irq-gic-v2m.c
drivers/irqchip/irq-gic-v3-its-pci-msi.c
drivers/irqchip/irq-gic-v3-its-platform-msi.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-imx-gpcv2.c
drivers/irqchip/irq-mips-gic.c
drivers/macintosh/macio_asic.c
drivers/md/bcache/request.c
drivers/md/bcache/super.c
drivers/md/dm-bufio.c
drivers/md/dm-mpath.c
drivers/md/dm-raid.c
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/md-multipath.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid1.c
drivers/md/raid1.h
drivers/md/raid10.c
drivers/md/raid10.h
drivers/md/raid5-log.h
drivers/md/raid5-ppl.c
drivers/md/raid5.c
drivers/md/raid5.h
drivers/media/Kconfig
drivers/media/common/videobuf2/Kconfig
drivers/media/common/videobuf2/Makefile
drivers/media/common/videobuf2/vb2-trace.c [new file with mode: 0644]
drivers/media/dvb-core/Makefile
drivers/media/dvb-core/dmxdev.c
drivers/media/dvb-core/dvb_demux.c
drivers/media/dvb-core/dvb_net.c
drivers/media/dvb-core/dvb_vb2.c
drivers/media/dvb-frontends/m88ds3103.c
drivers/media/i2c/tvp5150.c
drivers/media/pci/ttpci/av7110.c
drivers/media/pci/ttpci/av7110_av.c
drivers/media/platform/tegra-cec/tegra_cec.c
drivers/media/usb/au0828/Kconfig
drivers/media/usb/ttusb-dec/ttusb_dec.c
drivers/media/v4l2-core/Kconfig
drivers/media/v4l2-core/Makefile
drivers/media/v4l2-core/vb2-trace.c [deleted file]
drivers/memory/brcmstb_dpfe.c
drivers/message/fusion/mptctl.c
drivers/misc/mei/bus.c
drivers/misc/mei/client.c
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/pci-me.c
drivers/misc/ocxl/file.c
drivers/mmc/core/block.c
drivers/mmc/core/card.h
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/quirks.h
drivers/mmc/host/bcm2835.c
drivers/mmc/host/dw_mmc-exynos.c
drivers/mmc/host/dw_mmc-k3.c
drivers/mmc/host/dw_mmc-rockchip.c
drivers/mmc/host/dw_mmc-zx.c
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/dw_mmc.h
drivers/mmc/host/meson-gx-mmc.c
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mtd/mtdchar.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/fsl_ifc_nand.c
drivers/mtd/nand/vf610_nfc.c
drivers/net/can/cc770/cc770.c
drivers/net/can/cc770/cc770.h
drivers/net/can/ifi_canfd/ifi_canfd.c
drivers/net/can/m_can/m_can.c
drivers/net/can/peak_canfd/peak_canfd.c
drivers/net/can/peak_canfd/peak_pciefd_main.c
drivers/net/dsa/Makefile
drivers/net/dsa/b53/b53_common.c
drivers/net/ethernet/8390/Kconfig
drivers/net/ethernet/amd/xgbe/xgbe-pci.c
drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.h
drivers/net/ethernet/aquantia/atlantic/aq_vec.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
drivers/net/ethernet/aquantia/atlantic/ver.h
drivers/net/ethernet/arc/emac_rockchip.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bcmsysport.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h
drivers/net/ethernet/cavium/common/cavium_ptp.c
drivers/net/ethernet/cavium/thunder/nicvf_main.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.c
drivers/net/ethernet/cavium/thunder/nicvf_queues.h
drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/cortina/gemini.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fman/fman_dtsec.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/e1000e/defines.h
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/mac.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/marvell/mvpp2.c
drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/health.c
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/natsemi/Kconfig
drivers/net/ethernet/natsemi/Makefile
drivers/net/ethernet/qlogic/qed/qed_cxt.c
drivers/net/ethernet/qlogic/qed/qed_iwarp.c
drivers/net/ethernet/qlogic/qed/qed_rdma.c
drivers/net/ethernet/qlogic/qede/qede_main.c
drivers/net/ethernet/qlogic/qede/qede_ptp.c
drivers/net/ethernet/qualcomm/emac/emac-mac.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/smsc/Kconfig
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/socionext/sni_ave.c
drivers/net/ethernet/sun/sunvnet.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/hyperv/hyperv_net.h
drivers/net/hyperv/netvsc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/macsec.c
drivers/net/macvlan.c
drivers/net/phy/bcm-phy-lib.c
drivers/net/phy/marvell.c
drivers/net/phy/micrel.c
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/phy/realtek.c
drivers/net/ppp/ppp_generic.c
drivers/net/team/team.c
drivers/net/thunderbolt.c
drivers/net/tun.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/r8152.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/wan/hdlc_ppp.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
drivers/net/wireless/intel/iwlwifi/Kconfig
drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
drivers/net/wireless/intel/iwlwifi/fw/debugfs.h
drivers/net/wireless/intel/iwlwifi/fw/init.c
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/tx.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
drivers/net/xen-netfront.c
drivers/nvdimm/blk.c
drivers/nvdimm/btt.c
drivers/nvdimm/pfn_devs.c
drivers/nvdimm/pmem.c
drivers/nvdimm/region_devs.c
drivers/nvme/host/core.c
drivers/nvme/host/fabrics.c
drivers/nvme/host/fabrics.h
drivers/nvme/host/fc.c
drivers/nvme/host/multipath.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/rdma.c
drivers/nvme/target/core.c
drivers/nvme/target/io-cmd.c
drivers/nvme/target/loop.c
drivers/of/property.c
drivers/opp/cpu.c
drivers/pci/dwc/pcie-designware-host.c
drivers/pci/quirks.c
drivers/pci/setup-res.c
drivers/perf/arm_pmu.c
drivers/perf/arm_pmu_acpi.c
drivers/perf/arm_pmu_platform.c
drivers/phy/qualcomm/phy-qcom-ufs.c
drivers/pinctrl/meson/pinctrl-meson-axg.c
drivers/pinctrl/samsung/pinctrl-exynos-arm.c
drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
drivers/pinctrl/samsung/pinctrl-s3c24xx.c
drivers/pinctrl/samsung/pinctrl-s3c64xx.c
drivers/pinctrl/samsung/pinctrl-samsung.c
drivers/pinctrl/samsung/pinctrl-samsung.h
drivers/pinctrl/sh-pfc/pfc-r8a7795.c
drivers/platform/chrome/chromeos_laptop.c
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/dell-smbios-base.c [new file with mode: 0644]
drivers/platform/x86/dell-smbios-smm.c
drivers/platform/x86/dell-smbios-wmi.c
drivers/platform/x86/dell-smbios.c [deleted file]
drivers/platform/x86/dell-smbios.h
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel-hid.c
drivers/platform/x86/intel-vbtn.c
drivers/platform/x86/wmi.c
drivers/regulator/core.c
drivers/regulator/stm32-vrefbuf.c
drivers/s390/block/dasd.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/io_sch.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3.h
drivers/s390/net/qeth_l3_main.c
drivers/s390/virtio/virtio_ccw.c
drivers/scsi/Makefile
drivers/scsi/aacraid/linit.c
drivers/scsi/aic7xxx/aiclib.c [deleted file]
drivers/scsi/bnx2fc/bnx2fc_io.c
drivers/scsi/csiostor/csio_lnode.c
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/hosts.c
drivers/scsi/ibmvscsi/ibmvfc.h
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/mpt3sas/mpt3sas_base.h
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/qedi/qedi_fw.c
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/qla4xxx/ql4_def.h
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/sd_zbc.c
drivers/scsi/storvsc_drv.c
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/scsi/ufs/ufshcd.c
drivers/soc/fsl/qbman/qman.c
drivers/soc/imx/gpc.c
drivers/staging/android/ashmem.c
drivers/staging/android/ion/ion_cma_heap.c
drivers/staging/comedi/drivers.c
drivers/staging/fsl-mc/bus/Kconfig
drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/impedance-analyzer/ad5933.c
drivers/staging/ncpfs/ncplib_kernel.c
drivers/tty/n_tty.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/imx.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sh-sci.c
drivers/tty/tty_io.c
drivers/tty/vt/vt.c
drivers/usb/Kconfig
drivers/usb/class/cdc-acm.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/params.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/dwc3-of-simple.c
drivers/usb/dwc3/dwc3-omap.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/udc/Kconfig
drivers/usb/gadget/udc/bdc/bdc_pci.c
drivers/usb/gadget/udc/core.c
drivers/usb/gadget/udc/fsl_udc_core.c
drivers/usb/gadget/udc/renesas_usb3.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-q.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/pci-quirks.h
drivers/usb/host/xhci-dbgcap.c
drivers/usb/host/xhci-dbgtty.c
drivers/usb/host/xhci-debugfs.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-rcar.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/ldusb.c
drivers/usb/mon/mon_text.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_host.c
drivers/usb/phy/phy-mxs-usb.c
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/serial/option.c
drivers/usb/storage/uas.c
drivers/usb/storage/unusual_devs.h
drivers/usb/typec/fusb302/fusb302.c
drivers/usb/typec/tcpm.c
drivers/usb/usbip/stub_dev.c
drivers/usb/usbip/vhci_hcd.c
drivers/usb/usbip/vudc_sysfs.c
drivers/vfio/pci/vfio_pci.c
drivers/vfio/vfio_iommu_type1.c
drivers/vhost/net.c
drivers/video/fbdev/geode/video_gx.c
drivers/video/fbdev/sbuslib.c
drivers/virtio/virtio_ring.c
drivers/watchdog/Kconfig
drivers/watchdog/f71808e_wdt.c
drivers/watchdog/hpwdt.c
drivers/watchdog/sbsa_gwdt.c
drivers/watchdog/wdat_wdt.c
drivers/xen/events/events_base.c
drivers/xen/pvcalls-back.c
drivers/xen/pvcalls-front.c
drivers/xen/tmem.c
drivers/xen/xenbus/xenbus.h
drivers/xen/xenbus/xenbus_comms.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_xs.c
fs/aio.c
fs/block_dev.c
fs/btrfs/backref.c
fs/btrfs/ctree.h
fs/btrfs/delayed-ref.c
fs/btrfs/extent-tree.c
fs/btrfs/inode-item.c
fs/btrfs/inode.c
fs/btrfs/qgroup.c
fs/btrfs/raid56.c
fs/btrfs/relocation.c
fs/btrfs/send.c
fs/btrfs/super.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/super.c
fs/ceph/super.h
fs/dcache.c
fs/direct-io.c
fs/efivarfs/file.c
fs/gfs2/bmap.c
fs/hugetlbfs/inode.c
fs/namei.c
fs/nfs/callback_proc.c
fs/nfs/direct.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4client.c
fs/nfs/pnfs.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs4state.c
fs/overlayfs/Kconfig
fs/overlayfs/export.c
fs/overlayfs/inode.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c
fs/proc/kcore.c
fs/signalfd.c
fs/sysfs/symlink.c
fs/xfs/scrub/agheader.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_refcount_item.c
fs/xfs/xfs_rmap_item.c
fs/xfs/xfs_super.c
include/asm-generic/bitops/lock.h
include/asm-generic/bug.h
include/asm-generic/pgtable.h
include/drm/drm_atomic.h
include/drm/drm_crtc_helper.h
include/drm/drm_drv.h
include/dt-bindings/sound/rt5651.h [new file with mode: 0644]
include/kvm/arm_vgic.h
include/linux/acpi.h
include/linux/bio.h
include/linux/blkdev.h
include/linux/cgroup-defs.h
include/linux/compat.h
include/linux/compiler-clang.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/cpuidle.h
include/linux/cpumask.h
include/linux/dma-mapping.h
include/linux/fs.h
include/linux/fsl_ifc.h
include/linux/fwnode.h
include/linux/genhd.h
include/linux/if_tun.h
include/linux/if_vlan.h
include/linux/init.h
include/linux/irqchip/arm-gic-v3.h
include/linux/irqchip/arm-gic.h
include/linux/jump_label.h
include/linux/kconfig.h
include/linux/kcore.h
include/linux/kernel.h
include/linux/kvm_host.h
include/linux/memblock.h
include/linux/memcontrol.h
include/linux/mlx5/driver.h
include/linux/mm_inline.h
include/linux/mutex.h
include/linux/net.h
include/linux/netfilter/x_tables.h
include/linux/nospec.h
include/linux/of_pci.h
include/linux/percpu-refcount.h
include/linux/perf/arm_pmu.h
include/linux/phy.h
include/linux/property.h
include/linux/ptr_ring.h
include/linux/rhashtable.h
include/linux/sched/mm.h
include/linux/sched/user.h
include/linux/semaphore.h
include/linux/skbuff.h
include/linux/swap.h
include/linux/tty.h
include/linux/u64_stats_sync.h
include/linux/usb/quirks.h
include/linux/workqueue.h
include/media/demux.h
include/media/dmxdev.h
include/media/dvb_demux.h
include/media/dvb_vb2.h
include/net/devlink.h
include/net/ip.h
include/net/ip6_route.h
include/net/ip_fib.h
include/net/mac80211.h
include/net/regulatory.h
include/net/route.h
include/net/sch_generic.h
include/net/sock.h
include/net/udplite.h
include/rdma/ib_verbs.h
include/rdma/restrack.h
include/rdma/uverbs_ioctl.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_host.h
include/soc/arc/mcip.h
include/sound/ac97/regs.h
include/sound/da7219.h
include/sound/dmaengine_pcm.h
include/sound/hdaudio.h
include/sound/rt5651.h [deleted file]
include/sound/rt5659.h
include/sound/soc-dapm.h
include/sound/soc.h
include/trace/events/mmc.h
include/trace/events/xen.h
include/uapi/asm-generic/siginfo.h
include/uapi/drm/virtgpu_drm.h
include/uapi/linux/blktrace_api.h
include/uapi/linux/dvb/dmx.h
include/uapi/linux/if_ether.h
include/uapi/linux/kvm.h
include/uapi/linux/libc-compat.h
include/uapi/linux/lirc.h
include/uapi/linux/psp-sev.h
include/uapi/linux/ptrace.h
include/uapi/linux/usb/audio.h
include/uapi/misc/ocxl.h
include/uapi/rdma/rdma_user_ioctl.h
include/uapi/sound/asound.h
init/main.c
ipc/mqueue.c
kernel/bpf/arraymap.c
kernel/bpf/core.c
kernel/bpf/cpumap.c
kernel/bpf/lpm_trie.c
kernel/bpf/sockmap.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/cgroup/cgroup.c
kernel/compat.c
kernel/events/core.c
kernel/extable.c
kernel/fail_function.c
kernel/fork.c
kernel/irq/irqdomain.c
kernel/irq/matrix.c
kernel/jump_label.c
kernel/kprobes.c
kernel/locking/mutex.c
kernel/locking/qspinlock.c
kernel/locking/rtmutex.c
kernel/memremap.c
kernel/module.c
kernel/panic.c
kernel/printk/printk.c
kernel/relay.c
kernel/sched/core.c
kernel/sched/cpufreq_schedutil.c
kernel/sched/deadline.c
kernel/sched/debug.c
kernel/sched/rt.c
kernel/seccomp.c
kernel/time/posix-timers.c
kernel/time/timer.c
kernel/trace/bpf_trace.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_probe.c
kernel/trace/trace_probe.h
kernel/user.c
kernel/workqueue.c
lib/Kconfig.debug
lib/btree.c
lib/bug.c
lib/dma-debug.c
lib/dma-direct.c
lib/idr.c
lib/ioremap.c
lib/percpu-refcount.c
lib/radix-tree.c
lib/rhashtable.c
lib/test_bpf.c
lib/test_kmod.c
lib/test_rhashtable.c
lib/vsprintf.c
mm/gup.c
mm/huge_memory.c
mm/hugetlb.c
mm/khugepaged.c
mm/memblock.c
mm/memory-failure.c
mm/memory.c
mm/mempolicy.c
mm/mlock.c
mm/page_alloc.c
mm/percpu-km.c
mm/percpu-vm.c
mm/percpu.c
mm/shmem.c
mm/swap.c
mm/vmalloc.c
mm/vmscan.c
mm/zpool.c
mm/zswap.c
net/8021q/vlan_core.c
net/9p/trans_virtio.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bat_v.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/distributed-arp-table.c
net/batman-adv/fragmentation.c
net/batman-adv/hard-interface.c
net/batman-adv/icmp_socket.c
net/batman-adv/log.c
net/batman-adv/multicast.c
net/batman-adv/originator.c
net/batman-adv/originator.h
net/batman-adv/routing.c
net/batman-adv/soft-interface.c
net/batman-adv/types.h
net/bluetooth/smp.c
net/bridge/br_netfilter_hooks.c
net/bridge/br_sysfs_if.c
net/bridge/br_vlan.c
net/bridge/netfilter/ebt_among.c
net/bridge/netfilter/ebt_limit.c
net/bridge/netfilter/ebtables.c
net/ceph/ceph_common.c
net/core/dev.c
net/core/dev_ioctl.c
net/core/devlink.c
net/core/ethtool.c
net/core/filter.c
net/core/gen_estimator.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/dccp/proto.c
net/decnet/af_decnet.c
net/dsa/legacy.c
net/ieee802154/6lowpan/core.c
net/ipv4/fib_semantics.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/ip_forward.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_rpfilter.c
net/ipv4/netfilter/nf_flow_table_ipv4.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_illinois.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_policy.c
net/ipv6/datagram.c
net/ipv6/ip6_checksum.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/netfilter.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/ip6t_rpfilter.c
net/ipv6/netfilter/ip6t_srh.c
net/ipv6/netfilter/nf_flow_table_ipv6.c
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
net/ipv6/netfilter/nft_fib_ipv6.c
net/ipv6/route.c
net/ipv6/seg6_iptunnel.c
net/ipv6/sit.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_policy.c
net/iucv/af_iucv.c
net/kcm/kcmsock.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/l2tp/l2tp_ppp.c
net/mac80211/agg-rx.c
net/mac80211/cfg.c
net/mac80211/debugfs.c
net/mac80211/ieee80211_i.h
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/spectmgmt.c
net/mac80211/sta_info.c
net/mac80211/tx.c
net/mpls/af_mpls.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/nf_nat_proto_common.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_set_hash.c
net/netfilter/x_tables.c
net/netfilter/xt_AUDIT.c
net/netfilter/xt_CHECKSUM.c
net/netfilter/xt_CONNSECMARK.c
net/netfilter/xt_CT.c
net/netfilter/xt_DSCP.c
net/netfilter/xt_HL.c
net/netfilter/xt_HMARK.c
net/netfilter/xt_IDLETIMER.c
net/netfilter/xt_LED.c
net/netfilter/xt_NFQUEUE.c
net/netfilter/xt_SECMARK.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_TPROXY.c
net/netfilter/xt_addrtype.c
net/netfilter/xt_bpf.c
net/netfilter/xt_cgroup.c
net/netfilter/xt_cluster.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connlabel.c
net/netfilter/xt_connmark.c
net/netfilter/xt_conntrack.c
net/netfilter/xt_dscp.c
net/netfilter/xt_ecn.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_helper.c
net/netfilter/xt_ipcomp.c
net/netfilter/xt_ipvs.c
net/netfilter/xt_l2tp.c
net/netfilter/xt_limit.c
net/netfilter/xt_nat.c
net/netfilter/xt_nfacct.c
net/netfilter/xt_physdev.c
net/netfilter/xt_policy.c
net/netfilter/xt_recent.c
net/netfilter/xt_set.c
net/netfilter/xt_socket.c
net/netfilter/xt_state.c
net/netfilter/xt_time.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/nfc/llcp_commands.c
net/nfc/netlink.c
net/openvswitch/meter.c
net/qrtr/smd.c
net/rds/connection.c
net/rds/tcp_listen.c
net/rxrpc/output.c
net/rxrpc/recvmsg.c
net/sched/act_bpf.c
net/sched/act_csum.c
net/sched/act_ipt.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_sample.c
net/sched/act_simple.c
net/sched/act_skbmod.c
net/sched/act_tunnel_key.c
net/sched/act_vlan.c
net/sched/cls_api.c
net/sched/cls_u32.c
net/sched/sch_generic.c
net/sched/sch_netem.c
net/sched/sch_tbf.c
net/sctp/debug.c
net/sctp/input.c
net/sctp/inqueue.c
net/sctp/offload.c
net/sctp/stream.c
net/sctp/stream_interleave.c
net/smc/af_smc.c
net/smc/smc_cdc.c
net/smc/smc_close.c
net/smc/smc_core.c
net/smc/smc_llc.c
net/socket.c
net/tipc/bearer.c
net/tipc/bearer.h
net/tipc/group.c
net/tipc/net.c
net/tipc/net.h
net/tipc/netlink_compat.c
net/tipc/socket.c
net/tls/tls_main.c
net/unix/af_unix.c
net/wireless/Kconfig
net/wireless/mesh.c
net/wireless/sme.c
net/xfrm/xfrm_device.c
net/xfrm/xfrm_ipcomp.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_replay.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
samples/seccomp/Makefile
scripts/Makefile.build
scripts/Makefile.lib
scripts/basic/fixdep.c
scripts/bloat-o-meter
scripts/coccinelle/api/memdup.cocci
scripts/kallsyms.c
scripts/kconfig/confdata.c
scripts/kconfig/kxgettext.c
scripts/kconfig/lkc.h
scripts/kconfig/lxdialog/check-lxdialog.sh
scripts/kconfig/menu.c
scripts/kconfig/symbol.c
scripts/kconfig/util.c
scripts/kconfig/zconf.l
scripts/kconfig/zconf.y
scripts/link-vmlinux.sh
security/integrity/digsig.c
security/keys/big_key.c
sound/ac97/Kconfig
sound/core/control.c
sound/core/oss/pcm_oss.c
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_fifo.c
sound/core/seq/seq_memory.c
sound/core/seq/seq_memory.h
sound/core/seq/seq_prioq.c
sound/core/seq/seq_prioq.h
sound/core/seq/seq_queue.c
sound/drivers/aloop.c
sound/hda/hdac_device.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/amd/Kconfig
sound/soc/amd/Makefile
sound/soc/amd/acp-da7219-max98357a.c [new file with mode: 0644]
sound/soc/amd/acp-pcm-dma.c
sound/soc/amd/acp-rt5645.c
sound/soc/amd/acp.h
sound/soc/atmel/atmel-classd.c
sound/soc/atmel/atmel-pcm-pdc.c
sound/soc/atmel/atmel-pdmic.c
sound/soc/au1x/dbdma2.c
sound/soc/au1x/dma.c
sound/soc/bcm/cygnus-pcm.c
sound/soc/bcm/cygnus-ssp.c
sound/soc/blackfin/Kconfig [deleted file]
sound/soc/blackfin/Makefile [deleted file]
sound/soc/blackfin/bf5xx-ac97-pcm.c [deleted file]
sound/soc/blackfin/bf5xx-ac97.c [deleted file]
sound/soc/blackfin/bf5xx-ac97.h [deleted file]
sound/soc/blackfin/bf5xx-ad1836.c [deleted file]
sound/soc/blackfin/bf5xx-ad193x.c [deleted file]
sound/soc/blackfin/bf5xx-ad1980.c [deleted file]
sound/soc/blackfin/bf5xx-ad73311.c [deleted file]
sound/soc/blackfin/bf5xx-i2s-pcm.c [deleted file]
sound/soc/blackfin/bf5xx-i2s-pcm.h [deleted file]
sound/soc/blackfin/bf5xx-i2s.c [deleted file]
sound/soc/blackfin/bf5xx-sport.c [deleted file]
sound/soc/blackfin/bf5xx-sport.h [deleted file]
sound/soc/blackfin/bf5xx-ssm2602.c [deleted file]
sound/soc/blackfin/bf6xx-i2s.c [deleted file]
sound/soc/blackfin/bf6xx-sport.c [deleted file]
sound/soc/blackfin/bf6xx-sport.h [deleted file]
sound/soc/blackfin/bfin-eval-adau1373.c [deleted file]
sound/soc/blackfin/bfin-eval-adau1701.c [deleted file]
sound/soc/blackfin/bfin-eval-adau1x61.c [deleted file]
sound/soc/blackfin/bfin-eval-adau1x81.c [deleted file]
sound/soc/blackfin/bfin-eval-adav80x.c [deleted file]
sound/soc/codecs/88pm860x-codec.c
sound/soc/codecs/88pm860x-codec.h
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ac97.c
sound/soc/codecs/ad1836.c
sound/soc/codecs/ad193x-i2c.c
sound/soc/codecs/ad193x-spi.c
sound/soc/codecs/ad193x.c
sound/soc/codecs/ad1980.c
sound/soc/codecs/ad73311.c
sound/soc/codecs/adau1373.c
sound/soc/codecs/adau1701.c
sound/soc/codecs/adau1761.c
sound/soc/codecs/adau1781.c
sound/soc/codecs/adau17x1.c
sound/soc/codecs/adau17x1.h
sound/soc/codecs/adau1977-i2c.c
sound/soc/codecs/adau1977-spi.c
sound/soc/codecs/adau1977.c
sound/soc/codecs/adau7002.c
sound/soc/codecs/adav801.c
sound/soc/codecs/adav803.c
sound/soc/codecs/adav80x.c
sound/soc/codecs/ads117x.c
sound/soc/codecs/ak4104.c
sound/soc/codecs/ak4458.c [new file with mode: 0644]
sound/soc/codecs/ak4458.h [new file with mode: 0644]
sound/soc/codecs/ak4535.c
sound/soc/codecs/ak4554.c
sound/soc/codecs/ak4613.c
sound/soc/codecs/ak4641.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/ak4671.c
sound/soc/codecs/ak5386.c
sound/soc/codecs/ak5558.c [new file with mode: 0644]
sound/soc/codecs/ak5558.h [new file with mode: 0644]
sound/soc/codecs/alc5623.c
sound/soc/codecs/alc5632.c
sound/soc/codecs/arizona.c
sound/soc/codecs/arizona.h
sound/soc/codecs/bd28623.c [new file with mode: 0644]
sound/soc/codecs/bt-sco.c
sound/soc/codecs/cpcap.c [new file with mode: 0644]
sound/soc/codecs/cq93vc.c
sound/soc/codecs/cs35l32.c
sound/soc/codecs/cs35l33.c
sound/soc/codecs/cs35l34.c
sound/soc/codecs/cs35l35.c
sound/soc/codecs/cs4265.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/cs4271-i2c.c
sound/soc/codecs/cs4271-spi.c
sound/soc/codecs/cs4271.c
sound/soc/codecs/cs42l42.c
sound/soc/codecs/cs42l42.h
sound/soc/codecs/cs42l51-i2c.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l56.c
sound/soc/codecs/cs42l73.c
sound/soc/codecs/cs42xx8-i2c.c
sound/soc/codecs/cs42xx8.c
sound/soc/codecs/cs43130.c
sound/soc/codecs/cs43130.h
sound/soc/codecs/cs4349.c
sound/soc/codecs/cs47l24.c
sound/soc/codecs/cs53l30.c
sound/soc/codecs/cx20442.c
sound/soc/codecs/da7210.c
sound/soc/codecs/da7213.c
sound/soc/codecs/da7218.c
sound/soc/codecs/da7218.h
sound/soc/codecs/da7219-aad.c
sound/soc/codecs/da7219-aad.h
sound/soc/codecs/da7219.c
sound/soc/codecs/da7219.h
sound/soc/codecs/da732x.c
sound/soc/codecs/da9055.c
sound/soc/codecs/dmic.c
sound/soc/codecs/es7134.c
sound/soc/codecs/es8316.c
sound/soc/codecs/es8328-i2c.c
sound/soc/codecs/es8328-spi.c
sound/soc/codecs/es8328.c
sound/soc/codecs/gtm601.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/hdac_hdmi.h
sound/soc/codecs/hdmi-codec.c
sound/soc/codecs/ics43432.c
sound/soc/codecs/inno_rk3036.c
sound/soc/codecs/isabelle.c
sound/soc/codecs/jz4740.c
sound/soc/codecs/lm49453.c
sound/soc/codecs/max9759.c [new file with mode: 0644]
sound/soc/codecs/max98088.c
sound/soc/codecs/max98090.c
sound/soc/codecs/max98090.h
sound/soc/codecs/max98095.c
sound/soc/codecs/max98095.h
sound/soc/codecs/max98357a.c
sound/soc/codecs/max98371.c
sound/soc/codecs/max98371.h
sound/soc/codecs/max98373.c
sound/soc/codecs/max9850.c
sound/soc/codecs/max9860.c
sound/soc/codecs/max9867.c
sound/soc/codecs/max9867.h
sound/soc/codecs/max98925.c
sound/soc/codecs/max98925.h
sound/soc/codecs/max98926.c
sound/soc/codecs/max98926.h
sound/soc/codecs/max98927.c
sound/soc/codecs/max98927.h
sound/soc/codecs/mc13783.c
sound/soc/codecs/ml26124.c
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/codecs/msm8916-wcd-digital.c
sound/soc/codecs/nau8540.c
sound/soc/codecs/nau8810.c
sound/soc/codecs/nau8824.c
sound/soc/codecs/nau8824.h
sound/soc/codecs/nau8825.c
sound/soc/codecs/nau8825.h
sound/soc/codecs/pcm1681.c
sound/soc/codecs/pcm1789-i2c.c [new file with mode: 0644]
sound/soc/codecs/pcm1789.c [new file with mode: 0644]
sound/soc/codecs/pcm1789.h [new file with mode: 0644]
sound/soc/codecs/pcm179x-i2c.c
sound/soc/codecs/pcm179x-spi.c
sound/soc/codecs/pcm179x.c
sound/soc/codecs/pcm179x.h
sound/soc/codecs/pcm186x-i2c.c
sound/soc/codecs/pcm186x-spi.c
sound/soc/codecs/pcm186x.c
sound/soc/codecs/pcm186x.h
sound/soc/codecs/pcm3008.c
sound/soc/codecs/pcm3168a.c
sound/soc/codecs/pcm5102a.c
sound/soc/codecs/pcm512x.c
sound/soc/codecs/rt274.c
sound/soc/codecs/rt286.c
sound/soc/codecs/rt286.h
sound/soc/codecs/rt298.c
sound/soc/codecs/rt298.h
sound/soc/codecs/rt5514-spi.c
sound/soc/codecs/rt5514.c
sound/soc/codecs/rt5514.h
sound/soc/codecs/rt5616.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/rt5640.c
sound/soc/codecs/rt5640.h
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5645.h
sound/soc/codecs/rt5651.c
sound/soc/codecs/rt5651.h
sound/soc/codecs/rt5659.c
sound/soc/codecs/rt5659.h
sound/soc/codecs/rt5660.c
sound/soc/codecs/rt5660.h
sound/soc/codecs/rt5663.c
sound/soc/codecs/rt5663.h
sound/soc/codecs/rt5665.c
sound/soc/codecs/rt5665.h
sound/soc/codecs/rt5670.c
sound/soc/codecs/rt5670.h
sound/soc/codecs/rt5677.c
sound/soc/codecs/rt5677.h
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/si476x.c
sound/soc/codecs/sirf-audio-codec.c
sound/soc/codecs/spdif_receiver.c
sound/soc/codecs/spdif_transmitter.c
sound/soc/codecs/ssm2518.c
sound/soc/codecs/ssm2602-i2c.c
sound/soc/codecs/ssm2602-spi.c
sound/soc/codecs/ssm2602.c
sound/soc/codecs/ssm4567.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/sta350.c
sound/soc/codecs/sta529.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/sti-sas.c
sound/soc/codecs/tas2552.c
sound/soc/codecs/tas5086.c
sound/soc/codecs/tas571x.c
sound/soc/codecs/tas5720.c
sound/soc/codecs/tas6424.c
sound/soc/codecs/tda7419.c [new file with mode: 0644]
sound/soc/codecs/tfa9879.c
sound/soc/codecs/tlv320aic23-i2c.c
sound/soc/codecs/tlv320aic23-spi.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic31xx.c
sound/soc/codecs/tlv320aic31xx.h
sound/soc/codecs/tlv320aic32x4.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/tscs42xx.c
sound/soc/codecs/twl4030.c
sound/soc/codecs/twl6040.c
sound/soc/codecs/twl6040.h
sound/soc/codecs/uda134x.c
sound/soc/codecs/uda1380.c
sound/soc/codecs/wl1273.c
sound/soc/codecs/wl1273.h
sound/soc/codecs/wm0010.c
sound/soc/codecs/wm1250-ev1.c
sound/soc/codecs/wm2000.c
sound/soc/codecs/wm2200.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm5100.h
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8350.h
sound/soc/codecs/wm8400.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8524.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8727.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8737.c
sound/soc/codecs/wm8741.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8770.c
sound/soc/codecs/wm8782.c
sound/soc/codecs/wm8804.c
sound/soc/codecs/wm8997.c
sound/soc/codecs/wm8998.c
sound/soc/codecs/wm9705.c
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/codecs/wm_adsp.c
sound/soc/codecs/wm_adsp.h
sound/soc/davinci/davinci-i2s.c
sound/soc/dwc/dwc-i2s.c
sound/soc/dwc/dwc-pcm.c
sound/soc/fsl/Kconfig
sound/soc/fsl/Makefile
sound/soc/fsl/fsl-asoc-card.c
sound/soc/fsl/fsl_asrc.c
sound/soc/fsl/fsl_asrc.h
sound/soc/fsl/fsl_asrc_dma.c
sound/soc/fsl/fsl_dma.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/fsl_ssi.h
sound/soc/fsl/fsl_utils.c
sound/soc/fsl/imx-pcm-fiq.c
sound/soc/fsl/imx-wm8962.c [deleted file]
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/wm1133-ev1.c
sound/soc/img/pistachio-internal-dac.c
sound/soc/intel/atom/sst-atom-controls.c
sound/soc/intel/atom/sst-mfld-platform-compress.c
sound/soc/intel/atom/sst-mfld-platform-pcm.c
sound/soc/intel/atom/sst-mfld-platform.h
sound/soc/intel/atom/sst/sst.c
sound/soc/intel/atom/sst/sst.h
sound/soc/intel/atom/sst/sst_acpi.c
sound/soc/intel/atom/sst/sst_drv_interface.c
sound/soc/intel/atom/sst/sst_pvt.c
sound/soc/intel/atom/sst/sst_stream.c
sound/soc/intel/baytrail/sst-baytrail-pcm.c
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/Makefile
sound/soc/intel/boards/bdw-rt5677.c
sound/soc/intel/boards/broadwell.c
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/byt-rt5640.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/bytcr_rt5651.c
sound/soc/intel/boards/cht_bsw_nau8824.c [new file with mode: 0644]
sound/soc/intel/boards/cht_bsw_rt5645.c
sound/soc/intel/boards/cht_bsw_rt5672.c
sound/soc/intel/boards/haswell.c
sound/soc/intel/boards/kbl_da7219_max98357a.c [new file with mode: 0644]
sound/soc/intel/boards/kbl_rt5663_max98927.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/boards/skl_nau88l25_max98357a.c
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
sound/soc/intel/boards/skl_rt286.c
sound/soc/intel/common/soc-acpi-intel-cht-match.c
sound/soc/intel/haswell/sst-haswell-ipc.h
sound/soc/intel/haswell/sst-haswell-pcm.c
sound/soc/intel/skylake/skl-debug.c
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-ssp-clk.c
sound/soc/intel/skylake/skl-sst-ipc.h
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl.c
sound/soc/intel/skylake/skl.h
sound/soc/kirkwood/kirkwood-dma.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/kirkwood/kirkwood.h
sound/soc/mediatek/common/mtk-afe-fe-dai.c
sound/soc/mediatek/common/mtk-afe-platform-driver.c
sound/soc/mediatek/common/mtk-afe-platform-driver.h
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
sound/soc/mediatek/mt8173/mt8173-max98090.c
sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
sound/soc/mediatek/mt8173/mt8173-rt5650.c
sound/soc/nuc900/nuc900-pcm.c
sound/soc/omap/ams-delta.c
sound/soc/omap/omap-abe-twl6040.c
sound/soc/omap/omap-pcm.c
sound/soc/pxa/mioa701_wm9713.c
sound/soc/pxa/mmp-pcm.c
sound/soc/pxa/mmp-sspa.c
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/pxa/ttc-dkb.c
sound/soc/qcom/lpass-platform.c
sound/soc/rockchip/Kconfig
sound/soc/rockchip/rk3288_hdmi_analog.c
sound/soc/rockchip/rk3399_gru_sound.c
sound/soc/rockchip/rockchip_rt5645.c
sound/soc/samsung/Makefile
sound/soc/samsung/i2s-regs.h
sound/soc/samsung/i2s.c
sound/soc/samsung/i2s.h
sound/soc/samsung/idma.c
sound/soc/samsung/lowland.c
sound/soc/samsung/odroid.c
sound/soc/samsung/snow.c
sound/soc/samsung/tm2_wm5110.c
sound/soc/sh/dma-sh7760.c
sound/soc/sh/fsi.c
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/src.c
sound/soc/sh/rcar/ssi.c
sound/soc/sh/siu.h
sound/soc/sh/siu_dai.c
sound/soc/sh/siu_pcm.c
sound/soc/sirf/sirf-usp.h
sound/soc/soc-ac97.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-generic-dmaengine-pcm.c
sound/soc/soc-io.c
sound/soc/soc-pcm.c
sound/soc/soc-topology.c
sound/soc/soc-utils.c
sound/soc/stm/stm32_adfsdm.c
sound/soc/stm/stm32_sai.c
sound/soc/stm/stm32_sai.h
sound/soc/stm/stm32_sai_sub.c
sound/soc/stm/stm32_spdifrx.c
sound/soc/sunxi/sun4i-codec.c
sound/soc/sunxi/sun4i-i2s.c
sound/soc/sunxi/sun8i-codec.c
sound/soc/txx9/txx9aclc.c
sound/soc/uniphier/Kconfig
sound/soc/uniphier/Makefile
sound/soc/uniphier/aio-compress.c [new file with mode: 0644]
sound/soc/uniphier/aio-core.c [new file with mode: 0644]
sound/soc/uniphier/aio-cpu.c [new file with mode: 0644]
sound/soc/uniphier/aio-dma.c [new file with mode: 0644]
sound/soc/uniphier/aio-ld11.c [new file with mode: 0644]
sound/soc/uniphier/aio-pxs2.c [new file with mode: 0644]
sound/soc/uniphier/aio-reg.h [new file with mode: 0644]
sound/soc/uniphier/aio.h [new file with mode: 0644]
sound/soc/uniphier/evea.c
sound/soc/xtensa/xtfpga-i2s.c
sound/usb/mixer.c
sound/usb/pcm.c
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/x86/intel_hdmi_audio.c
tools/arch/powerpc/include/uapi/asm/kvm.h
tools/arch/s390/include/uapi/asm/unistd.h [deleted file]
tools/arch/x86/include/asm/cpufeatures.h
tools/bpf/bpftool/common.c
tools/bpf/bpftool/main.c
tools/bpf/bpftool/prog.c
tools/cgroup/Makefile
tools/gpio/Makefile
tools/hv/Makefile
tools/iio/Makefile
tools/include/uapi/drm/i915_drm.h
tools/include/uapi/linux/if_link.h
tools/include/uapi/linux/kvm.h
tools/kvm/kvm_stat/kvm_stat
tools/kvm/kvm_stat/kvm_stat.txt
tools/laptop/freefall/Makefile
tools/leds/Makefile
tools/lib/bpf/libbpf.c
tools/objtool/builtin-check.c
tools/objtool/builtin-orc.c
tools/objtool/builtin.h
tools/objtool/check.c
tools/objtool/check.h
tools/perf/Documentation/perf-data.txt
tools/perf/Documentation/perf-kallsyms.txt
tools/perf/Makefile.perf
tools/perf/arch/s390/Makefile
tools/perf/arch/s390/entry/syscalls/mksyscalltbl
tools/perf/arch/s390/entry/syscalls/syscall.tbl [new file with mode: 0644]
tools/perf/builtin-c2c.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-stat.c
tools/perf/builtin-top.c
tools/perf/check-headers.sh
tools/perf/perf.h
tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/cortex-a53/other.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/mapfile.csv
tools/perf/tests/backward-ring-buffer.c
tools/perf/tests/shell/trace+probe_libc_inet_pton.sh
tools/perf/ui/browsers/annotate.c
tools/perf/ui/browsers/hists.c
tools/perf/ui/browsers/hists.h
tools/perf/util/auxtrace.c
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/hist.h
tools/perf/util/mmap.c
tools/perf/util/mmap.h
tools/perf/util/record.c
tools/perf/util/trigger.h
tools/perf/util/util.c
tools/power/acpi/Makefile.config
tools/scripts/Makefile.include
tools/spi/Makefile
tools/testing/radix-tree/idr-test.c
tools/testing/radix-tree/linux.c
tools/testing/radix-tree/linux/compiler_types.h [new file with mode: 0644]
tools/testing/radix-tree/linux/gfp.h
tools/testing/radix-tree/linux/slab.h
tools/testing/selftests/android/Makefile
tools/testing/selftests/bpf/.gitignore
tools/testing/selftests/bpf/test_maps.c
tools/testing/selftests/bpf/test_tcpbpf_kern.c
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc [new file with mode: 0644]
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc [new file with mode: 0644]
tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc [new file with mode: 0644]
tools/testing/selftests/futex/Makefile
tools/testing/selftests/memfd/Makefile
tools/testing/selftests/memfd/config [new file with mode: 0644]
tools/testing/selftests/memory-hotplug/Makefile
tools/testing/selftests/powerpc/alignment/alignment_handler.c
tools/testing/selftests/powerpc/mm/subpage_prot.c
tools/testing/selftests/powerpc/tm/Makefile
tools/testing/selftests/powerpc/tm/tm-trap.c
tools/testing/selftests/pstore/config
tools/testing/selftests/seccomp/seccomp_bpf.c
tools/testing/selftests/sync/Makefile
tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
tools/testing/selftests/vDSO/Makefile
tools/testing/selftests/vm/.gitignore
tools/testing/selftests/vm/run_vmtests
tools/testing/selftests/x86/Makefile
tools/testing/selftests/x86/entry_from_vm86.c
tools/testing/selftests/x86/mpx-mini-test.c
tools/testing/selftests/x86/protection_keys.c
tools/testing/selftests/x86/ptrace_syscall.c
tools/testing/selftests/x86/single_step_syscall.c
tools/testing/selftests/x86/test_mremap_vdso.c
tools/testing/selftests/x86/test_vdso.c
tools/testing/selftests/x86/test_vsyscall.c
tools/usb/Makefile
tools/vm/Makefile
tools/wmi/Makefile
virt/kvm/arm/arch_timer.c
virt/kvm/arm/arm.c
virt/kvm/arm/hyp/vgic-v3-sr.c
virt/kvm/arm/mmu.c
virt/kvm/arm/vgic/vgic-mmio.c
virt/kvm/arm/vgic/vgic-v2.c
virt/kvm/arm/vgic/vgic-v3.c
virt/kvm/arm/vgic/vgic.c
virt/kvm/arm/vgic/vgic.h
virt/kvm/kvm_main.c

index 705e09913dc237cd4eb79e269bc1a0d83ea52d99..1be78fd8163bd10677163ae10b36b874a4c615a4 100644 (file)
@@ -127,3 +127,7 @@ all.config
 
 # Kdevelop4
 *.kdev4
+
+#Automatically generated by ASN.1 compiler
+net/ipv4/netfilter/nf_nat_snmp_basic-asn1.c
+net/ipv4/netfilter/nf_nat_snmp_basic-asn1.h
index aa4296498859e49617cc7fc6f377c6dcb7a8f6c1..9ab0ef1dd1c72d2be0c3d68f8000b225f79df963 100644 (file)
 What:          /sys/class/ata_...
-Date:          August 2008
-Contact:       Gwendal Grignou<gwendal@google.com>
 Description:
-
-Provide a place in sysfs for storing the ATA topology of the system.  This allows
-retrieving various information about ATA objects.
+               Provide a place in sysfs for storing the ATA topology of the
+               system. This allows retrieving various information about ATA
+               objects.
 
 Files under /sys/class/ata_port
 -------------------------------
 
-       For each port, a directory ataX is created where X is the ata_port_id of
-       the port. The device parent is the ata host device.
+For each port, a directory ataX is created where X is the ata_port_id of the
+port. The device parent is the ata host device.
 
-idle_irq (read)
 
-       Number of IRQ received by the port while idle [some ata HBA only].
+What:          /sys/class/ata_port/ataX/nr_pmp_links
+What:          /sys/class/ata_port/ataX/idle_irq
+Date:          May, 2010
+KernelVersion: v2.6.37
+Contact:       Gwendal Grignou <gwendal@chromium.org>
+Description:
+               nr_pmp_links:   (RO) If a SATA Port Multiplier (PM) is
+                               connected, the number of links behind it.
 
-nr_pmp_links (read)
+               idle_irq:       (RO) Number of IRQ received by the port while
+                               idle [some ata HBA only].
 
-       If a SATA Port Multiplier (PM) is connected, number of link behind it.
+
+What:          /sys/class/ata_port/ataX/port_no
+Date:          May, 2013
+KernelVersion: v3.11
+Contact:       Gwendal Grignou <gwendal@chromium.org>
+Description:
+               (RO) Host local port number. While registering host controller,
+               port numbers are tracked based upon number of ports available on
+               the controller. This attribute is needed by udev for composing
+               persistent links in /dev/disk/by-path.
 
 Files under /sys/class/ata_link
 -------------------------------
 
-       Behind each port, there is a ata_link. If there is a SATA PM in the
-       topology, 15 ata_link objects are created.
-
-       If a link is behind a port, the directory name is linkX, where X is
-       ata_port_id of the port.
-       If a link is behind a PM, its name is linkX.Y where X is ata_port_id
-       of the parent port and Y the PM port.
+Behind each port, there is a ata_link. If there is a SATA PM in the topology, 15
+ata_link objects are created.
 
-hw_sata_spd_limit
+If a link is behind a port, the directory name is linkX, where X is ata_port_id
+of the port. If a link is behind a PM, its name is linkX.Y where X is
+ata_port_id of the parent port and Y the PM port.
 
-       Maximum speed supported by the connected SATA device.
 
-sata_spd_limit
+What:          /sys/class/ata_link/linkX[.Y]/hw_sata_spd_limit
+What:          /sys/class/ata_link/linkX[.Y]/sata_spd_limit
+What:          /sys/class/ata_link/linkX[.Y]/sata_spd
+Date:          May, 2010
+KernelVersion: v2.6.37
+Contact:       Gwendal Grignou <gwendal@chromium.org>
+Description:
+               hw_sata_spd_limit:      (RO) Maximum speed supported by the
+                                       connected SATA device.
 
-       Maximum speed imposed by libata.
+               sata_spd_limit:         (RO) Maximum speed imposed by libata.
 
-sata_spd
+               sata_spd:               (RO) Current speed of the link
+                                       eg. 1.5, 3 Gbps etc.
 
-       Current speed of the link [1.5, 3Gps,...].
 
 Files under /sys/class/ata_device
 ---------------------------------
 
-       Behind each link, up to two ata device are created.
-       The name of the directory is devX[.Y].Z where:
-       - X is ata_port_id of the port where the device is connected,
-       - Y the port of the PM if any, and
-       - Z the device id: for PATA, there is usually 2 devices [0,1],
-       only 1 for SATA.
-
-class
-       Device class. Can be "ata" for disk, "atapi" for packet device,
-       "pmp" for PM, or "none" if no device was found behind the link.
-
-dma_mode
+Behind each link, up to two ata devices are created.
+The name of the directory is devX[.Y].Z where:
+- X is ata_port_id of the port where the device is connected,
+- Y the port of the PM if any, and
+- Z the device id: for PATA, there is usually 2 devices [0,1], only 1 for SATA.
+
+
+What:          /sys/class/ata_device/devX[.Y].Z/spdn_cnt
+What:          /sys/class/ata_device/devX[.Y].Z/gscr
+What:          /sys/class/ata_device/devX[.Y].Z/ering
+What:          /sys/class/ata_device/devX[.Y].Z/id
+What:          /sys/class/ata_device/devX[.Y].Z/pio_mode
+What:          /sys/class/ata_device/devX[.Y].Z/xfer_mode
+What:          /sys/class/ata_device/devX[.Y].Z/dma_mode
+What:          /sys/class/ata_device/devX[.Y].Z/class
+Date:          May, 2010
+KernelVersion: v2.6.37
+Contact:       Gwendal Grignou <gwendal@chromium.org>
+Description:
+               spdn_cnt:       (RO) Number of times libata decided to lower the
+                               speed of link due to errors.
 
-       Transfer modes supported by the device when in DMA mode.
-       Mostly used by PATA device.
+               gscr:           (RO) Cached result of the dump of PM GSCR
+                               register. Valid registers are:
 
-pio_mode
+                               0:      SATA_PMP_GSCR_PROD_ID,
+                               1:      SATA_PMP_GSCR_REV,
+                               2:      SATA_PMP_GSCR_PORT_INFO,
+                               32:     SATA_PMP_GSCR_ERROR,
+                               33:     SATA_PMP_GSCR_ERROR_EN,
+                               64:     SATA_PMP_GSCR_FEAT,
+                               96:     SATA_PMP_GSCR_FEAT_EN,
+                               130:    SATA_PMP_GSCR_SII_GPIO
 
-       Transfer modes supported by the device when in PIO mode.
-       Mostly used by PATA device.
+                               Only valid if the device is a PM.
 
-xfer_mode
+               ering:          (RO) Formatted output of the error ring of the
+                               device.
 
-       Current transfer mode.
+               id:             (RO) Cached result of IDENTIFY command, as
+                               described in ATA8 7.16 and 7.17. Only valid if
+                               the device is not a PM.
 
-id
+               pio_mode:       (RO) Transfer modes supported by the device when
+                               in PIO mode. Mostly used by PATA device.
 
-       Cached result of IDENTIFY command, as described in ATA8 7.16 and 7.17.
-       Only valid if the device is not a PM.
+               xfer_mode:      (RO) Current transfer mode
 
-gscr
+               dma_mode:       (RO) Transfer modes supported by the device when
+                               in DMA mode. Mostly used by PATA device.
 
-       Cached result of the dump of PM GSCR register.
-       Valid registers are:
-       0:      SATA_PMP_GSCR_PROD_ID,
-       1:      SATA_PMP_GSCR_REV,
-       2:      SATA_PMP_GSCR_PORT_INFO,
-       32:     SATA_PMP_GSCR_ERROR,
-       33:     SATA_PMP_GSCR_ERROR_EN,
-       64:     SATA_PMP_GSCR_FEAT,
-       96:     SATA_PMP_GSCR_FEAT_EN,
-       130:    SATA_PMP_GSCR_SII_GPIO
-       Only valid if the device is a PM.
+               class:          (RO) Device class. Can be "ata" for disk,
+                               "atapi" for packet device, "pmp" for PM, or
+                               "none" if no device was found behind the link.
 
-trim
 
-       Shows the DSM TRIM mode currently used by the device. Valid
-       values are:
-       unsupported:            Drive does not support DSM TRIM
-       unqueued:               Drive supports unqueued DSM TRIM only
-       queued:                 Drive supports queued DSM TRIM
-       forced_unqueued:        Drive's queued DSM support is known to be
-                               buggy and only unqueued TRIM commands
-                               are sent
+What:          /sys/class/ata_device/devX[.Y].Z/trim
+Date:          May, 2015
+KernelVersion: v4.10
+Contact:       Gwendal Grignou <gwendal@chromium.org>
+Description:
+               (RO) Shows the DSM TRIM mode currently used by the device. Valid
+               values are:
 
-spdn_cnt
+               unsupported:            Drive does not support DSM TRIM
 
-       Number of time libata decided to lower the speed of link due to errors.
+               unqueued:               Drive supports unqueued DSM TRIM only
 
-ering
+               queued:                 Drive supports queued DSM TRIM
 
-       Formatted output of the error ring of the device.
+               forced_unqueued:        Drive's queued DSM support is known to
+                                       be buggy and only unqueued TRIM commands
+                                       are sent
diff --git a/Documentation/ABI/testing/sysfs-block-device b/Documentation/ABI/testing/sysfs-block-device
new file mode 100644 (file)
index 0000000..82ef6ea
--- /dev/null
@@ -0,0 +1,58 @@
+What:          /sys/block/*/device/sw_activity
+Date:          Jun, 2008
+KernelVersion: v2.6.27
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RW) Used by drivers which support software controlled activity
+               LEDs.
+
+               It has the following valid values:
+
+               0       OFF - the LED is not activated on activity
+               1       BLINK_ON - the LED blinks on every 10ms when activity is
+                       detected.
+               2       BLINK_OFF - the LED is on when idle, and blinks off
+                       every 10ms when activity is detected.
+
+               Note that the user must turn sw_activity OFF it they wish to
+               control the activity LED via the em_message file.
+
+
+What:          /sys/block/*/device/unload_heads
+Date:          Sep, 2008
+KernelVersion: v2.6.28
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RW) Hard disk shock protection
+
+               Writing an integer value to this file will take the heads of the
+               respective drive off the platter and block all I/O operations
+               for the specified number of milliseconds.
+
+               - If the device does not support the unload heads feature,
+                 access is denied with -EOPNOTSUPP.
+               - The maximal value accepted for a timeout is 30000
+                 milliseconds.
+               - A previously set timeout can be cancelled and disk can resume
+                 normal operation immediately by specifying a timeout of 0.
+               - Some hard drives only comply with an earlier version of the
+                 ATA standard, but support the unload feature nonetheless.
+                 There is no safe way Linux can detect these devices, so this
+                 is not enabled by default. If it is known that your device
+                 does support the unload feature, then you can tell the kernel
+                 to enable it by writing -1. It can be disabled again by
+                 writing -2.
+               - Values below -2 are rejected with -EINVAL
+
+               For more information, see
+               Documentation/laptops/disk-shock-protection.txt
+
+
+What:          /sys/block/*/device/ncq_prio_enable
+Date:          Oct, 2016
+KernelVersion: v4.10
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RW) Write to the file to turn on or off the SATA ncq (native
+               command queueing) support. By default this feature is turned
+               off.
index 0eb255e7db123c84ebcd08d04f2cd867ee6bffa0..bafc59fd7b69ec355d6631681e3471195b0ae5ca 100644 (file)
@@ -27,3 +27,92 @@ Description: This file contains the current status of the "SSD Smart Path"
                the direct i/o path to physical devices.  This setting is
                controller wide, affecting all configured logical drives on the
                controller.  This file is readable and writable.
+
+What:          /sys/class/scsi_host/hostX/link_power_management_policy
+Date:          Oct, 2007
+KernelVersion: v2.6.24
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RW) This parameter allows the user to read and set the link
+               (interface) power management.
+
+               There are four possible options:
+
+               min_power: Tell the controller to try to make the link use the
+               least possible power when possible. This may sacrifice some
+               performance due to increased latency when coming out of lower
+               power states.
+
+               max_performance: Generally, this means no power management.
+               Tell the controller to have performance be a priority over power
+               management.
+
+               medium_power: Tell the controller to enter a lower power state
+               when possible, but do not enter the lowest power state, thus
+               improving latency over min_power setting.
+
+               med_power_with_dipm: Identical to the existing medium_power
+               setting except that it enables dipm (device initiated power
+               management) on top, which makes it match the Windows IRST (Intel
+               Rapid Storage Technology) driver settings. This setting is also
+               close to min_power, except that:
+               a) It does not use host-initiated slumber mode, but it does
+               allow device-initiated slumber
+               b) It does not enable low power device sleep mode (DevSlp).
+
+What:          /sys/class/scsi_host/hostX/em_message
+What:          /sys/class/scsi_host/hostX/em_message_type
+Date:          Jun, 2008
+KernelVersion: v2.6.27
+Contact:       linux-ide@vger.kernel.org
+Description:
+               em_message: (RW) Enclosure management support. For the LED
+               protocol, writes and reads correspond to the LED message format
+               as defined in the AHCI spec.
+
+               The user must turn sw_activity (under /sys/block/*/device/) OFF
+               it they wish to control the activity LED via the em_message
+               file.
+
+               em_message_type: (RO) Displays the current enclosure management
+               protocol that is being used by the driver (for eg. LED, SAF-TE,
+               SES-2, SGPIO etc).
+
+What:          /sys/class/scsi_host/hostX/ahci_port_cmd
+What:          /sys/class/scsi_host/hostX/ahci_host_caps
+What:          /sys/class/scsi_host/hostX/ahci_host_cap2
+Date:          Mar, 2010
+KernelVersion: v2.6.35
+Contact:       linux-ide@vger.kernel.org
+Description:
+               [to be documented]
+
+What:          /sys/class/scsi_host/hostX/ahci_host_version
+Date:          Mar, 2010
+KernelVersion: v2.6.35
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RO) Display the version of the AHCI spec implemented by the
+               host.
+
+What:          /sys/class/scsi_host/hostX/em_buffer
+Date:          Apr, 2010
+KernelVersion: v2.6.35
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RW) Allows access to AHCI EM (enclosure management) buffer
+               directly if the host supports EM.
+
+               For eg. the AHCI driver supports SGPIO EM messages but the
+               SATA/AHCI specs do not define the SGPIO message format of the EM
+               buffer. Different hardware(HW) vendors may have different
+               definitions. With the em_buffer attribute, this issue can be
+               solved by allowing HW vendors to provide userland drivers and
+               tools for their SGPIO initiators.
+
+What:          /sys/class/scsi_host/hostX/em_message_supported
+Date:          Oct, 2009
+KernelVersion: v2.6.39
+Contact:       linux-ide@vger.kernel.org
+Description:
+               (RO) Displays supported enclosure management message types.
diff --git a/Documentation/ABI/testing/sysfs-devices-platform-dock b/Documentation/ABI/testing/sysfs-devices-platform-dock
new file mode 100644 (file)
index 0000000..1d8c18f
--- /dev/null
@@ -0,0 +1,39 @@
+What:          /sys/devices/platform/dock.N/docked
+Date:          Dec, 2006
+KernelVersion: 2.6.19
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Value 1 or 0 indicates whether the software believes the
+               laptop is docked in a docking station.
+
+What:          /sys/devices/platform/dock.N/undock
+Date:          Dec, 2006
+KernelVersion: 2.6.19
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (WO) Writing to this file causes the software to initiate an
+               undock request to the firmware.
+
+What:          /sys/devices/platform/dock.N/uid
+Date:          Feb, 2007
+KernelVersion: v2.6.21
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Displays the docking station the laptop is docked to.
+
+What:          /sys/devices/platform/dock.N/flags
+Date:          May, 2007
+KernelVersion: v2.6.21
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Show dock station flags, useful for checking if undock
+               request has been made by the user (from the immediate_undock
+               option).
+
+What:          /sys/devices/platform/dock.N/type
+Date:          Aug, 2008
+KernelVersion: v2.6.27
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Display the dock station type- dock_station, ata_bay or
+               battery_bay.
index bfd29bc8d37af1bbc4913deee9d941b1692bedda..4ed63b6cfb155cbc8b5aaab64e1030662f19411f 100644 (file)
@@ -108,6 +108,8 @@ Description:        CPU topology files that describe a logical CPU's relationship
 
 What:          /sys/devices/system/cpu/cpuidle/current_driver
                /sys/devices/system/cpu/cpuidle/current_governer_ro
+               /sys/devices/system/cpu/cpuidle/available_governors
+               /sys/devices/system/cpu/cpuidle/current_governor
 Date:          September 2007
 Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
 Description:   Discover cpuidle policy and mechanism
@@ -119,13 +121,84 @@ Description:      Discover cpuidle policy and mechanism
                Idle policy (governor) is differentiated from idle mechanism
                (driver)
 
-               current_driver: displays current idle mechanism
+               current_driver: (RO) displays current idle mechanism
 
-               current_governor_ro: displays current idle policy
+               current_governor_ro: (RO) displays current idle policy
+
+               With the cpuidle_sysfs_switch boot option enabled (meant for
+               developer testing), the following three attributes are visible
+               instead:
+
+               current_driver: same as described above
+
+               available_governors: (RO) displays a space separated list of
+               available governors
+
+               current_governor: (RW) displays current idle policy. Users can
+               switch the governor at runtime by writing to this file.
 
                See files in Documentation/cpuidle/ for more information.
 
 
+What:          /sys/devices/system/cpu/cpuX/cpuidle/stateN/name
+               /sys/devices/system/cpu/cpuX/cpuidle/stateN/latency
+               /sys/devices/system/cpu/cpuX/cpuidle/stateN/power
+               /sys/devices/system/cpu/cpuX/cpuidle/stateN/time
+               /sys/devices/system/cpu/cpuX/cpuidle/stateN/usage
+Date:          September 2007
+KernelVersion: v2.6.24
+Contact:       Linux power management list <linux-pm@vger.kernel.org>
+Description:
+               The directory /sys/devices/system/cpu/cpuX/cpuidle contains per
+               logical CPU specific cpuidle information for each online cpu X.
+               The processor idle states which are available for use have the
+               following attributes:
+
+               name: (RO) Name of the idle state (string).
+
+               latency: (RO) The latency to exit out of this idle state (in
+               microseconds).
+
+               power: (RO) The power consumed while in this idle state (in
+               milliwatts).
+
+               time: (RO) The total time spent in this idle state (in microseconds).
+
+               usage: (RO) Number of times this state was entered (a count).
+
+
+What:          /sys/devices/system/cpu/cpuX/cpuidle/stateN/desc
+Date:          February 2008
+KernelVersion: v2.6.25
+Contact:       Linux power management list <linux-pm@vger.kernel.org>
+Description:
+               (RO) A small description about the idle state (string).
+
+
+What:          /sys/devices/system/cpu/cpuX/cpuidle/stateN/disable
+Date:          March 2012
+KernelVersion: v3.10
+Contact:       Linux power management list <linux-pm@vger.kernel.org>
+Description:
+               (RW) Option to disable this idle state (bool). The behavior and
+               the effect of the disable variable depends on the implementation
+               of a particular governor. In the ladder governor, for example,
+               it is not coherent, i.e. if one is disabling a light state, then
+               all deeper states are disabled as well, but the disable variable
+               does not reflect it. Likewise, if one enables a deep state but a
+               lighter state still is disabled, then this has no effect.
+
+
+What:          /sys/devices/system/cpu/cpuX/cpuidle/stateN/residency
+Date:          March 2014
+KernelVersion: v3.15
+Contact:       Linux power management list <linux-pm@vger.kernel.org>
+Description:
+               (RO) Display the target residency i.e. the minimum amount of
+               time (in microseconds) this cpu should spend in this idle state
+               to make the transition worth the effort.
+
+
 What:          /sys/devices/system/cpu/cpu#/cpufreq/*
 Date:          pre-git history
 Contact:       linux-pm@vger.kernel.org
diff --git a/Documentation/ABI/testing/sysfs-platform-dptf b/Documentation/ABI/testing/sysfs-platform-dptf
new file mode 100644 (file)
index 0000000..325dc06
--- /dev/null
@@ -0,0 +1,40 @@
+What:          /sys/bus/platform/devices/INT3407:00/dptf_power/charger_type
+Date:          Jul, 2016
+KernelVersion: v4.10
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) The charger type - Traditional, Hybrid or NVDC.
+
+What:          /sys/bus/platform/devices/INT3407:00/dptf_power/adapter_rating_mw
+Date:          Jul, 2016
+KernelVersion: v4.10
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Adapter rating in milliwatts (the maximum Adapter power).
+               Must be 0 if no AC Adaptor is plugged in.
+
+What:          /sys/bus/platform/devices/INT3407:00/dptf_power/max_platform_power_mw
+Date:          Jul, 2016
+KernelVersion: v4.10
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Maximum platform power that can be supported by the battery
+               in milliwatts.
+
+What:          /sys/bus/platform/devices/INT3407:00/dptf_power/platform_power_source
+Date:          Jul, 2016
+KernelVersion: v4.10
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) Display the platform power source
+               0x00 = DC
+               0x01 = AC
+               0x02 = USB
+               0x03 = Wireless Charger
+
+What:          /sys/bus/platform/devices/INT3407:00/dptf_power/battery_steady_power
+Date:          Jul, 2016
+KernelVersion: v4.10
+Contact:       linux-acpi@vger.kernel.org
+Description:
+               (RO) The maximum sustained power for battery in milliwatts.
index 611a75e4366ed2404b807dc03f1159f65d0a819a..badb26ac33dc8eec08d38c3ee13c24380568aadc 100644 (file)
@@ -570,7 +570,9 @@ your driver if they're helpful, or just use plain hex constants.
 The device IDs are arbitrary hex numbers (vendor controlled) and normally used
 only in a single location, the pci_device_id table.
 
-Please DO submit new vendor/device IDs to http://pciids.sourceforge.net/.
+Please DO submit new vendor/device IDs to http://pci-ids.ucw.cz/.
+There are mirrors of the pci.ids file at http://pciids.sourceforge.net/
+and https://github.com/pciutils/pciids.
 
 
 
index 4f7af841d935a261f5ffb96abd4f221364ee9e3d..ddcc58d01cfbce99a2da80a91101213203b83e82 100644 (file)
@@ -152,6 +152,11 @@ OCXL_IOCTL_IRQ_SET_FD:
   Associate an event fd to an AFU interrupt so that the user process
   can be notified when the AFU sends an interrupt.
 
+OCXL_IOCTL_GET_METADATA:
+
+  Obtains configuration information from the card, such at the size of
+  MMIO areas, the AFU version, and the PASID for the current context.
+
 
 mmap
 ----
index 5550bfdcce5f1cfaab57728f4c272e9e84902860..be70b32c95d918066ffa72dfa4a69e8b4e51a225 100644 (file)
@@ -58,7 +58,12 @@ Like with atomic_t, the rule of thumb is:
 
  - RMW operations that have a return value are fully ordered.
 
-Except for test_and_set_bit_lock() which has ACQUIRE semantics and
+ - RMW operations that are conditional are unordered on FAILURE,
+   otherwise the above rules apply. In the case of test_and_{}_bit() operations,
+   if the bit in memory is unchanged by the operation then it is deemed to have
+   failed.
+
+Except for a successful test_and_set_bit_lock() which has ACQUIRE semantics and
 clear_bit_unlock() which has RELEASE semantics.
 
 Since a platform only has a single means of achieving atomic operations
diff --git a/Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt b/Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
new file mode 100644 (file)
index 0000000..e28e2aa
--- /dev/null
@@ -0,0 +1,18 @@
+ARM Versatile Character LCD
+-----------------------------------------------------
+This binding defines the character LCD interface found on ARM Versatile AB
+and PB reference platforms.
+
+Required properties:
+- compatible : "arm,versatile-clcd"
+- reg : Location and size of character LCD registers
+
+Optional properties:
+- interrupts - single interrupt for character LCD. The character LCD can
+  operate in polled mode without an interrupt.
+
+Example:
+       lcd@10008000 {
+               compatible = "arm,versatile-lcd";
+               reg = <0x10008000 0x1000>;
+       };
index 6394ea9e3b9e5b45a8803dd5a6c7e98426a1b889..58b12e25bbb16d5ce85b7d11be530ec80dab71d0 100644 (file)
@@ -16,6 +16,7 @@ Required properties:
 - ddc: phandle to the hdmi ddc node
 - phy: phandle to the hdmi phy node
 - samsung,syscon-phandle: phandle for system controller node for PMU.
+- #sound-dai-cells: should be 0.
 
 Required properties for Exynos 4210, 4212, 5420 and 5433:
 - clocks: list of clock IDs from SoC clock driver.
index 217a90eaabe7f87db72539a2c9046f5ebc892b7c..9c38bbe7e6d7d86993be1f24ad011ee27a8e1d59 100644 (file)
@@ -11,7 +11,11 @@ Required properties:
   interrupts.
 
 Optional properties:
-- clocks: Optional reference to the clock used by the XOR engine.
+- clocks: Optional reference to the clocks used by the XOR engine.
+- clock-names: mandatory if there is a second clock, in this case the
+   name must be "core" for the first clock and "reg" for the second
+   one
+
 
 Example:
 
index 1812c848e369e2a261f42067eaf65d5e563f7f9a..abfae1beca2b4def66184cdf704fffdaddc846d3 100644 (file)
@@ -38,9 +38,9 @@ Required properties:
 
                 "catalyst",
                 "microchip",
+                "nxp",
                 "ramtron",
                 "renesas",
-                "nxp",
                 "st",
 
                 Some vendors use different model names for chips which are just
index e9ebb8a20e0d8c4ba0a386b6437bedc698459aa5..ba24ca7ba95edfd8a6b0c3a107c551662df6f1a0 100644 (file)
@@ -3,11 +3,11 @@ Device-Tree bindings for sigma delta modulator
 Required properties:
 - compatible: should be "ads1201", "sd-modulator". "sd-modulator" can be use
        as a generic SD modulator if modulator not specified in compatible list.
-- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers".
+- #io-channel-cells = <0>: See the IIO bindings section "IIO consumers".
 
 Example node:
 
        ads1202: adc@0 {
                compatible = "sd-modulator";
-               #io-channel-cells = <1>;
+               #io-channel-cells = <0>;
        };
index 33c9a10fdc91a1dca6f7e09308ab81862f2e5874..20f121daa9106f177a9224ecd12140e6d5f30781 100644 (file)
@@ -14,6 +14,7 @@ Required properties:
     - "renesas,irqc-r8a7794" (R-Car E2)
     - "renesas,intc-ex-r8a7795" (R-Car H3)
     - "renesas,intc-ex-r8a7796" (R-Car M3-W)
+    - "renesas,intc-ex-r8a77965" (R-Car M3-N)
     - "renesas,intc-ex-r8a77970" (R-Car V3M)
     - "renesas,intc-ex-r8a77995" (R-Car D3)
 - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
diff --git a/Documentation/devicetree/bindings/misc/arm-charlcd.txt b/Documentation/devicetree/bindings/misc/arm-charlcd.txt
deleted file mode 100644 (file)
index e28e2aa..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-ARM Versatile Character LCD
------------------------------------------------------
-This binding defines the character LCD interface found on ARM Versatile AB
-and PB reference platforms.
-
-Required properties:
-- compatible : "arm,versatile-clcd"
-- reg : Location and size of character LCD registers
-
-Optional properties:
-- interrupts - single interrupt for character LCD. The character LCD can
-  operate in polled mode without an interrupt.
-
-Example:
-       lcd@10008000 {
-               compatible = "arm,versatile-lcd";
-               reg = <0x10008000 0x1000>;
-       };
index 1d4d0f49c9d06eb66d9957fb0661cec35ddc7af9..8c033d48e2baf05efc326dafbe74b93ff98bae87 100644 (file)
@@ -50,14 +50,15 @@ Example:
                        compatible = "marvell,mv88e6085";
                        reg = <0>;
                        reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
-               };
-               mdio {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       switch1phy0: switch1phy0@0 {
-                               reg = <0>;
-                               interrupt-parent = <&switch0>;
-                               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+                       mdio {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               switch1phy0: switch1phy0@0 {
+                                       reg = <0>;
+                                       interrupt-parent = <&switch0>;
+                                       interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+                               };
                        };
                };
        };
@@ -74,23 +75,24 @@ Example:
                        compatible = "marvell,mv88e6390";
                        reg = <0>;
                        reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
-               };
-               mdio {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       switch1phy0: switch1phy0@0 {
-                               reg = <0>;
-                               interrupt-parent = <&switch0>;
-                               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+                       mdio {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               switch1phy0: switch1phy0@0 {
+                                       reg = <0>;
+                                       interrupt-parent = <&switch0>;
+                                       interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+                               };
                        };
-               };
 
-               mdio1 {
-                       compatible = "marvell,mv88e6xxx-mdio-external";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       switch1phy9: switch1phy0@9 {
-                               reg = <9>;
+                       mdio1 {
+                               compatible = "marvell,mv88e6xxx-mdio-external";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               switch1phy9: switch1phy0@9 {
+                                       reg = <9>;
+                               };
                        };
                };
        };
index c902261893b913f529b1ec8d9852048f9d711e59..b4dc455eb1554e2df9fa8c6b3b3c0a8fd3a8cb9b 100644 (file)
@@ -18,6 +18,7 @@ Required properties:
       - "renesas,etheravb-r8a7795" for the R8A7795 SoC.
       - "renesas,etheravb-r8a7796" for the R8A7796 SoC.
       - "renesas,etheravb-r8a77970" for the R8A77970 SoC.
+      - "renesas,etheravb-r8a77980" for the R8A77980 SoC.
       - "renesas,etheravb-r8a77995" for the R8A77995 SoC.
       - "renesas,etheravb-rcar-gen3" as a fallback for the above
                R-Car Gen3 devices.
@@ -26,7 +27,11 @@ Required properties:
        SoC-specific version corresponding to the platform first followed by
        the generic version.
 
-- reg: offset and length of (1) the register block and (2) the stream buffer.
+- reg: Offset and length of (1) the register block and (2) the stream buffer.
+       The region for the register block is mandatory.
+       The region for the stream buffer is optional, as it is only present on
+       R-Car Gen2 and RZ/G1 SoCs, and on R-Car H3 (R8A7795), M3-W (R8A7796),
+       and M3-N (R8A77965).
 - interrupts: A list of interrupt-specifiers, one for each entry in
              interrupt-names.
              If interrupt-names is not present, an interrupt specifier
diff --git a/Documentation/devicetree/bindings/power/mti,mips-cpc.txt b/Documentation/devicetree/bindings/power/mti,mips-cpc.txt
new file mode 100644 (file)
index 0000000..c6b8251
--- /dev/null
@@ -0,0 +1,8 @@
+Binding for MIPS Cluster Power Controller (CPC).
+
+This binding allows a system to specify where the CPC registers are
+located.
+
+Required properties:
+compatible : Should be "mti,mips-cpc".
+regs: Should describe the address & size of the CPC register region.
index 3c81f78b5c27d50bb809cf6bbf13766a779024f5..5d254ab13ebf384034b7e8629365a7b0070c2af3 100644 (file)
@@ -60,7 +60,7 @@ Examples
                #size-cells = <0>;
 
                button@1 {
-                       debounce_interval = <50>;
+                       debounce-interval = <50>;
                        wakeup-source;
                        linux,code = <116>;
                        label = "POWER";
diff --git a/Documentation/devicetree/bindings/sound/ak4458.txt b/Documentation/devicetree/bindings/sound/ak4458.txt
new file mode 100644 (file)
index 0000000..7839be7
--- /dev/null
@@ -0,0 +1,23 @@
+AK4458 audio DAC
+
+This device supports I2C mode.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak4458"
+- reg : The I2C address of the device for I2C
+
+Optional properties:
+- reset-gpios: A GPIO specifier for the power down & reset pin
+- mute-gpios: A GPIO specifier for the soft mute pin
+
+Example:
+
+&i2c {
+       ak4458: dac@10 {
+               compatible = "asahi-kasei,ak4458";
+               reg = <0x10>;
+               reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>
+               mute-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>
+       };
+};
diff --git a/Documentation/devicetree/bindings/sound/ak5558.txt b/Documentation/devicetree/bindings/sound/ak5558.txt
new file mode 100644 (file)
index 0000000..7d67ca6
--- /dev/null
@@ -0,0 +1,22 @@
+AK5558 8 channel differential 32-bit delta-sigma ADC
+
+This device supports I2C mode only.
+
+Required properties:
+
+- compatible : "asahi-kasei,ak5558"
+- reg : The I2C address of the device.
+
+Optional properties:
+
+- reset-gpios: A GPIO specifier for the power down & reset pin.
+
+Example:
+
+&i2c {
+       ak5558: adc@10 {
+               compatible = "asahi-kasei,ak5558";
+               reg = <0x10>;
+               reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+       };
+};
index 5b54d2d045c355808bf0f58afba9ec7539ff4472..c3df92d31c4b36e0e12e362d8f1068fb1ad5f314 100644 (file)
@@ -25,6 +25,9 @@ Optional properties:
   interrupt is to be used to wake system, otherwise "irq" should be used.
 - wakeup-source: Flag to indicate this device can wake system (suspend/resume).
 
+- #clock-cells :  Should be set to '<0>', only one clock source provided;
+- clock-output-names : Name given for DAI clocks output;
+
 - clocks : phandle and clock specifier for codec MCLK.
 - clock-names : Clock name string for 'clocks' attribute, should be "mclk".
 
@@ -83,6 +86,9 @@ Example:
                VDDMIC-supply = <&reg_audio>;
                VDDIO-supply = <&reg_audio>;
 
+               #clock-cells = <0>;
+               clock-output-names = "dai-clks";
+
                clocks = <&clks 201>;
                clock-names = "mclk";
 
index f7bf656114531971c51a2e4f146a8a5430c5abd1..e957b41367160bf1a01437f74d3b2dd494ebe887 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
 Optional properties:
        - dmicen-gpios: GPIO specifier for dmic to control start and stop
        - num-channels: Number of microphones on this DAI
+       - wakeup-delay-ms: Delay (in ms) after enabling the DMIC
 
 Example node:
 
@@ -15,4 +16,5 @@ Example node:
                compatible = "dmic-codec";
                dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
                num-channels = <1>;
+               wakeup-delay-ms <50>;
        };
index f749e2744824d8273bfe22a1592fa50803b4e51d..c60a5732d29c15edfcd7e574f292eba802397b41 100644 (file)
@@ -28,7 +28,6 @@ The compatible list for this generic sound card currently:
  (compatible with CS4271 and CS4272)
 
  "fsl,imx-audio-wm8962"
- (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt)
 
  "fsl,imx-audio-sgtl5000"
  (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt)
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
deleted file mode 100644 (file)
index acea71b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-Freescale i.MX audio complex with WM8962 codec
-
-Required properties:
-
-  - compatible         : "fsl,imx-audio-wm8962"
-
-  - model              : The user-visible name of this sound complex
-
-  - ssi-controller     : The phandle of the i.MX SSI controller
-
-  - audio-codec                : The phandle of the WM8962 audio codec
-
-  - audio-routing      : A list of the connections between audio components.
-                         Each entry is a pair of strings, the first being the
-                         connection's sink, the second being the connection's
-                         source. Valid names could be power supplies, WM8962
-                         pins, and the jacks on the board:
-
-                         Power supplies:
-                          * Mic Bias
-
-                         Board connectors:
-                          * Mic Jack
-                          * Headphone Jack
-                          * Ext Spk
-
-  - mux-int-port       : The internal port of the i.MX audio muxer (AUDMUX)
-
-  - mux-ext-port       : The external port of the i.MX audio muxer
-
-Note: The AUDMUX port numbering should start at 1, which is consistent with
-hardware manual.
-
-Example:
-
-sound {
-       compatible = "fsl,imx6q-sabresd-wm8962",
-                    "fsl,imx-audio-wm8962";
-       model = "wm8962-audio";
-       ssi-controller = <&ssi2>;
-       audio-codec = <&codec>;
-               audio-routing =
-               "Headphone Jack", "HPOUTL",
-               "Headphone Jack", "HPOUTR",
-               "Ext Spk", "SPKOUTL",
-               "Ext Spk", "SPKOUTR",
-               "MICBIAS", "AMIC",
-               "IN3R", "MICBIAS",
-               "DMIC", "MICBIAS",
-               "DMICDAT", "DMIC";
-       mux-int-port = <2>;
-       mux-ext-port = <3>;
-};
index 4e3be6682c98c97c04ea6e8983edaca1beb22fbe..7e1bbd5c27fd061602bd7683a223def6cbcd5b2e 100644 (file)
@@ -16,6 +16,8 @@ Optional properties:
 
 - clock-names: Should be "mclk"
 
+- #sound-dai-cells : should be 0.
+
 - maxim,dmic-freq: Frequency at which to clock DMIC
 
 - maxim,micbias: Micbias voltage applies to the analog mic, valid voltages value are:
diff --git a/Documentation/devicetree/bindings/sound/maxim,max9759.txt b/Documentation/devicetree/bindings/sound/maxim,max9759.txt
new file mode 100644 (file)
index 0000000..737a996
--- /dev/null
@@ -0,0 +1,18 @@
+Maxim MAX9759 Speaker Amplifier
+===============================
+
+Required properties:
+- compatible : "maxim,max9759"
+- shutdown-gpios : the gpio connected to the shutdown pin
+- mute-gpios : the gpio connected to the mute pin
+- gain-gpios : the 2 gpios connected to the g1 and g2 pins
+
+Example:
+
+max9759: analog-amplifier {
+       compatible = "maxim,max9759";
+       shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+       mute-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
+       gain-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>,
+                    <&gpio3 25 GPIO_ACTIVE_LOW>;
+};
index 6df87b97f7cb27c0293e823f78ac41e5721ab877..e2f7f49512155e1084c85ce9e3dd6b9770285a97 100644 (file)
@@ -53,7 +53,7 @@ See ../arm/mediatek/mediatek,audsys.txt for details about the parent node.
 Example:
 
        audsys: audio-subsystem@11220000 {
-               compatible = "mediatek,mt2701-audsys", "syscon", "simple-mfd";
+               compatible = "mediatek,mt2701-audsys", "syscon";
                ...
 
                afe: audio-controller {
diff --git a/Documentation/devicetree/bindings/sound/pcm1789.txt b/Documentation/devicetree/bindings/sound/pcm1789.txt
new file mode 100644 (file)
index 0000000..3c74ed2
--- /dev/null
@@ -0,0 +1,22 @@
+Texas Instruments pcm1789 DT bindings
+
+PCM1789 is a simple audio codec that can be connected via
+I2C or SPI. Currently, only I2C bus is supported.
+
+Required properties:
+
+ - compatible: "ti,pcm1789"
+
+Required properties on I2C:
+
+ - reg: the I2C address
+ - reset-gpios: GPIO to control the RESET pin
+
+Examples:
+
+       audio-codec@4c {
+               compatible = "ti,pcm1789";
+               reg = <0x4c>;
+               reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+               #sound-dai-cells = <0>;
+       };
index 5bed9a5957729453c3196a88781802bf41d853a5..b86d790f630ff79a390f6ef004c7fe595acf44e9 100644 (file)
@@ -351,6 +351,7 @@ Required properties:
                                    - "renesas,rcar_sound-r8a7793" (R-Car M2-N)
                                    - "renesas,rcar_sound-r8a7794" (R-Car E2)
                                    - "renesas,rcar_sound-r8a7795" (R-Car H3)
+                                   - "renesas,rcar_sound-r8a7796" (R-Car M3-W)
 - reg                          : Should contain the register physical address.
                                  required register is
                                   SRU/ADG/SSI      if generation1
index 2539e1d681075540ad8cd295e154f5e0eb1063f5..e5430d1d34e400402ffd365f0851deb08f47b36e 100644 (file)
@@ -22,7 +22,7 @@ Optionnal properties:
 Example:
 
 sound {
-       compatible = "rockchip,rockchip-audio-es8388";
+       compatible = "rockchip,rk3288-hdmi-analog";
        rockchip,model = "Analog audio output";
        rockchip,i2s-controller = <&i2s>;
        rockchip,audio-codec = <&es8388>;
diff --git a/Documentation/devicetree/bindings/sound/rohm,bd28623.txt b/Documentation/devicetree/bindings/sound/rohm,bd28623.txt
new file mode 100644 (file)
index 0000000..d84557c
--- /dev/null
@@ -0,0 +1,29 @@
+ROHM BD28623MUV Class D speaker amplifier for digital input
+
+This codec does not have any control buses such as I2C, it detect format and
+rate of I2S signal automatically. It has two signals that can be connected
+to GPIOs: reset and mute.
+
+Required properties:
+- compatible      : should be "rohm,bd28623"
+- #sound-dai-cells: should be 0.
+- VCCA-supply     : regulator phandle for the VCCA supply
+- VCCP1-supply    : regulator phandle for the VCCP1 supply
+- VCCP2-supply    : regulator phandle for the VCCP2 supply
+
+Optional properties:
+- reset-gpios     : GPIO specifier for the active low reset line
+- mute-gpios      : GPIO specifier for the active low mute line
+
+Example:
+
+       codec {
+               compatible = "rohm,bd28623";
+               #sound-dai-cells = <0>;
+
+               VCCA-supply = <&vcc_reg>;
+               VCCP1-supply = <&vcc_reg>;
+               VCCP2-supply = <&vcc_reg>;
+               reset-gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+               mute-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
+       };
index 3875233095f5eaef7001d421bce98d87ae72edbb..b85221864cec8a607f62dc27c41f4f37e05b941e 100644 (file)
@@ -16,6 +16,23 @@ Optional properties:
 - realtek,dmic-en
   Boolean. true if dmic is used.
 
+- realtek,jack-detect-source
+  u32. Valid values:
+  1: Use JD1_1 pin for jack-detect
+  2: Use JD1_2 pin for jack-detect
+  3: Use JD2 pin for jack-detect
+
+- realtek,over-current-threshold-microamp
+  u32, micbias over-current detection threshold in ÂµA, valid values are
+  600, 1500 and 2000µA.
+
+- realtek,over-current-scale-factor
+  u32, micbias over-current detection scale-factor, valid values are:
+  0: Scale current by 0.5
+  1: Scale current by 0.75
+  2: Scale current by 1.0
+  3: Scale current by 1.5
+
 Pins on the device (for linking into audio routes) for RT5651:
 
   * DMIC L1
index 419c89219681457bf473d618ddd81b51704c8e44..8df1705069863c1261a4b80866b6bf040cdbea32 100644 (file)
@@ -1,10 +1,10 @@
-RT5665/RT5666/RT5668 audio CODEC
+RT5665/RT5666 audio CODEC
 
 This device supports I2C only.
 
 Required properties:
 
-- compatible : One of "realtek,rt5665", "realtek,rt5666" or "realtek,rt5668".
+- compatible : One of "realtek,rt5665", "realtek,rt5666".
 
 - reg : The I2C address of the device.
 
index 625b1b18fd027b110f9bcef0ddae383c5e710925..e9da2200e1737cc821e2a624ac75ce0df9ff1190 100644 (file)
@@ -2,8 +2,10 @@ Samsung Exynos Odroid XU3/XU4 audio complex with MAX98090 codec
 
 Required properties:
 
- - compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board,
-               "samsung,odroidxu4-audio" - for Odroid XU4 board
+ - compatible - "hardkernel,odroid-xu3-audio" - for Odroid XU3 board,
+               "hardkernel,odroid-xu4-audio" - for Odroid XU4 board (deprecated),
+               "samsung,odroid-xu3-audio" - for Odroid XU3 board (deprecated),
+               "samsung,odroid-xu4-audio" - for Odroid XU4 board (deprecated)
  - model - the user-visible name of this sound complex
  - clocks - should contain entries matching clock names in the clock-names
     property
@@ -35,7 +37,7 @@ Required sub-nodes:
 Example:
 
 sound {
-       compatible = "samsung,odroidxu3-audio";
+       compatible = "hardkernel,odroid-xu3-audio";
        model = "Odroid-XU3";
        samsung,audio-routing =
                "Headphone Jack", "HPL",
index 94442e5673b358f0eb3e634078080429435e3e8e..f5ccc12ddc00e28dccd626bcc5de637fdafc8c52 100644 (file)
@@ -4,9 +4,13 @@ Required properties:
 
  - compatible           : "samsung,tm2-audio"
  - model                : the user-visible name of this sound complex
- - audio-codec          : the phandle of the wm5110 audio codec node,
-                          as described in ../mfd/arizona.txt
- - i2s-controller       : the phandle of the I2S controller
+ - audio-codec          : the first entry should be phandle of the wm5110 audio
+                          codec node, as described in ../mfd/arizona.txt;
+                          the second entry should be phandle of the HDMI
+                          transmitter node
+ - i2s-controller       : the list of phandle and argument tuples pointing to
+                          I2S controllers, the first entry should be I2S0 and
+                          the second one I2S1
  - audio-amplifier      : the phandle of the MAX98504 amplifier
  - samsung,audio-routing : a list of the connections between audio components;
                           each entry is a pair of strings, the first being the
@@ -22,8 +26,8 @@ Example:
 
 sound {
        compatible = "samsung,tm2-audio";
-       audio-codec = <&wm5110>;
-       i2s-controller = <&i2s0>;
+       audio-codec = <&wm5110>, <&hdmi>;
+       i2s-controller = <&i2s0 0>, <&i2s1 0>;
        audio-amplifier = <&max98504>;
        mic-bias-gpios = <&gpr3 2 0>;
        model = "wm5110";
index bf100cd0d0f7a83034dc40d42dcf3d934810c353..a88cb00fa09660c035db33f7306b977e3687d636 100644 (file)
@@ -7,7 +7,7 @@ Required SoC Specific Properties:
    - samsung,s5pv210-i2s: for 8/16/24bit multichannel(5.1) I2S with
      secondary fifo, s/w reset control and internal mux for root clk src.
    - samsung,exynos5420-i2s: for 8/16/24bit multichannel(5.1) I2S for
-     playback, sterio channel capture, secondary fifo using internal
+     playback, stereo channel capture, secondary fifo using internal
      or external dma, s/w reset control, internal mux for root clk src
      and 7.1 channel TDM support for playback. TDM (Time division multiplexing)
      is to allow transfer of multiple channel audio data on single data line.
@@ -25,7 +25,7 @@ Required SoC Specific Properties:
   These strings correspond 1:1 with the ordered pairs in dmas.
 - clocks: Handle to iis clock and RCLK source clk.
 - clock-names:
-  i2s0 uses some base clks from CMU and some are from audio subsystem internal
+  i2s0 uses some base clocks from CMU and some are from audio subsystem internal
   clock controller. The clock names for i2s0 should be "iis", "i2s_opclk0" and
   "i2s_opclk1" as shown in the example below.
   i2s1 and i2s2 uses clocks from CMU. The clock names for i2s1 and i2s2 should
@@ -36,9 +36,9 @@ Required SoC Specific Properties:
 - #clock-cells: should be 1, this property must be present if the I2S device
   is a clock provider in terms of the common clock bindings, described in
   ../clock/clock-bindings.txt.
-- clock-output-names: from the common clock bindings, names of the CDCLK
-  I2S output clocks, suggested values are "i2s_cdclk0", "i2s_cdclk1",
-  "i2s_cdclk3" for the I2S0, I2S1, I2S2 devices recpectively.
+- clock-output-names (deprecated): from the common clock bindings, names of
+  the CDCLK I2S output clocks, suggested values are "i2s_cdclk0", "i2s_cdclk1",
+  "i2s_cdclk3" for the I2S0, I2S1, I2S2 devices respectively.
 
 There are following clocks available at the I2S device nodes:
  CLK_I2S_CDCLK    - the CDCLK (CODECLKO) gate clock,
@@ -49,9 +49,10 @@ There are following clocks available at the I2S device nodes:
 
 Refer to the SoC datasheet for availability of the above clocks.
 The CLK_I2S_RCLK_PSR and CLK_I2S_RCLK_SRC clocks are usually only available
-in the IIS Multi Audio Interface (I2S0).
-Note: Old DTs may not have the #clock-cells, clock-output-names properties
-and then not use the I2S node as a clock supplier.
+in the IIS Multi Audio Interface.
+
+Note: Old DTs may not have the #clock-cells property and then not use the I2S
+node as a clock supplier.
 
 Optional SoC Specific Properties:
 
@@ -59,6 +60,7 @@ Optional SoC Specific Properties:
   sub system(used in secondary sound source).
 - pinctrl-0: Should specify pin control groups used for this controller.
 - pinctrl-names: Should contain only one value - "default".
+- #sound-dai-cells: should be 1.
 
 
 Example:
@@ -74,9 +76,9 @@ i2s0: i2s@3830000 {
                <&clock_audss EXYNOS_I2S_BUS>,
                <&clock_audss EXYNOS_SCLK_I2S>;
        clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
-       #clock-cells;
-       clock-output-names = "i2s_cdclk0";
+       #clock-cells = <1>;
        samsung,idma-addr = <0x03000000>;
        pinctrl-names = "default";
        pinctrl-0 = <&i2s0_bus>;
+       #sound-dai-cells = <1>;
 };
index 060cb4a3b47e0c942268b43be8016464ec344b1e..9a36c7e2a1434ad60bb61436d5da9df29d05f8f3 100644 (file)
@@ -5,6 +5,8 @@ Required properties:
 
 - reg : the I2C address of the device
 
+- #sound-dai-cells: must be equal to 0
+
 - clocks : the clock provider of SYS_MCLK
 
 - VDDA-supply : the regulator provider of VDDA
@@ -40,6 +42,7 @@ Example:
 codec: sgtl5000@a {
        compatible = "fsl,sgtl5000";
        reg = <0x0a>;
+       #sound-dai-cells = <0>;
        clocks = <&clks 150>;
        micbias-resistor-k-ohms = <2>;
        micbias-voltage-m-volts = <2250>;
index 6df74f15687f9839cd2015eae1d6a091d15433b5..80fd9a87bb3fba53e03ef608b678686517f6172a 100644 (file)
@@ -5,8 +5,17 @@ Required properties:
                        "google,snow-audio-max98090" or
                        "google,snow-audio-max98091" or
                        "google,snow-audio-max98095"
-- samsung,i2s-controller: The phandle of the Samsung I2S controller
-- samsung,audio-codec: The phandle of the audio codec
+- samsung,i2s-controller (deprecated): The phandle of the Samsung I2S controller
+- samsung,audio-codec (deprecated): The phandle of the audio codec
+
+Required sub-nodes:
+
+ - 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
+    controller
+ - 'codec' subnode with a 'sound-dai' property containing list of phandles
+    to the CODEC nodes, first entry must be the phandle of the MAX98090,
+    MAX98091 or MAX98095 CODEC (exact device type is indicated by the compatible
+    string) and the second entry must be the phandle of the HDMI IP block node
 
 Optional:
 - samsung,model: The name of the sound-card
index b1acc1a256baacb81f46d02286b9a5664d088333..f301cdf0b7e68942172253f077a93c8abb923b95 100644 (file)
@@ -45,6 +45,12 @@ SAI subnodes Optional properties:
        This property sets SAI sub-block as slave of another SAI sub-block.
        Must contain the phandle and index of the sai sub-block providing
        the synchronization.
+  - st,iec60958: support S/PDIF IEC6958 protocol for playback
+       IEC60958 protocol is not available for capture.
+       By default, custom protocol is assumed, meaning that protocol is
+       configured according to protocol defined in related DAI link node,
+       such as i2s, left justified, right justified, dsp and pdm protocols.
+       Note: ac97 protocol is not supported by SAI driver
 
 The device node should contain one 'port' child node with one child 'endpoint'
 node, according to the bindings defined in Documentation/devicetree/bindings/
diff --git a/Documentation/devicetree/bindings/sound/tda7419.txt b/Documentation/devicetree/bindings/sound/tda7419.txt
new file mode 100644 (file)
index 0000000..6b85ec3
--- /dev/null
@@ -0,0 +1,38 @@
+TDA7419 audio processor
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "st,tda7419"
+- reg : the I2C address of the device.
+- vdd-supply : a regulator spec for the common power supply (8-10V)
+
+Optional properties:
+
+- st,mute-gpios : a GPIO spec for the MUTE pin.
+
+Pins on the device (for linking into audio routes):
+
+  * SE3L
+  * SE3R
+  * SE2L
+  * SE2R
+  * SE1L
+  * SE1R
+  * DIFFL
+  * DIFFR
+  * MIX
+  * OUTLF
+  * OUTRF
+  * OUTLR
+  * OUTRR
+  * OUTSW
+
+Example:
+
+ap: tda7419@44 {
+       compatible = "st,tda7419";
+       reg = <0x44>;
+       vdd-supply = <&vdd_9v0_reg>;
+};
diff --git a/Documentation/devicetree/bindings/sound/uniphier,aio.txt b/Documentation/devicetree/bindings/sound/uniphier,aio.txt
new file mode 100644 (file)
index 0000000..4ce68ed
--- /dev/null
@@ -0,0 +1,45 @@
+Socionext UniPhier SoC audio driver
+
+The Socionext UniPhier audio subsystem consists of I2S and S/PDIF blocks in
+the same register space.
+
+Required properties:
+- compatible      : should be one of the following:
+                   "socionext,uniphier-ld11-aio"
+                   "socionext,uniphier-ld20-aio"
+                   "socionext,uniphier-pxs2-aio"
+- reg             : offset and length of the register set for the device.
+- interrupts      : should contain I2S or S/PDIF interrupt.
+- pinctrl-names   : should be "default".
+- pinctrl-0       : defined I2S signal pins for an external codec chip.
+- clock-names     : should include following entries:
+                    "aio"
+- clocks          : a list of phandle, should contain an entry for each
+                    entry in clock-names.
+- reset-names     : should include following entries:
+                    "aio"
+- resets          : a list of phandle, should contain an entry for each
+                    entry in reset-names.
+- #sound-dai-cells: should be 1.
+
+Optional properties:
+- socionext,syscon: a phandle, should contain soc-glue.
+                    The soc-glue is used for changing mode of S/PDIF signal pin
+                    to Output from Hi-Z. This property is optional if you use
+                    I2S signal pins only.
+
+Example:
+       audio {
+               compatible = "socionext,uniphier-ld20-aio";
+               reg = <0x56000000 0x80000>;
+               interrupts = <0 144 4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_aout>;
+               clock-names = "aio";
+               clocks = <&sys_clk 40>;
+               reset-names = "aio";
+               resets = <&sys_rst 40>;
+               #sound-dai-cells = <1>;
+
+               socionext,syscon = <&sg>;
+       };
index 20c62002cbcd45e3b200de1a44a0c515a96db6d4..0f0553563fc1c265ea759d1c7348ad1c71f97c57 100644 (file)
@@ -10,7 +10,7 @@ Required properties:
 
 Example:
 
-codec: wm8524@0 {
+codec: wm8524 {
        compatible = "wlf,wm8524";
        wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 };
index 28be51afdb6a2623a9eb9465a86e0ec3fa7a1d7a..379eb763073e68d4a63b540c6ca3384a3b09f642 100644 (file)
@@ -22,7 +22,32 @@ Optional properties:
 - clocks : thermal sensor's clock source.
 
 Example:
+ocotp: ocotp@21bc000 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "fsl,imx6sx-ocotp", "syscon";
+       reg = <0x021bc000 0x4000>;
+       clocks = <&clks IMX6SX_CLK_OCOTP>;
 
+       tempmon_calib: calib@38 {
+               reg = <0x38 4>;
+       };
+
+       tempmon_temp_grade: temp-grade@20 {
+               reg = <0x20 4>;
+       };
+};
+
+tempmon: tempmon {
+       compatible = "fsl,imx6sx-tempmon", "fsl,imx6q-tempmon";
+       interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+       fsl,tempmon = <&anatop>;
+       nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
+       nvmem-cell-names = "calib", "temp_grade";
+       clocks = <&clks IMX6SX_CLK_PLL3_USB_OTG>;
+};
+
+Legacy method (Deprecated):
 tempmon {
        compatible = "fsl,imx6q-tempmon";
        fsl,tempmon = <&anatop>;
index e64d903bcbe8177574cc1cf82c0bfeb37168206c..46da5f1844608fa85c9a88a947fe50643392a7f1 100644 (file)
@@ -19,7 +19,7 @@ Required properties:
   configured in FS mode;
   - "st,stm32f4x9-hsotg": The DWC2 USB HS controller instance in STM32F4x9 SoCs
   configured in HS mode;
-  - "st,stm32f7xx-hsotg": The DWC2 USB HS controller instance in STM32F7xx SoCs
+  - "st,stm32f7-hsotg": The DWC2 USB HS controller instance in STM32F7 SoCs
     configured in HS mode;
 - reg : Should contain 1 register range (address and length)
 - interrupts : Should contain 1 interrupt
index 87a45e2f9b7f99c1a26028e79dd38581bebec43e..2c071bb5801e7c8af98c44deb0c87d80627269b9 100644 (file)
@@ -4,6 +4,7 @@ Required properties:
   - compatible: Must contain one of the following:
        - "renesas,r8a7795-usb3-peri"
        - "renesas,r8a7796-usb3-peri"
+       - "renesas,r8a77965-usb3-peri"
        - "renesas,rcar-gen3-usb3-peri" for a generic R-Car Gen3 compatible
          device
 
index d060172f152914895bc59544d55eae0ba685cfc8..43960faf5a88c6c1c1c3f34e11d9ceef7d5e40cf 100644 (file)
@@ -12,6 +12,7 @@ Required properties:
        - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device
        - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device
        - "renesas,usbhs-r8a7796" for r8a7796 (R-Car M3-W) compatible device
+       - "renesas,usbhs-r8a77965" for r8a77965 (R-Car M3-N) compatible device
        - "renesas,usbhs-r8a77995" for r8a77995 (R-Car D3) compatible device
        - "renesas,usbhs-r7s72100" for r7s72100 (RZ/A1) compatible device
        - "renesas,rcar-gen2-usbhs" for R-Car Gen2 or RZ/G1 compatible devices
index e2ea59bbca93f1cd0ec107bd3d6ff3cc175a7043..1651483a7048a2df7e2bc7078af1f1e7233e7ccf 100644 (file)
@@ -13,6 +13,7 @@ Required properties:
     - "renesas,xhci-r8a7793" for r8a7793 SoC
     - "renesas,xhci-r8a7795" for r8a7795 SoC
     - "renesas,xhci-r8a7796" for r8a7796 SoC
+    - "renesas,xhci-r8a77965" for r8a77965 SoC
     - "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible
       device
     - "renesas,rcar-gen3-xhci" for a generic R-Car Gen3 compatible device
diff --git a/Documentation/features/sched/membarrier-sync-core/arch-support.txt b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
new file mode 100644 (file)
index 0000000..2c815a7
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Feature name:          membarrier-sync-core
+#         Kconfig:       ARCH_HAS_MEMBARRIER_SYNC_CORE
+#         description:   arch supports core serializing membarrier
+#
+# Architecture requirements
+#
+# * arm64
+#
+# Rely on eret context synchronization when returning from IPI handler, and
+# when returning to user-space.
+#
+# * x86
+#
+# x86-32 uses IRET as return from interrupt, which takes care of the IPI.
+# However, it uses both IRET and SYSEXIT to go back to user-space. The IRET
+# instruction is core serializing, but not SYSEXIT.
+#
+# x86-64 uses IRET as return from interrupt, which takes care of the IPI.
+# However, it can return to user-space through either SYSRETL (compat code),
+# SYSRETQ, or IRET.
+#
+# Given that neither SYSRET{L,Q}, nor SYSEXIT, are core serializing, we rely
+# instead on write_cr3() performed by switch_mm() to provide core serialization
+# after changing the current mm, and deal with the special case of kthread ->
+# uthread (temporarily keeping current mm into active_mm) by issuing a
+# sync_core_before_usermode() in that specific case.
+#
+    -----------------------
+    |         arch |status|
+    -----------------------
+    |       alpha: | TODO |
+    |         arc: | TODO |
+    |         arm: | TODO |
+    |       arm64: |  ok  |
+    |    blackfin: | TODO |
+    |         c6x: | TODO |
+    |        cris: | TODO |
+    |         frv: | TODO |
+    |       h8300: | TODO |
+    |     hexagon: | TODO |
+    |        ia64: | TODO |
+    |        m32r: | TODO |
+    |        m68k: | TODO |
+    |       metag: | TODO |
+    |  microblaze: | TODO |
+    |        mips: | TODO |
+    |     mn10300: | TODO |
+    |       nios2: | TODO |
+    |    openrisc: | TODO |
+    |      parisc: | TODO |
+    |     powerpc: | TODO |
+    |        s390: | TODO |
+    |       score: | TODO |
+    |          sh: | TODO |
+    |       sparc: | TODO |
+    |        tile: | TODO |
+    |          um: | TODO |
+    |   unicore32: | TODO |
+    |         x86: |  ok  |
+    |      xtensa: | TODO |
+    -----------------------
index 69b17b324e1273bd5353cf9e19bbbee428bfe917..152ea9398f7e56f00860ebfb3f283c8ad67e3b45 100644 (file)
@@ -3,4 +3,4 @@
 ==================================
 
 .. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c
-   :doc: Faraday TV Encoder 200
+   :doc: Faraday TV Encoder TVE200 DRM Driver
index d477024569269ff741720537ef609cafb60166f2..65514c25131877a77b5b0a85bbb8797129b87dca 100644 (file)
@@ -28,8 +28,10 @@ Supported adapters:
   * Intel Wildcat Point (PCH)
   * Intel Wildcat Point-LP (PCH)
   * Intel BayTrail (SOC)
+  * Intel Braswell (SOC)
   * Intel Sunrise Point-H (PCH)
   * Intel Sunrise Point-LP (PCH)
+  * Intel Kaby Lake-H (PCH)
   * Intel DNV (SOC)
   * Intel Broxton (SOC)
   * Intel Lewisburg (PCH)
index 6869c73de4e255ee54f7afd8e29cd51ad236e6e1..a63d2c54329b0a799469b9637fc566412df5d62a 100644 (file)
@@ -111,7 +111,7 @@ TROUBLESHOOTING SERIAL CONSOLE PROBLEMS
 
        - If you don't have an HCDP, the kernel doesn't know where
          your console lives until the driver discovers serial
-         devices.  Use "console=uart, io,0x3f8" (or appropriate
+         devices.  Use "console=uart,io,0x3f8" (or appropriate
          address for your machine).
 
     Kernel and init script output works fine, but no "login:" prompt:
index 60c482df1a38db2b300952832095ef41e2b8e655..818aca19612f4a763c96ee2eb1fbf8b3cb452e9e 100644 (file)
@@ -21,37 +21,23 @@ Implementation
 --------------
 
 Mutexes are represented by 'struct mutex', defined in include/linux/mutex.h
-and implemented in kernel/locking/mutex.c. These locks use a three
-state atomic counter (->count) to represent the different possible
-transitions that can occur during the lifetime of a lock:
-
-         1: unlocked
-         0: locked, no waiters
-   negative: locked, with potential waiters
-
-In its most basic form it also includes a wait-queue and a spinlock
-that serializes access to it. CONFIG_SMP systems can also include
-a pointer to the lock task owner (->owner) as well as a spinner MCS
-lock (->osq), both described below in (ii).
+and implemented in kernel/locking/mutex.c. These locks use an atomic variable
+(->owner) to keep track of the lock state during its lifetime.  Field owner
+actually contains 'struct task_struct *' to the current lock owner and it is
+therefore NULL if not currently owned. Since task_struct pointers are aligned
+at at least L1_CACHE_BYTES, low bits (3) are used to store extra state (e.g.,
+if waiter list is non-empty).  In its most basic form it also includes a
+wait-queue and a spinlock that serializes access to it. Furthermore,
+CONFIG_MUTEX_SPIN_ON_OWNER=y systems use a spinner MCS lock (->osq), described
+below in (ii).
 
 When acquiring a mutex, there are three possible paths that can be
 taken, depending on the state of the lock:
 
-(i) fastpath: tries to atomically acquire the lock by decrementing the
-    counter. If it was already taken by another task it goes to the next
-    possible path. This logic is architecture specific. On x86-64, the
-    locking fastpath is 2 instructions:
-
-    0000000000000e10 <mutex_lock>:
-    e21:   f0 ff 0b                lock decl (%rbx)
-    e24:   79 08                   jns    e2e <mutex_lock+0x1e>
-
-   the unlocking fastpath is equally tight:
-
-    0000000000000bc0 <mutex_unlock>:
-    bc8:   f0 ff 07                lock incl (%rdi)
-    bcb:   7f 0a                   jg     bd7 <mutex_unlock+0x17>
-
+(i) fastpath: tries to atomically acquire the lock by cmpxchg()ing the owner with
+    the current task. This only works in the uncontended case (cmpxchg() checks
+    against 0UL, so all 3 state bits above have to be 0). If the lock is
+    contended it goes to the next possible path.
 
 (ii) midpath: aka optimistic spinning, tries to spin for acquisition
      while the lock owner is running and there are no other tasks ready
@@ -143,11 +129,10 @@ Test if the mutex is taken:
 Disadvantages
 -------------
 
-Unlike its original design and purpose, 'struct mutex' is larger than
-most locks in the kernel. E.g: on x86-64 it is 40 bytes, almost twice
-as large as 'struct semaphore' (24 bytes) and tied, along with rwsems,
-for the largest lock in the kernel. Larger structure sizes mean more
-CPU cache and memory footprint.
+Unlike its original design and purpose, 'struct mutex' is among the largest
+locks in the kernel. E.g: on x86-64 it is 32 bytes, where 'struct semaphore'
+is 24 bytes and rw_semaphore is 40 bytes. Larger structure sizes mean more CPU
+cache and memory footprint.
 
 When to use mutexes
 -------------------
index 63f55a9ae2b1ffa54d088eb60b7e79e36c050f6e..a8c4239ed95bab6c87d8adcdb4edfa52de981099 100644 (file)
@@ -50,9 +50,15 @@ replace typedef dmx_filter_t :c:type:`dmx_filter`
 replace typedef dmx_pes_type_t :c:type:`dmx_pes_type`
 replace typedef dmx_input_t :c:type:`dmx_input`
 
-ignore symbol DMX_OUT_DECODER
-ignore symbol DMX_OUT_TAP
-ignore symbol DMX_OUT_TS_TAP
-ignore symbol DMX_OUT_TSDEMUX_TAP
+replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags`
+replace        symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags`
+replace        symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags`
+replace        symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags`
+replace        symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags`
+
+replace symbol DMX_OUT_DECODER :c:type:`dmx_output`
+replace symbol DMX_OUT_TAP :c:type:`dmx_output`
+replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output`
+replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output`
 
 replace ioctl DMX_DQBUF dmx_qbuf
index b48c4931658eda71586ec7ea4ddb380df518170f..be5a4c6f19040c6e5bf1acbb34f9598e6eec0b2f 100644 (file)
@@ -51,9 +51,10 @@ 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.
+(capturing) buffer from the driver's outgoing queue.
+They just set the ``index`` field withe the buffer ID to be queued.
+When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`,
+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
index 2f09455a993a13eb8e1774e1317f9ef31bd2dacf..aca542ec125c96bdc95411359fceffcaee9898a0 100644 (file)
@@ -13,14 +13,15 @@ The following technologies are described:
  * Generic Segmentation Offload - GSO
  * Generic Receive Offload - GRO
  * Partial Generic Segmentation Offload - GSO_PARTIAL
+ * SCTP accelleration with GSO - GSO_BY_FRAGS
 
 TCP Segmentation Offload
 ========================
 
 TCP segmentation allows a device to segment a single frame into multiple
 frames with a data payload size specified in skb_shinfo()->gso_size.
-When TCP segmentation requested the bit for either SKB_GSO_TCP or
-SKB_GSO_TCP6 should be set in skb_shinfo()->gso_type and
+When TCP segmentation requested the bit for either SKB_GSO_TCPV4 or
+SKB_GSO_TCPV6 should be set in skb_shinfo()->gso_type and
 skb_shinfo()->gso_size should be set to a non-zero value.
 
 TCP segmentation is dependent on support for the use of partial checksum
@@ -49,6 +50,10 @@ datagram into multiple IPv4 fragments.  Many of the requirements for UDP
 fragmentation offload are the same as TSO.  However the IPv4 ID for
 fragments should not increment as a single IPv4 datagram is fragmented.
 
+UFO is deprecated: modern kernels will no longer generate UFO skbs, but can
+still receive them from tuntap and similar devices. Offload of UDP-based
+tunnel protocols is still supported.
+
 IPIP, SIT, GRE, UDP Tunnel, and Remote Checksum Offloads
 ========================================================
 
@@ -83,10 +88,10 @@ SKB_GSO_UDP_TUNNEL_CSUM.  These two additional tunnel types reflect the
 fact that the outer header also requests to have a non-zero checksum
 included in the outer header.
 
-Finally there is SKB_GSO_REMCSUM which indicates that a given tunnel header
-has requested a remote checksum offload.  In this case the inner headers
-will be left with a partial checksum and only the outer header checksum
-will be computed.
+Finally there is SKB_GSO_TUNNEL_REMCSUM which indicates that a given tunnel
+header has requested a remote checksum offload.  In this case the inner
+headers will be left with a partial checksum and only the outer header
+checksum will be computed.
 
 Generic Segmentation Offload
 ============================
@@ -128,3 +133,38 @@ values for if the header was simply duplicated.  The one exception to this
 is the outer IPv4 ID field.  It is up to the device drivers to guarantee
 that the IPv4 ID field is incremented in the case that a given header does
 not have the DF bit set.
+
+SCTP accelleration with GSO
+===========================
+
+SCTP - despite the lack of hardware support - can still take advantage of
+GSO to pass one large packet through the network stack, rather than
+multiple small packets.
+
+This requires a different approach to other offloads, as SCTP packets
+cannot be just segmented to (P)MTU. Rather, the chunks must be contained in
+IP segments, padding respected. So unlike regular GSO, SCTP can't just
+generate a big skb, set gso_size to the fragmentation point and deliver it
+to IP layer.
+
+Instead, the SCTP protocol layer builds an skb with the segments correctly
+padded and stored as chained skbs, and skb_segment() splits based on those.
+To signal this, gso_size is set to the special value GSO_BY_FRAGS.
+
+Therefore, any code in the core networking stack must be aware of the
+possibility that gso_size will be GSO_BY_FRAGS and handle that case
+appropriately.
+
+There are some helpers to make this easier:
+
+ - skb_is_gso(skb) && skb_is_gso_sctp(skb) is the best way to see if
+   an skb is an SCTP GSO skb.
+
+ - For size checks, the skb_gso_validate_*_len family of helpers correctly
+   considers GSO_BY_FRAGS.
+
+ - For manipulating packets, skb_increase_gso_size and skb_decrease_gso_size
+   will check for GSO_BY_FRAGS and WARN if asked to manipulate these skbs.
+
+This also affects drivers with the NETIF_F_FRAGLIST & NETIF_F_GSO_SCTP bits
+set. Note also that NETIF_F_GSO_SCTP is included in NETIF_F_GSO_SOFTWARE.
index 39aa9e8697ccf8f1ad3e0d7210294eff20bd9cb0..fbedcc39460bb28b156db85ac085fbb077d3fe6e 100644 (file)
@@ -36,8 +36,7 @@ import glob
 
 from docutils import nodes, statemachine
 from docutils.statemachine import ViewList
-from docutils.parsers.rst import directives
-from sphinx.util.compat import Directive
+from docutils.parsers.rst import directives, Directive
 from sphinx.ext.autodoc import AutodocReporter
 
 __version__  = '1.0'
index 792fa8717d133e1aa7d6c73a8b948d53150e6d78..d6b3ff51a14fd96600cc9f65f8ed11cd5c64b768 100644 (file)
@@ -123,14 +123,15 @@ memory layout to fit in user mode), check KVM_CAP_MIPS_VZ and use the
 flag KVM_VM_MIPS_VZ.
 
 
-4.3 KVM_GET_MSR_INDEX_LIST
+4.3 KVM_GET_MSR_INDEX_LIST, KVM_GET_MSR_FEATURE_INDEX_LIST
 
-Capability: basic
+Capability: basic, KVM_CAP_GET_MSR_FEATURES for KVM_GET_MSR_FEATURE_INDEX_LIST
 Architectures: x86
-Type: system
+Type: system ioctl
 Parameters: struct kvm_msr_list (in/out)
 Returns: 0 on success; -1 on error
 Errors:
+  EFAULT:    the msr index list cannot be read from or written to
   E2BIG:     the msr index list is to be to fit in the array specified by
              the user.
 
@@ -139,16 +140,23 @@ struct kvm_msr_list {
        __u32 indices[0];
 };
 
-This ioctl returns the guest msrs that are supported.  The list varies
-by kvm version and host processor, but does not change otherwise.  The
-user fills in the size of the indices array in nmsrs, and in return
-kvm adjusts nmsrs to reflect the actual number of msrs and fills in
-the indices array with their numbers.
+The user fills in the size of the indices array in nmsrs, and in return
+kvm adjusts nmsrs to reflect the actual number of msrs and fills in the
+indices array with their numbers.
+
+KVM_GET_MSR_INDEX_LIST returns the guest msrs that are supported.  The list
+varies by kvm version and host processor, but does not change otherwise.
 
 Note: if kvm indicates supports MCE (KVM_CAP_MCE), then the MCE bank MSRs are
 not returned in the MSR list, as different vcpus can have a different number
 of banks, as set via the KVM_X86_SETUP_MCE ioctl.
 
+KVM_GET_MSR_FEATURE_INDEX_LIST returns the list of MSRs that can be passed
+to the KVM_GET_MSRS system ioctl.  This lets userspace probe host capabilities
+and processor features that are exposed via MSRs (e.g., VMX capabilities).
+This list also varies by kvm version and host processor, but does not change
+otherwise.
+
 
 4.4 KVM_CHECK_EXTENSION
 
@@ -475,14 +483,22 @@ Support for this has been removed.  Use KVM_SET_GUEST_DEBUG instead.
 
 4.18 KVM_GET_MSRS
 
-Capability: basic
+Capability: basic (vcpu), KVM_CAP_GET_MSR_FEATURES (system)
 Architectures: x86
-Type: vcpu ioctl
+Type: system ioctl, vcpu ioctl
 Parameters: struct kvm_msrs (in/out)
-Returns: 0 on success, -1 on error
+Returns: number of msrs successfully returned;
+        -1 on error
+
+When used as a system ioctl:
+Reads the values of MSR-based features that are available for the VM.  This
+is similar to KVM_GET_SUPPORTED_CPUID, but it returns MSR indices and values.
+The list of msr-based features can be obtained using KVM_GET_MSR_FEATURE_INDEX_LIST
+in a system ioctl.
 
+When used as a vcpu ioctl:
 Reads model-specific registers from the vcpu.  Supported msr indices can
-be obtained using KVM_GET_MSR_INDEX_LIST.
+be obtained using KVM_GET_MSR_INDEX_LIST in a system ioctl.
 
 struct kvm_msrs {
        __u32 nmsrs; /* number of msrs in entries */
index dcab6dc11e3b08117456f10903ad3ac2fa29eb99..87a7506f31c2b7f9b03be131ba3b3ef1c85f360b 100644 (file)
@@ -58,6 +58,10 @@ KVM_FEATURE_PV_TLB_FLUSH           ||     9 || guest checks this feature bit
                                    ||       || before enabling paravirtualized
                                    ||       || tlb flush.
 ------------------------------------------------------------------------------
+KVM_FEATURE_ASYNC_PF_VMEXIT        ||    10 || paravirtualized async PF VM exit
+                                   ||       || can be enabled by setting bit 2
+                                   ||       || when writing to msr 0x4b564d02
+------------------------------------------------------------------------------
 KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||    24 || host will warn if no guest-side
                                    ||       || per-cpu warps are expected in
                                    ||       || kvmclock.
index 1ebecc115dc6efdbbfa76eb4ab329f5b1d8b765e..f3f0d57ced8e1827fe8e8e6dc49808b18c9253fb 100644 (file)
@@ -170,7 +170,8 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02
        when asynchronous page faults are enabled on the vcpu 0 when
        disabled. Bit 1 is 1 if asynchronous page faults can be injected
        when vcpu is in cpl == 0. Bit 2 is 1 if asynchronous page faults
-       are delivered to L1 as #PF vmexits.
+       are delivered to L1 as #PF vmexits.  Bit 2 can be set only if
+       KVM_FEATURE_ASYNC_PF_VMEXIT is present in CPUID.
 
        First 4 byte of 64 byte memory location will be written to by
        the hypervisor at the time of asynchronous page fault (APF)
index 756fd76b78a6f95156abb68e7405e01384a75067..71c30984e94d58e9e1de13ac0ee05ef7655a020a 100644 (file)
@@ -671,7 +671,7 @@ occupancy of the real time threads on these cores.
 # mkdir p1
 
 Move the cpus 4-7 over to p1
-# echo f0 > p0/cpus
+# echo f0 > p1/cpus
 
 View the llc occupancy snapshot
 
index f3e9d7e9ed6cbcbe4e731881ffb5203925b758db..2953e3ec9a0259f102ce40b9c28340f761c2df4e 100644 (file)
@@ -108,7 +108,7 @@ The topology of a system is described in the units of:
 
     The number of online threads is also printed in /proc/cpuinfo "siblings."
 
-  - topology_sibling_mask():
+  - topology_sibling_cpumask():
 
     The cpumask contains all online threads in the core to which a thread
     belongs.
index 3bdc260e36b7a7eaac26003b187c436655fc3412..98d14aee828a05c7d1733235b97f9c396dc78341 100644 (file)
@@ -841,13 +841,6 @@ F: sound/soc/codecs/ad7*
 F:     sound/soc/codecs/ssm*
 F:     sound/soc/codecs/sigmadsp.*
 
-ANALOG DEVICES INC ASOC DRIVERS
-L:     adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
-L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
-W:     http://blackfin.uclinux.org/
-S:     Supported
-F:     sound/soc/blackfin/*
-
 ANALOG DEVICES INC DMA DRIVERS
 M:     Lars-Peter Clausen <lars@metafoo.de>
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -1238,7 +1231,7 @@ F:        drivers/clk/at91
 
 ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
 M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-M:     Alexandre Belloni <alexandre.belloni@free-electrons.com>
+M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.linux4sam.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git
@@ -1590,7 +1583,7 @@ ARM/Marvell Dove/MV78xx0/Orion SOC support
 M:     Jason Cooper <jason@lakedaemon.net>
 M:     Andrew Lunn <andrew@lunn.ch>
 M:     Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
-M:     Gregory Clement <gregory.clement@free-electrons.com>
+M:     Gregory Clement <gregory.clement@bootlin.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     Documentation/devicetree/bindings/soc/dove/
@@ -1604,7 +1597,7 @@ F:        arch/arm/boot/dts/orion5x*
 ARM/Marvell Kirkwood and Armada 370, 375, 38x, 39x, XP, 3700, 7K/8K SOC support
 M:     Jason Cooper <jason@lakedaemon.net>
 M:     Andrew Lunn <andrew@lunn.ch>
-M:     Gregory Clement <gregory.clement@free-electrons.com>
+M:     Gregory Clement <gregory.clement@bootlin.com>
 M:     Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -1999,8 +1992,10 @@ M:       Maxime Coquelin <mcoquelin.stm32@gmail.com>
 M:     Alexandre Torgue <alexandre.torgue@st.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git stm32-next
 N:     stm32
+F:     arch/arm/boot/dts/stm32*
+F:     arch/arm/mach-stm32/
 F:     drivers/clocksource/armv7m_systick.c
 
 ARM/TANGO ARCHITECTURE
@@ -7600,8 +7595,10 @@ F:       mm/kasan/
 F:     scripts/Makefile.kasan
 
 KCONFIG
+M:     Masahiro Yamada <yamada.masahiro@socionext.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kconfig
 L:     linux-kbuild@vger.kernel.org
-S:     Orphan
+S:     Maintained
 F:     Documentation/kbuild/kconfig-language.txt
 F:     scripts/kconfig/
 
@@ -7909,7 +7906,6 @@ S:        Maintained
 F:     scripts/leaking_addresses.pl
 
 LED SUBSYSTEM
-M:     Richard Purdie <rpurdie@rpsys.net>
 M:     Jacek Anaszewski <jacek.anaszewski@gmail.com>
 M:     Pavel Machek <pavel@ucw.cz>
 L:     linux-leds@vger.kernel.org
@@ -9206,6 +9202,7 @@ MIPS GENERIC PLATFORM
 M:     Paul Burton <paul.burton@mips.com>
 L:     linux-mips@linux-mips.org
 S:     Supported
+F:     Documentation/devicetree/bindings/power/mti,mips-cpc.txt
 F:     arch/mips/generic/
 F:     arch/mips/tools/generic-board-config.sh
 
@@ -9921,6 +9918,13 @@ F:       Documentation/ABI/stable/sysfs-bus-nvmem
 F:     include/linux/nvmem-consumer.h
 F:     include/linux/nvmem-provider.h
 
+NXP SGTL5000 DRIVER
+M:     Fabio Estevam <fabio.estevam@nxp.com>
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Maintained
+F:     Documentation/devicetree/bindings/sound/sgtl5000.txt
+F:     sound/soc/codecs/sgtl5000*
+
 NXP TDA998X DRM DRIVER
 M:     Russell King <linux@armlinux.org.uk>
 S:     Supported
@@ -9945,6 +9949,7 @@ F:        drivers/nfc/nxp-nci
 
 OBJTOOL
 M:     Josh Poimboeuf <jpoimboe@redhat.com>
+M:     Peter Zijlstra <peterz@infradead.org>
 S:     Supported
 F:     tools/objtool/
 
@@ -10322,7 +10327,7 @@ F:      drivers/oprofile/
 F:     include/linux/oprofile.h
 
 ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
-M:     Mark Fasheh <mfasheh@versity.com>
+M:     Mark Fasheh <mark@fasheh.com>
 M:     Joel Becker <jlbec@evilplan.org>
 L:     ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
 W:     http://ocfs2.wiki.kernel.org
@@ -10832,6 +10837,7 @@ F:      drivers/platform/x86/peaq-wmi.c
 PER-CPU MEMORY ALLOCATOR
 M:     Tejun Heo <tj@kernel.org>
 M:     Christoph Lameter <cl@linux.com>
+M:     Dennis Zhou <dennisszhou@gmail.com>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git
 S:     Maintained
 F:     include/linux/percpu*.h
@@ -10925,6 +10931,17 @@ L:     linux-gpio@vger.kernel.org
 S:     Supported
 F:     drivers/pinctrl/pinctrl-at91-pio4.*
 
+PIN CONTROLLER - FREESCALE
+M:     Dong Aisheng <aisheng.dong@nxp.com>
+M:     Fabio Estevam <festevam@gmail.com>
+M:     Shawn Guo <shawnguo@kernel.org>
+M:     Stefan Agner <stefan@agner.ch>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
+L:     linux-gpio@vger.kernel.org
+S:     Maintained
+F:     drivers/pinctrl/freescale/
+F:     Documentation/devicetree/bindings/pinctrl/fsl,*
+
 PIN CONTROLLER - INTEL
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
 M:     Heikki Krogerus <heikki.krogerus@linux.intel.com>
@@ -12091,6 +12108,7 @@ M:      Sylwester Nawrocki <s.nawrocki@samsung.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
 F:     sound/soc/samsung/
+F:     Documentation/devicetree/bindings/sound/samsung*
 
 SAMSUNG EXYNOS PSEUDO RANDOM NUMBER GENERATOR (RNG) DRIVER
 M:     Krzysztof Kozlowski <krzk@kernel.org>
index 79ad2bfa24b68f279af011f82e87f16d64d1440d..7ba478ab8c82c0a4c0800fcc57921e541b15c8b9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc7
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
@@ -388,7 +388,7 @@ PYTHON              = python
 CHECK          = sparse
 
 CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-                 -Wbitwise -Wno-return-void $(CF)
+                 -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
 NOSTDINC_FLAGS  =
 CFLAGS_MODULE   =
 AFLAGS_MODULE   =
@@ -489,6 +489,11 @@ KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 endif
 
+RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register
+RETPOLINE_CFLAGS_CLANG := -mretpoline-external-thunk
+RETPOLINE_CFLAGS := $(call cc-option,$(RETPOLINE_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_CFLAGS_CLANG)))
+export RETPOLINE_CFLAGS
+
 ifeq ($(config-targets),1)
 # ===========================================================================
 # *config targets only - make sure prerequisites are updated, and descend
@@ -579,10 +584,9 @@ ifeq ($(KBUILD_EXTMOD),)
 # To avoid any implicit rule to kick in, define an empty command
 $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
 
-# If .config is newer than include/config/auto.conf, someone tinkered
-# with it and forgot to run make oldconfig.
-# if auto.conf.cmd is missing then we are probably in a cleaned tree so
-# we execute the config step to be sure to catch updated Kconfig files
+# The actual configuration files used during the build are stored in
+# include/generated/ and include/config/. Update them if .config is newer than
+# include/config/auto.conf (which mirrors .config).
 include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
        $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 else
@@ -822,6 +826,15 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
 # disable invalid "can't wrap" optimizations for signed / pointers
 KBUILD_CFLAGS  += $(call cc-option,-fno-strict-overflow)
 
+# clang sets -fmerge-all-constants by default as optimization, but this
+# is non-conforming behavior for C and in fact breaks the kernel, so we
+# need to disable it here generally.
+KBUILD_CFLAGS  += $(call cc-option,-fno-merge-all-constants)
+
+# for gcc -fno-merge-all-constants disables everything, but it is fine
+# to have actual conforming behavior enabled.
+KBUILD_CFLAGS  += $(call cc-option,-fmerge-constants)
+
 # Make sure -fstack-check isn't enabled (like gentoo apparently did)
 KBUILD_CFLAGS  += $(call cc-option,-fno-stack-check,)
 
@@ -857,8 +870,7 @@ KBUILD_AFLAGS   += $(ARCH_AFLAGS)   $(KAFLAGS)
 KBUILD_CFLAGS   += $(ARCH_CFLAGS)   $(KCFLAGS)
 
 # Use --build-id when available.
-LDFLAGS_BUILD_ID := $(patsubst -Wl$(comma)%,%,\
-                             $(call cc-ldoption, -Wl$(comma)--build-id,))
+LDFLAGS_BUILD_ID := $(call ld-option, --build-id)
 KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
 LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
 
index 46ebf14aed4e55348b1b96aa82516348e00171c3..8a2b331e43febb724f2072498b1c4b31daa6f757 100644 (file)
@@ -6,7 +6,6 @@
  * Atomic exchange routines.
  */
 
-#define __ASM__MB
 #define ____xchg(type, args...)                __xchg ## type ## _local(args)
 #define ____cmpxchg(type, args...)     __cmpxchg ## type ## _local(args)
 #include <asm/xchg.h>
        cmpxchg_local((ptr), (o), (n));                                 \
 })
 
-#ifdef CONFIG_SMP
-#undef __ASM__MB
-#define __ASM__MB      "\tmb\n"
-#endif
 #undef ____xchg
 #undef ____cmpxchg
 #define ____xchg(type, args...)                __xchg ##type(args)
@@ -64,7 +59,6 @@
        cmpxchg((ptr), (o), (n));                                       \
 })
 
-#undef __ASM__MB
 #undef ____cmpxchg
 
 #endif /* _ALPHA_CMPXCHG_H */
index 68dfb3cb71454384dd187edfd0dded0fe4b65117..e2b59fac5257de10134c8d0c116d8a4827b76a09 100644 (file)
  * Atomic exchange.
  * Since it can be used to implement critical sections
  * it must clobber "memory" (also for interrupts in UP).
+ *
+ * The leading and the trailing memory barriers guarantee that these
+ * operations are fully ordered.
+ *
  */
 
 static inline unsigned long
@@ -19,6 +23,7 @@ ____xchg(_u8, volatile char *m, unsigned long val)
 {
        unsigned long ret, tmp, addr64;
 
+       smp_mb();
        __asm__ __volatile__(
        "       andnot  %4,7,%3\n"
        "       insbl   %1,%4,%1\n"
@@ -28,12 +33,12 @@ ____xchg(_u8, volatile char *m, unsigned long val)
        "       or      %1,%2,%2\n"
        "       stq_c   %2,0(%3)\n"
        "       beq     %2,2f\n"
-               __ASM__MB
        ".subsection 2\n"
        "2:     br      1b\n"
        ".previous"
        : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
        : "r" ((long)m), "1" (val) : "memory");
+       smp_mb();
 
        return ret;
 }
@@ -43,6 +48,7 @@ ____xchg(_u16, volatile short *m, unsigned long val)
 {
        unsigned long ret, tmp, addr64;
 
+       smp_mb();
        __asm__ __volatile__(
        "       andnot  %4,7,%3\n"
        "       inswl   %1,%4,%1\n"
@@ -52,12 +58,12 @@ ____xchg(_u16, volatile short *m, unsigned long val)
        "       or      %1,%2,%2\n"
        "       stq_c   %2,0(%3)\n"
        "       beq     %2,2f\n"
-               __ASM__MB
        ".subsection 2\n"
        "2:     br      1b\n"
        ".previous"
        : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
        : "r" ((long)m), "1" (val) : "memory");
+       smp_mb();
 
        return ret;
 }
@@ -67,17 +73,18 @@ ____xchg(_u32, volatile int *m, unsigned long val)
 {
        unsigned long dummy;
 
+       smp_mb();
        __asm__ __volatile__(
        "1:     ldl_l %0,%4\n"
        "       bis $31,%3,%1\n"
        "       stl_c %1,%2\n"
        "       beq %1,2f\n"
-               __ASM__MB
        ".subsection 2\n"
        "2:     br 1b\n"
        ".previous"
        : "=&r" (val), "=&r" (dummy), "=m" (*m)
        : "rI" (val), "m" (*m) : "memory");
+       smp_mb();
 
        return val;
 }
@@ -87,17 +94,18 @@ ____xchg(_u64, volatile long *m, unsigned long val)
 {
        unsigned long dummy;
 
+       smp_mb();
        __asm__ __volatile__(
        "1:     ldq_l %0,%4\n"
        "       bis $31,%3,%1\n"
        "       stq_c %1,%2\n"
        "       beq %1,2f\n"
-               __ASM__MB
        ".subsection 2\n"
        "2:     br 1b\n"
        ".previous"
        : "=&r" (val), "=&r" (dummy), "=m" (*m)
        : "rI" (val), "m" (*m) : "memory");
+       smp_mb();
 
        return val;
 }
@@ -128,10 +136,12 @@ ____xchg(, volatile void *ptr, unsigned long x, int size)
  * store NEW in MEM.  Return the initial value in MEM.  Success is
  * indicated by comparing RETURN with OLD.
  *
- * The memory barrier should be placed in SMP only when we actually
- * make the change. If we don't change anything (so if the returned
- * prev is equal to old) then we aren't acquiring anything new and
- * we don't need any memory barrier as far I can tell.
+ * The leading and the trailing memory barriers guarantee that these
+ * operations are fully ordered.
+ *
+ * The trailing memory barrier is placed in SMP unconditionally, in
+ * order to guarantee that dependency ordering is preserved when a
+ * dependency is headed by an unsuccessful operation.
  */
 
 static inline unsigned long
@@ -139,6 +149,7 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
 {
        unsigned long prev, tmp, cmp, addr64;
 
+       smp_mb();
        __asm__ __volatile__(
        "       andnot  %5,7,%4\n"
        "       insbl   %1,%5,%1\n"
@@ -150,13 +161,13 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
        "       or      %1,%2,%2\n"
        "       stq_c   %2,0(%4)\n"
        "       beq     %2,3f\n"
-               __ASM__MB
        "2:\n"
        ".subsection 2\n"
        "3:     br      1b\n"
        ".previous"
        : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
        : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+       smp_mb();
 
        return prev;
 }
@@ -166,6 +177,7 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
 {
        unsigned long prev, tmp, cmp, addr64;
 
+       smp_mb();
        __asm__ __volatile__(
        "       andnot  %5,7,%4\n"
        "       inswl   %1,%5,%1\n"
@@ -177,13 +189,13 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
        "       or      %1,%2,%2\n"
        "       stq_c   %2,0(%4)\n"
        "       beq     %2,3f\n"
-               __ASM__MB
        "2:\n"
        ".subsection 2\n"
        "3:     br      1b\n"
        ".previous"
        : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
        : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+       smp_mb();
 
        return prev;
 }
@@ -193,6 +205,7 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
 {
        unsigned long prev, cmp;
 
+       smp_mb();
        __asm__ __volatile__(
        "1:     ldl_l %0,%5\n"
        "       cmpeq %0,%3,%1\n"
@@ -200,13 +213,13 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
        "       mov %4,%1\n"
        "       stl_c %1,%2\n"
        "       beq %1,3f\n"
-               __ASM__MB
        "2:\n"
        ".subsection 2\n"
        "3:     br 1b\n"
        ".previous"
        : "=&r"(prev), "=&r"(cmp), "=m"(*m)
        : "r"((long) old), "r"(new), "m"(*m) : "memory");
+       smp_mb();
 
        return prev;
 }
@@ -216,6 +229,7 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
 {
        unsigned long prev, cmp;
 
+       smp_mb();
        __asm__ __volatile__(
        "1:     ldq_l %0,%5\n"
        "       cmpeq %0,%3,%1\n"
@@ -223,13 +237,13 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
        "       mov %4,%1\n"
        "       stq_c %1,%2\n"
        "       beq %1,3f\n"
-               __ASM__MB
        "2:\n"
        ".subsection 2\n"
        "3:     br 1b\n"
        ".previous"
        : "=&r"(prev), "=&r"(cmp), "=m"(*m)
        : "r"((long) old), "r"(new), "m"(*m) : "memory");
+       smp_mb();
 
        return prev;
 }
index f3a80cf164cc92a0860ddb77f5402dd7d8856ab0..d76bf4a8374016043963f1c04d42700e64ad605a 100644 (file)
@@ -484,7 +484,6 @@ config ARC_CURR_IN_REG
 
 config ARC_EMUL_UNALIGNED
        bool "Emulate unaligned memory access (userspace only)"
-       default N
        select SYSCTL_ARCH_UNALIGN_NO_WARN
        select SYSCTL_ARCH_UNALIGN_ALLOW
        depends on ISA_ARCOMPACT
index 70aec7d6ca600c2889d0a78bc3dac5b5fcb5b967..626b694c7be75ccf7868d7423aca79fb58eef586 100644 (file)
@@ -17,6 +17,6 @@
        compatible = "snps,axs101", "snps,arc-sdp";
 
        chosen {
-               bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 video=1280x720@60";
+               bootargs = "earlycon=uart8250,mmio32,0xe0022000,115200n8 console=tty0 console=ttyS3,115200n8 consoleblank=0 video=1280x720@60 print-fatal-signals=1";
        };
 };
index 74d070cd3c13a723fef1a2b3cd91cd2919392762..47b74fbc403c21cc2f493f6f84d6216b7c5ef5c1 100644 (file)
                        };
 
                        eeprom@0x54{
-                               compatible = "24c01";
+                               compatible = "atmel,24c01";
                                reg = <0x54>;
                                pagesize = <0x8>;
                        };
 
                        eeprom@0x57{
-                               compatible = "24c04";
+                               compatible = "atmel,24c04";
                                reg = <0x57>;
                                pagesize = <0x8>;
                        };
index 215cddd0b63baa4d1f865828e1df50914526e64e..0c603308aeb360880bca3a3403a74044cb1c12bc 100644 (file)
@@ -22,7 +22,7 @@
        };
 
        chosen {
-               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=ttyS0,115200n8 debug";
+               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=ttyS0,115200n8 debug print-fatal-signals=1";
        };
 
        aliases {
index 5ee96b067c085ce1f061e0aac02732d63d4ecf7e..ff2f2c70c545645f7cb38a526914378edc303aa1 100644 (file)
@@ -17,7 +17,7 @@
        interrupt-parent = <&core_intc>;
 
        chosen {
-               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
+               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1";
        };
 
        aliases {
index 8d787b251f73746191cfea3bd176bfb2869eccce..8e2489b16b0aeecb9bc83de255ccad3eeb33efd5 100644 (file)
@@ -24,7 +24,7 @@
        };
 
        chosen {
-               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
+               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1";
        };
 
        aliases {
index 4f98ebf71fd836624b248aa0cd107fb892bb76b2..ed12f494721df91f4597b2ead8b1c7ecd5a4f5e2 100644 (file)
@@ -15,7 +15,7 @@
        interrupt-parent = <&core_intc>;
 
        chosen {
-               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
+               bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1";
        };
 
        aliases {
index 3c391ba565ed080cfad8b66f4c3395975eec90da..7842e5eb4ab5cbb73c1bac4d881d7b332979bdaa 100644 (file)
@@ -20,7 +20,7 @@
                /* this is for console on PGU */
                /* bootargs = "console=tty0 consoleblank=0"; */
                /* this is for console on serial */
-               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug video=640x480-24";
+               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug video=640x480-24 print-fatal-signals=1";
        };
 
        aliases {
index 14a727cbf4c98e12590f0ad74148f24971f772f4..b8838cf2b4ec72ab119e72f367c6ef6184a72bce 100644 (file)
@@ -20,7 +20,7 @@
                /* this is for console on PGU */
                /* bootargs = "console=tty0 consoleblank=0"; */
                /* this is for console on serial */
-               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug video=640x480-24";
+               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug video=640x480-24 print-fatal-signals=1";
        };
 
        aliases {
index 5052917d4a99490ea77d2e18cc03b97ce3722f3a..72a2c723f1f7af826b07c49a416bf3265ed39f89 100644 (file)
@@ -18,7 +18,7 @@
 
        chosen {
                /* this is for console on serial */
-               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblan=0 debug video=640x480-24";
+               bootargs = "earlycon=uart8250,mmio32,0xf0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblan=0 debug video=640x480-24 print-fatal-signals=1";
        };
 
        aliases {
index ea022d47896cef2761bbb8a147844c506f358621..21ec82466d62c89922566ec3bf32551c2dce003b 100644 (file)
@@ -23,7 +23,8 @@ void die(const char *str, struct pt_regs *regs, unsigned long address);
 
 #define BUG()  do {                                                            \
        pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
-       dump_stack();                                                           \
+       barrier_before_unreachable();                                           \
+       __builtin_trap();                                                       \
 } while (0)
 
 #define HAVE_ARCH_BUG
index 257a68f3c2feef3a369093f5bade883e814b7648..309f4e6721b3e22829847f88a4da884fdc9edf93 100644 (file)
 .macro FAKE_RET_FROM_EXCPN
        lr      r9, [status32]
        bic     r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
-       or      r9, r9, (STATUS_L_MASK|STATUS_IE_MASK)
+       or      r9, r9, STATUS_IE_MASK
        kflag   r9
 .endm
 
index f61a52b01625b106143b089570b327b585e5a254..5fe84e481654ebe76a483bf81c2a11ffe870322d 100644 (file)
@@ -22,10 +22,79 @@ static DEFINE_RAW_SPINLOCK(mcip_lock);
 
 static char smp_cpuinfo_buf[128];
 
+/*
+ * Set mask to halt GFRC if any online core in SMP cluster is halted.
+ * Only works for ARC HS v3.0+, on earlier versions has no effect.
+ */
+static void mcip_update_gfrc_halt_mask(int cpu)
+{
+       struct bcr_generic gfrc;
+       unsigned long flags;
+       u32 gfrc_halt_mask;
+
+       READ_BCR(ARC_REG_GFRC_BUILD, gfrc);
+
+       /*
+        * CMD_GFRC_SET_CORE and CMD_GFRC_READ_CORE commands were added in
+        * GFRC 0x3 version.
+        */
+       if (gfrc.ver < 0x3)
+               return;
+
+       raw_spin_lock_irqsave(&mcip_lock, flags);
+
+       __mcip_cmd(CMD_GFRC_READ_CORE, 0);
+       gfrc_halt_mask = read_aux_reg(ARC_REG_MCIP_READBACK);
+       gfrc_halt_mask |= BIT(cpu);
+       __mcip_cmd_data(CMD_GFRC_SET_CORE, 0, gfrc_halt_mask);
+
+       raw_spin_unlock_irqrestore(&mcip_lock, flags);
+}
+
+static void mcip_update_debug_halt_mask(int cpu)
+{
+       u32 mcip_mask = 0;
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&mcip_lock, flags);
+
+       /*
+        * mcip_mask is same for CMD_DEBUG_SET_SELECT and CMD_DEBUG_SET_MASK
+        * commands. So read it once instead of reading both CMD_DEBUG_READ_MASK
+        * and CMD_DEBUG_READ_SELECT.
+        */
+       __mcip_cmd(CMD_DEBUG_READ_SELECT, 0);
+       mcip_mask = read_aux_reg(ARC_REG_MCIP_READBACK);
+
+       mcip_mask |= BIT(cpu);
+
+       __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, mcip_mask);
+       /*
+        * Parameter specified halt cause:
+        * STATUS32[H]/actionpoint/breakpoint/self-halt
+        * We choose all of them (0xF).
+        */
+       __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xF, mcip_mask);
+
+       raw_spin_unlock_irqrestore(&mcip_lock, flags);
+}
+
 static void mcip_setup_per_cpu(int cpu)
 {
+       struct mcip_bcr mp;
+
+       READ_BCR(ARC_REG_MCIP_BCR, mp);
+
        smp_ipi_irq_setup(cpu, IPI_IRQ);
        smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ);
+
+       /* Update GFRC halt mask as new CPU came online */
+       if (mp.gfrc)
+               mcip_update_gfrc_halt_mask(cpu);
+
+       /* Update MCIP debug mask as new CPU came online */
+       if (mp.dbg)
+               mcip_update_debug_halt_mask(cpu);
 }
 
 static void mcip_ipi_send(int cpu)
@@ -101,11 +170,6 @@ static void mcip_probe_n_setup(void)
                IS_AVAIL1(mp.gfrc, "GFRC"));
 
        cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
-
-       if (mp.dbg) {
-               __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
-               __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
-       }
 }
 
 struct plat_smp_ops plat_smp_ops = {
index 9d27331fe69a0eb441b34e51324138ef375070b0..b2cae79a25d716165eaf65060cb8ed0be11f3b6c 100644 (file)
@@ -51,7 +51,7 @@ static const struct id_to_str arc_cpu_rel[] = {
        { 0x51, "R2.0" },
        { 0x52, "R2.1" },
        { 0x53, "R3.0" },
-       { 0x54, "R4.0" },
+       { 0x54, "R3.10a" },
 #endif
        { 0x00, NULL   }
 };
@@ -373,7 +373,7 @@ static void arc_chk_core_config(void)
 {
        struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
        int saved = 0, present = 0;
-       char *opt_nm = NULL;;
+       char *opt_nm = NULL;
 
        if (!cpu->extn.timer0)
                panic("Timer0 is not present!\n");
index efe8b4200a676529a9f3f0af52d50faca176a1e3..21d86c36692b4f9bbf2e6c255832d7c98377c545 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/reboot.h>
 #include <linux/irqdomain.h>
 #include <linux/export.h>
+#include <linux/of_fdt.h>
 
 #include <asm/processor.h>
 #include <asm/setup.h>
@@ -47,6 +48,42 @@ void __init smp_prepare_boot_cpu(void)
 {
 }
 
+static int __init arc_get_cpu_map(const char *name, struct cpumask *cpumask)
+{
+       unsigned long dt_root = of_get_flat_dt_root();
+       const char *buf;
+
+       buf = of_get_flat_dt_prop(dt_root, name, NULL);
+       if (!buf)
+               return -EINVAL;
+
+       if (cpulist_parse(buf, cpumask))
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * Read from DeviceTree and setup cpu possible mask. If there is no
+ * "possible-cpus" property in DeviceTree pretend all [0..NR_CPUS-1] exist.
+ */
+static void __init arc_init_cpu_possible(void)
+{
+       struct cpumask cpumask;
+
+       if (arc_get_cpu_map("possible-cpus", &cpumask)) {
+               pr_warn("Failed to get possible-cpus from dtb, pretending all %u cpus exist\n",
+                       NR_CPUS);
+
+               cpumask_setall(&cpumask);
+       }
+
+       if (!cpumask_test_cpu(0, &cpumask))
+               panic("Master cpu (cpu[0]) is missed in cpu possible mask!");
+
+       init_cpu_possible(&cpumask);
+}
+
 /*
  * Called from setup_arch() before calling setup_processor()
  *
@@ -58,10 +95,7 @@ void __init smp_prepare_boot_cpu(void)
  */
 void __init smp_init_cpus(void)
 {
-       unsigned int i;
-
-       for (i = 0; i < NR_CPUS; i++)
-               set_cpu_possible(i, true);
+       arc_init_cpu_possible();
 
        if (plat_smp_ops.init_early_smp)
                plat_smp_ops.init_early_smp();
@@ -70,16 +104,12 @@ void __init smp_init_cpus(void)
 /* called from init ( ) =>  process 1 */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-       int i;
-
        /*
         * if platform didn't set the present map already, do it now
         * boot cpu is set to present already by init/main.c
         */
-       if (num_present_cpus() <= 1) {
-               for (i = 0; i < max_cpus; i++)
-                       set_cpu_present(i, true);
-       }
+       if (num_present_cpus() <= 1)
+               init_cpu_present(cpu_possible_mask);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
index 333daab7def028761478b4215bf7f50335d4f05d..183391d4d33a4138d04418da4b90d61efe38c6c4 100644 (file)
@@ -366,7 +366,7 @@ static void init_unwind_hdr(struct unwind_table *table,
        return;
 
 ret_err:
-       panic("Attention !!! Dwarf FDE parsing errors\n");;
+       panic("Attention !!! Dwarf FDE parsing errors\n");
 }
 
 #ifdef CONFIG_MODULES
index eee924dfffa6e1baf08221ee5e7e2cd23937d782..2072f3451e9c2127a076873113292a8ae2b5b9cb 100644 (file)
@@ -780,7 +780,10 @@ noinline static void slc_entire_op(const int op)
 
        write_aux_reg(r, ctrl);
 
-       write_aux_reg(ARC_REG_SLC_INVALIDATE, 1);
+       if (op & OP_INV)        /* Inv or flush-n-inv use same cmd reg */
+               write_aux_reg(ARC_REG_SLC_INVALIDATE, 0x1);
+       else
+               write_aux_reg(ARC_REG_SLC_FLUSH, 0x1);
 
        /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
        read_aux_reg(r);
index 18045c38bcf1af1f01b4732ae200cf274e3b6eec..db7cded1b7ada534ef34f49c27cd0dce34d7cdcc 100644 (file)
@@ -55,7 +55,7 @@
                      <0x3ff00100 0x100>;
        };
 
-       smc@0x3404c000 {
+       smc@3404c000 {
                compatible = "brcm,bcm11351-smc", "brcm,kona-smc";
                reg = <0x3404c000 0x400>; /* 1 KiB in SRAM */
        };
index 6dde95f21cef6b53c995b7311ddade7988dd965a..266f2611dc22126705aab35cb6cb67601e9f3704 100644 (file)
@@ -55,7 +55,7 @@
                      <0x3ff00100 0x100>;
        };
 
-       smc@0x3404e000 {
+       smc@3404e000 {
                compatible = "brcm,bcm21664-smc", "brcm,kona-smc";
                reg = <0x3404e000 0x400>; /* 1 KiB in SRAM */
        };
index 0e3d2a5ff2081425bd5ccb0097736ebdef3f99a5..a5c3824c80563cf3222f77af9a6ffe39e22b1e0f 100644 (file)
        soc {
                ranges = <0x7e000000 0x20000000 0x02000000>;
                dma-ranges = <0x40000000 0x00000000 0x20000000>;
+       };
 
-               arm-pmu {
-                       compatible = "arm,arm1176-pmu";
-               };
+       arm-pmu {
+               compatible = "arm,arm1176-pmu";
        };
 };
 
index 1dfd7644277736fb58fa4ad8352091677a000d5e..c933e841388421045d908e0147012d0fca0ae670 100644 (file)
@@ -9,19 +9,19 @@
                         <0x40000000 0x40000000 0x00001000>;
                dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
 
-               local_intc: local_intc {
+               local_intc: local_intc@40000000 {
                        compatible = "brcm,bcm2836-l1-intc";
                        reg = <0x40000000 0x100>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        interrupt-parent = <&local_intc>;
                };
+       };
 
-               arm-pmu {
-                       compatible = "arm,cortex-a7-pmu";
-                       interrupt-parent = <&local_intc>;
-                       interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
-               };
+       arm-pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupt-parent = <&local_intc>;
+               interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        timer {
index efa7d3387ab287fb72e66659644a36903c85e5fc..7704bb029605ed94f3ea8aad77dfe301e4b0beac 100644 (file)
@@ -8,7 +8,7 @@
                         <0x40000000 0x40000000 0x00001000>;
                dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
 
-               local_intc: local_intc {
+               local_intc: local_intc@40000000 {
                        compatible = "brcm,bcm2836-l1-intc";
                        reg = <0x40000000 0x100>;
                        interrupt-controller;
index 18db25a5a66e0c1685457cd7959bdf239db5c76c..9d293decf8d353cdda502f5035212d967c364973 100644 (file)
                        status = "disabled";
                };
 
-               aux: aux@0x7e215000 {
+               aux: aux@7e215000 {
                        compatible = "brcm,bcm2835-aux";
                        #clock-cells = <1>;
                        reg = <0x7e215000 0x8>;
index 6a44b8021702176c63d09e55925ffd3d7e02994e..f0e2008f7490146a22ae06fbc310dbe5cb18c4d5 100644 (file)
@@ -49,7 +49,7 @@
 
        memory {
                device_type = "memory";
-               reg = <0x60000000 0x80000000>;
+               reg = <0x60000000 0x20000000>;
        };
 
        gpio-restart {
index 08568ce24d06fc9576b57c373ab96aedc80c23b7..da8bb9d60f99e6b5af6a3e7ff4c30215f6a91844 100644 (file)
 
                sata: sata@46000000 {
                        /* The ROM uses this muxmode */
-                       cortina,gemini-ata-muxmode = <3>;
+                       cortina,gemini-ata-muxmode = <0>;
                        cortina,gemini-enable-sata-bridge;
                        status = "okay";
                };
index cf42c2f5cdc7f9d13409efbd8db6d18d969f2511..1281bc39b7ab87a430b5edaaacf187b82526186d 100644 (file)
@@ -42,7 +42,7 @@
 
 /dts-v1/;
 
-#include "imx6q.dtsi"
+#include "imx6dl.dtsi"
 #include "imx6qdl-icore-rqs.dtsi"
 
 / {
index c1aa7a4518fbaca19e734795e25b4767a06a6005..a30ee9fcb3ae537dacabc5ff8e942ef26933bcfd 100644 (file)
@@ -71,6 +71,8 @@
 };
 
 &i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
        clock-frequency = <2600000>;
 
        twl: twl@48 {
                >;
        };
 
-
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0)        /* i2c1_scl.i2c1_scl */
+                       OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)        /* i2c1_sda.i2c1_sda */
+               >;
+       };
 };
 
 &omap3_pmx_wkup {
index b50b796e15c778237926e91848e17802f584eb7c..47915447a82660c9a459b7041886be1cb6e52f1a 100644 (file)
@@ -66,6 +66,8 @@
 };
 
 &i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
        clock-frequency = <2600000>;
 
        twl: twl@48 {
                        OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0)        /* hsusb0_data7.hsusb0_data7 */
                >;
        };
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0)        /* i2c1_scl.i2c1_scl */
+                       OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0)        /* i2c1_sda.i2c1_sda */
+               >;
+       };
 };
 
 &uart2 {
index ec2c8baef62ac00bf40b7ae1d28da2eab3a327d0..592e17fd4eeb7ccd1faa8f9d16635cf562092982 100644 (file)
@@ -47,7 +47,7 @@
                        gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;    /* gpio3_83 */
                        wakeup-source;
                        autorepeat;
-                       debounce_interval = <50>;
+                       debounce-interval = <50>;
                };
        };
 
index 3b704cfed69ac1f7b39343925fb2037c9e78e10b..a97458112ff6e80ca198fe1377521372973e8ca4 100644 (file)
                max-frequency = <37500000>;
                clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
                         <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
                resets = <&cru SRST_SDIO>;
                max-frequency = <37500000>;
                clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
                         <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                default-sample-phase = <158>;
                disable-wp;
                dmas = <&pdma 12>;
index 780ec3a99b21f857b414d4d47b8e773cd28c7788..341deaf62ff621ad9122b7b9c2c9950edf5eaa71 100644 (file)
                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
                         <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                pinctrl-names = "default";
                pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
                interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
                         <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                pinctrl-names = "default";
                pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>;
                max-frequency = <37500000>;
                clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
                         <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                bus-width = <8>;
                default-sample-phase = <158>;
                fifo-depth = <0x100>;
index 99cfae875e12e6e3ec9e333c7534a058bbe0a3e8..5eae4776ffdeece372e74cc2ba799103b99cb04f 100644 (file)
        };
 };
 
-&cpu0 {
-       cpu0-supply = <&vdd_cpu>;
-       operating-points = <
-               /* KHz    uV */
-               1800000 1400000
-               1608000 1350000
-               1512000 1300000
-               1416000 1200000
-               1200000 1100000
-               1008000 1050000
-                816000 1000000
-                696000  950000
-                600000  900000
-                408000  900000
-                312000  900000
-                216000  900000
-                126000  900000
-       >;
-};
-
 &emmc {
        status = "okay";
        bus-width = <8>;
index 8a74efdb636062e28e309e130f557e5bc582d65f..240e7a23d81ff3cc2eb2facad8a126970775a152 100644 (file)
@@ -56,7 +56,7 @@
                        clocks = <&topclk ZX296702_A9_PERIPHCLK>;
                };
 
-               l2cc: l2-cache-controller@0x00c00000 {
+               l2cc: l2-cache-controller@c00000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00c00000 0x1000>;
                        cache-unified;
                        arm,double-linefill-incr = <0>;
                };
 
-               pcu: pcu@0xa0008000 {
+               pcu: pcu@a0008000 {
                        compatible = "zte,zx296702-pcu";
                        reg = <0xa0008000 0x1000>;
                };
 
-               topclk: topclk@0x09800000 {
+               topclk: topclk@9800000 {
                        compatible = "zte,zx296702-topcrm-clk";
                        reg = <0x09800000 0x1000>;
                        #clock-cells = <1>;
                };
 
-               lsp1clk: lsp1clk@0x09400000 {
+               lsp1clk: lsp1clk@9400000 {
                        compatible = "zte,zx296702-lsp1crpm-clk";
                        reg = <0x09400000 0x1000>;
                        #clock-cells = <1>;
                };
 
-               lsp0clk: lsp0clk@0x0b000000 {
+               lsp0clk: lsp0clk@b000000 {
                        compatible = "zte,zx296702-lsp0crpm-clk";
                        reg = <0x0b000000 0x1000>;
                        #clock-cells = <1>;
                };
 
-               uart0: serial@0x09405000 {
+               uart0: serial@9405000 {
                        compatible = "zte,zx296702-uart";
                        reg = <0x09405000 0x1000>;
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
@@ -98,7 +98,7 @@
                        status = "disabled";
                };
 
-               uart1: serial@0x09406000 {
+               uart1: serial@9406000 {
                        compatible = "zte,zx296702-uart";
                        reg = <0x09406000 0x1000>;
                        interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
-               mmc0: mmc@0x09408000 {
+               mmc0: mmc@9408000 {
                        compatible = "snps,dw-mshc";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
-               mmc1: mmc@0x0b003000 {
+               mmc1: mmc@b003000 {
                        compatible = "snps,dw-mshc";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
-               sysctrl: sysctrl@0xa0007000 {
+               sysctrl: sysctrl@a0007000 {
                        compatible = "zte,sysctrl", "syscon";
                        reg = <0xa0007000 0x1000>;
                };
index 2f145c4af93a0fb387d86fea028d0c82d0041be8..92674f247a12a48ee603f992c075a8d6ac5c7d71 100644 (file)
@@ -319,7 +319,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_RC_CORE=m
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_LIRC=m
+CONFIG_LIRC=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_RX51=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
index 629f8e9981f1ee775afa792d5cd86ddbded76493..cf2701cb0de8c67b605a19bc2f21bc1aa34daad2 100644 (file)
@@ -83,7 +83,7 @@ static void dummy_clock_access(struct timespec64 *ts)
 }
 
 static clock_access_fn __read_persistent_clock = dummy_clock_access;
-static clock_access_fn __read_boot_clock = dummy_clock_access;;
+static clock_access_fn __read_boot_clock = dummy_clock_access;
 
 void read_persistent_clock64(struct timespec64 *ts)
 {
index 5638ce0c95241f7f3afd3e994aaa9993347c9be7..63d6b404d88e39bf581c0434aff5d6b0e951279f 100644 (file)
@@ -7,6 +7,8 @@ ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING
 
 KVM=../../../../virt/kvm
 
+CFLAGS_ARMV7VE            :=$(call cc-option, -march=armv7ve)
+
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
@@ -15,7 +17,10 @@ obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
 obj-$(CONFIG_KVM_ARM_HOST) += cp15-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += vfp.o
 obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o
+CFLAGS_banked-sr.o        += $(CFLAGS_ARMV7VE)
+
 obj-$(CONFIG_KVM_ARM_HOST) += entry.o
 obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o
 obj-$(CONFIG_KVM_ARM_HOST) += switch.o
+CFLAGS_switch.o                   += $(CFLAGS_ARMV7VE)
 obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o
index 111bda8cdebdc7e59789103838087920aedf0efe..be4b8b0a40ade5c8e412bbc75f2b311c389aa979 100644 (file)
 
 #include <asm/kvm_hyp.h>
 
+/*
+ * gcc before 4.9 doesn't understand -march=armv7ve, so we have to
+ * trick the assembler.
+ */
 __asm__(".arch_extension     virt");
 
 void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt)
index ee1f83b1a3324383b09106f01b830ea2802e210d..4c89a8e9a2e374cedfe92941661f38c2b6bc3b10 100644 (file)
@@ -69,7 +69,7 @@ static void clps711x_restart(enum reboot_mode mode, const char *cmd)
        soft_restart(0);
 }
 
-static const char *clps711x_compat[] __initconst = {
+static const char *const clps711x_compat[] __initconst = {
        "cirrus,ep7209",
        NULL
 };
index e457f299cd4430d359063788886d244a53d39f12..d6b11907380c83ddce9bc4998835a11e7a466ec7 100644 (file)
@@ -368,7 +368,7 @@ static struct spi_eeprom at25640a = {
        .flags          = EE_ADDR2,
 };
 
-static struct spi_board_info dm355_evm_spi_info[] __initconst = {
+static const struct spi_board_info dm355_evm_spi_info[] __initconst = {
        {
                .modalias       = "at25",
                .platform_data  = &at25640a,
index be997243447b949699fd116970ec0aacaffbf444..fad9a5611a5d276ce15f0fcfe9aedcc9a5d03802 100644 (file)
@@ -217,7 +217,7 @@ static struct spi_eeprom at25640a = {
        .flags          = EE_ADDR2,
 };
 
-static struct spi_board_info dm355_leopard_spi_info[] __initconst = {
+static const struct spi_board_info dm355_leopard_spi_info[] __initconst = {
        {
                .modalias       = "at25",
                .platform_data  = &at25640a,
index e75741fb2c1da095bd59ba4e0f411a6274ce6255..e3780986d2a3b40aff033f0a22759be80272cf39 100644 (file)
@@ -726,7 +726,7 @@ static struct spi_eeprom at25640 = {
        .flags          = EE_ADDR2,
 };
 
-static struct spi_board_info dm365_evm_spi_info[] __initconst = {
+static const struct spi_board_info dm365_evm_spi_info[] __initconst = {
        {
                .modalias       = "at25",
                .platform_data  = &at25640,
index 6b32dc527edcd58396dc94781992f3970cc8e793..2c20599cc3506326eddc2993afd8df2bd308e268 100644 (file)
@@ -41,7 +41,7 @@ config MACH_ARMADA_375
        depends on ARCH_MULTI_V7
        select ARMADA_370_XP_IRQ
        select ARM_ERRATA_720789
-       select ARM_ERRATA_753970
+       select PL310_ERRATA_753970
        select ARM_GIC
        select ARMADA_375_CLK
        select HAVE_ARM_SCU
@@ -57,7 +57,7 @@ config MACH_ARMADA_38X
        bool "Marvell Armada 380/385 boards"
        depends on ARCH_MULTI_V7
        select ARM_ERRATA_720789
-       select ARM_ERRATA_753970
+       select PL310_ERRATA_753970
        select ARM_GIC
        select ARM_GLOBAL_TIMER
        select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
index 43e3e188f521341884d0a6e280d5724ef606e13f..fa512413a47172212483ebec6811bc5547aa729b 100644 (file)
@@ -1011,17 +1011,17 @@ static int clk_debugfs_register_one(struct clk *c)
                return -ENOMEM;
        c->dent = d;
 
-       d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
+       d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount);
        if (!d) {
                err = -ENOMEM;
                goto err_out;
        }
-       d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+       d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate);
        if (!d) {
                err = -ENOMEM;
                goto err_out;
        }
-       d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+       d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
        if (!d) {
                err = -ENOMEM;
                goto err_out;
index 4bb6751864a50e046e74c0952ad75571e1d979d0..fc5fb776a7101234bd64da673815d10a0b75f0f2 100644 (file)
@@ -299,8 +299,6 @@ static void irq_save_context(void)
        if (soc_is_dra7xx())
                return;
 
-       if (!sar_base)
-               sar_base = omap4_get_sar_ram_base();
        if (wakeupgen_ops && wakeupgen_ops->save_context)
                wakeupgen_ops->save_context();
 }
@@ -598,6 +596,8 @@ static int __init wakeupgen_init(struct device_node *node,
        irq_hotplug_init();
        irq_pm_init();
 
+       sar_base = omap4_get_sar_ram_base();
+
        return 0;
 }
 IRQCHIP_DECLARE(ti_wakeupgen, "ti,omap4-wugen-mpu", wakeupgen_init);
index 124f9af34a15a3145edecb30108ced8a3b13a2f5..34156eca8e234f45745e849fb460fd42381cfa76 100644 (file)
@@ -977,6 +977,9 @@ static int _enable_clocks(struct omap_hwmod *oh)
 
        pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
 
+       if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
+               _enable_optional_clocks(oh);
+
        if (oh->_clk)
                clk_enable(oh->_clk);
 
@@ -985,9 +988,6 @@ static int _enable_clocks(struct omap_hwmod *oh)
                        clk_enable(os->_clk);
        }
 
-       if (oh->flags & HWMOD_OPT_CLKS_NEEDED)
-               _enable_optional_clocks(oh);
-
        /* The opt clocks are controlled by the device driver. */
 
        return 0;
index 366158a54fcd8beae9ff50d712e1b5c63f87d456..6f68576e56956a635acae35af565d09bb2ff2d0f 100644 (file)
@@ -186,7 +186,7 @@ static void omap_pm_end(void)
        cpu_idle_poll_ctrl(false);
 }
 
-static void omap_pm_finish(void)
+static void omap_pm_wake(void)
 {
        if (soc_is_omap34xx())
                omap_prcm_irq_complete();
@@ -196,7 +196,7 @@ static const struct platform_suspend_ops omap_pm_ops = {
        .begin          = omap_pm_begin,
        .end            = omap_pm_end,
        .enter          = omap_pm_enter,
-       .finish         = omap_pm_finish,
+       .wake           = omap_pm_wake,
        .valid          = suspend_valid_only_mem,
 };
 
index ece09c9461f78d9b3908095615a688522b69e9b3..d61fbd7a2840a4980205c16d1c675a957c6292c8 100644 (file)
@@ -156,12 +156,6 @@ static struct clock_event_device clockevent_gpt = {
        .tick_resume            = omap2_gp_timer_shutdown,
 };
 
-static struct property device_disabled = {
-       .name = "status",
-       .length = sizeof("disabled"),
-       .value = "disabled",
-};
-
 static const struct of_device_id omap_timer_match[] __initconst = {
        { .compatible = "ti,omap2420-timer", },
        { .compatible = "ti,omap3430-timer", },
@@ -203,8 +197,17 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
                                  of_get_property(np, "ti,timer-secure", NULL)))
                        continue;
 
-               if (!of_device_is_compatible(np, "ti,omap-counter32k"))
-                       of_add_property(np, &device_disabled);
+               if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
+                       struct property *prop;
+
+                       prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+                       if (!prop)
+                               return NULL;
+                       prop->name = "status";
+                       prop->value = "disabled";
+                       prop->length = strlen(prop->value);
+                       of_add_property(np, prop);
+               }
                return np;
        }
 
index 2a7bb6ccdcb7eb219f515c6e0f1ba2bfe573a349..a810f4dd34b1e266a001f20a920f421ba7dcf3e8 100644 (file)
@@ -58,7 +58,6 @@ config MACH_KUROBOX_PRO
 
 config MACH_DNS323
        bool "D-Link DNS-323"
-       select GENERIC_NET_UTILS
        select I2C_BOARDINFO if I2C
        help
          Say 'Y' here if you want your kernel to support the
@@ -66,7 +65,6 @@ config MACH_DNS323
 
 config MACH_TS209
        bool "QNAP TS-109/TS-209"
-       select GENERIC_NET_UTILS
        help
          Say 'Y' here if you want your kernel to support the
          QNAP TS-109/TS-209 platform.
@@ -101,7 +99,6 @@ config MACH_LINKSTATION_LS_HGL
 
 config MACH_TS409
        bool "QNAP TS-409"
-       select GENERIC_NET_UTILS
        help
          Say 'Y' here if you want your kernel to support the
          QNAP TS-409 platform.
index cd483bfb5ca82cd3d6289a47e6cc0a56f7787e1f..d13344b2ddcd4ef0ad6c8b8554733a0fc6063610 100644 (file)
@@ -173,10 +173,42 @@ static struct mv643xx_eth_platform_data dns323_eth_data = {
        .phy_addr = MV643XX_ETH_PHY_ADDR(8),
 };
 
+/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these
+ * functions be kept somewhere?
+ */
+static int __init dns323_parse_hex_nibble(char n)
+{
+       if (n >= '0' && n <= '9')
+               return n - '0';
+
+       if (n >= 'A' && n <= 'F')
+               return n - 'A' + 10;
+
+       if (n >= 'a' && n <= 'f')
+               return n - 'a' + 10;
+
+       return -1;
+}
+
+static int __init dns323_parse_hex_byte(const char *b)
+{
+       int hi;
+       int lo;
+
+       hi = dns323_parse_hex_nibble(b[0]);
+       lo = dns323_parse_hex_nibble(b[1]);
+
+       if (hi < 0 || lo < 0)
+               return -1;
+
+       return (hi << 4) | lo;
+}
+
 static int __init dns323_read_mac_addr(void)
 {
        u_int8_t addr[6];
-       void __iomem *mac_page;
+       int i;
+       char *mac_page;
 
        /* MAC address is stored as a regular ol' string in /dev/mtdblock4
         * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
@@ -185,8 +217,23 @@ static int __init dns323_read_mac_addr(void)
        if (!mac_page)
                return -ENOMEM;
 
-       if (!mac_pton((__force const char *) mac_page, addr))
-               goto error_fail;
+       /* Sanity check the string we're looking at */
+       for (i = 0; i < 5; i++) {
+               if (*(mac_page + (i * 3) + 2) != ':') {
+                       goto error_fail;
+               }
+       }
+
+       for (i = 0; i < 6; i++) {
+               int byte;
+
+               byte = dns323_parse_hex_byte(mac_page + (i * 3));
+               if (byte < 0) {
+                       goto error_fail;
+               }
+
+               addr[i] = byte;
+       }
 
        iounmap(mac_page);
        printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
index 89774985d3803fbc8c84a7eb993a7d3e18bf0d75..905d4f2dd0b827938862f1a089e18651eea2757f 100644 (file)
@@ -53,12 +53,53 @@ struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
        .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
+static int __init qnap_tsx09_parse_hex_nibble(char n)
+{
+       if (n >= '0' && n <= '9')
+               return n - '0';
+
+       if (n >= 'A' && n <= 'F')
+               return n - 'A' + 10;
+
+       if (n >= 'a' && n <= 'f')
+               return n - 'a' + 10;
+
+       return -1;
+}
+
+static int __init qnap_tsx09_parse_hex_byte(const char *b)
+{
+       int hi;
+       int lo;
+
+       hi = qnap_tsx09_parse_hex_nibble(b[0]);
+       lo = qnap_tsx09_parse_hex_nibble(b[1]);
+
+       if (hi < 0 || lo < 0)
+               return -1;
+
+       return (hi << 4) | lo;
+}
+
 static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
 {
        u_int8_t addr[6];
+       int i;
 
-       if (!mac_pton(addr_str, addr))
-               return -1;
+       for (i = 0; i < 6; i++) {
+               int byte;
+
+               /*
+                * Enforce "xx:xx:xx:xx:xx:xx\n" format.
+                */
+               if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
+                       return -1;
+
+               byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
+               if (byte < 0)
+                       return -1;
+               addr[i] = byte;
+       }
 
        printk(KERN_INFO "tsx09: found ethernet mac address %pM\n", addr);
 
@@ -77,12 +118,12 @@ void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
        unsigned long addr;
 
        for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
-               void __iomem *nor_page;
+               char *nor_page;
                int ret = 0;
 
                nor_page = ioremap(addr, 1024);
                if (nor_page != NULL) {
-                       ret = qnap_tsx09_check_mac_addr((__force const char *)nor_page);
+                       ret = qnap_tsx09_check_mac_addr(nor_page);
                        iounmap(nor_page);
                }
 
index 57058ac46f49733887e439012afa3247f03e1737..7e5d7a083707074b639dc35ba18c40a14312a38c 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <linux/perf/arm_pmu.h>
 #include <linux/regulator/machine.h>
 
 #include <asm/outercache.h>
@@ -112,37 +111,6 @@ static void ux500_restart(enum reboot_mode mode, const char *cmd)
        prcmu_system_reset(0);
 }
 
-/*
- * The PMU IRQ lines of two cores are wired together into a single interrupt.
- * Bounce the interrupt to the other core if it's not ours.
- */
-static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
-{
-       irqreturn_t ret = handler(irq, dev);
-       int other = !smp_processor_id();
-
-       if (ret == IRQ_NONE && cpu_online(other))
-               irq_set_affinity(irq, cpumask_of(other));
-
-       /*
-        * We should be able to get away with the amount of IRQ_NONEs we give,
-        * while still having the spurious IRQ detection code kick in if the
-        * interrupt really starts hitting spuriously.
-        */
-       return ret;
-}
-
-static struct arm_pmu_platdata db8500_pmu_platdata = {
-       .handle_irq             = db8500_pmu_handler,
-       .irq_flags              = IRQF_NOBALANCING | IRQF_NO_THREAD,
-};
-
-static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
-       /* Requires call-back bindings. */
-       OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
-       {},
-};
-
 static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", NULL),
        {},
@@ -165,9 +133,6 @@ static void __init u8500_init_machine(void)
        if (of_machine_is_compatible("st-ericsson,u8540"))
                of_platform_populate(NULL, u8500_local_bus_nodes,
                                     u8540_auxdata_lookup, NULL);
-       else
-               of_platform_populate(NULL, u8500_local_bus_nodes,
-                                    u8500_auxdata_lookup, NULL);
 }
 
 static const char * stericsson_dt_platform_compat[] = {
index aff6994950ba6db7eb6579a90cc94e5b2bfc7329..a2399fd66e97cef3db011508dc73c718c9456bc9 100644 (file)
@@ -472,28 +472,27 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
 /*****************************************************************************
  * Ethernet switch
  ****************************************************************************/
-static __initconst const char *orion_ge00_mvmdio_bus_name = "orion-mii";
-static __initdata struct mdio_board_info
-                 orion_ge00_switch_board_info;
+static __initdata struct mdio_board_info orion_ge00_switch_board_info = {
+       .bus_id   = "orion-mii",
+       .modalias = "mv88e6085",
+};
 
 void __init orion_ge00_switch_init(struct dsa_chip_data *d)
 {
-       struct mdio_board_info *bd;
        unsigned int i;
 
        if (!IS_BUILTIN(CONFIG_PHYLIB))
                return;
 
-       for (i = 0; i < ARRAY_SIZE(d->port_names); i++)
-               if (!strcmp(d->port_names[i], "cpu"))
+       for (i = 0; i < ARRAY_SIZE(d->port_names); i++) {
+               if (!strcmp(d->port_names[i], "cpu")) {
+                       d->netdev[i] = &orion_ge00.dev;
                        break;
+               }
+       }
 
-       bd = &orion_ge00_switch_board_info;
-       bd->bus_id = orion_ge00_mvmdio_bus_name;
-       bd->mdio_addr = d->sw_addr;
-       d->netdev[i] = &orion_ge00.dev;
-       strcpy(bd->modalias, "mv88e6085");
-       bd->platform_data = d;
+       orion_ge00_switch_board_info.mdio_addr = d->sw_addr;
+       orion_ge00_switch_board_info.platform_data = d;
 
        mdiobus_register_board_info(&orion_ge00_switch_board_info, 1);
 }
index a80632641b39f8cb5dc8554aa2b2e85b6551e0ea..70c776ef7aa7321450def075b8f150ef1dbbbf9f 100644 (file)
 
                        uart_A: serial@24000 {
                                compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart";
-                               reg = <0x0 0x24000 0x0 0x14>;
+                               reg = <0x0 0x24000 0x0 0x18>;
                                interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        uart_B: serial@23000 {
                                compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart";
-                               reg = <0x0 0x23000 0x0 0x14>;
+                               reg = <0x0 0x23000 0x0 0x18>;
                                interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
index 6cb3c2a52bafe5f0db8a0018b35e88998ed90f01..4ee2e7951482f43122620d2668b244de1744e6b9 100644 (file)
 
                        uart_A: serial@84c0 {
                                compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x84c0 0x0 0x14>;
+                               reg = <0x0 0x84c0 0x0 0x18>;
                                interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        uart_B: serial@84dc {
                                compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x84dc 0x0 0x14>;
+                               reg = <0x0 0x84dc 0x0 0x18>;
                                interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        uart_C: serial@8700 {
                                compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x8700 0x0 0x14>;
+                               reg = <0x0 0x8700 0x0 0x18>;
                                interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        uart_AO: serial@4c0 {
                                compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
-                               reg = <0x0 0x004c0 0x0 0x14>;
+                               reg = <0x0 0x004c0 0x0 0x18>;
                                interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
                        uart_AO_B: serial@4e0 {
                                compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
-                               reg = <0x0 0x004e0 0x0 0x14>;
+                               reg = <0x0 0x004e0 0x0 0x18>;
                                interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
index 4f355f17eed6bcc29dcc14fb4546fce6a083a57f..c8514110b9da2dc2f40988ad0ae733437e33420a 100644 (file)
 
                        internal_phy: ethernet-phy@8 {
                                compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <8>;
                                max-speed = <100>;
                        };
index 4220fbdcb24a7f18c5e3ab66574ba22c8c92c873..ff5c4c47b22bfecfa36f0090dc8be5c85b171271 100644 (file)
@@ -98,7 +98,7 @@
                clock-output-names = "clk125mhz";
        };
 
-       pci {
+       pcie@30000000 {
                compatible = "pci-host-ecam-generic";
                device_type = "pci";
                #interrupt-cells = <1>;
                ranges =
                  <0x02000000    0 0x40000000    0 0x40000000    0 0x20000000
                   0x43000000 0x40 0x00000000 0x40 0x00000000 0x20 0x00000000>;
+               bus-range = <0 0xff>;
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map =
                      /* addr  pin  ic   icaddr  icintr */
index e94fa1a531922ee6b160246c4399435574909641..047641fe294c64c9dbc04dcb477827814a809677 100644 (file)
@@ -51,7 +51,7 @@
                #size-cells = <2>;
                ranges;
 
-               ramoops@0x21f00000 {
+               ramoops@21f00000 {
                        compatible = "ramoops";
                        reg = <0x0 0x21f00000 0x0 0x00100000>;
                        record-size     = <0x00020000>;
index 9fbe4705ee88bfaf1eb12a7208de0c5899d7f9d3..94597e33c8065eb4b12ee805885988991d43e42c 100644 (file)
                        reg = <0 0x10005000 0 0x1000>;
                };
 
-               pio: pinctrl@0x10005000 {
+               pio: pinctrl@10005000 {
                        compatible = "mediatek,mt8173-pinctrl";
                        reg = <0 0x1000b000 0 0x1000>;
                        mediatek,pctl-regmap = <&syscfg_pctl_a>;
index 492a011f14f6cef933dc16ce9cf591d8cdc5c79e..1c8f1b86472de9c149b706502dcc552f19376ae5 100644 (file)
                };
 
                agnoc@0 {
-                       qcom,pcie@00600000 {
+                       qcom,pcie@600000 {
                                perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>;
                        };
 
-                       qcom,pcie@00608000 {
+                       qcom,pcie@608000 {
                                status = "okay";
                                perst-gpio = <&msmgpio 130 GPIO_ACTIVE_LOW>;
                        };
 
-                       qcom,pcie@00610000 {
+                       qcom,pcie@610000 {
                                status = "okay";
                                perst-gpio = <&msmgpio 114 GPIO_ACTIVE_LOW>;
                        };
index 4b2afcc4fdf4791da816c6bba3c6f2ef7741ad8d..0a6f7952bbb18d65847261957715e331756c46c4 100644 (file)
                        #size-cells = <1>;
                        ranges;
 
-                       pcie0: qcom,pcie@00600000 {
+                       pcie0: qcom,pcie@600000 {
                                compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
                                status = "disabled";
                                power-domains = <&gcc PCIE0_GDSC>;
 
                        };
 
-                       pcie1: qcom,pcie@00608000 {
+                       pcie1: qcom,pcie@608000 {
                                compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
                                power-domains = <&gcc PCIE1_GDSC>;
                                bus-range = <0x00 0xff>;
                                                "bus_slave";
                        };
 
-                       pcie2: qcom,pcie@00610000 {
+                       pcie2: qcom,pcie@610000 {
                                compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
                                power-domains = <&gcc PCIE2_GDSC>;
                                bus-range = <0x00 0xff>;
index 3890468678ce1caa78a411aeb0a4a9cdedfc1302..28257724a56e74b79b83c69a76bea0da4e0fd9ed 100644 (file)
        assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
        assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>;
        clock_in_out = "input";
-       /* shows instability at 1GBit right now */
-       max-speed = <100>;
        phy-supply = <&vcc_io>;
        phy-mode = "rgmii";
        pinctrl-names = "default";
        pinctrl-0 = <&rgmiim1_pins>;
+       snps,force_thresh_dma_mode;
        snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
        snps,reset-active-low;
        snps,reset-delays-us = <0 10000 50000>;
-       tx_delay = <0x26>;
-       rx_delay = <0x11>;
+       tx_delay = <0x24>;
+       rx_delay = <0x18>;
        status = "okay";
 };
 
index a037ee56fead6db1b0bcedbbf740f6a54ca82977..cae3415544862dfddf06a034ecea62bd50739fd2 100644 (file)
                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
                         <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                status = "disabled";
        };
                interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
                         <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                status = "disabled";
        };
                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
                         <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                status = "disabled";
        };
index aa4d07046a7ba9644316cd7c57b43b64b5327766..03458ac44201c7c66d0e991881ab24e292bfdee2 100644 (file)
                max-frequency = <150000000>;
                clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
                         <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
                resets = <&cru SRST_SDIO0>;
index 0f873c897d0de5a75f9d4e4d90d7c658b7a173d3..ce592a4c0c4cdeb473a1c96106620583a8a4abef 100644 (file)
        assigned-clocks = <&cru SCLK_PCIEPHY_REF>;
        assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>;
        assigned-clock-rates = <100000000>;
-       ep-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_HIGH>;
+       ep-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>;
        num-lanes = <4>;
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_clkreqn_cpm>;
index 7aa2144e0d47d1fb8e30a2389d4d0fbc5fc4030f..2605118d4b4ce74755ced75843d91ca22ad38ce8 100644 (file)
                compatible = "rockchip,rk3399-edp";
                reg = <0x0 0xff970000 0x0 0x8000>;
                interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
-               clocks = <&cru PCLK_EDP>, <&cru PCLK_EDP_CTRL>;
-               clock-names = "dp", "pclk";
+               clocks = <&cru PCLK_EDP>, <&cru PCLK_EDP_CTRL>, <&cru PCLK_VIO_GRF>;
+               clock-names = "dp", "pclk", "grf";
                pinctrl-names = "default";
                pinctrl-0 = <&edp_hpd>;
                power-domains = <&power RK3399_PD_EDP>;
index be7bd19c87ec23949c4dcbdfe8bbd4972dbae00a..350c76a1d15ba7b6d8935928305aa80f53d9649e 100644 (file)
@@ -20,7 +20,7 @@
 
 #define MPIDR_UP_BITMASK       (0x1 << 30)
 #define MPIDR_MT_BITMASK       (0x1 << 24)
-#define MPIDR_HWID_BITMASK     0xff00ffffff
+#define MPIDR_HWID_BITMASK     UL(0xff00ffffff)
 
 #define MPIDR_LEVEL_BITS_SHIFT 3
 #define MPIDR_LEVEL_BITS       (1 << MPIDR_LEVEL_BITS_SHIFT)
index 1dca41bea16ad61fc8fe6f2be528ba452bffdf27..e73f6856962461952287b244831395200cdc3853 100644 (file)
@@ -22,7 +22,7 @@
 
 static inline pte_t huge_ptep_get(pte_t *ptep)
 {
-       return *ptep;
+       return READ_ONCE(*ptep);
 }
 
 
index 9679067a15746ce921ba5a138c6508c0a4972d0a..7faed6e48b46212709485b7225c512f3fb99831e 100644 (file)
@@ -185,42 +185,42 @@ static inline pmd_t kvm_s2pmd_mkexec(pmd_t pmd)
        return pmd;
 }
 
-static inline void kvm_set_s2pte_readonly(pte_t *pte)
+static inline void kvm_set_s2pte_readonly(pte_t *ptep)
 {
        pteval_t old_pteval, pteval;
 
-       pteval = READ_ONCE(pte_val(*pte));
+       pteval = READ_ONCE(pte_val(*ptep));
        do {
                old_pteval = pteval;
                pteval &= ~PTE_S2_RDWR;
                pteval |= PTE_S2_RDONLY;
-               pteval = cmpxchg_relaxed(&pte_val(*pte), old_pteval, pteval);
+               pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval);
        } while (pteval != old_pteval);
 }
 
-static inline bool kvm_s2pte_readonly(pte_t *pte)
+static inline bool kvm_s2pte_readonly(pte_t *ptep)
 {
-       return (pte_val(*pte) & PTE_S2_RDWR) == PTE_S2_RDONLY;
+       return (READ_ONCE(pte_val(*ptep)) & PTE_S2_RDWR) == PTE_S2_RDONLY;
 }
 
-static inline bool kvm_s2pte_exec(pte_t *pte)
+static inline bool kvm_s2pte_exec(pte_t *ptep)
 {
-       return !(pte_val(*pte) & PTE_S2_XN);
+       return !(READ_ONCE(pte_val(*ptep)) & PTE_S2_XN);
 }
 
-static inline void kvm_set_s2pmd_readonly(pmd_t *pmd)
+static inline void kvm_set_s2pmd_readonly(pmd_t *pmdp)
 {
-       kvm_set_s2pte_readonly((pte_t *)pmd);
+       kvm_set_s2pte_readonly((pte_t *)pmdp);
 }
 
-static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
+static inline bool kvm_s2pmd_readonly(pmd_t *pmdp)
 {
-       return kvm_s2pte_readonly((pte_t *)pmd);
+       return kvm_s2pte_readonly((pte_t *)pmdp);
 }
 
-static inline bool kvm_s2pmd_exec(pmd_t *pmd)
+static inline bool kvm_s2pmd_exec(pmd_t *pmdp)
 {
-       return !(pmd_val(*pmd) & PMD_S2_XN);
+       return !(READ_ONCE(pmd_val(*pmdp)) & PMD_S2_XN);
 }
 
 static inline bool kvm_page_empty(void *ptr)
index 8d3331985d2e34b2099eab6cec8b456d40983052..39ec0b8a689eea3e495029685bed047737d64c5e 100644 (file)
@@ -141,13 +141,13 @@ static inline void cpu_install_idmap(void)
  * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
  * avoiding the possibility of conflicting TLB entries being allocated.
  */
-static inline void cpu_replace_ttbr1(pgd_t *pgd)
+static inline void cpu_replace_ttbr1(pgd_t *pgdp)
 {
        typedef void (ttbr_replace_func)(phys_addr_t);
        extern ttbr_replace_func idmap_cpu_replace_ttbr1;
        ttbr_replace_func *replace_phys;
 
-       phys_addr_t pgd_phys = virt_to_phys(pgd);
+       phys_addr_t pgd_phys = virt_to_phys(pgdp);
 
        replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
 
index e9d9f1b006efec5708fd0f33c006d2e017711a4d..2e05bcd944c8395b9fd5af993b6214054352aefc 100644 (file)
@@ -36,23 +36,23 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
        return (pmd_t *)__get_free_page(PGALLOC_GFP);
 }
 
-static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
 {
-       BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
-       free_page((unsigned long)pmd);
+       BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
+       free_page((unsigned long)pmdp);
 }
 
-static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
+static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
 {
-       set_pud(pud, __pud(__phys_to_pud_val(pmd) | prot));
+       set_pud(pudp, __pud(__phys_to_pud_val(pmdp) | prot));
 }
 
-static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
 {
-       __pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE);
+       __pud_populate(pudp, __pa(pmdp), PMD_TYPE_TABLE);
 }
 #else
-static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
+static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
 {
        BUILD_BUG();
 }
@@ -65,30 +65,30 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
        return (pud_t *)__get_free_page(PGALLOC_GFP);
 }
 
-static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+static inline void pud_free(struct mm_struct *mm, pud_t *pudp)
 {
-       BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
-       free_page((unsigned long)pud);
+       BUG_ON((unsigned long)pudp & (PAGE_SIZE-1));
+       free_page((unsigned long)pudp);
 }
 
-static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pudp, pgdval_t prot)
 {
-       set_pgd(pgdp, __pgd(__phys_to_pgd_val(pud) | prot));
+       set_pgd(pgdp, __pgd(__phys_to_pgd_val(pudp) | prot));
 }
 
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, pud_t *pudp)
 {
-       __pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE);
+       __pgd_populate(pgdp, __pa(pudp), PUD_TYPE_TABLE);
 }
 #else
-static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pudp, pgdval_t prot)
 {
        BUILD_BUG();
 }
 #endif /* CONFIG_PGTABLE_LEVELS > 3 */
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
-extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgdp);
 
 static inline pte_t *
 pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
@@ -114,10 +114,10 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
 /*
  * Free a PTE table.
  */
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *ptep)
 {
-       if (pte)
-               free_page((unsigned long)pte);
+       if (ptep)
+               free_page((unsigned long)ptep);
 }
 
 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
@@ -126,10 +126,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
        __free_page(pte);
 }
 
-static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
+static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
                                  pmdval_t prot)
 {
-       set_pmd(pmdp, __pmd(__phys_to_pmd_val(pte) | prot));
+       set_pmd(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot));
 }
 
 /*
index 094374c82db088816d6a35ec75e1658dfc446ec4..7e2c27e63cd894371655a569046faaa67cfc1837 100644 (file)
@@ -218,7 +218,7 @@ static inline pmd_t pmd_mkcont(pmd_t pmd)
 
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
-       *ptep = pte;
+       WRITE_ONCE(*ptep, pte);
 
        /*
         * Only if the new pte is valid and kernel, otherwise TLB maintenance
@@ -250,6 +250,8 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep, pte_t pte)
 {
+       pte_t old_pte;
+
        if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
                __sync_icache_dcache(pte, addr);
 
@@ -258,14 +260,15 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
         * hardware updates of the pte (ptep_set_access_flags safely changes
         * valid ptes without going through an invalid entry).
         */
-       if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(*ptep) && pte_valid(pte) &&
+       old_pte = READ_ONCE(*ptep);
+       if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(old_pte) && pte_valid(pte) &&
           (mm == current->active_mm || atomic_read(&mm->mm_users) > 1)) {
                VM_WARN_ONCE(!pte_young(pte),
                             "%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
-                            __func__, pte_val(*ptep), pte_val(pte));
-               VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(pte),
+                            __func__, pte_val(old_pte), pte_val(pte));
+               VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
                             "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
-                            __func__, pte_val(*ptep), pte_val(pte));
+                            __func__, pte_val(old_pte), pte_val(pte));
        }
 
        set_pte(ptep, pte);
@@ -431,7 +434,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 
 static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
-       *pmdp = pmd;
+       WRITE_ONCE(*pmdp, pmd);
        dsb(ishst);
        isb();
 }
@@ -482,7 +485,7 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
 
 static inline void set_pud(pud_t *pudp, pud_t pud)
 {
-       *pudp = pud;
+       WRITE_ONCE(*pudp, pud);
        dsb(ishst);
        isb();
 }
@@ -500,7 +503,7 @@ static inline phys_addr_t pud_page_paddr(pud_t pud)
 /* Find an entry in the second-level page table. */
 #define pmd_index(addr)                (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
 
-#define pmd_offset_phys(dir, addr)     (pud_page_paddr(*(dir)) + pmd_index(addr) * sizeof(pmd_t))
+#define pmd_offset_phys(dir, addr)     (pud_page_paddr(READ_ONCE(*(dir))) + pmd_index(addr) * sizeof(pmd_t))
 #define pmd_offset(dir, addr)          ((pmd_t *)__va(pmd_offset_phys((dir), (addr))))
 
 #define pmd_set_fixmap(addr)           ((pmd_t *)set_fixmap_offset(FIX_PMD, addr))
@@ -535,7 +538,7 @@ static inline phys_addr_t pud_page_paddr(pud_t pud)
 
 static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
 {
-       *pgdp = pgd;
+       WRITE_ONCE(*pgdp, pgd);
        dsb(ishst);
 }
 
@@ -552,7 +555,7 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
 /* Find an entry in the frst-level page table. */
 #define pud_index(addr)                (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
 
-#define pud_offset_phys(dir, addr)     (pgd_page_paddr(*(dir)) + pud_index(addr) * sizeof(pud_t))
+#define pud_offset_phys(dir, addr)     (pgd_page_paddr(READ_ONCE(*(dir))) + pud_index(addr) * sizeof(pud_t))
 #define pud_offset(dir, addr)          ((pud_t *)__va(pud_offset_phys((dir), (addr))))
 
 #define pud_set_fixmap(addr)           ((pud_t *)set_fixmap_offset(FIX_PUD, addr))
index 472ef944e93260be2faad4182431331e21bc3569..902f9edacbea94b96a85321ff79d45e8ac59fd73 100644 (file)
@@ -28,7 +28,7 @@ struct stackframe {
        unsigned long fp;
        unsigned long pc;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-       unsigned int graph;
+       int graph;
 #endif
 };
 
index 543e11f0f657e932aa17916a0750f7d83cf5d7b8..e66b0fca99c2f9e500788db6fa2e24693ade11c3 100644 (file)
@@ -72,15 +72,15 @@ static inline void set_fs(mm_segment_t fs)
  * This is equivalent to the following test:
  * (u65)addr + (u65)size <= (u65)current->addr_limit + 1
  */
-static inline unsigned long __range_ok(unsigned long addr, unsigned long size)
+static inline unsigned long __range_ok(const void __user *addr, unsigned long size)
 {
-       unsigned long limit = current_thread_info()->addr_limit;
+       unsigned long ret, limit = current_thread_info()->addr_limit;
 
        __chk_user_ptr(addr);
        asm volatile(
        // A + B <= C + 1 for all A,B,C, in four easy steps:
        // 1: X = A + B; X' = X % 2^64
-       "       adds    %0, %0, %2\n"
+       "       adds    %0, %3, %2\n"
        // 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4
        "       csel    %1, xzr, %1, hi\n"
        // 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X'
@@ -92,9 +92,9 @@ static inline unsigned long __range_ok(unsigned long addr, unsigned long size)
        //    testing X' - C == 0, subject to the previous adjustments.
        "       sbcs    xzr, %0, %1\n"
        "       cset    %0, ls\n"
-       : "+r" (addr), "+r" (limit) : "Ir" (size) : "cc");
+       : "=&r" (ret), "+r" (limit) : "Ir" (size), "0" (addr) : "cc");
 
-       return addr;
+       return ret;
 }
 
 /*
@@ -104,7 +104,7 @@ static inline unsigned long __range_ok(unsigned long addr, unsigned long size)
  */
 #define untagged_addr(addr)            sign_extend64(addr, 55)
 
-#define access_ok(type, addr, size)    __range_ok((unsigned long)(addr), size)
+#define access_ok(type, addr, size)    __range_ok(addr, size)
 #define user_addr_max                  get_fs
 
 #define _ASM_EXTABLE(from, to)                                         \
index c33b5e4010ab7660140025f9c17d6be10b66706d..68450e954d47d7d241740d0de4ca3b9d2df53b75 100644 (file)
@@ -370,6 +370,7 @@ static unsigned int __kprobes aarch32_check_condition(u32 opcode, u32 psr)
 static int swp_handler(struct pt_regs *regs, u32 instr)
 {
        u32 destreg, data, type, address = 0;
+       const void __user *user_ptr;
        int rn, rt2, res = 0;
 
        perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc);
@@ -401,7 +402,8 @@ static int swp_handler(struct pt_regs *regs, u32 instr)
                aarch32_insn_extract_reg_num(instr, A32_RT2_OFFSET), data);
 
        /* Check access in reasonable access range for both SWP and SWPB */
-       if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
+       user_ptr = (const void __user *)(unsigned long)(address & ~3);
+       if (!access_ok(VERIFY_WRITE, user_ptr, 4)) {
                pr_debug("SWP{B} emulation: access to 0x%08x not allowed!\n",
                        address);
                goto fault;
index 07823595b7f01690823da724584965bca0872588..b5a28336c07712af8d10aa62f1669b8a798065d8 100644 (file)
@@ -178,7 +178,7 @@ static int enable_smccc_arch_workaround_1(void *data)
        case PSCI_CONDUIT_HVC:
                arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
                                  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
-               if (res.a0)
+               if ((int)res.a0 < 0)
                        return 0;
                cb = call_hvc_arch_workaround_1;
                smccc_start = __smccc_workaround_1_hvc_start;
@@ -188,7 +188,7 @@ static int enable_smccc_arch_workaround_1(void *data)
        case PSCI_CONDUIT_SMC:
                arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
                                  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
-               if (res.a0)
+               if ((int)res.a0 < 0)
                        return 0;
                cb = call_smc_arch_workaround_1;
                smccc_start = __smccc_workaround_1_smc_start;
@@ -406,6 +406,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
                .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
                MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
        },
+       {
+               .capability = ARM64_HARDEN_BRANCH_PREDICTOR,
+               MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
+               .enable = qcom_enable_link_stack_sanitization,
+       },
+       {
+               .capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
+               MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
+       },
        {
                .capability = ARM64_HARDEN_BRANCH_PREDICTOR,
                MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
index 29b1f873e337fb6a423c3406c02d43af18bc4847..2985a067fc131c468b7213ed1a5b0ec6548fb1c8 100644 (file)
@@ -199,9 +199,11 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
 };
 
 static const struct arm64_ftr_bits ftr_ctr[] = {
-       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1),   /* RAO */
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1),           /* RES1 */
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 29, 1, 1),      /* DIC */
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 28, 1, 1),      /* IDC */
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0),     /* CWG */
-       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0),      /* ERG */
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, 20, 4, 0),     /* ERG */
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1),      /* DminLine */
        /*
         * Linux can handle differing I-cache policies. Userspace JITs will
index f85ac58d08a35676f38fa2a6d7b0887fb6f1d2ec..a8bf1c892b9065ca40ed4b263317deced2b8d693 100644 (file)
@@ -90,7 +90,7 @@ static int __init set_permissions(pte_t *ptep, pgtable_t token,
                                  unsigned long addr, void *data)
 {
        efi_memory_desc_t *md = data;
-       pte_t pte = *ptep;
+       pte_t pte = READ_ONCE(*ptep);
 
        if (md->attribute & EFI_MEMORY_RO)
                pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
index f20cf7e992495adffcd2049c4c40f9ec6798c99f..1ec5f28c39fc56c4aae85cc5801bd513cc3ea2c3 100644 (file)
@@ -202,10 +202,10 @@ static int create_safe_exec_page(void *src_start, size_t length,
                                 gfp_t mask)
 {
        int rc = 0;
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
+       pgd_t *pgdp;
+       pud_t *pudp;
+       pmd_t *pmdp;
+       pte_t *ptep;
        unsigned long dst = (unsigned long)allocator(mask);
 
        if (!dst) {
@@ -216,38 +216,38 @@ static int create_safe_exec_page(void *src_start, size_t length,
        memcpy((void *)dst, src_start, length);
        flush_icache_range(dst, dst + length);
 
-       pgd = pgd_offset_raw(allocator(mask), dst_addr);
-       if (pgd_none(*pgd)) {
-               pud = allocator(mask);
-               if (!pud) {
+       pgdp = pgd_offset_raw(allocator(mask), dst_addr);
+       if (pgd_none(READ_ONCE(*pgdp))) {
+               pudp = allocator(mask);
+               if (!pudp) {
                        rc = -ENOMEM;
                        goto out;
                }
-               pgd_populate(&init_mm, pgd, pud);
+               pgd_populate(&init_mm, pgdp, pudp);
        }
 
-       pud = pud_offset(pgd, dst_addr);
-       if (pud_none(*pud)) {
-               pmd = allocator(mask);
-               if (!pmd) {
+       pudp = pud_offset(pgdp, dst_addr);
+       if (pud_none(READ_ONCE(*pudp))) {
+               pmdp = allocator(mask);
+               if (!pmdp) {
                        rc = -ENOMEM;
                        goto out;
                }
-               pud_populate(&init_mm, pud, pmd);
+               pud_populate(&init_mm, pudp, pmdp);
        }
 
-       pmd = pmd_offset(pud, dst_addr);
-       if (pmd_none(*pmd)) {
-               pte = allocator(mask);
-               if (!pte) {
+       pmdp = pmd_offset(pudp, dst_addr);
+       if (pmd_none(READ_ONCE(*pmdp))) {
+               ptep = allocator(mask);
+               if (!ptep) {
                        rc = -ENOMEM;
                        goto out;
                }
-               pmd_populate_kernel(&init_mm, pmd, pte);
+               pmd_populate_kernel(&init_mm, pmdp, ptep);
        }
 
-       pte = pte_offset_kernel(pmd, dst_addr);
-       set_pte(pte, pfn_pte(virt_to_pfn(dst), PAGE_KERNEL_EXEC));
+       ptep = pte_offset_kernel(pmdp, dst_addr);
+       set_pte(ptep, pfn_pte(virt_to_pfn(dst), PAGE_KERNEL_EXEC));
 
        /*
         * Load our new page tables. A strict BBM approach requires that we
@@ -263,7 +263,7 @@ static int create_safe_exec_page(void *src_start, size_t length,
         */
        cpu_set_reserved_ttbr0();
        local_flush_tlb_all();
-       write_sysreg(phys_to_ttbr(virt_to_phys(pgd)), ttbr0_el1);
+       write_sysreg(phys_to_ttbr(virt_to_phys(pgdp)), ttbr0_el1);
        isb();
 
        *phys_dst_addr = virt_to_phys((void *)dst);
@@ -320,9 +320,9 @@ int swsusp_arch_suspend(void)
        return ret;
 }
 
-static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr)
+static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
 {
-       pte_t pte = *src_pte;
+       pte_t pte = READ_ONCE(*src_ptep);
 
        if (pte_valid(pte)) {
                /*
@@ -330,7 +330,7 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr)
                 * read only (code, rodata). Clear the RDONLY bit from
                 * the temporary mappings we use during restore.
                 */
-               set_pte(dst_pte, pte_mkwrite(pte));
+               set_pte(dst_ptep, pte_mkwrite(pte));
        } else if (debug_pagealloc_enabled() && !pte_none(pte)) {
                /*
                 * debug_pagealloc will removed the PTE_VALID bit if
@@ -343,112 +343,116 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr)
                 */
                BUG_ON(!pfn_valid(pte_pfn(pte)));
 
-               set_pte(dst_pte, pte_mkpresent(pte_mkwrite(pte)));
+               set_pte(dst_ptep, pte_mkpresent(pte_mkwrite(pte)));
        }
 }
 
-static int copy_pte(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long start,
+static int copy_pte(pmd_t *dst_pmdp, pmd_t *src_pmdp, unsigned long start,
                    unsigned long end)
 {
-       pte_t *src_pte;
-       pte_t *dst_pte;
+       pte_t *src_ptep;
+       pte_t *dst_ptep;
        unsigned long addr = start;
 
-       dst_pte = (pte_t *)get_safe_page(GFP_ATOMIC);
-       if (!dst_pte)
+       dst_ptep = (pte_t *)get_safe_page(GFP_ATOMIC);
+       if (!dst_ptep)
                return -ENOMEM;
-       pmd_populate_kernel(&init_mm, dst_pmd, dst_pte);
-       dst_pte = pte_offset_kernel(dst_pmd, start);
+       pmd_populate_kernel(&init_mm, dst_pmdp, dst_ptep);
+       dst_ptep = pte_offset_kernel(dst_pmdp, start);
 
-       src_pte = pte_offset_kernel(src_pmd, start);
+       src_ptep = pte_offset_kernel(src_pmdp, start);
        do {
-               _copy_pte(dst_pte, src_pte, addr);
-       } while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
+               _copy_pte(dst_ptep, src_ptep, addr);
+       } while (dst_ptep++, src_ptep++, addr += PAGE_SIZE, addr != end);
 
        return 0;
 }
 
-static int copy_pmd(pud_t *dst_pud, pud_t *src_pud, unsigned long start,
+static int copy_pmd(pud_t *dst_pudp, pud_t *src_pudp, unsigned long start,
                    unsigned long end)
 {
-       pmd_t *src_pmd;
-       pmd_t *dst_pmd;
+       pmd_t *src_pmdp;
+       pmd_t *dst_pmdp;
        unsigned long next;
        unsigned long addr = start;
 
-       if (pud_none(*dst_pud)) {
-               dst_pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
-               if (!dst_pmd)
+       if (pud_none(READ_ONCE(*dst_pudp))) {
+               dst_pmdp = (pmd_t *)get_safe_page(GFP_ATOMIC);
+               if (!dst_pmdp)
                        return -ENOMEM;
-               pud_populate(&init_mm, dst_pud, dst_pmd);
+               pud_populate(&init_mm, dst_pudp, dst_pmdp);
        }
-       dst_pmd = pmd_offset(dst_pud, start);
+       dst_pmdp = pmd_offset(dst_pudp, start);
 
-       src_pmd = pmd_offset(src_pud, start);
+       src_pmdp = pmd_offset(src_pudp, start);
        do {
+               pmd_t pmd = READ_ONCE(*src_pmdp);
+
                next = pmd_addr_end(addr, end);
-               if (pmd_none(*src_pmd))
+               if (pmd_none(pmd))
                        continue;
-               if (pmd_table(*src_pmd)) {
-                       if (copy_pte(dst_pmd, src_pmd, addr, next))
+               if (pmd_table(pmd)) {
+                       if (copy_pte(dst_pmdp, src_pmdp, addr, next))
                                return -ENOMEM;
                } else {
-                       set_pmd(dst_pmd,
-                               __pmd(pmd_val(*src_pmd) & ~PMD_SECT_RDONLY));
+                       set_pmd(dst_pmdp,
+                               __pmd(pmd_val(pmd) & ~PMD_SECT_RDONLY));
                }
-       } while (dst_pmd++, src_pmd++, addr = next, addr != end);
+       } while (dst_pmdp++, src_pmdp++, addr = next, addr != end);
 
        return 0;
 }
 
-static int copy_pud(pgd_t *dst_pgd, pgd_t *src_pgd, unsigned long start,
+static int copy_pud(pgd_t *dst_pgdp, pgd_t *src_pgdp, unsigned long start,
                    unsigned long end)
 {
-       pud_t *dst_pud;
-       pud_t *src_pud;
+       pud_t *dst_pudp;
+       pud_t *src_pudp;
        unsigned long next;
        unsigned long addr = start;
 
-       if (pgd_none(*dst_pgd)) {
-               dst_pud = (pud_t *)get_safe_page(GFP_ATOMIC);
-               if (!dst_pud)
+       if (pgd_none(READ_ONCE(*dst_pgdp))) {
+               dst_pudp = (pud_t *)get_safe_page(GFP_ATOMIC);
+               if (!dst_pudp)
                        return -ENOMEM;
-               pgd_populate(&init_mm, dst_pgd, dst_pud);
+               pgd_populate(&init_mm, dst_pgdp, dst_pudp);
        }
-       dst_pud = pud_offset(dst_pgd, start);
+       dst_pudp = pud_offset(dst_pgdp, start);
 
-       src_pud = pud_offset(src_pgd, start);
+       src_pudp = pud_offset(src_pgdp, start);
        do {
+               pud_t pud = READ_ONCE(*src_pudp);
+
                next = pud_addr_end(addr, end);
-               if (pud_none(*src_pud))
+               if (pud_none(pud))
                        continue;
-               if (pud_table(*(src_pud))) {
-                       if (copy_pmd(dst_pud, src_pud, addr, next))
+               if (pud_table(pud)) {
+                       if (copy_pmd(dst_pudp, src_pudp, addr, next))
                                return -ENOMEM;
                } else {
-                       set_pud(dst_pud,
-                               __pud(pud_val(*src_pud) & ~PMD_SECT_RDONLY));
+                       set_pud(dst_pudp,
+                               __pud(pud_val(pud) & ~PMD_SECT_RDONLY));
                }
-       } while (dst_pud++, src_pud++, addr = next, addr != end);
+       } while (dst_pudp++, src_pudp++, addr = next, addr != end);
 
        return 0;
 }
 
-static int copy_page_tables(pgd_t *dst_pgd, unsigned long start,
+static int copy_page_tables(pgd_t *dst_pgdp, unsigned long start,
                            unsigned long end)
 {
        unsigned long next;
        unsigned long addr = start;
-       pgd_t *src_pgd = pgd_offset_k(start);
+       pgd_t *src_pgdp = pgd_offset_k(start);
 
-       dst_pgd = pgd_offset_raw(dst_pgd, start);
+       dst_pgdp = pgd_offset_raw(dst_pgdp, start);
        do {
                next = pgd_addr_end(addr, end);
-               if (pgd_none(*src_pgd))
+               if (pgd_none(READ_ONCE(*src_pgdp)))
                        continue;
-               if (copy_pud(dst_pgd, src_pgd, addr, next))
+               if (copy_pud(dst_pgdp, src_pgdp, addr, next))
                        return -ENOMEM;
-       } while (dst_pgd++, src_pgd++, addr = next, addr != end);
+       } while (dst_pgdp++, src_pgdp++, addr = next, addr != end);
 
        return 0;
 }
index 75b220ba73a3234b7815062537e9367d36e6a040..85a251b6dfa840dd41e852683cec4032b6a9f0d9 100644 (file)
@@ -908,9 +908,9 @@ static void __armv8pmu_probe_pmu(void *info)
        int pmuver;
 
        dfr0 = read_sysreg(id_aa64dfr0_el1);
-       pmuver = cpuid_feature_extract_signed_field(dfr0,
+       pmuver = cpuid_feature_extract_unsigned_field(dfr0,
                        ID_AA64DFR0_PMUVER_SHIFT);
-       if (pmuver < 1)
+       if (pmuver == 0xf || pmuver == 0)
                return;
 
        probe->present = true;
index ad8aeb098b31ed5887aa98a438622bb2304abe97..c0da6efe546558a0b4fc7c75c63a585ff37832ea 100644 (file)
@@ -220,8 +220,15 @@ void __show_regs(struct pt_regs *regs)
 
        show_regs_print_info(KERN_DEFAULT);
        print_pstate(regs);
-       printk("pc : %pS\n", (void *)regs->pc);
-       printk("lr : %pS\n", (void *)lr);
+
+       if (!user_mode(regs)) {
+               printk("pc : %pS\n", (void *)regs->pc);
+               printk("lr : %pS\n", (void *)lr);
+       } else {
+               printk("pc : %016llx\n", regs->pc);
+               printk("lr : %016llx\n", lr);
+       }
+
        printk("sp : %016llx\n", sp);
 
        i = top_reg;
index 6618036ae6d4697c78a93bd6d1659dee703be23c..9ae31f7e224365d054a9712551b9ac75a0b19e9e 100644 (file)
@@ -1419,7 +1419,7 @@ static int compat_ptrace_hbp_get(unsigned int note_type,
        u64 addr = 0;
        u32 ctrl = 0;
 
-       int err, idx = compat_ptrace_hbp_num_to_idx(num);;
+       int err, idx = compat_ptrace_hbp_num_to_idx(num);
 
        if (num & 1) {
                err = ptrace_hbp_get_addr(note_type, tsk, idx, &addr);
index 76809ccd309ccaf330e45ac4b814922ae5949624..d5718a060672e1696618904c8844447daa042007 100644 (file)
@@ -59,6 +59,11 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        if (tsk->ret_stack &&
                        (frame->pc == (unsigned long)return_to_handler)) {
+               if (WARN_ON_ONCE(frame->graph == -1))
+                       return -EINVAL;
+               if (frame->graph < -1)
+                       frame->graph += FTRACE_NOTRACE_DEPTH;
+
                /*
                 * This is a case where function graph tracer has
                 * modified a return address (LR) in a stack frame
index 8b8bbd3eaa52cc8df71d66ab1063427232319692..a382b2a1b84e3204b5794fb5f367ac15a0bddf43 100644 (file)
@@ -57,7 +57,7 @@ do_compat_cache_op(unsigned long start, unsigned long end, int flags)
        if (end < start || flags)
                return -EINVAL;
 
-       if (!access_ok(VERIFY_READ, start, end - start))
+       if (!access_ok(VERIFY_READ, (const void __user *)start, end - start))
                return -EFAULT;
 
        return __do_compat_cache_op(start, end);
index a4391280fba9631d69cf8bda434c307956b92668..f258636273c9588dca80420341a3627cfdd61d2c 100644 (file)
@@ -52,7 +52,7 @@ unsigned long profile_pc(struct pt_regs *regs)
        frame.fp = regs->regs[29];
        frame.pc = regs->pc;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-       frame.graph = -1; /* no task info */
+       frame.graph = current->curr_ret_stack;
 #endif
        do {
                int ret = unwind_frame(NULL, &frame);
index bbb0fde2780ef780cd3c2de7a071691556d5ce6d..eb2d15147e8d3bb2be8731400990f18979022fce 100644 (file)
@@ -57,7 +57,7 @@ static const char *handler[]= {
        "Error"
 };
 
-int show_unhandled_signals = 1;
+int show_unhandled_signals = 0;
 
 static void dump_backtrace_entry(unsigned long where)
 {
@@ -526,14 +526,6 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
        }
 #endif
 
-       if (show_unhandled_signals_ratelimited()) {
-               pr_info("%s[%d]: syscall %d\n", current->comm,
-                       task_pid_nr(current), regs->syscallno);
-               dump_instr("", regs);
-               if (user_mode(regs))
-                       __show_regs(regs);
-       }
-
        return sys_ni_syscall();
 }
 
index d7e3299a773460fcd3b39930864e078e72453475..959e50d2588c0f14b9eb9230522c3f12c3f7daf9 100644 (file)
@@ -363,8 +363,6 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 {
        int ret = 0;
 
-       vcpu_load(vcpu);
-
        trace_kvm_set_guest_debug(vcpu, dbg->control);
 
        if (dbg->control & ~KVM_GUESTDBG_VALID_MASK) {
@@ -386,7 +384,6 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
        }
 
 out:
-       vcpu_put(vcpu);
        return ret;
 }
 
index 116252a8d3a5507295ed30abfd740e1cc07446ae..870f4b1587f97496c3fd427fe6b652bae1a96cd7 100644 (file)
@@ -407,8 +407,10 @@ again:
                u32 midr = read_cpuid_id();
 
                /* Apply BTAC predictors mitigation to all Falkor chips */
-               if ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)
+               if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) ||
+                   ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) {
                        __qcom_hyp_sanitize_btac_predictors();
+               }
        }
 
        fp_enabled = __fpsimd_enabled();
index 7b60d62ac5939e83c8e153ec1c3a0447565f23eb..65dfc8571bf8397c3f2a6297d21b5112794461e1 100644 (file)
@@ -286,48 +286,52 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
 
 }
 
-static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start)
+static void walk_pte(struct pg_state *st, pmd_t *pmdp, unsigned long start)
 {
-       pte_t *pte = pte_offset_kernel(pmd, 0UL);
+       pte_t *ptep = pte_offset_kernel(pmdp, 0UL);
        unsigned long addr;
        unsigned i;
 
-       for (i = 0; i < PTRS_PER_PTE; i++, pte++) {
+       for (i = 0; i < PTRS_PER_PTE; i++, ptep++) {
                addr = start + i * PAGE_SIZE;
-               note_page(st, addr, 4, pte_val(*pte));
+               note_page(st, addr, 4, READ_ONCE(pte_val(*ptep)));
        }
 }
 
-static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
+static void walk_pmd(struct pg_state *st, pud_t *pudp, unsigned long start)
 {
-       pmd_t *pmd = pmd_offset(pud, 0UL);
+       pmd_t *pmdp = pmd_offset(pudp, 0UL);
        unsigned long addr;
        unsigned i;
 
-       for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
+       for (i = 0; i < PTRS_PER_PMD; i++, pmdp++) {
+               pmd_t pmd = READ_ONCE(*pmdp);
+
                addr = start + i * PMD_SIZE;
-               if (pmd_none(*pmd) || pmd_sect(*pmd)) {
-                       note_page(st, addr, 3, pmd_val(*pmd));
+               if (pmd_none(pmd) || pmd_sect(pmd)) {
+                       note_page(st, addr, 3, pmd_val(pmd));
                } else {
-                       BUG_ON(pmd_bad(*pmd));
-                       walk_pte(st, pmd, addr);
+                       BUG_ON(pmd_bad(pmd));
+                       walk_pte(st, pmdp, addr);
                }
        }
 }
 
-static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
+static void walk_pud(struct pg_state *st, pgd_t *pgdp, unsigned long start)
 {
-       pud_t *pud = pud_offset(pgd, 0UL);
+       pud_t *pudp = pud_offset(pgdp, 0UL);
        unsigned long addr;
        unsigned i;
 
-       for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
+       for (i = 0; i < PTRS_PER_PUD; i++, pudp++) {
+               pud_t pud = READ_ONCE(*pudp);
+
                addr = start + i * PUD_SIZE;
-               if (pud_none(*pud) || pud_sect(*pud)) {
-                       note_page(st, addr, 2, pud_val(*pud));
+               if (pud_none(pud) || pud_sect(pud)) {
+                       note_page(st, addr, 2, pud_val(pud));
                } else {
-                       BUG_ON(pud_bad(*pud));
-                       walk_pmd(st, pud, addr);
+                       BUG_ON(pud_bad(pud));
+                       walk_pmd(st, pudp, addr);
                }
        }
 }
@@ -335,17 +339,19 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
 static void walk_pgd(struct pg_state *st, struct mm_struct *mm,
                     unsigned long start)
 {
-       pgd_t *pgd = pgd_offset(mm, 0UL);
+       pgd_t *pgdp = pgd_offset(mm, 0UL);
        unsigned i;
        unsigned long addr;
 
-       for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
+       for (i = 0; i < PTRS_PER_PGD; i++, pgdp++) {
+               pgd_t pgd = READ_ONCE(*pgdp);
+
                addr = start + i * PGDIR_SIZE;
-               if (pgd_none(*pgd)) {
-                       note_page(st, addr, 1, pgd_val(*pgd));
+               if (pgd_none(pgd)) {
+                       note_page(st, addr, 1, pgd_val(pgd));
                } else {
-                       BUG_ON(pgd_bad(*pgd));
-                       walk_pud(st, pgd, addr);
+                       BUG_ON(pgd_bad(pgd));
+                       walk_pud(st, pgdp, addr);
                }
        }
 }
index f76bb2c3c9434dc29c572d4103f9eb10b42dc278..bff11553eb050306dfa9df7fec0682f6a03cbf61 100644 (file)
@@ -130,7 +130,8 @@ static void mem_abort_decode(unsigned int esr)
 void show_pte(unsigned long addr)
 {
        struct mm_struct *mm;
-       pgd_t *pgd;
+       pgd_t *pgdp;
+       pgd_t pgd;
 
        if (addr < TASK_SIZE) {
                /* TTBR0 */
@@ -149,33 +150,37 @@ void show_pte(unsigned long addr)
                return;
        }
 
-       pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgd = %p\n",
+       pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp = %p\n",
                 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
                 VA_BITS, mm->pgd);
-       pgd = pgd_offset(mm, addr);
-       pr_alert("[%016lx] *pgd=%016llx", addr, pgd_val(*pgd));
+       pgdp = pgd_offset(mm, addr);
+       pgd = READ_ONCE(*pgdp);
+       pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
 
        do {
-               pud_t *pud;
-               pmd_t *pmd;
-               pte_t *pte;
+               pud_t *pudp, pud;
+               pmd_t *pmdp, pmd;
+               pte_t *ptep, pte;
 
-               if (pgd_none(*pgd) || pgd_bad(*pgd))
+               if (pgd_none(pgd) || pgd_bad(pgd))
                        break;
 
-               pud = pud_offset(pgd, addr);
-               pr_cont(", *pud=%016llx", pud_val(*pud));
-               if (pud_none(*pud) || pud_bad(*pud))
+               pudp = pud_offset(pgdp, addr);
+               pud = READ_ONCE(*pudp);
+               pr_cont(", pud=%016llx", pud_val(pud));
+               if (pud_none(pud) || pud_bad(pud))
                        break;
 
-               pmd = pmd_offset(pud, addr);
-               pr_cont(", *pmd=%016llx", pmd_val(*pmd));
-               if (pmd_none(*pmd) || pmd_bad(*pmd))
+               pmdp = pmd_offset(pudp, addr);
+               pmd = READ_ONCE(*pmdp);
+               pr_cont(", pmd=%016llx", pmd_val(pmd));
+               if (pmd_none(pmd) || pmd_bad(pmd))
                        break;
 
-               pte = pte_offset_map(pmd, addr);
-               pr_cont(", *pte=%016llx", pte_val(*pte));
-               pte_unmap(pte);
+               ptep = pte_offset_map(pmdp, addr);
+               pte = READ_ONCE(*ptep);
+               pr_cont(", pte=%016llx", pte_val(pte));
+               pte_unmap(ptep);
        } while(0);
 
        pr_cont("\n");
@@ -196,8 +201,9 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
                          pte_t entry, int dirty)
 {
        pteval_t old_pteval, pteval;
+       pte_t pte = READ_ONCE(*ptep);
 
-       if (pte_same(*ptep, entry))
+       if (pte_same(pte, entry))
                return 0;
 
        /* only preserve the access flags and write permission */
@@ -210,7 +216,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
         * (calculated as: a & b == ~(~a | ~b)).
         */
        pte_val(entry) ^= PTE_RDONLY;
-       pteval = READ_ONCE(pte_val(*ptep));
+       pteval = pte_val(pte);
        do {
                old_pteval = pteval;
                pteval ^= PTE_RDONLY;
index 6cb0fa92a65162ecce1e84b8ef09177fcc54785d..ecc6818191df961eac49e6ca0c7d8b8d38d0c855 100644 (file)
@@ -54,14 +54,14 @@ static inline pgprot_t pte_pgprot(pte_t pte)
 static int find_num_contig(struct mm_struct *mm, unsigned long addr,
                           pte_t *ptep, size_t *pgsize)
 {
-       pgd_t *pgd = pgd_offset(mm, addr);
-       pud_t *pud;
-       pmd_t *pmd;
+       pgd_t *pgdp = pgd_offset(mm, addr);
+       pud_t *pudp;
+       pmd_t *pmdp;
 
        *pgsize = PAGE_SIZE;
-       pud = pud_offset(pgd, addr);
-       pmd = pmd_offset(pud, addr);
-       if ((pte_t *)pmd == ptep) {
+       pudp = pud_offset(pgdp, addr);
+       pmdp = pmd_offset(pudp, addr);
+       if ((pte_t *)pmdp == ptep) {
                *pgsize = PMD_SIZE;
                return CONT_PMDS;
        }
@@ -181,11 +181,8 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 
        clear_flush(mm, addr, ptep, pgsize, ncontig);
 
-       for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) {
-               pr_debug("%s: set pte %p to 0x%llx\n", __func__, ptep,
-                        pte_val(pfn_pte(pfn, hugeprot)));
+       for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
                set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
-       }
 }
 
 void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
@@ -203,20 +200,20 @@ void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
 pte_t *huge_pte_alloc(struct mm_struct *mm,
                      unsigned long addr, unsigned long sz)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pte_t *pte = NULL;
-
-       pr_debug("%s: addr:0x%lx sz:0x%lx\n", __func__, addr, sz);
-       pgd = pgd_offset(mm, addr);
-       pud = pud_alloc(mm, pgd, addr);
-       if (!pud)
+       pgd_t *pgdp;
+       pud_t *pudp;
+       pmd_t *pmdp;
+       pte_t *ptep = NULL;
+
+       pgdp = pgd_offset(mm, addr);
+       pudp = pud_alloc(mm, pgdp, addr);
+       if (!pudp)
                return NULL;
 
        if (sz == PUD_SIZE) {
-               pte = (pte_t *)pud;
+               ptep = (pte_t *)pudp;
        } else if (sz == (PAGE_SIZE * CONT_PTES)) {
-               pmd_t *pmd = pmd_alloc(mm, pud, addr);
+               pmdp = pmd_alloc(mm, pudp, addr);
 
                WARN_ON(addr & (sz - 1));
                /*
@@ -226,60 +223,55 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
                 * will be no pte_unmap() to correspond with this
                 * pte_alloc_map().
                 */
-               pte = pte_alloc_map(mm, pmd, addr);
+               ptep = pte_alloc_map(mm, pmdp, addr);
        } else if (sz == PMD_SIZE) {
                if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) &&
-                   pud_none(*pud))
-                       pte = huge_pmd_share(mm, addr, pud);
+                   pud_none(READ_ONCE(*pudp)))
+                       ptep = huge_pmd_share(mm, addr, pudp);
                else
-                       pte = (pte_t *)pmd_alloc(mm, pud, addr);
+                       ptep = (pte_t *)pmd_alloc(mm, pudp, addr);
        } else if (sz == (PMD_SIZE * CONT_PMDS)) {
-               pmd_t *pmd;
-
-               pmd = pmd_alloc(mm, pud, addr);
+               pmdp = pmd_alloc(mm, pudp, addr);
                WARN_ON(addr & (sz - 1));
-               return (pte_t *)pmd;
+               return (pte_t *)pmdp;
        }
 
-       pr_debug("%s: addr:0x%lx sz:0x%lx ret pte=%p/0x%llx\n", __func__, addr,
-              sz, pte, pte_val(*pte));
-       return pte;
+       return ptep;
 }
 
 pte_t *huge_pte_offset(struct mm_struct *mm,
                       unsigned long addr, unsigned long sz)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
+       pgd_t *pgdp;
+       pud_t *pudp, pud;
+       pmd_t *pmdp, pmd;
 
-       pgd = pgd_offset(mm, addr);
-       pr_debug("%s: addr:0x%lx pgd:%p\n", __func__, addr, pgd);
-       if (!pgd_present(*pgd))
+       pgdp = pgd_offset(mm, addr);
+       if (!pgd_present(READ_ONCE(*pgdp)))
                return NULL;
 
-       pud = pud_offset(pgd, addr);
-       if (sz != PUD_SIZE && pud_none(*pud))
+       pudp = pud_offset(pgdp, addr);
+       pud = READ_ONCE(*pudp);
+       if (sz != PUD_SIZE && pud_none(pud))
                return NULL;
        /* hugepage or swap? */
-       if (pud_huge(*pud) || !pud_present(*pud))
-               return (pte_t *)pud;
+       if (pud_huge(pud) || !pud_present(pud))
+               return (pte_t *)pudp;
        /* table; check the next level */
 
        if (sz == CONT_PMD_SIZE)
                addr &= CONT_PMD_MASK;
 
-       pmd = pmd_offset(pud, addr);
+       pmdp = pmd_offset(pudp, addr);
+       pmd = READ_ONCE(*pmdp);
        if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) &&
-           pmd_none(*pmd))
+           pmd_none(pmd))
                return NULL;
-       if (pmd_huge(*pmd) || !pmd_present(*pmd))
-               return (pte_t *)pmd;
+       if (pmd_huge(pmd) || !pmd_present(pmd))
+               return (pte_t *)pmdp;
 
-       if (sz == CONT_PTE_SIZE) {
-               pte_t *pte = pte_offset_kernel(pmd, (addr & CONT_PTE_MASK));
-               return pte;
-       }
+       if (sz == CONT_PTE_SIZE)
+               return pte_offset_kernel(pmdp, (addr & CONT_PTE_MASK));
 
        return NULL;
 }
@@ -367,7 +359,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
        size_t pgsize;
        pte_t pte;
 
-       if (!pte_cont(*ptep)) {
+       if (!pte_cont(READ_ONCE(*ptep))) {
                ptep_set_wrprotect(mm, addr, ptep);
                return;
        }
@@ -391,7 +383,7 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma,
        size_t pgsize;
        int ncontig;
 
-       if (!pte_cont(*ptep)) {
+       if (!pte_cont(READ_ONCE(*ptep))) {
                ptep_clear_flush(vma, addr, ptep);
                return;
        }
index 6e02e6fb4c7b9e12da9796b2e8a2be68ca143ae0..dabfc1ecda3d3a9d57a430f1641eca05c1114703 100644 (file)
@@ -44,92 +44,92 @@ static phys_addr_t __init kasan_alloc_zeroed_page(int node)
        return __pa(p);
 }
 
-static pte_t *__init kasan_pte_offset(pmd_t *pmd, unsigned long addr, int node,
+static pte_t *__init kasan_pte_offset(pmd_t *pmdp, unsigned long addr, int node,
                                      bool early)
 {
-       if (pmd_none(*pmd)) {
+       if (pmd_none(READ_ONCE(*pmdp))) {
                phys_addr_t pte_phys = early ? __pa_symbol(kasan_zero_pte)
                                             : kasan_alloc_zeroed_page(node);
-               __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE);
+               __pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
        }
 
-       return early ? pte_offset_kimg(pmd, addr)
-                    : pte_offset_kernel(pmd, addr);
+       return early ? pte_offset_kimg(pmdp, addr)
+                    : pte_offset_kernel(pmdp, addr);
 }
 
-static pmd_t *__init kasan_pmd_offset(pud_t *pud, unsigned long addr, int node,
+static pmd_t *__init kasan_pmd_offset(pud_t *pudp, unsigned long addr, int node,
                                      bool early)
 {
-       if (pud_none(*pud)) {
+       if (pud_none(READ_ONCE(*pudp))) {
                phys_addr_t pmd_phys = early ? __pa_symbol(kasan_zero_pmd)
                                             : kasan_alloc_zeroed_page(node);
-               __pud_populate(pud, pmd_phys, PMD_TYPE_TABLE);
+               __pud_populate(pudp, pmd_phys, PMD_TYPE_TABLE);
        }
 
-       return early ? pmd_offset_kimg(pud, addr) : pmd_offset(pud, addr);
+       return early ? pmd_offset_kimg(pudp, addr) : pmd_offset(pudp, addr);
 }
 
-static pud_t *__init kasan_pud_offset(pgd_t *pgd, unsigned long addr, int node,
+static pud_t *__init kasan_pud_offset(pgd_t *pgdp, unsigned long addr, int node,
                                      bool early)
 {
-       if (pgd_none(*pgd)) {
+       if (pgd_none(READ_ONCE(*pgdp))) {
                phys_addr_t pud_phys = early ? __pa_symbol(kasan_zero_pud)
                                             : kasan_alloc_zeroed_page(node);
-               __pgd_populate(pgd, pud_phys, PMD_TYPE_TABLE);
+               __pgd_populate(pgdp, pud_phys, PMD_TYPE_TABLE);
        }
 
-       return early ? pud_offset_kimg(pgd, addr) : pud_offset(pgd, addr);
+       return early ? pud_offset_kimg(pgdp, addr) : pud_offset(pgdp, addr);
 }
 
-static void __init kasan_pte_populate(pmd_t *pmd, unsigned long addr,
+static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
                                      unsigned long end, int node, bool early)
 {
        unsigned long next;
-       pte_t *pte = kasan_pte_offset(pmd, addr, node, early);
+       pte_t *ptep = kasan_pte_offset(pmdp, addr, node, early);
 
        do {
                phys_addr_t page_phys = early ? __pa_symbol(kasan_zero_page)
                                              : kasan_alloc_zeroed_page(node);
                next = addr + PAGE_SIZE;
-               set_pte(pte, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
-       } while (pte++, addr = next, addr != end && pte_none(*pte));
+               set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
+       } while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep)));
 }
 
-static void __init kasan_pmd_populate(pud_t *pud, unsigned long addr,
+static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
                                      unsigned long end, int node, bool early)
 {
        unsigned long next;
-       pmd_t *pmd = kasan_pmd_offset(pud, addr, node, early);
+       pmd_t *pmdp = kasan_pmd_offset(pudp, addr, node, early);
 
        do {
                next = pmd_addr_end(addr, end);
-               kasan_pte_populate(pmd, addr, next, node, early);
-       } while (pmd++, addr = next, addr != end && pmd_none(*pmd));
+               kasan_pte_populate(pmdp, addr, next, node, early);
+       } while (pmdp++, addr = next, addr != end && pmd_none(READ_ONCE(*pmdp)));
 }
 
-static void __init kasan_pud_populate(pgd_t *pgd, unsigned long addr,
+static void __init kasan_pud_populate(pgd_t *pgdp, unsigned long addr,
                                      unsigned long end, int node, bool early)
 {
        unsigned long next;
-       pud_t *pud = kasan_pud_offset(pgd, addr, node, early);
+       pud_t *pudp = kasan_pud_offset(pgdp, addr, node, early);
 
        do {
                next = pud_addr_end(addr, end);
-               kasan_pmd_populate(pud, addr, next, node, early);
-       } while (pud++, addr = next, addr != end && pud_none(*pud));
+               kasan_pmd_populate(pudp, addr, next, node, early);
+       } while (pudp++, addr = next, addr != end && pud_none(READ_ONCE(*pudp)));
 }
 
 static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
                                      int node, bool early)
 {
        unsigned long next;
-       pgd_t *pgd;
+       pgd_t *pgdp;
 
-       pgd = pgd_offset_k(addr);
+       pgdp = pgd_offset_k(addr);
        do {
                next = pgd_addr_end(addr, end);
-               kasan_pud_populate(pgd, addr, next, node, early);
-       } while (pgd++, addr = next, addr != end);
+               kasan_pud_populate(pgdp, addr, next, node, early);
+       } while (pgdp++, addr = next, addr != end);
 }
 
 /* The early shadow maps everything to a single page of zeroes */
@@ -155,14 +155,14 @@ static void __init kasan_map_populate(unsigned long start, unsigned long end,
  */
 void __init kasan_copy_shadow(pgd_t *pgdir)
 {
-       pgd_t *pgd, *pgd_new, *pgd_end;
+       pgd_t *pgdp, *pgdp_new, *pgdp_end;
 
-       pgd = pgd_offset_k(KASAN_SHADOW_START);
-       pgd_end = pgd_offset_k(KASAN_SHADOW_END);
-       pgd_new = pgd_offset_raw(pgdir, KASAN_SHADOW_START);
+       pgdp = pgd_offset_k(KASAN_SHADOW_START);
+       pgdp_end = pgd_offset_k(KASAN_SHADOW_END);
+       pgdp_new = pgd_offset_raw(pgdir, KASAN_SHADOW_START);
        do {
-               set_pgd(pgd_new, *pgd);
-       } while (pgd++, pgd_new++, pgd != pgd_end);
+               set_pgd(pgdp_new, READ_ONCE(*pgdp));
+       } while (pgdp++, pgdp_new++, pgdp != pgdp_end);
 }
 
 static void __init clear_pgds(unsigned long start,
index 4694cda823c9541527b95f269658bdbc4b8243d7..2dbb2c9f1ec1770e7f9f5aca7176eac2cc153d32 100644 (file)
@@ -108,7 +108,7 @@ static bool pgattr_change_is_safe(u64 old, u64 new)
         * The following mapping attributes may be updated in live
         * kernel mappings without the need for break-before-make.
         */
-       static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE;
+       static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG;
 
        /* creating or taking down mappings is always safe */
        if (old == 0 || new == 0)
@@ -118,52 +118,55 @@ static bool pgattr_change_is_safe(u64 old, u64 new)
        if ((old | new) & PTE_CONT)
                return false;
 
-       /* Transitioning from Global to Non-Global is safe */
-       if (((old ^ new) == PTE_NG) && (new & PTE_NG))
-               return true;
+       /* Transitioning from Non-Global to Global is unsafe */
+       if (old & ~new & PTE_NG)
+               return false;
 
        return ((old ^ new) & ~mask) == 0;
 }
 
-static void init_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
+static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
                     phys_addr_t phys, pgprot_t prot)
 {
-       pte_t *pte;
+       pte_t *ptep;
 
-       pte = pte_set_fixmap_offset(pmd, addr);
+       ptep = pte_set_fixmap_offset(pmdp, addr);
        do {
-               pte_t old_pte = *pte;
+               pte_t old_pte = READ_ONCE(*ptep);
 
-               set_pte(pte, pfn_pte(__phys_to_pfn(phys), prot));
+               set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
 
                /*
                 * After the PTE entry has been populated once, we
                 * only allow updates to the permission attributes.
                 */
-               BUG_ON(!pgattr_change_is_safe(pte_val(old_pte), pte_val(*pte)));
+               BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
+                                             READ_ONCE(pte_val(*ptep))));
 
                phys += PAGE_SIZE;
-       } while (pte++, addr += PAGE_SIZE, addr != end);
+       } while (ptep++, addr += PAGE_SIZE, addr != end);
 
        pte_clear_fixmap();
 }
 
-static void alloc_init_cont_pte(pmd_t *pmd, unsigned long addr,
+static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
                                unsigned long end, phys_addr_t phys,
                                pgprot_t prot,
                                phys_addr_t (*pgtable_alloc)(void),
                                int flags)
 {
        unsigned long next;
+       pmd_t pmd = READ_ONCE(*pmdp);
 
-       BUG_ON(pmd_sect(*pmd));
-       if (pmd_none(*pmd)) {
+       BUG_ON(pmd_sect(pmd));
+       if (pmd_none(pmd)) {
                phys_addr_t pte_phys;
                BUG_ON(!pgtable_alloc);
                pte_phys = pgtable_alloc();
-               __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE);
+               __pmd_populate(pmdp, pte_phys, PMD_TYPE_TABLE);
+               pmd = READ_ONCE(*pmdp);
        }
-       BUG_ON(pmd_bad(*pmd));
+       BUG_ON(pmd_bad(pmd));
 
        do {
                pgprot_t __prot = prot;
@@ -175,67 +178,69 @@ static void alloc_init_cont_pte(pmd_t *pmd, unsigned long addr,
                    (flags & NO_CONT_MAPPINGS) == 0)
                        __prot = __pgprot(pgprot_val(prot) | PTE_CONT);
 
-               init_pte(pmd, addr, next, phys, __prot);
+               init_pte(pmdp, addr, next, phys, __prot);
 
                phys += next - addr;
        } while (addr = next, addr != end);
 }
 
-static void init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
+static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
                     phys_addr_t phys, pgprot_t prot,
                     phys_addr_t (*pgtable_alloc)(void), int flags)
 {
        unsigned long next;
-       pmd_t *pmd;
+       pmd_t *pmdp;
 
-       pmd = pmd_set_fixmap_offset(pud, addr);
+       pmdp = pmd_set_fixmap_offset(pudp, addr);
        do {
-               pmd_t old_pmd = *pmd;
+               pmd_t old_pmd = READ_ONCE(*pmdp);
 
                next = pmd_addr_end(addr, end);
 
                /* try section mapping first */
                if (((addr | next | phys) & ~SECTION_MASK) == 0 &&
                    (flags & NO_BLOCK_MAPPINGS) == 0) {
-                       pmd_set_huge(pmd, phys, prot);
+                       pmd_set_huge(pmdp, phys, prot);
 
                        /*
                         * After the PMD entry has been populated once, we
                         * only allow updates to the permission attributes.
                         */
                        BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd),
-                                                     pmd_val(*pmd)));
+                                                     READ_ONCE(pmd_val(*pmdp))));
                } else {
-                       alloc_init_cont_pte(pmd, addr, next, phys, prot,
+                       alloc_init_cont_pte(pmdp, addr, next, phys, prot,
                                            pgtable_alloc, flags);
 
                        BUG_ON(pmd_val(old_pmd) != 0 &&
-                              pmd_val(old_pmd) != pmd_val(*pmd));
+                              pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp)));
                }
                phys += next - addr;
-       } while (pmd++, addr = next, addr != end);
+       } while (pmdp++, addr = next, addr != end);
 
        pmd_clear_fixmap();
 }
 
-static void alloc_init_cont_pmd(pud_t *pud, unsigned long addr,
+static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
                                unsigned long end, phys_addr_t phys,
                                pgprot_t prot,
                                phys_addr_t (*pgtable_alloc)(void), int flags)
 {
        unsigned long next;
+       pud_t pud = READ_ONCE(*pudp);
 
        /*
         * Check for initial section mappings in the pgd/pud.
         */
-       BUG_ON(pud_sect(*pud));
-       if (pud_none(*pud)) {
+       BUG_ON(pud_sect(pud));
+       if (pud_none(pud)) {
                phys_addr_t pmd_phys;
                BUG_ON(!pgtable_alloc);
                pmd_phys = pgtable_alloc();
-               __pud_populate(pud, pmd_phys, PUD_TYPE_TABLE);
+               __pud_populate(pudp, pmd_phys, PUD_TYPE_TABLE);
+               pud = READ_ONCE(*pudp);
        }
-       BUG_ON(pud_bad(*pud));
+       BUG_ON(pud_bad(pud));
 
        do {
                pgprot_t __prot = prot;
@@ -247,7 +252,7 @@ static void alloc_init_cont_pmd(pud_t *pud, unsigned long addr,
                    (flags & NO_CONT_MAPPINGS) == 0)
                        __prot = __pgprot(pgprot_val(prot) | PTE_CONT);
 
-               init_pmd(pud, addr, next, phys, __prot, pgtable_alloc, flags);
+               init_pmd(pudp, addr, next, phys, __prot, pgtable_alloc, flags);
 
                phys += next - addr;
        } while (addr = next, addr != end);
@@ -265,25 +270,27 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
        return true;
 }
 
-static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
-                                 phys_addr_t phys, pgprot_t prot,
-                                 phys_addr_t (*pgtable_alloc)(void),
-                                 int flags)
+static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
+                          phys_addr_t phys, pgprot_t prot,
+                          phys_addr_t (*pgtable_alloc)(void),
+                          int flags)
 {
-       pud_t *pud;
        unsigned long next;
+       pud_t *pudp;
+       pgd_t pgd = READ_ONCE(*pgdp);
 
-       if (pgd_none(*pgd)) {
+       if (pgd_none(pgd)) {
                phys_addr_t pud_phys;
                BUG_ON(!pgtable_alloc);
                pud_phys = pgtable_alloc();
-               __pgd_populate(pgd, pud_phys, PUD_TYPE_TABLE);
+               __pgd_populate(pgdp, pud_phys, PUD_TYPE_TABLE);
+               pgd = READ_ONCE(*pgdp);
        }
-       BUG_ON(pgd_bad(*pgd));
+       BUG_ON(pgd_bad(pgd));
 
-       pud = pud_set_fixmap_offset(pgd, addr);
+       pudp = pud_set_fixmap_offset(pgdp, addr);
        do {
-               pud_t old_pud = *pud;
+               pud_t old_pud = READ_ONCE(*pudp);
 
                next = pud_addr_end(addr, end);
 
@@ -292,23 +299,23 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
                 */
                if (use_1G_block(addr, next, phys) &&
                    (flags & NO_BLOCK_MAPPINGS) == 0) {
-                       pud_set_huge(pud, phys, prot);
+                       pud_set_huge(pudp, phys, prot);
 
                        /*
                         * After the PUD entry has been populated once, we
                         * only allow updates to the permission attributes.
                         */
                        BUG_ON(!pgattr_change_is_safe(pud_val(old_pud),
-                                                     pud_val(*pud)));
+                                                     READ_ONCE(pud_val(*pudp))));
                } else {
-                       alloc_init_cont_pmd(pud, addr, next, phys, prot,
+                       alloc_init_cont_pmd(pudp, addr, next, phys, prot,
                                            pgtable_alloc, flags);
 
                        BUG_ON(pud_val(old_pud) != 0 &&
-                              pud_val(old_pud) != pud_val(*pud));
+                              pud_val(old_pud) != READ_ONCE(pud_val(*pudp)));
                }
                phys += next - addr;
-       } while (pud++, addr = next, addr != end);
+       } while (pudp++, addr = next, addr != end);
 
        pud_clear_fixmap();
 }
@@ -320,7 +327,7 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
                                 int flags)
 {
        unsigned long addr, length, end, next;
-       pgd_t *pgd = pgd_offset_raw(pgdir, virt);
+       pgd_t *pgdp = pgd_offset_raw(pgdir, virt);
 
        /*
         * If the virtual and physical address don't have the same offset
@@ -336,10 +343,10 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
        end = addr + length;
        do {
                next = pgd_addr_end(addr, end);
-               alloc_init_pud(pgd, addr, next, phys, prot, pgtable_alloc,
+               alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
                               flags);
                phys += next - addr;
-       } while (pgd++, addr = next, addr != end);
+       } while (pgdp++, addr = next, addr != end);
 }
 
 static phys_addr_t pgd_pgtable_alloc(void)
@@ -401,10 +408,10 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
        flush_tlb_kernel_range(virt, virt + size);
 }
 
-static void __init __map_memblock(pgd_t *pgd, phys_addr_t start,
+static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start,
                                  phys_addr_t end, pgprot_t prot, int flags)
 {
-       __create_pgd_mapping(pgd, start, __phys_to_virt(start), end - start,
+       __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start,
                             prot, early_pgtable_alloc, flags);
 }
 
@@ -418,7 +425,7 @@ void __init mark_linear_text_alias_ro(void)
                            PAGE_KERNEL_RO);
 }
 
-static void __init map_mem(pgd_t *pgd)
+static void __init map_mem(pgd_t *pgdp)
 {
        phys_addr_t kernel_start = __pa_symbol(_text);
        phys_addr_t kernel_end = __pa_symbol(__init_begin);
@@ -451,7 +458,7 @@ static void __init map_mem(pgd_t *pgd)
                if (memblock_is_nomap(reg))
                        continue;
 
-               __map_memblock(pgd, start, end, PAGE_KERNEL, flags);
+               __map_memblock(pgdp, start, end, PAGE_KERNEL, flags);
        }
 
        /*
@@ -464,7 +471,7 @@ static void __init map_mem(pgd_t *pgd)
         * Note that contiguous mappings cannot be remapped in this way,
         * so we should avoid them here.
         */
-       __map_memblock(pgd, kernel_start, kernel_end,
+       __map_memblock(pgdp, kernel_start, kernel_end,
                       PAGE_KERNEL, NO_CONT_MAPPINGS);
        memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
 
@@ -475,7 +482,7 @@ static void __init map_mem(pgd_t *pgd)
         * through /sys/kernel/kexec_crash_size interface.
         */
        if (crashk_res.end) {
-               __map_memblock(pgd, crashk_res.start, crashk_res.end + 1,
+               __map_memblock(pgdp, crashk_res.start, crashk_res.end + 1,
                               PAGE_KERNEL,
                               NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
                memblock_clear_nomap(crashk_res.start,
@@ -499,7 +506,7 @@ void mark_rodata_ro(void)
        debug_checkwx();
 }
 
-static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
+static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
                                      pgprot_t prot, struct vm_struct *vma,
                                      int flags, unsigned long vm_flags)
 {
@@ -509,7 +516,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
        BUG_ON(!PAGE_ALIGNED(pa_start));
        BUG_ON(!PAGE_ALIGNED(size));
 
-       __create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot,
+       __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot,
                             early_pgtable_alloc, flags);
 
        if (!(vm_flags & VM_NO_GUARD))
@@ -562,7 +569,7 @@ core_initcall(map_entry_trampoline);
 /*
  * Create fine-grained mappings for the kernel.
  */
-static void __init map_kernel(pgd_t *pgd)
+static void __init map_kernel(pgd_t *pgdp)
 {
        static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext,
                                vmlinux_initdata, vmlinux_data;
@@ -578,24 +585,24 @@ static void __init map_kernel(pgd_t *pgd)
         * Only rodata will be remapped with different permissions later on,
         * all other segments are allowed to use contiguous mappings.
         */
-       map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text, 0,
+       map_kernel_segment(pgdp, _text, _etext, text_prot, &vmlinux_text, 0,
                           VM_NO_GUARD);
-       map_kernel_segment(pgd, __start_rodata, __inittext_begin, PAGE_KERNEL,
+       map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL,
                           &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);
-       map_kernel_segment(pgd, __inittext_begin, __inittext_end, text_prot,
+       map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot,
                           &vmlinux_inittext, 0, VM_NO_GUARD);
-       map_kernel_segment(pgd, __initdata_begin, __initdata_end, PAGE_KERNEL,
+       map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL,
                           &vmlinux_initdata, 0, VM_NO_GUARD);
-       map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
+       map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
 
-       if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) {
+       if (!READ_ONCE(pgd_val(*pgd_offset_raw(pgdp, FIXADDR_START)))) {
                /*
                 * The fixmap falls in a separate pgd to the kernel, and doesn't
                 * live in the carveout for the swapper_pg_dir. We can simply
                 * re-use the existing dir for the fixmap.
                 */
-               set_pgd(pgd_offset_raw(pgd, FIXADDR_START),
-                       *pgd_offset_k(FIXADDR_START));
+               set_pgd(pgd_offset_raw(pgdp, FIXADDR_START),
+                       READ_ONCE(*pgd_offset_k(FIXADDR_START)));
        } else if (CONFIG_PGTABLE_LEVELS > 3) {
                /*
                 * The fixmap shares its top level pgd entry with the kernel
@@ -604,14 +611,15 @@ static void __init map_kernel(pgd_t *pgd)
                 * entry instead.
                 */
                BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
-               pud_populate(&init_mm, pud_set_fixmap_offset(pgd, FIXADDR_START),
+               pud_populate(&init_mm,
+                            pud_set_fixmap_offset(pgdp, FIXADDR_START),
                             lm_alias(bm_pmd));
                pud_clear_fixmap();
        } else {
                BUG();
        }
 
-       kasan_copy_shadow(pgd);
+       kasan_copy_shadow(pgdp);
 }
 
 /*
@@ -621,10 +629,10 @@ static void __init map_kernel(pgd_t *pgd)
 void __init paging_init(void)
 {
        phys_addr_t pgd_phys = early_pgtable_alloc();
-       pgd_t *pgd = pgd_set_fixmap(pgd_phys);
+       pgd_t *pgdp = pgd_set_fixmap(pgd_phys);
 
-       map_kernel(pgd);
-       map_mem(pgd);
+       map_kernel(pgdp);
+       map_mem(pgdp);
 
        /*
         * We want to reuse the original swapper_pg_dir so we don't have to
@@ -635,7 +643,7 @@ void __init paging_init(void)
         * To do this we need to go via a temporary pgd.
         */
        cpu_replace_ttbr1(__va(pgd_phys));
-       memcpy(swapper_pg_dir, pgd, PGD_SIZE);
+       memcpy(swapper_pg_dir, pgdp, PGD_SIZE);
        cpu_replace_ttbr1(lm_alias(swapper_pg_dir));
 
        pgd_clear_fixmap();
@@ -655,37 +663,40 @@ void __init paging_init(void)
  */
 int kern_addr_valid(unsigned long addr)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
+       pgd_t *pgdp;
+       pud_t *pudp, pud;
+       pmd_t *pmdp, pmd;
+       pte_t *ptep, pte;
 
        if ((((long)addr) >> VA_BITS) != -1UL)
                return 0;
 
-       pgd = pgd_offset_k(addr);
-       if (pgd_none(*pgd))
+       pgdp = pgd_offset_k(addr);
+       if (pgd_none(READ_ONCE(*pgdp)))
                return 0;
 
-       pud = pud_offset(pgd, addr);
-       if (pud_none(*pud))
+       pudp = pud_offset(pgdp, addr);
+       pud = READ_ONCE(*pudp);
+       if (pud_none(pud))
                return 0;
 
-       if (pud_sect(*pud))
-               return pfn_valid(pud_pfn(*pud));
+       if (pud_sect(pud))
+               return pfn_valid(pud_pfn(pud));
 
-       pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd))
+       pmdp = pmd_offset(pudp, addr);
+       pmd = READ_ONCE(*pmdp);
+       if (pmd_none(pmd))
                return 0;
 
-       if (pmd_sect(*pmd))
-               return pfn_valid(pmd_pfn(*pmd));
+       if (pmd_sect(pmd))
+               return pfn_valid(pmd_pfn(pmd));
 
-       pte = pte_offset_kernel(pmd, addr);
-       if (pte_none(*pte))
+       ptep = pte_offset_kernel(pmdp, addr);
+       pte = READ_ONCE(*ptep);
+       if (pte_none(pte))
                return 0;
 
-       return pfn_valid(pte_pfn(*pte));
+       return pfn_valid(pte_pfn(pte));
 }
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 #if !ARM64_SWAPPER_USES_SECTION_MAPS
@@ -700,32 +711,32 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
 {
        unsigned long addr = start;
        unsigned long next;
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
+       pgd_t *pgdp;
+       pud_t *pudp;
+       pmd_t *pmdp;
 
        do {
                next = pmd_addr_end(addr, end);
 
-               pgd = vmemmap_pgd_populate(addr, node);
-               if (!pgd)
+               pgdp = vmemmap_pgd_populate(addr, node);
+               if (!pgdp)
                        return -ENOMEM;
 
-               pud = vmemmap_pud_populate(pgd, addr, node);
-               if (!pud)
+               pudp = vmemmap_pud_populate(pgdp, addr, node);
+               if (!pudp)
                        return -ENOMEM;
 
-               pmd = pmd_offset(pud, addr);
-               if (pmd_none(*pmd)) {
+               pmdp = pmd_offset(pudp, addr);
+               if (pmd_none(READ_ONCE(*pmdp))) {
                        void *p = NULL;
 
                        p = vmemmap_alloc_block_buf(PMD_SIZE, node);
                        if (!p)
                                return -ENOMEM;
 
-                       pmd_set_huge(pmd, __pa(p), __pgprot(PROT_SECT_NORMAL));
+                       pmd_set_huge(pmdp, __pa(p), __pgprot(PROT_SECT_NORMAL));
                } else
-                       vmemmap_verify((pte_t *)pmd, node, addr, next);
+                       vmemmap_verify((pte_t *)pmdp, node, addr, next);
        } while (addr = next, addr != end);
 
        return 0;
@@ -739,20 +750,22 @@ void vmemmap_free(unsigned long start, unsigned long end,
 
 static inline pud_t * fixmap_pud(unsigned long addr)
 {
-       pgd_t *pgd = pgd_offset_k(addr);
+       pgd_t *pgdp = pgd_offset_k(addr);
+       pgd_t pgd = READ_ONCE(*pgdp);
 
-       BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd));
+       BUG_ON(pgd_none(pgd) || pgd_bad(pgd));
 
-       return pud_offset_kimg(pgd, addr);
+       return pud_offset_kimg(pgdp, addr);
 }
 
 static inline pmd_t * fixmap_pmd(unsigned long addr)
 {
-       pud_t *pud = fixmap_pud(addr);
+       pud_t *pudp = fixmap_pud(addr);
+       pud_t pud = READ_ONCE(*pudp);
 
-       BUG_ON(pud_none(*pud) || pud_bad(*pud));
+       BUG_ON(pud_none(pud) || pud_bad(pud));
 
-       return pmd_offset_kimg(pud, addr);
+       return pmd_offset_kimg(pudp, addr);
 }
 
 static inline pte_t * fixmap_pte(unsigned long addr)
@@ -768,30 +781,31 @@ static inline pte_t * fixmap_pte(unsigned long addr)
  */
 void __init early_fixmap_init(void)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
+       pgd_t *pgdp, pgd;
+       pud_t *pudp;
+       pmd_t *pmdp;
        unsigned long addr = FIXADDR_START;
 
-       pgd = pgd_offset_k(addr);
+       pgdp = pgd_offset_k(addr);
+       pgd = READ_ONCE(*pgdp);
        if (CONFIG_PGTABLE_LEVELS > 3 &&
-           !(pgd_none(*pgd) || pgd_page_paddr(*pgd) == __pa_symbol(bm_pud))) {
+           !(pgd_none(pgd) || pgd_page_paddr(pgd) == __pa_symbol(bm_pud))) {
                /*
                 * We only end up here if the kernel mapping and the fixmap
                 * share the top level pgd entry, which should only happen on
                 * 16k/4 levels configurations.
                 */
                BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
-               pud = pud_offset_kimg(pgd, addr);
+               pudp = pud_offset_kimg(pgdp, addr);
        } else {
-               if (pgd_none(*pgd))
-                       __pgd_populate(pgd, __pa_symbol(bm_pud), PUD_TYPE_TABLE);
-               pud = fixmap_pud(addr);
+               if (pgd_none(pgd))
+                       __pgd_populate(pgdp, __pa_symbol(bm_pud), PUD_TYPE_TABLE);
+               pudp = fixmap_pud(addr);
        }
-       if (pud_none(*pud))
-               __pud_populate(pud, __pa_symbol(bm_pmd), PMD_TYPE_TABLE);
-       pmd = fixmap_pmd(addr);
-       __pmd_populate(pmd, __pa_symbol(bm_pte), PMD_TYPE_TABLE);
+       if (pud_none(READ_ONCE(*pudp)))
+               __pud_populate(pudp, __pa_symbol(bm_pmd), PMD_TYPE_TABLE);
+       pmdp = fixmap_pmd(addr);
+       __pmd_populate(pmdp, __pa_symbol(bm_pte), PMD_TYPE_TABLE);
 
        /*
         * The boot-ioremap range spans multiple pmds, for which
@@ -800,11 +814,11 @@ void __init early_fixmap_init(void)
        BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
                     != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
 
-       if ((pmd != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
-            || pmd != fixmap_pmd(fix_to_virt(FIX_BTMAP_END))) {
+       if ((pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
+            || pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_END))) {
                WARN_ON(1);
-               pr_warn("pmd %p != %p, %p\n",
-                       pmd, fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)),
+               pr_warn("pmdp %p != %p, %p\n",
+                       pmdp, fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)),
                        fixmap_pmd(fix_to_virt(FIX_BTMAP_END)));
                pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
                        fix_to_virt(FIX_BTMAP_BEGIN));
@@ -824,16 +838,16 @@ void __set_fixmap(enum fixed_addresses idx,
                               phys_addr_t phys, pgprot_t flags)
 {
        unsigned long addr = __fix_to_virt(idx);
-       pte_t *pte;
+       pte_t *ptep;
 
        BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses);
 
-       pte = fixmap_pte(addr);
+       ptep = fixmap_pte(addr);
 
        if (pgprot_val(flags)) {
-               set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
+               set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
        } else {
-               pte_clear(&init_mm, addr, pte);
+               pte_clear(&init_mm, addr, ptep);
                flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
        }
 }
@@ -915,36 +929,56 @@ int __init arch_ioremap_pmd_supported(void)
        return 1;
 }
 
-int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot)
+int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
 {
        pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
                                        pgprot_val(mk_sect_prot(prot)));
+
+       /* ioremap_page_range doesn't honour BBM */
+       if (pud_present(READ_ONCE(*pudp)))
+               return 0;
+
        BUG_ON(phys & ~PUD_MASK);
-       set_pud(pud, pfn_pud(__phys_to_pfn(phys), sect_prot));
+       set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot));
        return 1;
 }
 
-int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot)
+int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
 {
        pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
                                        pgprot_val(mk_sect_prot(prot)));
+
+       /* ioremap_page_range doesn't honour BBM */
+       if (pmd_present(READ_ONCE(*pmdp)))
+               return 0;
+
        BUG_ON(phys & ~PMD_MASK);
-       set_pmd(pmd, pfn_pmd(__phys_to_pfn(phys), sect_prot));
+       set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot));
        return 1;
 }
 
-int pud_clear_huge(pud_t *pud)
+int pud_clear_huge(pud_t *pudp)
 {
-       if (!pud_sect(*pud))
+       if (!pud_sect(READ_ONCE(*pudp)))
                return 0;
-       pud_clear(pud);
+       pud_clear(pudp);
        return 1;
 }
 
-int pmd_clear_huge(pmd_t *pmd)
+int pmd_clear_huge(pmd_t *pmdp)
 {
-       if (!pmd_sect(*pmd))
+       if (!pmd_sect(READ_ONCE(*pmdp)))
                return 0;
-       pmd_clear(pmd);
+       pmd_clear(pmdp);
        return 1;
 }
+
+int pud_free_pmd_page(pud_t *pud)
+{
+       return pud_none(*pud);
+}
+
+int pmd_free_pte_page(pmd_t *pmd)
+{
+       return pmd_none(*pmd);
+}
index a682a0a2a0fa4d5db9175256e78100b1afde344a..a56359373d8b3592e6cde6891d9b44206bd96137 100644 (file)
@@ -29,7 +29,7 @@ static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
                        void *data)
 {
        struct page_change_data *cdata = data;
-       pte_t pte = *ptep;
+       pte_t pte = READ_ONCE(*ptep);
 
        pte = clear_pte_bit(pte, cdata->clear_mask);
        pte = set_pte_bit(pte, cdata->set_mask);
@@ -156,30 +156,32 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
  */
 bool kernel_page_present(struct page *page)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
+       pgd_t *pgdp;
+       pud_t *pudp, pud;
+       pmd_t *pmdp, pmd;
+       pte_t *ptep;
        unsigned long addr = (unsigned long)page_address(page);
 
-       pgd = pgd_offset_k(addr);
-       if (pgd_none(*pgd))
+       pgdp = pgd_offset_k(addr);
+       if (pgd_none(READ_ONCE(*pgdp)))
                return false;
 
-       pud = pud_offset(pgd, addr);
-       if (pud_none(*pud))
+       pudp = pud_offset(pgdp, addr);
+       pud = READ_ONCE(*pudp);
+       if (pud_none(pud))
                return false;
-       if (pud_sect(*pud))
+       if (pud_sect(pud))
                return true;
 
-       pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd))
+       pmdp = pmd_offset(pudp, addr);
+       pmd = READ_ONCE(*pmdp);
+       if (pmd_none(pmd))
                return false;
-       if (pmd_sect(*pmd))
+       if (pmd_sect(pmd))
                return true;
 
-       pte = pte_offset_kernel(pmd, addr);
-       return pte_valid(*pte);
+       ptep = pte_offset_kernel(pmdp, addr);
+       return pte_valid(READ_ONCE(*ptep));
 }
 #endif /* CONFIG_HIBERNATION */
 #endif /* CONFIG_DEBUG_PAGEALLOC */
index 71baed7e592a499196a1c7bc239dbbc3297d3bc2..c0af4761729986da832a8e844b256e64da8cb4c1 100644 (file)
@@ -205,7 +205,8 @@ ENDPROC(idmap_cpu_replace_ttbr1)
        dc      cvac, cur_\()\type\()p          // Ensure any existing dirty
        dmb     sy                              // lines are written back before
        ldr     \type, [cur_\()\type\()p]       // loading the entry
-       tbz     \type, #0, next_\()\type        // Skip invalid entries
+       tbz     \type, #0, skip_\()\type        // Skip invalid and
+       tbnz    \type, #11, skip_\()\type       // non-global entries
        .endm
 
        .macro __idmap_kpti_put_pgtable_ent_ng, type
@@ -265,8 +266,9 @@ ENTRY(idmap_kpti_install_ng_mappings)
        add     end_pgdp, cur_pgdp, #(PTRS_PER_PGD * 8)
 do_pgd:        __idmap_kpti_get_pgtable_ent    pgd
        tbnz    pgd, #1, walk_puds
-       __idmap_kpti_put_pgtable_ent_ng pgd
 next_pgd:
+       __idmap_kpti_put_pgtable_ent_ng pgd
+skip_pgd:
        add     cur_pgdp, cur_pgdp, #8
        cmp     cur_pgdp, end_pgdp
        b.ne    do_pgd
@@ -294,8 +296,9 @@ walk_puds:
        add     end_pudp, cur_pudp, #(PTRS_PER_PUD * 8)
 do_pud:        __idmap_kpti_get_pgtable_ent    pud
        tbnz    pud, #1, walk_pmds
-       __idmap_kpti_put_pgtable_ent_ng pud
 next_pud:
+       __idmap_kpti_put_pgtable_ent_ng pud
+skip_pud:
        add     cur_pudp, cur_pudp, 8
        cmp     cur_pudp, end_pudp
        b.ne    do_pud
@@ -314,8 +317,9 @@ walk_pmds:
        add     end_pmdp, cur_pmdp, #(PTRS_PER_PMD * 8)
 do_pmd:        __idmap_kpti_get_pgtable_ent    pmd
        tbnz    pmd, #1, walk_ptes
-       __idmap_kpti_put_pgtable_ent_ng pmd
 next_pmd:
+       __idmap_kpti_put_pgtable_ent_ng pmd
+skip_pmd:
        add     cur_pmdp, cur_pmdp, #8
        cmp     cur_pmdp, end_pmdp
        b.ne    do_pmd
@@ -333,7 +337,7 @@ walk_ptes:
        add     end_ptep, cur_ptep, #(PTRS_PER_PTE * 8)
 do_pte:        __idmap_kpti_get_pgtable_ent    pte
        __idmap_kpti_put_pgtable_ent_ng pte
-next_pte:
+skip_pte:
        add     cur_ptep, cur_ptep, #8
        cmp     cur_ptep, end_ptep
        b.ne    do_pte
index 1d4f1da7c58f8d51371947523e91649915e4320d..a93350451e8ece754a2f565764d47505e48b85ef 100644 (file)
@@ -250,8 +250,9 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
        off = offsetof(struct bpf_array, map.max_entries);
        emit_a64_mov_i64(tmp, off, ctx);
        emit(A64_LDR32(tmp, r2, tmp), ctx);
+       emit(A64_MOV(0, r3, r3), ctx);
        emit(A64_CMP(0, r3, tmp), ctx);
-       emit(A64_B_(A64_COND_GE, jmp_offset), ctx);
+       emit(A64_B_(A64_COND_CS, jmp_offset), ctx);
 
        /* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
         *     goto out;
@@ -259,7 +260,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
         */
        emit_a64_mov_i64(tmp, MAX_TAIL_CALL_CNT, ctx);
        emit(A64_CMP(1, tcc, tmp), ctx);
-       emit(A64_B_(A64_COND_GT, jmp_offset), ctx);
+       emit(A64_B_(A64_COND_HI, jmp_offset), ctx);
        emit(A64_ADD_I(1, tcc, tcc, 1), ctx);
 
        /* prog = array->ptrs[index];
index 905afeacfedf53de44b3ba08487b04b46141e564..06da9d49152a0fd78ef1bac764df62aa38e35c83 100644 (file)
@@ -44,18 +44,25 @@ struct bug_frame {
  * not be used like this with newer versions of gcc.
  */
 #define BUG()                                                          \
+do {                                                                   \
        __asm__ __volatile__ ("clear.d [" __stringify(BUG_MAGIC) "]\n\t"\
                              "movu.w " __stringify(__LINE__) ",$r0\n\t"\
                              "jump 0f\n\t"                             \
                              ".section .rodata\n"                      \
                              "0:\t.string \"" __FILE__ "\"\n\t"        \
-                             ".previous")
+                             ".previous");                             \
+       unreachable();                                                  \
+} while (0)
 #endif
 
 #else
 
 /* This just causes an oops. */
-#define BUG() (*(int *)0 = 0)
+#define BUG()                                                          \
+do {                                                                   \
+       barrier_before_unreachable();                                   \
+       __builtin_trap();                                               \
+} while (0)
 
 #endif
 
index ecff2d1ca5a389b82614600464f0ab70981a766a..6eaa7ad5fc2c99fcdaadb4ce3f7bf677fb968262 100644 (file)
@@ -2,7 +2,6 @@
 #ifndef __H8300_BYTEORDER_H__
 #define __H8300_BYTEORDER_H__
 
-#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
 #include <linux/byteorder/big_endian.h>
 
 #endif
index 762eeb0fcc1dcaec27a4dff140274113a2c31fbf..2524fb60fbc28518ad7635092ac1bdd5d62114fd 100644 (file)
@@ -66,38 +66,35 @@ ATOMIC_OPS(add, +)
 ATOMIC_OPS(sub, -)
 
 #ifdef __OPTIMIZE__
-#define __ia64_atomic_const(i) __builtin_constant_p(i) ?               \
+#define __ia64_atomic_const(i)                                         \
+       static const int __ia64_atomic_p = __builtin_constant_p(i) ?    \
                ((i) == 1 || (i) == 4 || (i) == 8 || (i) == 16 ||       \
-                (i) == -1 || (i) == -4 || (i) == -8 || (i) == -16) : 0
+                (i) == -1 || (i) == -4 || (i) == -8 || (i) == -16) : 0;\
+       __ia64_atomic_p
+#else
+#define __ia64_atomic_const(i) 0
+#endif
 
-#define atomic_add_return(i, v)                                                \
+#define atomic_add_return(i,v)                                         \
 ({                                                                     \
-       int __i = (i);                                                  \
-       static const int __ia64_atomic_p = __ia64_atomic_const(i);      \
-       __ia64_atomic_p ? ia64_fetch_and_add(__i, &(v)->counter) :      \
-                               ia64_atomic_add(__i, v);                \
+       int __ia64_aar_i = (i);                                         \
+       __ia64_atomic_const(i)                                          \
+               ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter)       \
+               : ia64_atomic_add(__ia64_aar_i, v);                     \
 })
 
-#define atomic_sub_return(i, v)                                                \
+#define atomic_sub_return(i,v)                                         \
 ({                                                                     \
-       int __i = (i);                                                  \
-       static const int __ia64_atomic_p = __ia64_atomic_const(i);      \
-       __ia64_atomic_p ? ia64_fetch_and_add(-__i, &(v)->counter) :     \
-                               ia64_atomic_sub(__i, v);                \
+       int __ia64_asr_i = (i);                                         \
+       __ia64_atomic_const(i)                                          \
+               ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)      \
+               : ia64_atomic_sub(__ia64_asr_i, v);                     \
 })
-#else
-#define atomic_add_return(i, v)        ia64_atomic_add(i, v)
-#define atomic_sub_return(i, v)        ia64_atomic_sub(i, v)
-#endif
 
 #define atomic_fetch_add(i,v)                                          \
 ({                                                                     \
        int __ia64_aar_i = (i);                                         \
-       (__builtin_constant_p(i)                                        \
-        && (   (__ia64_aar_i ==  1) || (__ia64_aar_i ==   4)           \
-            || (__ia64_aar_i ==  8) || (__ia64_aar_i ==  16)           \
-            || (__ia64_aar_i == -1) || (__ia64_aar_i ==  -4)           \
-            || (__ia64_aar_i == -8) || (__ia64_aar_i == -16)))         \
+       __ia64_atomic_const(i)                                          \
                ? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq)       \
                : ia64_atomic_fetch_add(__ia64_aar_i, v);               \
 })
@@ -105,11 +102,7 @@ ATOMIC_OPS(sub, -)
 #define atomic_fetch_sub(i,v)                                          \
 ({                                                                     \
        int __ia64_asr_i = (i);                                         \
-       (__builtin_constant_p(i)                                        \
-        && (   (__ia64_asr_i ==   1) || (__ia64_asr_i ==   4)          \
-            || (__ia64_asr_i ==   8) || (__ia64_asr_i ==  16)          \
-            || (__ia64_asr_i ==  -1) || (__ia64_asr_i ==  -4)          \
-            || (__ia64_asr_i ==  -8) || (__ia64_asr_i == -16)))        \
+       __ia64_atomic_const(i)                                          \
                ? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq)      \
                : ia64_atomic_fetch_sub(__ia64_asr_i, v);               \
 })
@@ -170,11 +163,7 @@ ATOMIC64_OPS(sub, -)
 #define atomic64_add_return(i,v)                                       \
 ({                                                                     \
        long __ia64_aar_i = (i);                                        \
-       (__builtin_constant_p(i)                                        \
-        && (   (__ia64_aar_i ==  1) || (__ia64_aar_i ==   4)           \
-            || (__ia64_aar_i ==  8) || (__ia64_aar_i ==  16)           \
-            || (__ia64_aar_i == -1) || (__ia64_aar_i ==  -4)           \
-            || (__ia64_aar_i == -8) || (__ia64_aar_i == -16)))         \
+       __ia64_atomic_const(i)                                          \
                ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter)       \
                : ia64_atomic64_add(__ia64_aar_i, v);                   \
 })
@@ -182,11 +171,7 @@ ATOMIC64_OPS(sub, -)
 #define atomic64_sub_return(i,v)                                       \
 ({                                                                     \
        long __ia64_asr_i = (i);                                        \
-       (__builtin_constant_p(i)                                        \
-        && (   (__ia64_asr_i ==   1) || (__ia64_asr_i ==   4)          \
-            || (__ia64_asr_i ==   8) || (__ia64_asr_i ==  16)          \
-            || (__ia64_asr_i ==  -1) || (__ia64_asr_i ==  -4)          \
-            || (__ia64_asr_i ==  -8) || (__ia64_asr_i == -16)))        \
+       __ia64_atomic_const(i)                                          \
                ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter)      \
                : ia64_atomic64_sub(__ia64_asr_i, v);                   \
 })
@@ -194,11 +179,7 @@ ATOMIC64_OPS(sub, -)
 #define atomic64_fetch_add(i,v)                                                \
 ({                                                                     \
        long __ia64_aar_i = (i);                                        \
-       (__builtin_constant_p(i)                                        \
-        && (   (__ia64_aar_i ==  1) || (__ia64_aar_i ==   4)           \
-            || (__ia64_aar_i ==  8) || (__ia64_aar_i ==  16)           \
-            || (__ia64_aar_i == -1) || (__ia64_aar_i ==  -4)           \
-            || (__ia64_aar_i == -8) || (__ia64_aar_i == -16)))         \
+       __ia64_atomic_const(i)                                          \
                ? ia64_fetchadd(__ia64_aar_i, &(v)->counter, acq)       \
                : ia64_atomic64_fetch_add(__ia64_aar_i, v);             \
 })
@@ -206,11 +187,7 @@ ATOMIC64_OPS(sub, -)
 #define atomic64_fetch_sub(i,v)                                                \
 ({                                                                     \
        long __ia64_asr_i = (i);                                        \
-       (__builtin_constant_p(i)                                        \
-        && (   (__ia64_asr_i ==   1) || (__ia64_asr_i ==   4)          \
-            || (__ia64_asr_i ==   8) || (__ia64_asr_i ==  16)          \
-            || (__ia64_asr_i ==  -1) || (__ia64_asr_i ==  -4)          \
-            || (__ia64_asr_i ==  -8) || (__ia64_asr_i == -16)))        \
+       __ia64_atomic_const(i)                                          \
                ? ia64_fetchadd(-__ia64_asr_i, &(v)->counter, acq)      \
                : ia64_atomic64_fetch_sub(__ia64_asr_i, v);             \
 })
index bd3eeb8d1cfa379a56456a3fd27909dbeaf2b55b..66b37a5327654f87a40fc277fad53d927875c355 100644 (file)
@@ -4,7 +4,11 @@
 
 #ifdef CONFIG_BUG
 #define ia64_abort()   __builtin_trap()
-#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
+#define BUG() do {                                             \
+       printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__);   \
+       barrier_before_unreachable();                           \
+       ia64_abort();                                           \
+} while (0)
 
 /* should this BUG be made generic? */
 #define HAVE_ARCH_BUG
index 0b4c65a1af25fbe264766ee1e14c4c0bf19bc5e6..498f3da3f225d2ed8479af540bbbc22786e2c55d 100644 (file)
@@ -41,7 +41,6 @@ ifneq ($(CONFIG_IA64_ESI),)
 obj-y                          += esi_stub.o   # must be in kernel proper
 endif
 obj-$(CONFIG_INTEL_IOMMU)      += pci-dma.o
-obj-$(CONFIG_SWIOTLB)          += pci-swiotlb.o
 
 obj-$(CONFIG_BINFMT_ELF)       += elfcore.o
 
index 85bba43e7d5dc7638138f90f1eb0dd56609c5807..8b5b8e6bc9d9ad9937119531d102e410b005b7ac 100644 (file)
@@ -117,7 +117,7 @@ store_call_start(struct device *dev, struct device_attribute *attr,
 
 #ifdef ERR_INJ_DEBUG
        printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]);
-       printk(KERN_DEBUG "capapbilities=%lx,\n", capabilities[cpu]);
+       printk(KERN_DEBUG "capabilities=%lx,\n", capabilities[cpu]);
        printk(KERN_DEBUG "resources=%lx\n", resources[cpu]);
 #endif
        return size;
@@ -142,7 +142,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
        u64 virt_addr=simple_strtoull(buf, NULL, 16);
        int ret;
 
-       ret = get_user_pages(virt_addr, 1, FOLL_WRITE, NULL, NULL);
+       ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL);
        if (ret<=0) {
 #ifdef ERR_INJ_DEBUG
                printk("Virtual address %lx is not existing.\n",virt_addr);
index 89f3a1480a637ffcf8b51ff64ddd1c7dd8e1aa46..c55276e31b6b68050a3b2ed84386cfd9d39b5eb3 100644 (file)
@@ -16,7 +16,7 @@ import re
 import sys
 
 if len(sys.argv) != 2:
-    print "Usage: %s FILE" % sys.argv[0]
+    print("Usage: %s FILE" % sys.argv[0])
     sys.exit(2)
 
 readelf = os.getenv("READELF", "readelf")
@@ -29,7 +29,7 @@ def check_func (func, slots, rlen_sum):
         global num_errors
         num_errors += 1
         if not func: func = "[%#x-%#x]" % (start, end)
-        print "ERROR: %s: %lu slots, total region length = %lu" % (func, slots, rlen_sum)
+        print("ERROR: %s: %lu slots, total region length = %lu" % (func, slots, rlen_sum))
     return
 
 num_funcs = 0
@@ -43,23 +43,23 @@ for line in os.popen("%s -u %s" % (readelf, sys.argv[1])):
         check_func(func, slots, rlen_sum)
 
         func  = m.group(1)
-        start = long(m.group(2), 16)
-        end   = long(m.group(3), 16)
+        start = int(m.group(2), 16)
+        end   = int(m.group(3), 16)
         slots = 3 * (end - start) / 16
-        rlen_sum = 0L
+        rlen_sum = 0
         num_funcs += 1
     else:
         m = rlen_pattern.match(line)
         if m:
-            rlen_sum += long(m.group(1))
+            rlen_sum += int(m.group(1))
 check_func(func, slots, rlen_sum)
 
 if num_errors == 0:
-    print "No errors detected in %u functions." % num_funcs
+    print("No errors detected in %u functions." % num_funcs)
 else:
     if num_errors > 1:
         err="errors"
     else:
         err="error"
-    print "%u %s detected in %u functions." % (num_errors, err, num_funcs)
+    print("%u %s detected in %u functions." % (num_errors, err, num_funcs))
     sys.exit(1)
index b7e2bf1ba4a60d1e139aedf50c7a82fc0b0235cd..275dca1435bf9f64202b0a9249b0a07138105c82 100644 (file)
@@ -8,16 +8,19 @@
 #ifndef CONFIG_SUN3
 #define BUG() do { \
        pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+       barrier_before_unreachable(); \
        __builtin_trap(); \
 } while (0)
 #else
 #define BUG() do { \
        pr_crit("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+       barrier_before_unreachable(); \
        panic("BUG!"); \
 } while (0)
 #endif
 #else
 #define BUG() do { \
+       barrier_before_unreachable(); \
        __builtin_trap(); \
 } while (0)
 #endif
index 4f798aa671ddd2f481c35689f03be1ea73318ae8..3817a3e2146cf3e807dad894c3e18ddae31d57a1 100644 (file)
@@ -24,6 +24,7 @@ config MICROBLAZE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACER
+       select NO_BOOTMEM
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_OPROFILE
index 6996f397c16c1dbfddcffd69809142ce5d8a8d2b..f7f1739c11b9fef091b1176c0120c4613232cfeb 100644 (file)
@@ -8,7 +8,6 @@ menu "Platform options"
 
 config OPT_LIB_FUNCTION
        bool "Optimalized lib function"
-       depends on CPU_LITTLE_ENDIAN
        default y
        help
          Allows turn on optimalized library function (memcpy and memmove).
@@ -21,6 +20,7 @@ config OPT_LIB_FUNCTION
 config OPT_LIB_ASM
        bool "Optimalized lib function ASM"
        depends on OPT_LIB_FUNCTION && (XILINX_MICROBLAZE0_USE_BARREL = 1)
+       depends on CPU_BIG_ENDIAN
        default n
        help
          Allows turn on optimalized library function (memcpy and memmove).
index be84a4d3917fc1c901bc71c6ca44362c28680257..7c968c1d1729ed00233a716534843175a3c2bc27 100644 (file)
@@ -44,7 +44,6 @@ void machine_shutdown(void);
 void machine_halt(void);
 void machine_power_off(void);
 
-extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
 
 # endif /* __ASSEMBLY__ */
index 62021d7e249e0665cd6a1483c12de5b8b0bf5739..fdc48bb065d89fe3b2443ef054d1a6ece3744b54 100644 (file)
  *     between mem locations with size of xfer spec'd in bytes
  */
 
-#ifdef __MICROBLAZEEL__
-#error Microblaze LE not support ASM optimized lib func. Disable OPT_LIB_ASM.
-#endif
-
 #include <linux/linkage.h>
        .text
        .globl  memcpy
index 434639f9a3a6b024b5af2b2319b46376c88c6ada..df6de7ccdc2eb6fad45f93fcb1dbd74c0fff01e8 100644 (file)
@@ -32,9 +32,6 @@ int mem_init_done;
 #ifndef CONFIG_MMU
 unsigned int __page_offset;
 EXPORT_SYMBOL(__page_offset);
-
-#else
-static int init_bootmem_done;
 #endif /* CONFIG_MMU */
 
 char *klimit = _end;
@@ -117,7 +114,6 @@ static void __init paging_init(void)
 
 void __init setup_memory(void)
 {
-       unsigned long map_size;
        struct memblock_region *reg;
 
 #ifndef CONFIG_MMU
@@ -174,17 +170,6 @@ void __init setup_memory(void)
        pr_info("%s: max_low_pfn: %#lx\n", __func__, max_low_pfn);
        pr_info("%s: max_pfn: %#lx\n", __func__, max_pfn);
 
-       /*
-        * Find an area to use for the bootmem bitmap.
-        * We look for the first area which is at least
-        * 128kB in length (128kB is enough for a bitmap
-        * for 4GB of memory, using 4kB pages), plus 1 page
-        * (in case the address isn't page-aligned).
-        */
-       map_size = init_bootmem_node(NODE_DATA(0),
-               PFN_UP(TOPHYS((u32)klimit)), min_low_pfn, max_low_pfn);
-       memblock_reserve(PFN_UP(TOPHYS((u32)klimit)) << PAGE_SHIFT, map_size);
-
        /* Add active regions with valid PFNs */
        for_each_memblock(memory, reg) {
                unsigned long start_pfn, end_pfn;
@@ -196,32 +181,9 @@ void __init setup_memory(void)
                                  &memblock.memory, 0);
        }
 
-       /* free bootmem is whole main memory */
-       free_bootmem_with_active_regions(0, max_low_pfn);
-
-       /* reserve allocate blocks */
-       for_each_memblock(reserved, reg) {
-               unsigned long top = reg->base + reg->size - 1;
-
-               pr_debug("reserved - 0x%08x-0x%08x, %lx, %lx\n",
-                        (u32) reg->base, (u32) reg->size, top,
-                                               memory_start + lowmem_size - 1);
-
-               if (top <= (memory_start + lowmem_size - 1)) {
-                       reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-               } else if (reg->base < (memory_start + lowmem_size - 1)) {
-                       unsigned long trunc_size = memory_start + lowmem_size -
-                                                               reg->base;
-                       reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
-               }
-       }
-
        /* XXX need to clip this if using highmem? */
        sparse_memory_present_with_active_regions(0);
 
-#ifdef CONFIG_MMU
-       init_bootmem_done = 1;
-#endif
        paging_init();
 }
 
@@ -398,30 +360,16 @@ asmlinkage void __init mmu_init(void)
 /* This is only called until mem_init is done. */
 void __init *early_get_page(void)
 {
-       void *p;
-       if (init_bootmem_done) {
-               p = alloc_bootmem_pages(PAGE_SIZE);
-       } else {
-               /*
-                * Mem start + kernel_tlb -> here is limit
-                * because of mem mapping from head.S
-                */
-               p = __va(memblock_alloc_base(PAGE_SIZE, PAGE_SIZE,
-                                       memory_start + kernel_tlb));
-       }
-       return p;
+       /*
+        * Mem start + kernel_tlb -> here is limit
+        * because of mem mapping from head.S
+        */
+       return __va(memblock_alloc_base(PAGE_SIZE, PAGE_SIZE,
+                               memory_start + kernel_tlb));
 }
 
 #endif /* CONFIG_MMU */
 
-void * __ref alloc_maybe_bootmem(size_t size, gfp_t mask)
-{
-       if (mem_init_done)
-               return kmalloc(size, mask);
-       else
-               return alloc_bootmem(size);
-}
-
 void * __ref zalloc_maybe_bootmem(size_t size, gfp_t mask)
 {
        void *p;
index 9ab48ff80c1c8de3a5de0050e2d4d5f22dc0c773..6d11ae581ea775bc2e919e16bdd63cdb6b06d86f 100644 (file)
@@ -135,6 +135,8 @@ int __init ath25_find_config(phys_addr_t base, unsigned long size)
        }
 
        board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);
+       if (!board_data)
+               goto error;
        ath25_board.config = (struct ath25_boarddata *)board_data;
        memcpy_fromio(board_data, bcfg, 0x100);
        if (broken_boarddata) {
index 1bd5c4f00d19bd7ff4aee34789e0fbb371240a4d..c22da16d67b82f7752f6ba39291e2acd4e18fb47 100644 (file)
@@ -126,6 +126,7 @@ $(obj)/vmlinux.its.S: $(addprefix $(srctree)/arch/mips/$(PLATFORM)/,$(ITS_INPUTS
 
 quiet_cmd_cpp_its_S = ITS     $@
       cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \
+                       -D__ASSEMBLY__ \
                        -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \
                        -DVMLINUX_BINARY="\"$(3)\"" \
                        -DVMLINUX_COMPRESSION="\"$(2)\"" \
index 5b3a3f6a9ad31fd845bd18cdd3197d9c75833c84..d99f5242169e7acb31f8cfa71cd6e14d24e94c82 100644 (file)
@@ -2277,6 +2277,8 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
        }
 
        host_data = kzalloc(sizeof(*host_data), GFP_KERNEL);
+       if (!host_data)
+               return -ENOMEM;
        raw_spin_lock_init(&host_data->lock);
 
        addr = of_get_address(ciu_node, 0, NULL, NULL);
index 946681db8dc3a680e319617e43e209ba50b51e98..9a0fa66b81aca6c47dab0189cbba57b7c413a952 100644 (file)
@@ -86,7 +86,6 @@ struct compat_flock {
        compat_off_t    l_len;
        s32             l_sysid;
        compat_pid_t    l_pid;
-       short           __unused;
        s32             pad[4];
 };
 
index 19c88d770054617bfc23b15c81c20b12a7f7cc3f..fcf9af492d60229a491337e56b1ebc9adf60f7fb 100644 (file)
@@ -10,6 +10,8 @@
 
 #include <linux/errno.h>
 #include <linux/percpu.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/spinlock.h>
 
 #include <asm/mips-cps.h>
@@ -22,6 +24,17 @@ static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
 
 phys_addr_t __weak mips_cpc_default_phys_base(void)
 {
+       struct device_node *cpc_node;
+       struct resource res;
+       int err;
+
+       cpc_node = of_find_compatible_node(of_root, NULL, "mti,mips-cpc");
+       if (cpc_node) {
+               err = of_address_to_resource(cpc_node, 0, &res);
+               if (!err)
+                       return res.start;
+       }
+
        return 0;
 }
 
index 85bc601e9a0d43ffd89669eac4b359de99566083..5f8b0a9e30b3d6faec9befca1e759a8f9263f8c8 100644 (file)
@@ -375,6 +375,7 @@ static void __init bootmem_init(void)
        unsigned long reserved_end;
        unsigned long mapstart = ~0UL;
        unsigned long bootmap_size;
+       phys_addr_t ramstart = (phys_addr_t)ULLONG_MAX;
        bool bootmap_valid = false;
        int i;
 
@@ -395,7 +396,8 @@ static void __init bootmem_init(void)
        max_low_pfn = 0;
 
        /*
-        * Find the highest page frame number we have available.
+        * Find the highest page frame number we have available
+        * and the lowest used RAM address
         */
        for (i = 0; i < boot_mem_map.nr_map; i++) {
                unsigned long start, end;
@@ -407,6 +409,8 @@ static void __init bootmem_init(void)
                end = PFN_DOWN(boot_mem_map.map[i].addr
                                + boot_mem_map.map[i].size);
 
+               ramstart = min(ramstart, boot_mem_map.map[i].addr);
+
 #ifndef CONFIG_HIGHMEM
                /*
                 * Skip highmem here so we get an accurate max_low_pfn if low
@@ -436,6 +440,13 @@ static void __init bootmem_init(void)
                mapstart = max(reserved_end, start);
        }
 
+       /*
+        * Reserve any memory between the start of RAM and PHYS_OFFSET
+        */
+       if (ramstart > PHYS_OFFSET)
+               add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
+                                 BOOT_MEM_RESERVED);
+
        if (min_low_pfn >= max_low_pfn)
                panic("Incorrect memory mapping !!!");
        if (min_low_pfn > ARCH_PFN_OFFSET) {
@@ -664,9 +675,6 @@ static int __init early_parse_mem(char *p)
 
        add_memory_region(start, size, BOOT_MEM_RAM);
 
-       if (start && start > PHYS_OFFSET)
-               add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
-                               BOOT_MEM_RESERVED);
        return 0;
 }
 early_param("mem", early_parse_mem);
index 87dcac2447c8df20a572139d5053624e91acf2ca..159e83add4bb3e6b43f105b521761eb9cb80491b 100644 (file)
@@ -168,11 +168,11 @@ static void bmips_prepare_cpus(unsigned int max_cpus)
                return;
        }
 
-       if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
-                       "smp_ipi0", NULL))
+       if (request_irq(IPI0_IRQ, bmips_ipi_interrupt,
+                       IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi0", NULL))
                panic("Can't request IPI0 interrupt");
-       if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
-                       "smp_ipi1", NULL))
+       if (request_irq(IPI1_IRQ, bmips_ipi_interrupt,
+                       IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi1", NULL))
                panic("Can't request IPI1 interrupt");
 }
 
@@ -572,7 +572,7 @@ asmlinkage void __weak plat_wired_tlb_setup(void)
         */
 }
 
-void __init bmips_cpu_setup(void)
+void bmips_cpu_setup(void)
 {
        void __iomem __maybe_unused *cbr = BMIPS_GET_CBR();
        u32 __maybe_unused cfg;
index 692ae85a3e3d4452e145346aabc9012fce3ec963..8e3a1fc2bc398e19635efa7fbbc3d7f026b2397e 100644 (file)
@@ -13,6 +13,8 @@ choice
 config SOC_AMAZON_SE
        bool "Amazon SE"
        select SOC_TYPE_XWAY
+       select MFD_SYSCON
+       select MFD_CORE
 
 config SOC_XWAY
        bool "XWAY"
index 52500d3b7004be3be3eda4364baef23cd5c47dc4..e0af39b33e2875bec2482392831d3d6907a05452 100644 (file)
@@ -549,9 +549,9 @@ void __init ltq_soc_init(void)
                clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
                                ltq_ar9_fpi_hz(), CLOCK_250M);
                clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
-               clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
                clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
-               clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1);
+               clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM);
                clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
                clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
                clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
@@ -560,7 +560,7 @@ void __init ltq_soc_init(void)
        } else {
                clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
                                ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
-               clkdev_add_pmu("1f203018.usb2-phy", "ctrl", 1, 0, PMU_USB0);
+               clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
                clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
                clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
                clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
index bc2fdbfa8223c343e6ed455f44bf6393d8d43d0a..72af0c18396983df62327d5a4dcf000bf557d326 100644 (file)
@@ -7,6 +7,8 @@ choice
 config LEMOTE_FULOONG2E
        bool "Lemote Fuloong(2e) mini-PC"
        select ARCH_SPARSEMEM_ENABLE
+       select ARCH_MIGHT_HAVE_PC_PARPORT
+       select ARCH_MIGHT_HAVE_PC_SERIO
        select CEVT_R4K
        select CSRC_R4K
        select SYS_HAS_CPU_LOONGSON2E
@@ -33,6 +35,8 @@ config LEMOTE_FULOONG2E
 config LEMOTE_MACH2F
        bool "Lemote Loongson 2F family machines"
        select ARCH_SPARSEMEM_ENABLE
+       select ARCH_MIGHT_HAVE_PC_PARPORT
+       select ARCH_MIGHT_HAVE_PC_SERIO
        select BOARD_SCACHE
        select BOOT_ELF32
        select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
@@ -62,6 +66,8 @@ config LEMOTE_MACH2F
 config LOONGSON_MACH3X
        bool "Generic Loongson 3 family machines"
        select ARCH_SPARSEMEM_ENABLE
+       select ARCH_MIGHT_HAVE_PC_PARPORT
+       select ARCH_MIGHT_HAVE_PC_SERIO
        select GENERIC_ISA_DMA_SUPPORT_BROKEN
        select BOOT_ELF32
        select BOARD_SCACHE
index 1b274742077dc191161c95ea62ea15a3b329b59f..d2718de60b9b5f89e8e0179f057cb84163018579 100644 (file)
@@ -170,6 +170,28 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
        u32 n1;
        u32 rev;
 
+       /* Early detection of CMP support */
+       mips_cm_probe();
+       mips_cpc_probe();
+
+       if (mips_cps_numiocu(0)) {
+               /*
+                * mips_cm_probe() wipes out bootloader
+                * config for CM regions and we have to configure them
+                * again. This SoC cannot talk to pamlbus devices
+                * witout proper iocu region set up.
+                *
+                * FIXME: it would be better to do this with values
+                * from DT, but we need this very early because
+                * without this we cannot talk to pretty much anything
+                * including serial.
+                */
+               write_gcr_reg0_base(MT7621_PALMBUS_BASE);
+               write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
+                                   CM_GCR_REGn_MASK_CMTGT_IOCU0);
+               __sync();
+       }
+
        n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
        n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
 
@@ -194,26 +216,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 
        rt2880_pinmux_data = mt7621_pinmux_data;
 
-       /* Early detection of CMP support */
-       mips_cm_probe();
-       mips_cpc_probe();
-
-       if (mips_cps_numiocu(0)) {
-               /*
-                * mips_cm_probe() wipes out bootloader
-                * config for CM regions and we have to configure them
-                * again. This SoC cannot talk to pamlbus devices
-                * witout proper iocu region set up.
-                *
-                * FIXME: it would be better to do this with values
-                * from DT, but we need this very early because
-                * without this we cannot talk to pretty much anything
-                * including serial.
-                */
-               write_gcr_reg0_base(MT7621_PALMBUS_BASE);
-               write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
-                                   CM_GCR_REGn_MASK_CMTGT_IOCU0);
-       }
 
        if (!register_cps_smp_ops())
                return;
index 64543d66e76b50ccace33bf942e0b3c61c7e7fa4..e9531fea23a297adf2aac05d68ffd04dede6e0d4 100644 (file)
@@ -96,16 +96,9 @@ static void ralink_restart(char *command)
        unreachable();
 }
 
-static void ralink_halt(void)
-{
-       local_irq_disable();
-       unreachable();
-}
-
 static int __init mips_reboot_setup(void)
 {
        _machine_restart = ralink_restart;
-       _machine_halt = ralink_halt;
 
        return 0;
 }
index 3742508cc5345882510d907dc5f58b48a08ad9e7..bd5ce31936f5b196c3ce0482ee962eb93df46216 100644 (file)
@@ -26,6 +26,7 @@ void flush_user_icache_range_asm(unsigned long, unsigned long);
 void flush_kernel_icache_range_asm(unsigned long, unsigned long);
 void flush_user_dcache_range_asm(unsigned long, unsigned long);
 void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
+void purge_kernel_dcache_range_asm(unsigned long, unsigned long);
 void flush_kernel_dcache_page_asm(void *);
 void flush_kernel_icache_page(void *);
 
index 0e6ab6e4a4e9f87ba8ffc17f4d1c1e0041b5ab02..2dbe5580a1a4420ba693329a0f2622f68f759276 100644 (file)
@@ -316,6 +316,8 @@ extern int _parisc_requires_coherency;
 #define parisc_requires_coherency()    (0)
 #endif
 
+extern int running_on_qemu;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_PARISC_PROCESSOR_H */
index 19c0c141bc3f9f0edd509708f978a2d7ca16c230..e3b45546d589b4e8ec3410d8229a3049bf7b062f 100644 (file)
@@ -465,10 +465,10 @@ EXPORT_SYMBOL(copy_user_page);
 int __flush_tlb_range(unsigned long sid, unsigned long start,
                      unsigned long end)
 {
-       unsigned long flags, size;
+       unsigned long flags;
 
-       size = (end - start);
-       if (size >= parisc_tlb_flush_threshold) {
+       if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+           end - start >= parisc_tlb_flush_threshold) {
                flush_tlb_all();
                return 1;
        }
@@ -539,13 +539,12 @@ void flush_cache_mm(struct mm_struct *mm)
        struct vm_area_struct *vma;
        pgd_t *pgd;
 
-       /* Flush the TLB to avoid speculation if coherency is required. */
-       if (parisc_requires_coherency())
-               flush_tlb_all();
-
        /* Flushing the whole cache on each cpu takes forever on
           rp3440, etc.  So, avoid it if the mm isn't too big.  */
-       if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
+       if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+           mm_total_size(mm) >= parisc_cache_flush_threshold) {
+               if (mm->context)
+                       flush_tlb_all();
                flush_cache_all();
                return;
        }
@@ -553,9 +552,9 @@ void flush_cache_mm(struct mm_struct *mm)
        if (mm->context == mfsp(3)) {
                for (vma = mm->mmap; vma; vma = vma->vm_next) {
                        flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
-                       if ((vma->vm_flags & VM_EXEC) == 0)
-                               continue;
-                       flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
+                       if (vma->vm_flags & VM_EXEC)
+                               flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
+                       flush_tlb_range(vma, vma->vm_start, vma->vm_end);
                }
                return;
        }
@@ -573,6 +572,8 @@ void flush_cache_mm(struct mm_struct *mm)
                        pfn = pte_pfn(*ptep);
                        if (!pfn_valid(pfn))
                                continue;
+                       if (unlikely(mm->context))
+                               flush_tlb_page(vma, addr);
                        __flush_cache_page(vma, addr, PFN_PHYS(pfn));
                }
        }
@@ -581,30 +582,45 @@ void flush_cache_mm(struct mm_struct *mm)
 void flush_cache_range(struct vm_area_struct *vma,
                unsigned long start, unsigned long end)
 {
-       BUG_ON(!vma->vm_mm->context);
-
-       /* Flush the TLB to avoid speculation if coherency is required. */
-       if (parisc_requires_coherency())
-               flush_tlb_range(vma, start, end);
+       pgd_t *pgd;
+       unsigned long addr;
 
-       if ((end - start) >= parisc_cache_flush_threshold
-           || vma->vm_mm->context != mfsp(3)) {
+       if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+           end - start >= parisc_cache_flush_threshold) {
+               if (vma->vm_mm->context)
+                       flush_tlb_range(vma, start, end);
                flush_cache_all();
                return;
        }
 
-       flush_user_dcache_range_asm(start, end);
-       if (vma->vm_flags & VM_EXEC)
-               flush_user_icache_range_asm(start, end);
+       if (vma->vm_mm->context == mfsp(3)) {
+               flush_user_dcache_range_asm(start, end);
+               if (vma->vm_flags & VM_EXEC)
+                       flush_user_icache_range_asm(start, end);
+               flush_tlb_range(vma, start, end);
+               return;
+       }
+
+       pgd = vma->vm_mm->pgd;
+       for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
+               unsigned long pfn;
+               pte_t *ptep = get_ptep(pgd, addr);
+               if (!ptep)
+                       continue;
+               pfn = pte_pfn(*ptep);
+               if (pfn_valid(pfn)) {
+                       if (unlikely(vma->vm_mm->context))
+                               flush_tlb_page(vma, addr);
+                       __flush_cache_page(vma, addr, PFN_PHYS(pfn));
+               }
+       }
 }
 
 void
 flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
 {
-       BUG_ON(!vma->vm_mm->context);
-
        if (pfn_valid(pfn)) {
-               if (parisc_requires_coherency())
+               if (likely(vma->vm_mm->context))
                        flush_tlb_page(vma, vmaddr);
                __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
        }
@@ -613,21 +629,33 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
 void flush_kernel_vmap_range(void *vaddr, int size)
 {
        unsigned long start = (unsigned long)vaddr;
+       unsigned long end = start + size;
 
-       if ((unsigned long)size > parisc_cache_flush_threshold)
+       if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+           (unsigned long)size >= parisc_cache_flush_threshold) {
+               flush_tlb_kernel_range(start, end);
                flush_data_cache();
-       else
-               flush_kernel_dcache_range_asm(start, start + size);
+               return;
+       }
+
+       flush_kernel_dcache_range_asm(start, end);
+       flush_tlb_kernel_range(start, end);
 }
 EXPORT_SYMBOL(flush_kernel_vmap_range);
 
 void invalidate_kernel_vmap_range(void *vaddr, int size)
 {
        unsigned long start = (unsigned long)vaddr;
+       unsigned long end = start + size;
 
-       if ((unsigned long)size > parisc_cache_flush_threshold)
+       if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
+           (unsigned long)size >= parisc_cache_flush_threshold) {
+               flush_tlb_kernel_range(start, end);
                flush_data_cache();
-       else
-               flush_kernel_dcache_range_asm(start, start + size);
+               return;
+       }
+
+       purge_kernel_dcache_range_asm(start, end);
+       flush_tlb_kernel_range(start, end);
 }
 EXPORT_SYMBOL(invalidate_kernel_vmap_range);
index bbbe360b458f511c068620db2dd670a770ea8362..fbb4e43fda05332de57bdc135ec3711d4bd5ee77 100644 (file)
@@ -138,6 +138,16 @@ $pgt_fill_loop:
        std             %dp,0x18(%r10)
 #endif
 
+#ifdef CONFIG_64BIT
+       /* Get PDCE_PROC for monarch CPU. */
+#define MEM_PDC_LO 0x388
+#define MEM_PDC_HI 0x35C
+       ldw             MEM_PDC_LO(%r0),%r3
+       ldw             MEM_PDC_HI(%r0),%r10
+       depd            %r10, 31, 32, %r3        /* move to upper word */
+#endif
+
+
 #ifdef CONFIG_SMP
        /* Set the smp rendezvous address into page zero.
        ** It would be safer to do this in init_smp_config() but
@@ -196,12 +206,6 @@ common_stext:
         ** Someday, palo might not do this for the Monarch either.
         */
 2:
-#define MEM_PDC_LO 0x388
-#define MEM_PDC_HI 0x35C
-       ldw             MEM_PDC_LO(%r0),%r3
-       ldw             MEM_PDC_HI(%r0),%r6
-       depd            %r6, 31, 32, %r3        /* move to upper word */
-
        mfctl           %cr30,%r6               /* PCX-W2 firmware bug */
 
        ldo             PDC_PSW(%r0),%arg0              /* 21 */
@@ -268,6 +272,8 @@ $install_iva:
 aligned_rfi:
        pcxt_ssm_bug
 
+       copy            %r3, %arg0      /* PDCE_PROC for smp_callin() */
+
        rsm             PSW_SM_QUIET,%r0        /* off troublesome PSW bits */
        /* Don't need NOPs, have 8 compliant insn before rfi */
 
index 2d40c4ff3f6918ae9b2e2c6af71e20658a9850e1..67b0f7532e835f4db1214c6ccecf62183eb84e50 100644 (file)
@@ -1110,6 +1110,28 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
        .procend
 ENDPROC_CFI(flush_kernel_dcache_range_asm)
 
+ENTRY_CFI(purge_kernel_dcache_range_asm)
+       .proc
+       .callinfo NO_CALLS
+       .entry
+
+       ldil            L%dcache_stride, %r1
+       ldw             R%dcache_stride(%r1), %r23
+       ldo             -1(%r23), %r21
+       ANDCM           %r26, %r21, %r26
+
+1:      cmpb,COND(<<),n        %r26, %r25,1b
+       pdc,m           %r23(%r26)
+
+       sync
+       syncdma
+       bv              %r0(%r2)
+       nop
+       .exit
+
+       .procend
+ENDPROC_CFI(purge_kernel_dcache_range_asm)
+
 ENTRY_CFI(flush_user_icache_range_asm)
        .proc
        .callinfo NO_CALLS
index 30c28ab145409b5966f7237ec2b6ca07121adc10..4065b5e48c9d68e70b38da3743e219e02934fe5b 100644 (file)
@@ -292,10 +292,15 @@ smp_cpu_init(int cpunum)
  * Slaves start using C here. Indirectly called from smp_slave_stext.
  * Do what start_kernel() and main() do for boot strap processor (aka monarch)
  */
-void __init smp_callin(void)
+void __init smp_callin(unsigned long pdce_proc)
 {
        int slave_id = cpu_now_booting;
 
+#ifdef CONFIG_64BIT
+       WARN_ON(((unsigned long)(PAGE0->mem_pdc_hi) << 32
+                       | PAGE0->mem_pdc) != pdce_proc);
+#endif
+
        smp_cpu_init(slave_id);
        preempt_disable();
 
index 4b8fd6dc22dabebcf1da3b2e32381d2df3197eda..f7e684560186f9c3d5db133b8e66281c0f3c0e12 100644 (file)
@@ -76,10 +76,10 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
        next_tick = cpuinfo->it_value;
 
        /* Calculate how many ticks have elapsed. */
+       now = mfctl(16);
        do {
                ++ticks_elapsed;
                next_tick += cpt;
-               now = mfctl(16);
        } while (next_tick - now > cpt);
 
        /* Store (in CR16 cycles) up to when we are accounting right now. */
@@ -103,16 +103,17 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
         * if one or the other wrapped. If "now" is "bigger" we'll end up
         * with a very large unsigned number.
         */
-       while (next_tick - mfctl(16) > cpt)
+       now = mfctl(16);
+       while (next_tick - now > cpt)
                next_tick += cpt;
 
        /* Program the IT when to deliver the next interrupt.
         * Only bottom 32-bits of next_tick are writable in CR16!
         * Timer interrupt will be delivered at least a few hundred cycles
-        * after the IT fires, so if we are too close (<= 500 cycles) to the
+        * after the IT fires, so if we are too close (<= 8000 cycles) to the
         * next cycle, simply skip it.
         */
-       if (next_tick - mfctl(16) <= 500)
+       if (next_tick - now <= 8000)
                next_tick += cpt;
        mtctl(next_tick, 16);
 
@@ -248,7 +249,7 @@ static int __init init_cr16_clocksource(void)
         * different sockets, so mark them unstable and lower rating on
         * multi-socket SMP systems.
         */
-       if (num_online_cpus() > 1) {
+       if (num_online_cpus() > 1 && !running_on_qemu) {
                int cpu;
                unsigned long cpu0_loc;
                cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
index 48f41399fc0b8b63acd84d774a09ad2d0aba5086..cab32ee824d2ac4b7fe9adf4f3bb25533cc043c6 100644 (file)
@@ -629,7 +629,12 @@ void __init mem_init(void)
 #endif
 
        mem_init_print_info(NULL);
-#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */
+
+#if 0
+       /*
+        * Do not expose the virtual kernel memory layout to userspace.
+        * But keep code for debugging purposes.
+        */
        printk("virtual kernel memory layout:\n"
               "    vmalloc : 0x%px - 0x%px   (%4ld MB)\n"
               "    memory  : 0x%px - 0x%px   (%4ld MB)\n"
index ef6549e5715717003bf3fe9fc3a3c869e1fd5b2f..26d5d2a5b8e99bc923eeb2a2fabd67ce5b3af1ab 100644 (file)
@@ -101,7 +101,8 @@ $(addprefix $(obj)/,$(zlib-y)): \
 libfdt       := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
 libfdtheader := fdt.h libfdt.h libfdt_internal.h
 
-$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o opal.o): \
+$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o opal.o \
+       treeboot-akebono.o treeboot-currituck.o treeboot-iss4xx.o): \
        $(addprefix $(obj)/,$(libfdtheader))
 
 src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \
index 30a155c0a6b07e31ca69d5a7418fb19a1f6e7872..c615abdce119ea34ff6c33d02109cd700036db64 100644 (file)
@@ -16,6 +16,7 @@
 #define PGD_INDEX_SIZE (32 - PGDIR_SHIFT)
 
 #define PMD_CACHE_INDEX        PMD_INDEX_SIZE
+#define PUD_CACHE_INDEX        PUD_INDEX_SIZE
 
 #ifndef __ASSEMBLY__
 #define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
index 949d691094a46d674880dd1e54da971a4161f815..67c5475311ee6e03b29486f8518dc74758263224 100644 (file)
@@ -63,7 +63,8 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
  * keeping the prototype consistent across the two formats.
  */
 static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
-                       unsigned int subpg_index, unsigned long hidx)
+                                        unsigned int subpg_index, unsigned long hidx,
+                                        int offset)
 {
        return (hidx << H_PAGE_F_GIX_SHIFT) &
                (H_PAGE_F_SECOND | H_PAGE_F_GIX);
index 338b7da468cef309fa2b787c852e96ab05f014e5..3bcf269f8f55470097ac56680685321bf13e62ba 100644 (file)
@@ -45,7 +45,7 @@
  * generic accessors and iterators here
  */
 #define __real_pte __real_pte
-static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
+static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep, int offset)
 {
        real_pte_t rpte;
        unsigned long *hidxp;
@@ -59,7 +59,7 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
         */
        smp_rmb();
 
-       hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
+       hidxp = (unsigned long *)(ptep + offset);
        rpte.hidx = *hidxp;
        return rpte;
 }
@@ -86,9 +86,10 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
  * expected to modify the PTE bits accordingly and commit the PTE to memory.
  */
 static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
-               unsigned int subpg_index, unsigned long hidx)
+                                        unsigned int subpg_index,
+                                        unsigned long hidx, int offset)
 {
-       unsigned long *hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
+       unsigned long *hidxp = (unsigned long *)(ptep + offset);
 
        rpte.hidx &= ~HIDX_BITS(0xfUL, subpg_index);
        *hidxp = rpte.hidx  | HIDX_BITS(HIDX_SHIFT_BY_ONE(hidx), subpg_index);
@@ -140,13 +141,18 @@ static inline int hash__remap_4k_pfn(struct vm_area_struct *vma, unsigned long a
 }
 
 #define H_PTE_TABLE_SIZE       PTE_FRAG_SIZE
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined (CONFIG_HUGETLB_PAGE)
 #define H_PMD_TABLE_SIZE       ((sizeof(pmd_t) << PMD_INDEX_SIZE) + \
                                 (sizeof(unsigned long) << PMD_INDEX_SIZE))
 #else
 #define H_PMD_TABLE_SIZE       (sizeof(pmd_t) << PMD_INDEX_SIZE)
 #endif
+#ifdef CONFIG_HUGETLB_PAGE
+#define H_PUD_TABLE_SIZE       ((sizeof(pud_t) << PUD_INDEX_SIZE) +    \
+                                (sizeof(unsigned long) << PUD_INDEX_SIZE))
+#else
 #define H_PUD_TABLE_SIZE       (sizeof(pud_t) << PUD_INDEX_SIZE)
+#endif
 #define H_PGD_TABLE_SIZE       (sizeof(pgd_t) << PGD_INDEX_SIZE)
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
index 0920eff731b385221edeb46a04ed5f280ad76ff8..935adcd92a81655ed79e9c21fb6e196233ca69b1 100644 (file)
@@ -23,7 +23,8 @@
                                 H_PUD_INDEX_SIZE + H_PGD_INDEX_SIZE + PAGE_SHIFT)
 #define H_PGTABLE_RANGE                (ASM_CONST(1) << H_PGTABLE_EADDR_SIZE)
 
-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) &&  defined(CONFIG_PPC_64K_PAGES)
+#if (defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)) && \
+       defined(CONFIG_PPC_64K_PAGES)
 /*
  * only with hash 64k we need to use the second half of pmd page table
  * to store pointer to deposited pgtable_t
 #else
 #define H_PMD_CACHE_INDEX      H_PMD_INDEX_SIZE
 #endif
+/*
+ * We store the slot details in the second half of page table.
+ * Increase the pud level table so that hugetlb ptes can be stored
+ * at pud level.
+ */
+#if defined(CONFIG_HUGETLB_PAGE) &&  defined(CONFIG_PPC_64K_PAGES)
+#define H_PUD_CACHE_INDEX      (H_PUD_INDEX_SIZE + 1)
+#else
+#define H_PUD_CACHE_INDEX      (H_PUD_INDEX_SIZE)
+#endif
 /*
  * Define the address range of the kernel non-linear virtual area
  */
index 1fcfa425cefaf205fe787cc9a480265aec758e0f..4746bc68d446d8e95427e67a86c3493a1d1f1668 100644 (file)
@@ -73,10 +73,16 @@ static inline void radix__pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
+       pgd_t *pgd;
+
        if (radix_enabled())
                return radix__pgd_alloc(mm);
-       return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE),
-               pgtable_gfp_flags(mm, GFP_KERNEL));
+
+       pgd = kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE),
+                              pgtable_gfp_flags(mm, GFP_KERNEL));
+       memset(pgd, 0, PGD_TABLE_SIZE);
+
+       return pgd;
 }
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
@@ -93,13 +99,13 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-       return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
+       return kmem_cache_alloc(PGT_CACHE(PUD_CACHE_INDEX),
                pgtable_gfp_flags(mm, GFP_KERNEL));
 }
 
 static inline void pud_free(struct mm_struct *mm, pud_t *pud)
 {
-       kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
+       kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), pud);
 }
 
 static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
@@ -115,7 +121,7 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
         * ahead and flush the page walk cache
         */
        flush_tlb_pgtable(tlb, address);
-        pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE);
+       pgtable_free_tlb(tlb, pud, PUD_CACHE_INDEX);
 }
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
index 51017726d49539fda8cba5b346460aeba104c3f9..a6b9f1d746002cd3479686603c76322d52676db9 100644 (file)
@@ -232,11 +232,13 @@ extern unsigned long __pmd_index_size;
 extern unsigned long __pud_index_size;
 extern unsigned long __pgd_index_size;
 extern unsigned long __pmd_cache_index;
+extern unsigned long __pud_cache_index;
 #define PTE_INDEX_SIZE  __pte_index_size
 #define PMD_INDEX_SIZE  __pmd_index_size
 #define PUD_INDEX_SIZE  __pud_index_size
 #define PGD_INDEX_SIZE  __pgd_index_size
 #define PMD_CACHE_INDEX __pmd_cache_index
+#define PUD_CACHE_INDEX __pud_cache_index
 /*
  * Because of use of pte fragments and THP, size of page table
  * are not always derived out of index size above.
@@ -348,7 +350,7 @@ extern unsigned long pci_io_base;
  */
 #ifndef __real_pte
 
-#define __real_pte(e,p)                ((real_pte_t){(e)})
+#define __real_pte(e, p, o)            ((real_pte_t){(e)})
 #define __rpte_to_pte(r)       ((r).pte)
 #define __rpte_to_hidx(r,index)        (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT)
 
index 176dfb73d42c073df181013c6497cb42f9c8f85d..471b2274fbeba815f04c1957d975f0f1a74bcdbe 100644 (file)
@@ -645,7 +645,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
                                          EXC_HV, SOFTEN_TEST_HV, bitmask)
 
 #define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask)           \
-       MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec, bitmask);\
+       MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\
        EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
 
 /*
index 511acfd7ab0d3e20066dcd60e22bd3048ad34119..535add3f779133fefcb1422616d0fc3fef23588b 100644 (file)
@@ -52,7 +52,7 @@
 #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000)
 #define FW_FEATURE_PRRN                ASM_CONST(0x0000000200000000)
 #define FW_FEATURE_DRMEM_V2    ASM_CONST(0x0000000400000000)
-#define FW_FEATURE_DRC_INFO    ASM_CONST(0x0000000400000000)
+#define FW_FEATURE_DRC_INFO    ASM_CONST(0x0000000800000000)
 
 #ifndef __ASSEMBLY__
 
index 88e5e8f17e9896e5a051845235bfa0c822684552..855e17d158b11f04120b9b39a352af91cedb95c8 100644 (file)
 #define PACA_IRQ_HMI           0x20
 #define PACA_IRQ_PMI           0x40
 
+/*
+ * Some soft-masked interrupts must be hard masked until they are replayed
+ * (e.g., because the soft-masked handler does not clear the exception).
+ */
+#ifdef CONFIG_PPC_BOOK3S
+#define PACA_IRQ_MUST_HARD_MASK        (PACA_IRQ_EE|PACA_IRQ_PMI)
+#else
+#define PACA_IRQ_MUST_HARD_MASK        (PACA_IRQ_EE)
+#endif
+
 /*
  * flags for paca->irq_soft_mask
  */
@@ -244,7 +254,7 @@ static inline bool lazy_irq_pending(void)
 static inline void may_hard_irq_enable(void)
 {
        get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
-       if (!(get_paca()->irq_happened & PACA_IRQ_EE))
+       if (!(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK))
                __hard_irq_enable();
 }
 
index 9dcbfa6bbb91e740e483fa6c5c56b8422b8440c8..d8b1e8e7e035b31acd7372eee6bd8017166987d4 100644 (file)
@@ -140,6 +140,12 @@ static inline bool kdump_in_progress(void)
        return false;
 }
 
+static inline void crash_ipi_callback(struct pt_regs *regs) { }
+
+static inline void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
+{
+}
+
 #endif /* CONFIG_KEXEC_CORE */
 #endif /* ! __ASSEMBLY__ */
 #endif /* __KERNEL__ */
index 504a3c36ce5c9b311a9c8864d112792ae60fab9f..03bbd1149530d3115d7c9e84c66893428fe4af43 100644 (file)
@@ -24,6 +24,7 @@ extern int icache_44x_need_flush;
 #define PGD_INDEX_SIZE (32 - PGDIR_SHIFT)
 
 #define PMD_CACHE_INDEX        PMD_INDEX_SIZE
+#define PUD_CACHE_INDEX        PUD_INDEX_SIZE
 
 #ifndef __ASSEMBLY__
 #define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)
index abddf5830ad5550ee2c72875b209d9546afec579..5c5f75d005ada6289633455dc89bc0d2641c2e54 100644 (file)
@@ -27,6 +27,7 @@
 #else
 #define PMD_CACHE_INDEX        PMD_INDEX_SIZE
 #endif
+#define PUD_CACHE_INDEX PUD_INDEX_SIZE
 
 /*
  * Define the address range of the kernel non-linear virtual area
index 88187c285c70d5d823ccdf0a572cb8a7e24a6341..9f421641a35c8240cbacf192f6a1b22b4f33c63c 100644 (file)
@@ -44,6 +44,11 @@ extern int sysfs_add_device_to_node(struct device *dev, int nid);
 extern void sysfs_remove_device_from_node(struct device *dev, int nid);
 extern int numa_update_cpu_topology(bool cpus_locked);
 
+static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node)
+{
+       numa_cpu_lookup_table[cpu] = node;
+}
+
 static inline int early_cpu_to_node(int cpu)
 {
        int nid;
@@ -76,12 +81,16 @@ static inline int numa_update_cpu_topology(bool cpus_locked)
 {
        return 0;
 }
+
+static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {}
+
 #endif /* CONFIG_NUMA */
 
 #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
 extern int start_topology_update(void);
 extern int stop_topology_update(void);
 extern int prrn_is_enabled(void);
+extern int find_and_online_cpu_nid(int cpu);
 #else
 static inline int start_topology_update(void)
 {
@@ -95,6 +104,10 @@ static inline int prrn_is_enabled(void)
 {
        return 0;
 }
+static inline int find_and_online_cpu_nid(int cpu)
+{
+       return 0;
+}
 #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */
 
 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_NEED_MULTIPLE_NODES)
index beea2182d754bcd2d1f79184bcef1d390525cbb3..0c0b66fc5bfb32f6c61e8fa454fbfe1a467db89b 100644 (file)
@@ -384,7 +384,8 @@ static void *eeh_report_resume(void *data, void *userdata)
        eeh_pcid_put(dev);
        pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED);
 #ifdef CONFIG_PCI_IOV
-       eeh_ops->notify_resume(eeh_dev_to_pdn(edev));
+       if (eeh_ops->notify_resume && eeh_dev_to_pdn(edev))
+               eeh_ops->notify_resume(eeh_dev_to_pdn(edev));
 #endif
        return NULL;
 }
index ee832d344a5a265018d8fa98f0c38c0a94549db5..9b6e653e501a1264a8bfa398400dd88ecfa38d25 100644 (file)
@@ -943,6 +943,8 @@ kernel_dbg_exc:
 /*
  * An interrupt came in while soft-disabled; We mark paca->irq_happened
  * accordingly and if the interrupt is level sensitive, we hard disable
+ * hard disable (full_mask) corresponds to PACA_IRQ_MUST_HARD_MASK, so
+ * keep these in synch.
  */
 
 .macro masked_interrupt_book3e paca_irq full_mask
index 243d072a225aac1f7c7eaa69b6e5ef8cd21ce2c6..3ac87e53b3da0fdc0c41bd967ac731f5d98d6efb 100644 (file)
@@ -1426,7 +1426,7 @@ EXC_COMMON_BEGIN(soft_nmi_common)
  *   triggered and won't automatically refire.
  * - If it was a HMI we return immediately since we handled it in realmode
  *   and it won't refire.
- * - else we hard disable and return.
+ * - Else it is one of PACA_IRQ_MUST_HARD_MASK, so hard disable and return.
  * This is called with r10 containing the value to OR to the paca field.
  */
 #define MASKED_INTERRUPT(_H)                           \
@@ -1441,8 +1441,8 @@ masked_##_H##interrupt:                                   \
        ori     r10,r10,0xffff;                         \
        mtspr   SPRN_DEC,r10;                           \
        b       MASKED_DEC_HANDLER_LABEL;               \
-1:     andi.   r10,r10,(PACA_IRQ_DBELL|PACA_IRQ_HMI);  \
-       bne     2f;                                     \
+1:     andi.   r10,r10,PACA_IRQ_MUST_HARD_MASK;        \
+       beq     2f;                                     \
        mfspr   r10,SPRN_##_H##SRR1;                    \
        xori    r10,r10,MSR_EE; /* clear MSR_EE */      \
        mtspr   SPRN_##_H##SRR1,r10;                    \
index adf044daafd763a544685b92f60dbe434cc64f90..acf4b2e0530cb671df1e80d56927e8650f0c2f84 100644 (file)
@@ -874,7 +874,6 @@ struct ibm_arch_vec __cacheline_aligned ibm_architecture_vec = {
                .mmu = 0,
                .hash_ext = 0,
                .radix_ext = 0,
-               .byte22 = OV5_FEAT(OV5_DRC_INFO),
        },
 
        /* option vector 6: IBM PAPR hints */
index 5a8bfee6e1877c58ae607445ea77af1ed6b2e869..04d0bbd7a1dd03e13e47e4c5e10a647672955ea3 100644 (file)
@@ -788,7 +788,8 @@ static int register_cpu_online(unsigned int cpu)
        if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2))
                device_create_file(s, &dev_attr_pir);
 
-       if (cpu_has_feature(CPU_FTR_ARCH_206))
+       if (cpu_has_feature(CPU_FTR_ARCH_206) &&
+               !firmware_has_feature(FW_FEATURE_LPAR))
                device_create_file(s, &dev_attr_tscr);
 #endif /* CONFIG_PPC64 */
 
@@ -873,7 +874,8 @@ static int unregister_cpu_online(unsigned int cpu)
        if (cpu_has_feature(CPU_FTR_PPCAS_ARCH_V2))
                device_remove_file(s, &dev_attr_pir);
 
-       if (cpu_has_feature(CPU_FTR_ARCH_206))
+       if (cpu_has_feature(CPU_FTR_ARCH_206) &&
+               !firmware_has_feature(FW_FEATURE_LPAR))
                device_remove_file(s, &dev_attr_tscr);
 #endif /* CONFIG_PPC64 */
 
index 0c854816e653e25238f87c1cf9c44a8ed911df44..5cb4e4687107e1204667e3314bee2ce49de32de7 100644 (file)
@@ -195,6 +195,12 @@ static void kvmppc_pte_free(pte_t *ptep)
        kmem_cache_free(kvm_pte_cache, ptep);
 }
 
+/* Like pmd_huge() and pmd_large(), but works regardless of config options */
+static inline int pmd_is_leaf(pmd_t pmd)
+{
+       return !!(pmd_val(pmd) & _PAGE_PTE);
+}
+
 static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
                             unsigned int level, unsigned long mmu_seq)
 {
@@ -219,7 +225,7 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
        else
                new_pmd = pmd_alloc_one(kvm->mm, gpa);
 
-       if (level == 0 && !(pmd && pmd_present(*pmd)))
+       if (level == 0 && !(pmd && pmd_present(*pmd) && !pmd_is_leaf(*pmd)))
                new_ptep = kvmppc_pte_alloc();
 
        /* Check if we might have been invalidated; let the guest retry if so */
@@ -244,12 +250,30 @@ static int kvmppc_create_pte(struct kvm *kvm, pte_t pte, unsigned long gpa,
                new_pmd = NULL;
        }
        pmd = pmd_offset(pud, gpa);
-       if (pmd_large(*pmd)) {
-               /* Someone else has instantiated a large page here; retry */
-               ret = -EAGAIN;
-               goto out_unlock;
-       }
-       if (level == 1 && !pmd_none(*pmd)) {
+       if (pmd_is_leaf(*pmd)) {
+               unsigned long lgpa = gpa & PMD_MASK;
+
+               /*
+                * If we raced with another CPU which has just put
+                * a 2MB pte in after we saw a pte page, try again.
+                */
+               if (level == 0 && !new_ptep) {
+                       ret = -EAGAIN;
+                       goto out_unlock;
+               }
+               /* Valid 2MB page here already, remove it */
+               old = kvmppc_radix_update_pte(kvm, pmdp_ptep(pmd),
+                                             ~0UL, 0, lgpa, PMD_SHIFT);
+               kvmppc_radix_tlbie_page(kvm, lgpa, PMD_SHIFT);
+               if (old & _PAGE_DIRTY) {
+                       unsigned long gfn = lgpa >> PAGE_SHIFT;
+                       struct kvm_memory_slot *memslot;
+                       memslot = gfn_to_memslot(kvm, gfn);
+                       if (memslot && memslot->dirty_bitmap)
+                               kvmppc_update_dirty_map(memslot,
+                                                       gfn, PMD_SIZE);
+               }
+       } else if (level == 1 && !pmd_none(*pmd)) {
                /*
                 * There's a page table page here, but we wanted
                 * to install a large page.  Tell the caller and let
@@ -412,28 +436,24 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
        } else {
                page = pages[0];
                pfn = page_to_pfn(page);
-               if (PageHuge(page)) {
-                       page = compound_head(page);
-                       pte_size <<= compound_order(page);
+               if (PageCompound(page)) {
+                       pte_size <<= compound_order(compound_head(page));
                        /* See if we can insert a 2MB large-page PTE here */
                        if (pte_size >= PMD_SIZE &&
-                           (gpa & PMD_MASK & PAGE_MASK) ==
-                           (hva & PMD_MASK & PAGE_MASK)) {
+                           (gpa & (PMD_SIZE - PAGE_SIZE)) ==
+                           (hva & (PMD_SIZE - PAGE_SIZE))) {
                                level = 1;
                                pfn &= ~((PMD_SIZE >> PAGE_SHIFT) - 1);
                        }
                }
                /* See if we can provide write access */
                if (writing) {
-                       /*
-                        * We assume gup_fast has set dirty on the host PTE.
-                        */
                        pgflags |= _PAGE_WRITE;
                } else {
                        local_irq_save(flags);
                        ptep = find_current_mm_pte(current->mm->pgd,
                                                   hva, NULL, NULL);
-                       if (ptep && pte_write(*ptep) && pte_dirty(*ptep))
+                       if (ptep && pte_write(*ptep))
                                pgflags |= _PAGE_WRITE;
                        local_irq_restore(flags);
                }
@@ -459,18 +479,15 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
                pte = pfn_pte(pfn, __pgprot(pgflags));
                ret = kvmppc_create_pte(kvm, pte, gpa, level, mmu_seq);
        }
-       if (ret == 0 || ret == -EAGAIN)
-               ret = RESUME_GUEST;
 
        if (page) {
-               /*
-                * We drop pages[0] here, not page because page might
-                * have been set to the head page of a compound, but
-                * we have to drop the reference on the correct tail
-                * page to match the get inside gup()
-                */
-               put_page(pages[0]);
+               if (!ret && (pgflags & _PAGE_WRITE))
+                       set_page_dirty_lock(page);
+               put_page(page);
        }
+
+       if (ret == 0 || ret == -EAGAIN)
+               ret = RESUME_GUEST;
        return ret;
 }
 
@@ -644,7 +661,7 @@ void kvmppc_free_radix(struct kvm *kvm)
                                continue;
                        pmd = pmd_offset(pud, 0);
                        for (im = 0; im < PTRS_PER_PMD; ++im, ++pmd) {
-                               if (pmd_huge(*pmd)) {
+                               if (pmd_is_leaf(*pmd)) {
                                        pmd_clear(pmd);
                                        continue;
                                }
index 89707354c2efd89e95d1d1f861a170e8b6bfe51a..9cb9448163c4bf7021822d6632fb6c94452187ed 100644 (file)
@@ -2885,7 +2885,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
         */
        trace_hardirqs_on();
 
-       guest_enter();
+       guest_enter_irqoff();
 
        srcu_idx = srcu_read_lock(&vc->kvm->srcu);
 
@@ -2893,8 +2893,6 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 
        srcu_read_unlock(&vc->kvm->srcu, srcu_idx);
 
-       guest_exit();
-
        trace_hardirqs_off();
        set_irq_happened(trap);
 
@@ -2937,6 +2935,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
        kvmppc_set_host_core(pcpu);
 
        local_irq_enable();
+       guest_exit();
 
        /* Let secondaries go back to the offline loop */
        for (i = 0; i < controlled_threads; ++i) {
@@ -3656,15 +3655,17 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
                goto up_out;
 
        psize = vma_kernel_pagesize(vma);
-       porder = __ilog2(psize);
 
        up_read(&current->mm->mmap_sem);
 
        /* We can handle 4k, 64k or 16M pages in the VRMA */
-       err = -EINVAL;
-       if (!(psize == 0x1000 || psize == 0x10000 ||
-             psize == 0x1000000))
-               goto out_srcu;
+       if (psize >= 0x1000000)
+               psize = 0x1000000;
+       else if (psize >= 0x10000)
+               psize = 0x10000;
+       else
+               psize = 0x1000;
+       porder = __ilog2(psize);
 
        senc = slb_pgsize_encoding(psize);
        kvm->arch.vrma_slb_v = senc | SLB_VSID_B_1T |
index f31f357b8c5ae6657bac7a85fb89f66d86f13268..d33264697a31a13c2e84f2faaa02f055007a4948 100644 (file)
@@ -320,7 +320,6 @@ kvm_novcpu_exit:
        stw     r12, STACK_SLOT_TRAP(r1)
        bl      kvmhv_commence_exit
        nop
-       lwz     r12, STACK_SLOT_TRAP(r1)
        b       kvmhv_switch_to_host
 
 /*
@@ -1220,6 +1219,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
 secondary_too_late:
        li      r12, 0
+       stw     r12, STACK_SLOT_TRAP(r1)
        cmpdi   r4, 0
        beq     11f
        stw     r12, VCPU_TRAP(r4)
@@ -1558,12 +1558,12 @@ mc_cont:
 3:     stw     r5,VCPU_SLB_MAX(r9)
 
 guest_bypass:
+       stw     r12, STACK_SLOT_TRAP(r1)
        mr      r3, r12
        /* Increment exit count, poke other threads to exit */
        bl      kvmhv_commence_exit
        nop
        ld      r9, HSTATE_KVM_VCPU(r13)
-       lwz     r12, VCPU_TRAP(r9)
 
        /* Stop others sending VCPU interrupts to this physical CPU */
        li      r0, -1
@@ -1898,6 +1898,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_POWER9_DD1)
         * POWER7/POWER8 guest -> host partition switch code.
         * We don't have to lock against tlbies but we do
         * have to coordinate the hardware threads.
+        * Here STACK_SLOT_TRAP(r1) contains the trap number.
         */
 kvmhv_switch_to_host:
        /* Secondary threads wait for primary to do partition switch */
@@ -1950,12 +1951,12 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
        /* If HMI, call kvmppc_realmode_hmi_handler() */
+       lwz     r12, STACK_SLOT_TRAP(r1)
        cmpwi   r12, BOOK3S_INTERRUPT_HMI
        bne     27f
        bl      kvmppc_realmode_hmi_handler
        nop
        cmpdi   r3, 0
-       li      r12, BOOK3S_INTERRUPT_HMI
        /*
         * At this point kvmppc_realmode_hmi_handler may have resync-ed
         * the TB, and if it has, we must not subtract the guest timebase
@@ -2008,10 +2009,8 @@ BEGIN_FTR_SECTION
        lwz     r8, KVM_SPLIT_DO_RESTORE(r3)
        cmpwi   r8, 0
        beq     47f
-       stw     r12, STACK_SLOT_TRAP(r1)
        bl      kvmhv_p9_restore_lpcr
        nop
-       lwz     r12, STACK_SLOT_TRAP(r1)
        b       48f
 47:
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
@@ -2049,6 +2048,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
        li      r0, KVM_GUEST_MODE_NONE
        stb     r0, HSTATE_IN_GUEST(r13)
 
+       lwz     r12, STACK_SLOT_TRAP(r1)        /* return trap # in r12 */
        ld      r0, SFS+PPC_LR_STKOFF(r1)
        addi    r1, r1, SFS
        mtlr    r0
index f0f5cd4d2fe7cf796336cd56cc3d8c9011be8cab..f9818d7d3381d8c072605534202fb6c91b7d58e4 100644 (file)
@@ -188,7 +188,7 @@ static int xive_provision_queue(struct kvm_vcpu *vcpu, u8 prio)
        if (!qpage) {
                pr_err("Failed to allocate queue %d for VCPU %d\n",
                       prio, xc->server_num);
-               return -ENOMEM;;
+               return -ENOMEM;
        }
        memset(qpage, 0, 1 << xive->q_order);
 
index 403e642c78f5170b81855ef329e7148f454bfa3b..52c2053739862d2e7c53210458b0fbc9943f510b 100644 (file)
@@ -1345,7 +1345,7 @@ static int kvmppc_emulate_mmio_vsx_loadstore(struct kvm_vcpu *vcpu,
 int kvmppc_handle_load128_by2x64(struct kvm_run *run, struct kvm_vcpu *vcpu,
                unsigned int rt, int is_default_endian)
 {
-       enum emulation_result emulated;
+       enum emulation_result emulated = EMULATE_DONE;
 
        while (vcpu->arch.mmio_vmx_copy_nums) {
                emulated = __kvmppc_handle_load(run, vcpu, rt, 8,
@@ -1608,7 +1608,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
        kvm_sigset_deactivate(vcpu);
 
+#ifdef CONFIG_ALTIVEC
 out:
+#endif
        vcpu_put(vcpu);
        return r;
 }
index 1604110c42386c39dea239aaa1a564ba5bc7b38e..3f1803672c9bb1062da0238999a82338f7c3c387 100644 (file)
@@ -98,7 +98,7 @@ static void init_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
        dr_cell->base_addr = cpu_to_be64(lmb->base_addr);
        dr_cell->drc_index = cpu_to_be32(lmb->drc_index);
        dr_cell->aa_index = cpu_to_be32(lmb->aa_index);
-       dr_cell->flags = cpu_to_be32(lmb->flags);
+       dr_cell->flags = cpu_to_be32(drmem_lmb_flags(lmb));
 }
 
 static int drmem_update_dt_v2(struct device_node *memory,
@@ -121,7 +121,7 @@ static int drmem_update_dt_v2(struct device_node *memory,
                }
 
                if (prev_lmb->aa_index != lmb->aa_index ||
-                   prev_lmb->flags != lmb->flags)
+                   drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb))
                        lmb_sets++;
 
                prev_lmb = lmb;
@@ -150,7 +150,7 @@ static int drmem_update_dt_v2(struct device_node *memory,
                }
 
                if (prev_lmb->aa_index != lmb->aa_index ||
-                   prev_lmb->flags != lmb->flags) {
+                   drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb)) {
                        /* end of one set, start of another */
                        dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs);
                        dr_cell++;
@@ -216,6 +216,8 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
        u32 i, n_lmbs;
 
        n_lmbs = of_read_number(prop++, 1);
+       if (n_lmbs == 0)
+               return;
 
        for (i = 0; i < n_lmbs; i++) {
                read_drconf_v1_cell(&lmb, &prop);
@@ -245,6 +247,8 @@ static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
        u32 i, j, lmb_sets;
 
        lmb_sets = of_read_number(prop++, 1);
+       if (lmb_sets == 0)
+               return;
 
        for (i = 0; i < lmb_sets; i++) {
                read_drconf_v2_cell(&dr_cell, &prop);
@@ -354,6 +358,8 @@ static void __init init_drmem_v1_lmbs(const __be32 *prop)
        struct drmem_lmb *lmb;
 
        drmem_info->n_lmbs = of_read_number(prop++, 1);
+       if (drmem_info->n_lmbs == 0)
+               return;
 
        drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
                                   GFP_KERNEL);
@@ -373,6 +379,8 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
        int lmb_index;
 
        lmb_sets = of_read_number(prop++, 1);
+       if (lmb_sets == 0)
+               return;
 
        /* first pass, calculate the number of LMBs */
        p = prop;
index 5a69b51d08a3615f319a325536a209b6399db2a7..d573d7d07f25f4d718043a71e199475d3df9597c 100644 (file)
@@ -55,7 +55,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
         * need to add in 0x1 if it's a read-only user page
         */
        rflags = htab_convert_pte_flags(new_pte);
-       rpte = __real_pte(__pte(old_pte), ptep);
+       rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
 
        if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
            !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -117,7 +117,7 @@ repeat:
                        return -1;
                }
                new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
-               new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
+               new_pte |= pte_set_hidx(ptep, rpte, 0, slot, PTRS_PER_PTE);
        }
        *ptep = __pte(new_pte & ~H_PAGE_BUSY);
        return 0;
index 2253bbc6a599d7804cb81dc49b2c6f82b81a435d..e601d95c3b20271d7b9cc6483cab402d51d80436 100644 (file)
@@ -86,7 +86,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
 
        subpg_index = (ea & (PAGE_SIZE - 1)) >> shift;
        vpn  = hpt_vpn(ea, vsid, ssize);
-       rpte = __real_pte(__pte(old_pte), ptep);
+       rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
        /*
         *None of the sub 4k page is hashed
         */
@@ -214,7 +214,7 @@ repeat:
                return -1;
        }
 
-       new_pte |= pte_set_hidx(ptep, rpte, subpg_index, slot);
+       new_pte |= pte_set_hidx(ptep, rpte, subpg_index, slot, PTRS_PER_PTE);
        new_pte |= H_PAGE_HASHPTE;
 
        *ptep = __pte(new_pte & ~H_PAGE_BUSY);
@@ -262,7 +262,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
        } while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
 
        rflags = htab_convert_pte_flags(new_pte);
-       rpte = __real_pte(__pte(old_pte), ptep);
+       rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
 
        if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
            !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -327,7 +327,7 @@ repeat:
                }
 
                new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
-               new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
+               new_pte |= pte_set_hidx(ptep, rpte, 0, slot, PTRS_PER_PTE);
        }
        *ptep = __pte(new_pte & ~H_PAGE_BUSY);
        return 0;
index 7d07c7e17db6708334ea38cad711e1f5c32de1c6..cf290d415dcd8e9e314c63134c49cbd687e63fd7 100644 (file)
@@ -1008,6 +1008,7 @@ void __init hash__early_init_mmu(void)
        __pmd_index_size = H_PMD_INDEX_SIZE;
        __pud_index_size = H_PUD_INDEX_SIZE;
        __pgd_index_size = H_PGD_INDEX_SIZE;
+       __pud_cache_index = H_PUD_CACHE_INDEX;
        __pmd_cache_index = H_PMD_CACHE_INDEX;
        __pte_table_size = H_PTE_TABLE_SIZE;
        __pmd_table_size = H_PMD_TABLE_SIZE;
index 12511f5a015fcfee349e9dd7ac00f6ecd3b8df90..b320f5097a0616dce810c31e42fa42659475d4c3 100644 (file)
@@ -27,7 +27,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
        unsigned long vpn;
        unsigned long old_pte, new_pte;
        unsigned long rflags, pa, sz;
-       long slot;
+       long slot, offset;
 
        BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
 
@@ -63,7 +63,11 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
        } while(!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
 
        rflags = htab_convert_pte_flags(new_pte);
-       rpte = __real_pte(__pte(old_pte), ptep);
+       if (unlikely(mmu_psize == MMU_PAGE_16G))
+               offset = PTRS_PER_PUD;
+       else
+               offset = PTRS_PER_PMD;
+       rpte = __real_pte(__pte(old_pte), ptep, offset);
 
        sz = ((1UL) << shift);
        if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -104,7 +108,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
                        return -1;
                }
 
-               new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
+               new_pte |= pte_set_hidx(ptep, rpte, 0, slot, offset);
        }
 
        /*
index eb8c6c8c4851a9a7e25a555dd3e61c7b0613fb4e..2b656e67f2eaaa3914cd74d1cd57e36a5060486b 100644 (file)
@@ -100,6 +100,6 @@ void pgtable_cache_init(void)
         * same size as either the pgd or pmd index except with THP enabled
         * on book3s 64
         */
-       if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE))
-               pgtable_cache_add(PUD_INDEX_SIZE, pud_ctor);
+       if (PUD_CACHE_INDEX && !PGT_CACHE(PUD_CACHE_INDEX))
+               pgtable_cache_add(PUD_CACHE_INDEX, pud_ctor);
 }
index 314d19ab9385e038a4f38c18a50364da4873eb86..edd8d0bc9364f2843688498b221d90f53647390d 100644 (file)
@@ -143,11 +143,6 @@ static void reset_numa_cpu_lookup_table(void)
                numa_cpu_lookup_table[cpu] = -1;
 }
 
-static void update_numa_cpu_lookup_table(unsigned int cpu, int node)
-{
-       numa_cpu_lookup_table[cpu] = node;
-}
-
 static void map_cpu_to_node(int cpu, int node)
 {
        update_numa_cpu_lookup_table(cpu, node);
index 573a9a2ee4555c53ab2416e70fb4fdd05fb464da..2e10a964e29080149fe60b5d9a2220fdc710bb79 100644 (file)
 #include <linux/of_fdt.h>
 #include <linux/mm.h>
 #include <linux/string_helpers.h>
+#include <linux/stop_machine.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
 #include <asm/dma.h>
 #include <asm/machdep.h>
 #include <asm/mmu.h>
@@ -333,6 +335,22 @@ static void __init radix_init_pgtable(void)
                     "r" (TLBIEL_INVAL_SET_LPID), "r" (0));
        asm volatile("eieio; tlbsync; ptesync" : : : "memory");
        trace_tlbie(0, 0, TLBIEL_INVAL_SET_LPID, 0, 2, 1, 1);
+
+       /*
+        * The init_mm context is given the first available (non-zero) PID,
+        * which is the "guard PID" and contains no page table. PIDR should
+        * never be set to zero because that duplicates the kernel address
+        * space at the 0x0... offset (quadrant 0)!
+        *
+        * An arbitrary PID that may later be allocated by the PID allocator
+        * for userspace processes must not be used either, because that
+        * would cause stale user mappings for that PID on CPUs outside of
+        * the TLB invalidation scheme (because it won't be in mm_cpumask).
+        *
+        * So permanently carve out one PID for the purpose of a guard PID.
+        */
+       init_mm.context.id = mmu_base_pid;
+       mmu_base_pid++;
 }
 
 static void __init radix_init_partition_table(void)
@@ -535,6 +553,7 @@ void __init radix__early_init_mmu(void)
        __pmd_index_size = RADIX_PMD_INDEX_SIZE;
        __pud_index_size = RADIX_PUD_INDEX_SIZE;
        __pgd_index_size = RADIX_PGD_INDEX_SIZE;
+       __pud_cache_index = RADIX_PUD_INDEX_SIZE;
        __pmd_cache_index = RADIX_PMD_INDEX_SIZE;
        __pte_table_size = RADIX_PTE_TABLE_SIZE;
        __pmd_table_size = RADIX_PMD_TABLE_SIZE;
@@ -579,7 +598,8 @@ void __init radix__early_init_mmu(void)
 
        radix_init_iamr();
        radix_init_pgtable();
-
+       /* Switch to the guard PID before turning on MMU */
+       radix__switch_mmu_context(NULL, &init_mm);
        if (cpu_has_feature(CPU_FTR_HVMODE))
                tlbiel_all();
 }
@@ -604,6 +624,7 @@ void radix__early_init_mmu_secondary(void)
        }
        radix_init_iamr();
 
+       radix__switch_mmu_context(NULL, &init_mm);
        if (cpu_has_feature(CPU_FTR_HVMODE))
                tlbiel_all();
 }
@@ -666,6 +687,30 @@ static void free_pmd_table(pmd_t *pmd_start, pud_t *pud)
        pud_clear(pud);
 }
 
+struct change_mapping_params {
+       pte_t *pte;
+       unsigned long start;
+       unsigned long end;
+       unsigned long aligned_start;
+       unsigned long aligned_end;
+};
+
+static int stop_machine_change_mapping(void *data)
+{
+       struct change_mapping_params *params =
+                       (struct change_mapping_params *)data;
+
+       if (!data)
+               return -1;
+
+       spin_unlock(&init_mm.page_table_lock);
+       pte_clear(&init_mm, params->aligned_start, params->pte);
+       create_physical_mapping(params->aligned_start, params->start);
+       create_physical_mapping(params->end, params->aligned_end);
+       spin_lock(&init_mm.page_table_lock);
+       return 0;
+}
+
 static void remove_pte_table(pte_t *pte_start, unsigned long addr,
                             unsigned long end)
 {
@@ -694,6 +739,52 @@ static void remove_pte_table(pte_t *pte_start, unsigned long addr,
        }
 }
 
+/*
+ * clear the pte and potentially split the mapping helper
+ */
+static void split_kernel_mapping(unsigned long addr, unsigned long end,
+                               unsigned long size, pte_t *pte)
+{
+       unsigned long mask = ~(size - 1);
+       unsigned long aligned_start = addr & mask;
+       unsigned long aligned_end = addr + size;
+       struct change_mapping_params params;
+       bool split_region = false;
+
+       if ((end - addr) < size) {
+               /*
+                * We're going to clear the PTE, but not flushed
+                * the mapping, time to remap and flush. The
+                * effects if visible outside the processor or
+                * if we are running in code close to the
+                * mapping we cleared, we are in trouble.
+                */
+               if (overlaps_kernel_text(aligned_start, addr) ||
+                       overlaps_kernel_text(end, aligned_end)) {
+                       /*
+                        * Hack, just return, don't pte_clear
+                        */
+                       WARN_ONCE(1, "Linear mapping %lx->%lx overlaps kernel "
+                                 "text, not splitting\n", addr, end);
+                       return;
+               }
+               split_region = true;
+       }
+
+       if (split_region) {
+               params.pte = pte;
+               params.start = addr;
+               params.end = end;
+               params.aligned_start = addr & ~(size - 1);
+               params.aligned_end = min_t(unsigned long, aligned_end,
+                               (unsigned long)__va(memblock_end_of_DRAM()));
+               stop_machine(stop_machine_change_mapping, &params, NULL);
+               return;
+       }
+
+       pte_clear(&init_mm, addr, pte);
+}
+
 static void remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
                             unsigned long end)
 {
@@ -709,13 +800,7 @@ static void remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
                        continue;
 
                if (pmd_huge(*pmd)) {
-                       if (!IS_ALIGNED(addr, PMD_SIZE) ||
-                           !IS_ALIGNED(next, PMD_SIZE)) {
-                               WARN_ONCE(1, "%s: unaligned range\n", __func__);
-                               continue;
-                       }
-
-                       pte_clear(&init_mm, addr, (pte_t *)pmd);
+                       split_kernel_mapping(addr, end, PMD_SIZE, (pte_t *)pmd);
                        continue;
                }
 
@@ -740,13 +825,7 @@ static void remove_pud_table(pud_t *pud_start, unsigned long addr,
                        continue;
 
                if (pud_huge(*pud)) {
-                       if (!IS_ALIGNED(addr, PUD_SIZE) ||
-                           !IS_ALIGNED(next, PUD_SIZE)) {
-                               WARN_ONCE(1, "%s: unaligned range\n", __func__);
-                               continue;
-                       }
-
-                       pte_clear(&init_mm, addr, (pte_t *)pud);
+                       split_kernel_mapping(addr, end, PUD_SIZE, (pte_t *)pud);
                        continue;
                }
 
@@ -772,13 +851,7 @@ static void remove_pagetable(unsigned long start, unsigned long end)
                        continue;
 
                if (pgd_huge(*pgd)) {
-                       if (!IS_ALIGNED(addr, PGDIR_SIZE) ||
-                           !IS_ALIGNED(next, PGDIR_SIZE)) {
-                               WARN_ONCE(1, "%s: unaligned range\n", __func__);
-                               continue;
-                       }
-
-                       pte_clear(&init_mm, addr, (pte_t *)pgd);
+                       split_kernel_mapping(addr, end, PGDIR_SIZE, (pte_t *)pgd);
                        continue;
                }
 
index c9a623c2d8a270a14966003258f035fb95d08cff..28c980eb4422284d788716e245934c679925ad86 100644 (file)
@@ -82,6 +82,8 @@ unsigned long __pgd_index_size;
 EXPORT_SYMBOL(__pgd_index_size);
 unsigned long __pmd_cache_index;
 EXPORT_SYMBOL(__pmd_cache_index);
+unsigned long __pud_cache_index;
+EXPORT_SYMBOL(__pud_cache_index);
 unsigned long __pte_table_size;
 EXPORT_SYMBOL(__pte_table_size);
 unsigned long __pmd_table_size;
@@ -471,6 +473,8 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
        if (old & PATB_HR) {
                asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
                             "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+               asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
+                            "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
                trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
        } else {
                asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
index 881ebd53ffc27c8840ae57b088c4d247ba7ef191..9b23f12e863cc14ff324b9c5ffed077c3a1012e8 100644 (file)
@@ -51,7 +51,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
        unsigned int psize;
        int ssize;
        real_pte_t rpte;
-       int i;
+       int i, offset;
 
        i = batch->index;
 
@@ -67,6 +67,10 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
                psize = get_slice_psize(mm, addr);
                /* Mask the address for the correct page size */
                addr &= ~((1UL << mmu_psize_defs[psize].shift) - 1);
+               if (unlikely(psize == MMU_PAGE_16G))
+                       offset = PTRS_PER_PUD;
+               else
+                       offset = PTRS_PER_PMD;
 #else
                BUG();
                psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */
@@ -78,6 +82,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
                 * support 64k pages, this might be different from the
                 * hardware page size encoded in the slice table. */
                addr &= PAGE_MASK;
+               offset = PTRS_PER_PTE;
        }
 
 
@@ -91,7 +96,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
        }
        WARN_ON(vsid == 0);
        vpn = hpt_vpn(addr, vsid, ssize);
-       rpte = __real_pte(__pte(pte), ptep);
+       rpte = __real_pte(__pte(pte), ptep, offset);
 
        /*
         * Check if we have an active batch on this CPU. If not, just
index 872d1f6dd11e179793c4394e48313649028820e1..a9636d8cba153a1fb43469c1b8070b59ae4ba210 100644 (file)
@@ -327,6 +327,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
                        PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
                        break;
+               case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */
+                       PPC_LWZ_OFFS(r_A, r_skb, K);
+                       break;
                case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */
                        PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len));
                        break;
index 0a34b0cec7b7c87fd6bbc08a608fb80b7e13d958..0ef3d9580e98ca7c4f747edb115b16c56ccf6d43 100644 (file)
@@ -240,6 +240,7 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
         *   goto out;
         */
        PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries));
+       PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31);
        PPC_CMPLW(b2p_index, b2p[TMP_REG_1]);
        PPC_BCC(COND_GE, out);
 
index dd4c9b8b8a81e6967b29061014918b4f591921df..f6f55ab4980e7684a09942a510daf689f79f6d1c 100644 (file)
@@ -199,9 +199,11 @@ static void disable_nest_pmu_counters(void)
        const struct cpumask *l_cpumask;
 
        get_online_cpus();
-       for_each_online_node(nid) {
+       for_each_node_with_cpus(nid) {
                l_cpumask = cpumask_of_node(nid);
-               cpu = cpumask_first(l_cpumask);
+               cpu = cpumask_first_and(l_cpumask, cpu_online_mask);
+               if (cpu >= nr_cpu_ids)
+                       continue;
                opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
                                       get_hard_smp_processor_id(cpu));
        }
index 496e47696ed0c57c413b6ce4c920c7c3beda745f..a6c92c78c9b20b9cc2507cfb5c3e749e05a6e19d 100644 (file)
@@ -1854,7 +1854,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
        s64 rc;
 
        if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
-               return -ENODEV;;
+               return -ENODEV;
 
        pe = &phb->ioda.pe_array[pdn->pe_number];
        if (pe->tce_bypass_enabled) {
index 4fb21e17504aad72295a9e1cdffe54c5547379bd..092715b9674bb93309b3793ed4ccd2719407e5db 100644 (file)
@@ -80,6 +80,10 @@ static void pnv_setup_rfi_flush(void)
                if (np && of_property_read_bool(np, "disabled"))
                        enable--;
 
+               np = of_get_child_by_name(fw_features, "speculation-policy-favor-security");
+               if (np && of_property_read_bool(np, "disabled"))
+                       enable = 0;
+
                of_node_put(np);
                of_node_put(fw_features);
        }
index 2b3eb01ab1107145395b0c697da4743bd2e97c8c..b7c53a51c31bbe5ba5fa62adbf6d1e97c3c1e8c3 100644 (file)
@@ -1063,16 +1063,16 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop,
                        rc = PTR_ERR(txwin->paste_kaddr);
                        goto free_window;
                }
+       } else {
+               /*
+                * A user mapping must ensure that context switch issues
+                * CP_ABORT for this thread.
+                */
+               rc = set_thread_uses_vas();
+               if (rc)
+                       goto free_window;
        }
 
-       /*
-        * Now that we have a send window, ensure context switch issues
-        * CP_ABORT for this thread.
-        */
-       rc = -EINVAL;
-       if (set_thread_uses_vas() < 0)
-               goto free_window;
-
        set_vinst_win(vinst, txwin);
 
        return txwin;
index dceb51454d8d212a5cbc78ef891322bddf499800..652d3e96b812b93834323e1a3a60a1e5bbab3612 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/xics.h>
 #include <asm/xive.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/topology.h>
 
 #include "pseries.h"
 #include "offline_states.h"
@@ -331,6 +332,7 @@ static void pseries_remove_processor(struct device_node *np)
                        BUG_ON(cpu_online(cpu));
                        set_cpu_present(cpu, false);
                        set_hard_smp_processor_id(cpu, -1);
+                       update_numa_cpu_lookup_table(cpu, -1);
                        break;
                }
                if (cpu >= nr_cpu_ids)
@@ -340,8 +342,6 @@ static void pseries_remove_processor(struct device_node *np)
        cpu_maps_update_done();
 }
 
-extern int find_and_online_cpu_nid(int cpu);
-
 static int dlpar_online_cpu(struct device_node *dn)
 {
        int rc = 0;
index 81d8614e73790b1923a3c8cfd336a2531fee76ce..5e1ef915018208c3511ef0e91c0064c8c9474389 100644 (file)
@@ -48,6 +48,28 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
 static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
 
 
+/*
+ * Enable the hotplug interrupt late because processing them may touch other
+ * devices or systems (e.g. hugepages) that have not been initialized at the
+ * subsys stage.
+ */
+int __init init_ras_hotplug_IRQ(void)
+{
+       struct device_node *np;
+
+       /* Hotplug Events */
+       np = of_find_node_by_path("/event-sources/hot-plug-events");
+       if (np != NULL) {
+               if (dlpar_workqueue_init() == 0)
+                       request_event_sources_irqs(np, ras_hotplug_interrupt,
+                                                  "RAS_HOTPLUG");
+               of_node_put(np);
+       }
+
+       return 0;
+}
+machine_late_initcall(pseries, init_ras_hotplug_IRQ);
+
 /*
  * Initialize handlers for the set of interrupts caused by hardware errors
  * and power system events.
@@ -66,15 +88,6 @@ static int __init init_ras_IRQ(void)
                of_node_put(np);
        }
 
-       /* Hotplug Events */
-       np = of_find_node_by_path("/event-sources/hot-plug-events");
-       if (np != NULL) {
-               if (dlpar_workqueue_init() == 0)
-                       request_event_sources_irqs(np, ras_hotplug_interrupt,
-                                          "RAS_HOTPLUG");
-               of_node_put(np);
-       }
-
        /* EPOW Events */
        np = of_find_node_by_path("/event-sources/epow-events");
        if (np != NULL) {
index 372d7ada1a0c115aa9078cb1ba0d01d69a80a73d..1a527625acf78dea27f7bde430e23f02f12f5baf 100644 (file)
@@ -482,7 +482,8 @@ static void pseries_setup_rfi_flush(void)
                if (types == L1D_FLUSH_NONE)
                        types = L1D_FLUSH_FALLBACK;
 
-               if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
+               if ((!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) ||
+                   (!(result.behaviour & H_CPU_BEHAV_FAVOUR_SECURITY)))
                        enable = false;
        } else {
                /* Default to fallback if case hcall is not available */
index d9c4c93660491849029044d37ab8e60160b0d7de..091f1d0d0af190a0d6f274b8cab32960cc1eef86 100644 (file)
@@ -356,7 +356,8 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio,
 
        rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size);
        if (rc) {
-               pr_err("Error %lld getting queue info prio %d\n", rc, prio);
+               pr_err("Error %lld getting queue info CPU %d prio %d\n", rc,
+                      target, prio);
                rc = -EIO;
                goto fail;
        }
@@ -370,7 +371,8 @@ static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio,
        /* Configure and enable the queue in HW */
        rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order);
        if (rc) {
-               pr_err("Error %lld setting queue for prio %d\n", rc, prio);
+               pr_err("Error %lld setting queue for CPU %d prio %d\n", rc,
+                      target, prio);
                rc = -EIO;
        } else {
                q->qpage = qpage;
@@ -389,8 +391,8 @@ static int xive_spapr_setup_queue(unsigned int cpu, struct xive_cpu *xc,
        if (IS_ERR(qpage))
                return PTR_ERR(qpage);
 
-       return xive_spapr_configure_queue(cpu, q, prio, qpage,
-                                         xive_queue_shift);
+       return xive_spapr_configure_queue(get_hard_smp_processor_id(cpu),
+                                         q, prio, qpage, xive_queue_shift);
 }
 
 static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc,
@@ -399,10 +401,12 @@ static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc,
        struct xive_q *q = &xc->queue[prio];
        unsigned int alloc_order;
        long rc;
+       int hw_cpu = get_hard_smp_processor_id(cpu);
 
-       rc = plpar_int_set_queue_config(0, cpu, prio, 0, 0);
+       rc = plpar_int_set_queue_config(0, hw_cpu, prio, 0, 0);
        if (rc)
-               pr_err("Error %ld setting queue for prio %d\n", rc, prio);
+               pr_err("Error %ld setting queue for CPU %d prio %d\n", rc,
+                      hw_cpu, prio);
 
        alloc_order = xive_alloc_order(xive_queue_shift);
        free_pages((unsigned long)q->qpage, alloc_order);
index b6722c246d9c80b81e26fd30ef3f60b2281d1f20..04807c7f64cc58f7b2e4be1ec1d10b4cf1b018a8 100644 (file)
@@ -8,7 +8,6 @@ config RISCV
        select OF
        select OF_EARLY_FLATTREE
        select OF_IRQ
-       select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select ARCH_WANT_FRAME_POINTERS
        select CLONE_BACKWARDS
        select COMMON_CLK
@@ -20,7 +19,6 @@ config RISCV
        select GENERIC_STRNLEN_USER
        select GENERIC_SMP_IDLE_THREAD
        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
@@ -34,7 +32,6 @@ config RISCV
        select HAVE_ARCH_TRACEHOOK
        select MODULES_USE_ELF_RELA if MODULES
        select THREAD_INFO_IN_TASK
-       select RISCV_IRQ_INTC
        select RISCV_TIMER
 
 config MMU
index c0319cbf1eec58d7ea8960259838b865c23f49a1..5510366d169aea821e9f09ffe613363a2009db93 100644 (file)
@@ -34,9 +34,9 @@
 #define wmb()          RISCV_FENCE(ow,ow)
 
 /* These barriers do not need to enforce ordering on devices, just memory. */
-#define smp_mb()       RISCV_FENCE(rw,rw)
-#define smp_rmb()      RISCV_FENCE(r,r)
-#define smp_wmb()      RISCV_FENCE(w,w)
+#define __smp_mb()     RISCV_FENCE(rw,rw)
+#define __smp_rmb()    RISCV_FENCE(r,r)
+#define __smp_wmb()    RISCV_FENCE(w,w)
 
 /*
  * This is a very specific barrier: it's currently only used in two places in
index 87fc045be51fa8078f5176de0f384c79a4a687c5..56fa592cfa349b9cbf1e2e9e580bbd4c27bb9d51 100644 (file)
@@ -172,6 +172,9 @@ ENTRY(handle_exception)
        move a1, sp /* pt_regs */
        tail do_IRQ
 1:
+       /* Exceptions run with interrupts enabled */
+       csrs sstatus, SR_SIE
+
        /* Handle syscalls */
        li t0, EXC_SYSCALL
        beq s4, t0, handle_syscall
@@ -198,8 +201,6 @@ handle_syscall:
         */
        addi s2, s2, 0x4
        REG_S s2, PT_SEPC(sp)
-       /* System calls run with interrupts enabled */
-       csrs sstatus, SR_SIE
        /* Trace syscalls, but only if requested by the user. */
        REG_L t0, TASK_TI_FLAGS(tp)
        andi t0, t0, _TIF_SYSCALL_TRACE
index 226eeb190f908daef2a714944599e69c35271a4d..6e07ed37bbff794bb52664670b42c10c59810e01 100644 (file)
@@ -64,7 +64,7 @@ ENTRY(_start)
        /* Start the kernel */
        mv a0, s0
        mv a1, s1
-       call sbi_save
+       call parse_dtb
        tail start_kernel
 
 relocate:
index 09f7064e898cc7616628feee3e46bd48fcaef5e6..c11f40c1b2a881f8cf779988f4838a806104d042 100644 (file)
@@ -144,7 +144,7 @@ asmlinkage void __init setup_vm(void)
 #endif
 }
 
-void __init sbi_save(unsigned int hartid, void *dtb)
+void __init parse_dtb(unsigned int hartid, void *dtb)
 {
        early_init_dt_scan(__va(dtb));
 }
index 65154eaa3714a4e9182cb87654e7b896e7be3e2f..6c8ce15cde7b349d45c27c6d2cfbd7436e13322a 100644 (file)
@@ -63,6 +63,7 @@ static inline int init_new_context(struct task_struct *tsk,
                                   _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT;
                /* pgd_alloc() did not account this pmd */
                mm_inc_nr_pmds(mm);
+               mm_inc_nr_puds(mm);
        }
        crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
        return 0;
index 13a133a6015c9adbe1c821269490199bec2cf438..a5621ea6d1234f1c3b6c8aec8612bd933f5cc6f3 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 #include <asm/ctl_reg.h>
+#include <asm/dwarf.h>
 #include <asm/errno.h>
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
@@ -230,7 +231,7 @@ _PIF_WORK   = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
        .hidden \name
        .type \name,@function
 \name:
-       .cfi_startproc
+       CFI_STARTPROC
 #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
        exrl    0,0f
 #else
@@ -239,7 +240,7 @@ _PIF_WORK   = (_PIF_PER_TRAP | _PIF_SYSCALL_RESTART)
 #endif
        j       .
 0:     br      \reg
-       .cfi_endproc
+       CFI_ENDPROC
        .endm
 
        GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
@@ -426,13 +427,13 @@ ENTRY(system_call)
        UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
        BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
        stmg    %r0,%r7,__PT_R0(%r11)
-       # clear user controlled register to prevent speculative use
-       xgr     %r0,%r0
        mvc     __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
        mvc     __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
        mvc     __PT_INT_CODE(4,%r11),__LC_SVC_ILC
        stg     %r14,__PT_FLAGS(%r11)
 .Lsysc_do_svc:
+       # clear user controlled register to prevent speculative use
+       xgr     %r0,%r0
        # load address of system call table
        lg      %r10,__THREAD_sysc_table(%r13,%r12)
        llgh    %r8,__PT_INT_CODE+2(%r11)
@@ -1439,6 +1440,7 @@ cleanup_critical:
        stg     %r15,__LC_SYSTEM_TIMER
 0:     # update accounting time stamp
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+       BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP
        # set up saved register r11
        lg      %r15,__LC_KERNEL_STACK
        la      %r9,STACK_FRAME_OVERHEAD(%r15)
index 69d7fcf48158892e6e5aac74bb6b4ab82e7516b9..9aff72d3abda3148a0a6decb358713e6369a43a7 100644 (file)
@@ -2,8 +2,8 @@
 #include <linux/module.h>
 #include <asm/nospec-branch.h>
 
-int nospec_call_disable = IS_ENABLED(EXPOLINE_OFF);
-int nospec_return_disable = !IS_ENABLED(EXPOLINE_FULL);
+int nospec_call_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
+int nospec_return_disable = !IS_ENABLED(CONFIG_EXPOLINE_FULL);
 
 static int __init nospectre_v2_setup_early(char *str)
 {
index 9c7d707158622e7f0743570db60599fa95a9de3b..07c6e81163bf5e248c1b744f69b75548aeae5d44 100644 (file)
 #include "trace.h"
 #include "trace-s390.h"
 
-
-static const intercept_handler_t instruction_handlers[256] = {
-       [0x01] = kvm_s390_handle_01,
-       [0x82] = kvm_s390_handle_lpsw,
-       [0x83] = kvm_s390_handle_diag,
-       [0xaa] = kvm_s390_handle_aa,
-       [0xae] = kvm_s390_handle_sigp,
-       [0xb2] = kvm_s390_handle_b2,
-       [0xb6] = kvm_s390_handle_stctl,
-       [0xb7] = kvm_s390_handle_lctl,
-       [0xb9] = kvm_s390_handle_b9,
-       [0xe3] = kvm_s390_handle_e3,
-       [0xe5] = kvm_s390_handle_e5,
-       [0xeb] = kvm_s390_handle_eb,
-};
-
 u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu)
 {
        struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
@@ -129,16 +113,39 @@ static int handle_validity(struct kvm_vcpu *vcpu)
 
 static int handle_instruction(struct kvm_vcpu *vcpu)
 {
-       intercept_handler_t handler;
-
        vcpu->stat.exit_instruction++;
        trace_kvm_s390_intercept_instruction(vcpu,
                                             vcpu->arch.sie_block->ipa,
                                             vcpu->arch.sie_block->ipb);
-       handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8];
-       if (handler)
-               return handler(vcpu);
-       return -EOPNOTSUPP;
+
+       switch (vcpu->arch.sie_block->ipa >> 8) {
+       case 0x01:
+               return kvm_s390_handle_01(vcpu);
+       case 0x82:
+               return kvm_s390_handle_lpsw(vcpu);
+       case 0x83:
+               return kvm_s390_handle_diag(vcpu);
+       case 0xaa:
+               return kvm_s390_handle_aa(vcpu);
+       case 0xae:
+               return kvm_s390_handle_sigp(vcpu);
+       case 0xb2:
+               return kvm_s390_handle_b2(vcpu);
+       case 0xb6:
+               return kvm_s390_handle_stctl(vcpu);
+       case 0xb7:
+               return kvm_s390_handle_lctl(vcpu);
+       case 0xb9:
+               return kvm_s390_handle_b9(vcpu);
+       case 0xe3:
+               return kvm_s390_handle_e3(vcpu);
+       case 0xe5:
+               return kvm_s390_handle_e5(vcpu);
+       case 0xeb:
+               return kvm_s390_handle_eb(vcpu);
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static int inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu)
index aabf46f5f883d44d71cddc88b5ef28ec677ff200..b04616b57a94713a24ed19b142adb94b8c96e748 100644 (file)
@@ -169,8 +169,15 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
 
 static int ckc_irq_pending(struct kvm_vcpu *vcpu)
 {
-       if (vcpu->arch.sie_block->ckc >= kvm_s390_get_tod_clock_fast(vcpu->kvm))
+       const u64 now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
+       const u64 ckc = vcpu->arch.sie_block->ckc;
+
+       if (vcpu->arch.sie_block->gcr[0] & 0x0020000000000000ul) {
+               if ((s64)ckc >= (s64)now)
+                       return 0;
+       } else if (ckc >= now) {
                return 0;
+       }
        return ckc_interrupts_enabled(vcpu);
 }
 
@@ -187,12 +194,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
        return kvm_s390_get_cpu_timer(vcpu) >> 63;
 }
 
-static inline int is_ioirq(unsigned long irq_type)
-{
-       return ((irq_type >= IRQ_PEND_IO_ISC_7) &&
-               (irq_type <= IRQ_PEND_IO_ISC_0));
-}
-
 static uint64_t isc_to_isc_bits(int isc)
 {
        return (0x80 >> isc) << 24;
@@ -236,10 +237,15 @@ static inline int kvm_s390_gisa_tac_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gis
        return test_and_clear_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
 }
 
-static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
+static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu)
 {
        return vcpu->kvm->arch.float_int.pending_irqs |
-               vcpu->arch.local_int.pending_irqs |
+               vcpu->arch.local_int.pending_irqs;
+}
+
+static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
+{
+       return pending_irqs_no_gisa(vcpu) |
                kvm_s390_gisa_get_ipm(vcpu->kvm->arch.gisa) << IRQ_PEND_IO_ISC_7;
 }
 
@@ -337,7 +343,7 @@ static void __reset_intercept_indicators(struct kvm_vcpu *vcpu)
 
 static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
 {
-       if (!(pending_irqs(vcpu) & IRQ_PEND_IO_MASK))
+       if (!(pending_irqs_no_gisa(vcpu) & IRQ_PEND_IO_MASK))
                return;
        else if (psw_ioint_disabled(vcpu))
                kvm_s390_set_cpuflags(vcpu, CPUSTAT_IO_INT);
@@ -1011,24 +1017,6 @@ out:
        return rc;
 }
 
-typedef int (*deliver_irq_t)(struct kvm_vcpu *vcpu);
-
-static const deliver_irq_t deliver_irq_funcs[] = {
-       [IRQ_PEND_MCHK_EX]        = __deliver_machine_check,
-       [IRQ_PEND_MCHK_REP]       = __deliver_machine_check,
-       [IRQ_PEND_PROG]           = __deliver_prog,
-       [IRQ_PEND_EXT_EMERGENCY]  = __deliver_emergency_signal,
-       [IRQ_PEND_EXT_EXTERNAL]   = __deliver_external_call,
-       [IRQ_PEND_EXT_CLOCK_COMP] = __deliver_ckc,
-       [IRQ_PEND_EXT_CPU_TIMER]  = __deliver_cpu_timer,
-       [IRQ_PEND_RESTART]        = __deliver_restart,
-       [IRQ_PEND_SET_PREFIX]     = __deliver_set_prefix,
-       [IRQ_PEND_PFAULT_INIT]    = __deliver_pfault_init,
-       [IRQ_PEND_EXT_SERVICE]    = __deliver_service,
-       [IRQ_PEND_PFAULT_DONE]    = __deliver_pfault_done,
-       [IRQ_PEND_VIRTIO]         = __deliver_virtio,
-};
-
 /* Check whether an external call is pending (deliverable or not) */
 int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu)
 {
@@ -1066,13 +1054,19 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 
 static u64 __calculate_sltime(struct kvm_vcpu *vcpu)
 {
-       u64 now, cputm, sltime = 0;
+       const u64 now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
+       const u64 ckc = vcpu->arch.sie_block->ckc;
+       u64 cputm, sltime = 0;
 
        if (ckc_interrupts_enabled(vcpu)) {
-               now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
-               sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
-               /* already expired or overflow? */
-               if (!sltime || vcpu->arch.sie_block->ckc <= now)
+               if (vcpu->arch.sie_block->gcr[0] & 0x0020000000000000ul) {
+                       if ((s64)now < (s64)ckc)
+                               sltime = tod_to_ns((s64)ckc - (s64)now);
+               } else if (now < ckc) {
+                       sltime = tod_to_ns(ckc - now);
+               }
+               /* already expired */
+               if (!sltime)
                        return 0;
                if (cpu_timer_interrupts_enabled(vcpu)) {
                        cputm = kvm_s390_get_cpu_timer(vcpu);
@@ -1192,7 +1186,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
 int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
 {
        struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
-       deliver_irq_t func;
        int rc = 0;
        unsigned long irq_type;
        unsigned long irqs;
@@ -1212,16 +1205,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
        while ((irqs = deliverable_irqs(vcpu)) && !rc) {
                /* bits are in the reverse order of interrupt priority */
                irq_type = find_last_bit(&irqs, IRQ_PEND_COUNT);
-               if (is_ioirq(irq_type)) {
+               switch (irq_type) {
+               case IRQ_PEND_IO_ISC_0:
+               case IRQ_PEND_IO_ISC_1:
+               case IRQ_PEND_IO_ISC_2:
+               case IRQ_PEND_IO_ISC_3:
+               case IRQ_PEND_IO_ISC_4:
+               case IRQ_PEND_IO_ISC_5:
+               case IRQ_PEND_IO_ISC_6:
+               case IRQ_PEND_IO_ISC_7:
                        rc = __deliver_io(vcpu, irq_type);
-               } else {
-                       func = deliver_irq_funcs[irq_type];
-                       if (!func) {
-                               WARN_ON_ONCE(func == NULL);
-                               clear_bit(irq_type, &li->pending_irqs);
-                               continue;
-                       }
-                       rc = func(vcpu);
+                       break;
+               case IRQ_PEND_MCHK_EX:
+               case IRQ_PEND_MCHK_REP:
+                       rc = __deliver_machine_check(vcpu);
+                       break;
+               case IRQ_PEND_PROG:
+                       rc = __deliver_prog(vcpu);
+                       break;
+               case IRQ_PEND_EXT_EMERGENCY:
+                       rc = __deliver_emergency_signal(vcpu);
+                       break;
+               case IRQ_PEND_EXT_EXTERNAL:
+                       rc = __deliver_external_call(vcpu);
+                       break;
+               case IRQ_PEND_EXT_CLOCK_COMP:
+                       rc = __deliver_ckc(vcpu);
+                       break;
+               case IRQ_PEND_EXT_CPU_TIMER:
+                       rc = __deliver_cpu_timer(vcpu);
+                       break;
+               case IRQ_PEND_RESTART:
+                       rc = __deliver_restart(vcpu);
+                       break;
+               case IRQ_PEND_SET_PREFIX:
+                       rc = __deliver_set_prefix(vcpu);
+                       break;
+               case IRQ_PEND_PFAULT_INIT:
+                       rc = __deliver_pfault_init(vcpu);
+                       break;
+               case IRQ_PEND_EXT_SERVICE:
+                       rc = __deliver_service(vcpu);
+                       break;
+               case IRQ_PEND_PFAULT_DONE:
+                       rc = __deliver_pfault_done(vcpu);
+                       break;
+               case IRQ_PEND_VIRTIO:
+                       rc = __deliver_virtio(vcpu);
+                       break;
+               default:
+                       WARN_ONCE(1, "Unknown pending irq type %ld", irq_type);
+                       clear_bit(irq_type, &li->pending_irqs);
                }
        }
 
@@ -1701,7 +1735,8 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
                kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT);
                break;
        case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
-               kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
+               if (!(type & KVM_S390_INT_IO_AI_MASK && kvm->arch.gisa))
+                       kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
                break;
        default:
                kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_EXT_INT);
index ba4c7092335ad254fe0d385b99aa231dbecd2d53..339ac0964590a1337935ea55ee0cbc7d7c2e441e 100644 (file)
@@ -86,6 +86,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
        { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
        { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
+       { "deliver_io_interrupt", VCPU_STAT(deliver_io_int) },
        { "exit_wait_state", VCPU_STAT(exit_wait_state) },
        { "instruction_epsw", VCPU_STAT(instruction_epsw) },
        { "instruction_gs", VCPU_STAT(instruction_gs) },
@@ -179,6 +180,28 @@ int kvm_arch_hardware_enable(void)
 static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start,
                              unsigned long end);
 
+static void kvm_clock_sync_scb(struct kvm_s390_sie_block *scb, u64 delta)
+{
+       u8 delta_idx = 0;
+
+       /*
+        * The TOD jumps by delta, we have to compensate this by adding
+        * -delta to the epoch.
+        */
+       delta = -delta;
+
+       /* sign-extension - we're adding to signed values below */
+       if ((s64)delta < 0)
+               delta_idx = -1;
+
+       scb->epoch += delta;
+       if (scb->ecd & ECD_MEF) {
+               scb->epdx += delta_idx;
+               if (scb->epoch < delta)
+                       scb->epdx += 1;
+       }
+}
+
 /*
  * This callback is executed during stop_machine(). All CPUs are therefore
  * temporarily stopped. In order not to change guest behavior, we have to
@@ -194,13 +217,17 @@ static int kvm_clock_sync(struct notifier_block *notifier, unsigned long val,
        unsigned long long *delta = v;
 
        list_for_each_entry(kvm, &vm_list, vm_list) {
-               kvm->arch.epoch -= *delta;
                kvm_for_each_vcpu(i, vcpu, kvm) {
-                       vcpu->arch.sie_block->epoch -= *delta;
+                       kvm_clock_sync_scb(vcpu->arch.sie_block, *delta);
+                       if (i == 0) {
+                               kvm->arch.epoch = vcpu->arch.sie_block->epoch;
+                               kvm->arch.epdx = vcpu->arch.sie_block->epdx;
+                       }
                        if (vcpu->arch.cputm_enabled)
                                vcpu->arch.cputm_start += *delta;
                        if (vcpu->arch.vsie_block)
-                               vcpu->arch.vsie_block->epoch -= *delta;
+                               kvm_clock_sync_scb(vcpu->arch.vsie_block,
+                                                  *delta);
                }
        }
        return NOTIFY_OK;
@@ -902,12 +929,9 @@ static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr)
        if (copy_from_user(&gtod, (void __user *)attr->addr, sizeof(gtod)))
                return -EFAULT;
 
-       if (test_kvm_facility(kvm, 139))
-               kvm_s390_set_tod_clock_ext(kvm, &gtod);
-       else if (gtod.epoch_idx == 0)
-               kvm_s390_set_tod_clock(kvm, gtod.tod);
-       else
+       if (!test_kvm_facility(kvm, 139) && gtod.epoch_idx)
                return -EINVAL;
+       kvm_s390_set_tod_clock(kvm, &gtod);
 
        VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx",
                gtod.epoch_idx, gtod.tod);
@@ -932,13 +956,14 @@ static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
 
 static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
 {
-       u64 gtod;
+       struct kvm_s390_vm_tod_clock gtod = { 0 };
 
-       if (copy_from_user(&gtod, (void __user *)attr->addr, sizeof(gtod)))
+       if (copy_from_user(&gtod.tod, (void __user *)attr->addr,
+                          sizeof(gtod.tod)))
                return -EFAULT;
 
-       kvm_s390_set_tod_clock(kvm, gtod);
-       VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod);
+       kvm_s390_set_tod_clock(kvm, &gtod);
+       VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod.tod);
        return 0;
 }
 
@@ -2122,6 +2147,7 @@ static void sca_add_vcpu(struct kvm_vcpu *vcpu)
                /* we still need the basic sca for the ipte control */
                vcpu->arch.sie_block->scaoh = (__u32)(((__u64)sca) >> 32);
                vcpu->arch.sie_block->scaol = (__u32)(__u64)sca;
+               return;
        }
        read_lock(&vcpu->kvm->arch.sca_lock);
        if (vcpu->kvm->arch.use_esca) {
@@ -2389,6 +2415,7 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
        mutex_lock(&vcpu->kvm->lock);
        preempt_disable();
        vcpu->arch.sie_block->epoch = vcpu->kvm->arch.epoch;
+       vcpu->arch.sie_block->epdx = vcpu->kvm->arch.epdx;
        preempt_enable();
        mutex_unlock(&vcpu->kvm->lock);
        if (!kvm_is_ucontrol(vcpu->kvm)) {
@@ -3021,8 +3048,8 @@ retry:
        return 0;
 }
 
-void kvm_s390_set_tod_clock_ext(struct kvm *kvm,
-                                const struct kvm_s390_vm_tod_clock *gtod)
+void kvm_s390_set_tod_clock(struct kvm *kvm,
+                           const struct kvm_s390_vm_tod_clock *gtod)
 {
        struct kvm_vcpu *vcpu;
        struct kvm_s390_tod_clock_ext htod;
@@ -3034,10 +3061,12 @@ void kvm_s390_set_tod_clock_ext(struct kvm *kvm,
        get_tod_clock_ext((char *)&htod);
 
        kvm->arch.epoch = gtod->tod - htod.tod;
-       kvm->arch.epdx = gtod->epoch_idx - htod.epoch_idx;
-
-       if (kvm->arch.epoch > gtod->tod)
-               kvm->arch.epdx -= 1;
+       kvm->arch.epdx = 0;
+       if (test_kvm_facility(kvm, 139)) {
+               kvm->arch.epdx = gtod->epoch_idx - htod.epoch_idx;
+               if (kvm->arch.epoch > gtod->tod)
+                       kvm->arch.epdx -= 1;
+       }
 
        kvm_s390_vcpu_block_all(kvm);
        kvm_for_each_vcpu(i, vcpu, kvm) {
@@ -3050,22 +3079,6 @@ void kvm_s390_set_tod_clock_ext(struct kvm *kvm,
        mutex_unlock(&kvm->lock);
 }
 
-void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod)
-{
-       struct kvm_vcpu *vcpu;
-       int i;
-
-       mutex_lock(&kvm->lock);
-       preempt_disable();
-       kvm->arch.epoch = tod - get_tod_clock();
-       kvm_s390_vcpu_block_all(kvm);
-       kvm_for_each_vcpu(i, vcpu, kvm)
-               vcpu->arch.sie_block->epoch = kvm->arch.epoch;
-       kvm_s390_vcpu_unblock_all(kvm);
-       preempt_enable();
-       mutex_unlock(&kvm->lock);
-}
-
 /**
  * kvm_arch_fault_in_page - fault-in guest page if necessary
  * @vcpu: The corresponding virtual cpu
index bd31b37b0e6f83905e7204b2eb439050aaeb1187..f55ac0ef99ea70bf3fb1d8f7eb7e303eb405b2b4 100644 (file)
@@ -19,8 +19,6 @@
 #include <asm/processor.h>
 #include <asm/sclp.h>
 
-typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
-
 /* Transactional Memory Execution related macros */
 #define IS_TE_ENABLED(vcpu)    ((vcpu->arch.sie_block->ecb & ECB_TE))
 #define TDB_FORMAT1            1
@@ -283,9 +281,8 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu);
 
 /* implemented in kvm-s390.c */
-void kvm_s390_set_tod_clock_ext(struct kvm *kvm,
-                                const struct kvm_s390_vm_tod_clock *gtod);
-void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod);
+void kvm_s390_set_tod_clock(struct kvm *kvm,
+                           const struct kvm_s390_vm_tod_clock *gtod);
 long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
 int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
 int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr);
index c4c4e157c03631a1d745ccafdfec111a6a08a49e..f0b4185158afcb229cac5b06f23f5664afffebec 100644 (file)
@@ -85,9 +85,10 @@ int kvm_s390_handle_e3(struct kvm_vcpu *vcpu)
 /* Handle SCK (SET CLOCK) interception */
 static int handle_set_clock(struct kvm_vcpu *vcpu)
 {
+       struct kvm_s390_vm_tod_clock gtod = { 0 };
        int rc;
        u8 ar;
-       u64 op2, val;
+       u64 op2;
 
        vcpu->stat.instruction_sck++;
 
@@ -97,12 +98,12 @@ static int handle_set_clock(struct kvm_vcpu *vcpu)
        op2 = kvm_s390_get_base_disp_s(vcpu, &ar);
        if (op2 & 7)    /* Operand must be on a doubleword boundary */
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
-       rc = read_guest(vcpu, op2, ar, &val, sizeof(val));
+       rc = read_guest(vcpu, op2, ar, &gtod.tod, sizeof(gtod.tod));
        if (rc)
                return kvm_s390_inject_prog_cond(vcpu, rc);
 
-       VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", val);
-       kvm_s390_set_tod_clock(vcpu->kvm, val);
+       VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", gtod.tod);
+       kvm_s390_set_tod_clock(vcpu->kvm, &gtod);
 
        kvm_s390_set_psw_cc(vcpu, 0);
        return 0;
@@ -795,55 +796,60 @@ out:
        return rc;
 }
 
-static const intercept_handler_t b2_handlers[256] = {
-       [0x02] = handle_stidp,
-       [0x04] = handle_set_clock,
-       [0x10] = handle_set_prefix,
-       [0x11] = handle_store_prefix,
-       [0x12] = handle_store_cpu_address,
-       [0x14] = kvm_s390_handle_vsie,
-       [0x21] = handle_ipte_interlock,
-       [0x29] = handle_iske,
-       [0x2a] = handle_rrbe,
-       [0x2b] = handle_sske,
-       [0x2c] = handle_test_block,
-       [0x30] = handle_io_inst,
-       [0x31] = handle_io_inst,
-       [0x32] = handle_io_inst,
-       [0x33] = handle_io_inst,
-       [0x34] = handle_io_inst,
-       [0x35] = handle_io_inst,
-       [0x36] = handle_io_inst,
-       [0x37] = handle_io_inst,
-       [0x38] = handle_io_inst,
-       [0x39] = handle_io_inst,
-       [0x3a] = handle_io_inst,
-       [0x3b] = handle_io_inst,
-       [0x3c] = handle_io_inst,
-       [0x50] = handle_ipte_interlock,
-       [0x56] = handle_sthyi,
-       [0x5f] = handle_io_inst,
-       [0x74] = handle_io_inst,
-       [0x76] = handle_io_inst,
-       [0x7d] = handle_stsi,
-       [0xb1] = handle_stfl,
-       [0xb2] = handle_lpswe,
-};
-
 int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
 {
-       intercept_handler_t handler;
-
-       /*
-        * A lot of B2 instructions are priviledged. Here we check for
-        * the privileged ones, that we can handle in the kernel.
-        * Anything else goes to userspace.
-        */
-       handler = b2_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-       if (handler)
-               return handler(vcpu);
-
-       return -EOPNOTSUPP;
+       switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+       case 0x02:
+               return handle_stidp(vcpu);
+       case 0x04:
+               return handle_set_clock(vcpu);
+       case 0x10:
+               return handle_set_prefix(vcpu);
+       case 0x11:
+               return handle_store_prefix(vcpu);
+       case 0x12:
+               return handle_store_cpu_address(vcpu);
+       case 0x14:
+               return kvm_s390_handle_vsie(vcpu);
+       case 0x21:
+       case 0x50:
+               return handle_ipte_interlock(vcpu);
+       case 0x29:
+               return handle_iske(vcpu);
+       case 0x2a:
+               return handle_rrbe(vcpu);
+       case 0x2b:
+               return handle_sske(vcpu);
+       case 0x2c:
+               return handle_test_block(vcpu);
+       case 0x30:
+       case 0x31:
+       case 0x32:
+       case 0x33:
+       case 0x34:
+       case 0x35:
+       case 0x36:
+       case 0x37:
+       case 0x38:
+       case 0x39:
+       case 0x3a:
+       case 0x3b:
+       case 0x3c:
+       case 0x5f:
+       case 0x74:
+       case 0x76:
+               return handle_io_inst(vcpu);
+       case 0x56:
+               return handle_sthyi(vcpu);
+       case 0x7d:
+               return handle_stsi(vcpu);
+       case 0xb1:
+               return handle_stfl(vcpu);
+       case 0xb2:
+               return handle_lpswe(vcpu);
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static int handle_epsw(struct kvm_vcpu *vcpu)
@@ -1105,25 +1111,22 @@ static int handle_essa(struct kvm_vcpu *vcpu)
        return 0;
 }
 
-static const intercept_handler_t b9_handlers[256] = {
-       [0x8a] = handle_ipte_interlock,
-       [0x8d] = handle_epsw,
-       [0x8e] = handle_ipte_interlock,
-       [0x8f] = handle_ipte_interlock,
-       [0xab] = handle_essa,
-       [0xaf] = handle_pfmf,
-};
-
 int kvm_s390_handle_b9(struct kvm_vcpu *vcpu)
 {
-       intercept_handler_t handler;
-
-       /* This is handled just as for the B2 instructions. */
-       handler = b9_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-       if (handler)
-               return handler(vcpu);
-
-       return -EOPNOTSUPP;
+       switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+       case 0x8a:
+       case 0x8e:
+       case 0x8f:
+               return handle_ipte_interlock(vcpu);
+       case 0x8d:
+               return handle_epsw(vcpu);
+       case 0xab:
+               return handle_essa(vcpu);
+       case 0xaf:
+               return handle_pfmf(vcpu);
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu)
@@ -1271,22 +1274,20 @@ static int handle_stctg(struct kvm_vcpu *vcpu)
        return rc ? kvm_s390_inject_prog_cond(vcpu, rc) : 0;
 }
 
-static const intercept_handler_t eb_handlers[256] = {
-       [0x2f] = handle_lctlg,
-       [0x25] = handle_stctg,
-       [0x60] = handle_ri,
-       [0x61] = handle_ri,
-       [0x62] = handle_ri,
-};
-
 int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
 {
-       intercept_handler_t handler;
-
-       handler = eb_handlers[vcpu->arch.sie_block->ipb & 0xff];
-       if (handler)
-               return handler(vcpu);
-       return -EOPNOTSUPP;
+       switch (vcpu->arch.sie_block->ipb & 0x000000ff) {
+       case 0x25:
+               return handle_stctg(vcpu);
+       case 0x2f:
+               return handle_lctlg(vcpu);
+       case 0x60:
+       case 0x61:
+       case 0x62:
+               return handle_ri(vcpu);
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static int handle_tprot(struct kvm_vcpu *vcpu)
@@ -1346,10 +1347,12 @@ out_unlock:
 
 int kvm_s390_handle_e5(struct kvm_vcpu *vcpu)
 {
-       /* For e5xx... instructions we only handle TPROT */
-       if ((vcpu->arch.sie_block->ipa & 0x00ff) == 0x01)
+       switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+       case 0x01:
                return handle_tprot(vcpu);
-       return -EOPNOTSUPP;
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static int handle_sckpf(struct kvm_vcpu *vcpu)
@@ -1380,17 +1383,14 @@ static int handle_ptff(struct kvm_vcpu *vcpu)
        return 0;
 }
 
-static const intercept_handler_t x01_handlers[256] = {
-       [0x04] = handle_ptff,
-       [0x07] = handle_sckpf,
-};
-
 int kvm_s390_handle_01(struct kvm_vcpu *vcpu)
 {
-       intercept_handler_t handler;
-
-       handler = x01_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-       if (handler)
-               return handler(vcpu);
-       return -EOPNOTSUPP;
+       switch (vcpu->arch.sie_block->ipa & 0x00ff) {
+       case 0x04:
+               return handle_ptff(vcpu);
+       case 0x07:
+               return handle_sckpf(vcpu);
+       default:
+               return -EOPNOTSUPP;
+       }
 }
index ec772700ff9659350543534272a92eb531bbd181..8961e3970901d4b06c87b20f147115b683ad5170 100644 (file)
@@ -821,6 +821,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
 {
        struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
        struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
+       int guest_bp_isolation;
        int rc;
 
        handle_last_fault(vcpu, vsie_page);
@@ -831,6 +832,20 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
                s390_handle_mcck();
 
        srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
+
+       /* save current guest state of bp isolation override */
+       guest_bp_isolation = test_thread_flag(TIF_ISOLATE_BP_GUEST);
+
+       /*
+        * The guest is running with BPBC, so we have to force it on for our
+        * nested guest. This is done by enabling BPBC globally, so the BPBC
+        * control in the SCB (which the nested guest can modify) is simply
+        * ignored.
+        */
+       if (test_kvm_facility(vcpu->kvm, 82) &&
+           vcpu->arch.sie_block->fpf & FPF_BPBC)
+               set_thread_flag(TIF_ISOLATE_BP_GUEST);
+
        local_irq_disable();
        guest_enter_irqoff();
        local_irq_enable();
@@ -840,6 +855,11 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
        local_irq_disable();
        guest_exit_irqoff();
        local_irq_enable();
+
+       /* restore guest state for bp isolation override */
+       if (!guest_bp_isolation)
+               clear_thread_flag(TIF_ISOLATE_BP_GUEST);
+
        vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 
        if (rc == -EINTR) {
index 715def00a436c21a1822e18251b83f6afe86941a..01d0f7fb14cce7b8e0afc17798d6cc8a1d2938d1 100644 (file)
@@ -1 +1,3 @@
-obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
+ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
+obj-y += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
+endif
index 6bf594ace663ec82f746132b4f62fc351bf5160c..8767e45f1b2b70953583a7a7157707696466d407 100644 (file)
@@ -430,6 +430,8 @@ config SPARC_LEON
        depends on SPARC32
        select USB_EHCI_BIG_ENDIAN_MMIO
        select USB_EHCI_BIG_ENDIAN_DESC
+       select USB_UHCI_BIG_ENDIAN_MMIO
+       select USB_UHCI_BIG_ENDIAN_DESC
        ---help---
          If you say Y here if you are running on a SPARC-LEON processor.
          The LEON processor is a synthesizable VHDL model of the
index 6f17528356b2f71c8a71764a0ac2715a3398a33f..ea53e418f6c045763ff030a1dc2fa73d524c38b8 100644 (file)
@@ -9,10 +9,14 @@
 void do_BUG(const char *file, int line);
 #define BUG() do {                                     \
        do_BUG(__FILE__, __LINE__);                     \
+       barrier_before_unreachable();                   \
        __builtin_trap();                               \
 } while (0)
 #else
-#define BUG()          __builtin_trap()
+#define BUG() do {                                     \
+       barrier_before_unreachable();                   \
+       __builtin_trap();                               \
+} while (0)
 #endif
 
 #define HAVE_ARCH_BUG
index 847ddffbf38ad797afbdef3777cdfea552f282d3..b5cfab7116514814cd244fb89f485d75c104e946 100644 (file)
@@ -163,13 +163,10 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
        pte_unmap(pte);
 }
 
-void set_pmd_at(struct mm_struct *mm, unsigned long addr,
-               pmd_t *pmdp, pmd_t pmd)
-{
-       pmd_t orig = *pmdp;
-
-       *pmdp = pmd;
 
+static void __set_pmd_acct(struct mm_struct *mm, unsigned long addr,
+                          pmd_t orig, pmd_t pmd)
+{
        if (mm == &init_mm)
                return;
 
@@ -219,6 +216,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
        }
 }
 
+void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+               pmd_t *pmdp, pmd_t pmd)
+{
+       pmd_t orig = *pmdp;
+
+       *pmdp = pmd;
+       __set_pmd_acct(mm, addr, orig, pmd);
+}
+
 static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
                unsigned long address, pmd_t *pmdp, pmd_t pmd)
 {
@@ -227,6 +233,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
        do {
                old = *pmdp;
        } while (cmpxchg64(&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd);
+       __set_pmd_acct(vma->vm_mm, address, old, pmd);
 
        return old;
 }
index aff152c87cf4ba62ed26ed6b7eb567b576dd84fd..5a82bac5e0bc7985529aa537e981997109945309 100644 (file)
@@ -1,6 +1,7 @@
 boot/compressed/vmlinux
 tools/test_get_len
 tools/insn_sanity
+tools/insn_decoder_test
 purgatory/kexec-purgatory.c
 purgatory/purgatory.ro
 
index 63bf349b2b24a8807c4f65869af50bab99e4c2f7..0fa71a78ec99a9ae2e4dcbbadfa74773a5ebc031 100644 (file)
@@ -423,12 +423,6 @@ config X86_MPPARSE
          For old smp systems that do not have proper acpi support. Newer systems
          (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
 
-config X86_BIGSMP
-       bool "Support for big SMP systems with more than 8 CPUs"
-       depends on X86_32 && SMP
-       ---help---
-         This option is needed for the systems that have more than 8 CPUs
-
 config GOLDFISH
        def_bool y
        depends on X86_GOLDFISH
@@ -436,6 +430,7 @@ config GOLDFISH
 config RETPOLINE
        bool "Avoid speculative indirect branches in kernel"
        default y
+       select STACK_VALIDATION if HAVE_STACK_VALIDATION
        help
          Compile kernel with the retpoline compiler options to guard against
          kernel-to-user data leaks by avoiding speculative indirect
@@ -460,6 +455,12 @@ config INTEL_RDT
          Say N if unsure.
 
 if X86_32
+config X86_BIGSMP
+       bool "Support for big SMP systems with more than 8 CPUs"
+       depends on SMP
+       ---help---
+         This option is needed for the systems that have more than 8 CPUs
+
 config X86_EXTENDED_PLATFORM
        bool "Support for extended (non-PC) x86 platforms"
        default y
@@ -949,25 +950,66 @@ config MAXSMP
          Enable maximum number of CPUS and NUMA Nodes for this architecture.
          If unsure, say N.
 
+#
+# The maximum number of CPUs supported:
+#
+# The main config value is NR_CPUS, which defaults to NR_CPUS_DEFAULT,
+# and which can be configured interactively in the
+# [NR_CPUS_RANGE_BEGIN ... NR_CPUS_RANGE_END] range.
+#
+# The ranges are different on 32-bit and 64-bit kernels, depending on
+# hardware capabilities and scalability features of the kernel.
+#
+# ( If MAXSMP is enabled we just use the highest possible value and disable
+#   interactive configuration. )
+#
+
+config NR_CPUS_RANGE_BEGIN
+       int
+       default NR_CPUS_RANGE_END if MAXSMP
+       default    1 if !SMP
+       default    2
+
+config NR_CPUS_RANGE_END
+       int
+       depends on X86_32
+       default   64 if  SMP &&  X86_BIGSMP
+       default    8 if  SMP && !X86_BIGSMP
+       default    1 if !SMP
+
+config NR_CPUS_RANGE_END
+       int
+       depends on X86_64
+       default 8192 if  SMP && ( MAXSMP ||  CPUMASK_OFFSTACK)
+       default  512 if  SMP && (!MAXSMP && !CPUMASK_OFFSTACK)
+       default    1 if !SMP
+
+config NR_CPUS_DEFAULT
+       int
+       depends on X86_32
+       default   32 if  X86_BIGSMP
+       default    8 if  SMP
+       default    1 if !SMP
+
+config NR_CPUS_DEFAULT
+       int
+       depends on X86_64
+       default 8192 if  MAXSMP
+       default   64 if  SMP
+       default    1 if !SMP
+
 config NR_CPUS
        int "Maximum number of CPUs" if SMP && !MAXSMP
-       range 2 8 if SMP && X86_32 && !X86_BIGSMP
-       range 2 64 if SMP && X86_32 && X86_BIGSMP
-       range 2 512 if SMP && !MAXSMP && !CPUMASK_OFFSTACK && X86_64
-       range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64
-       default "1" if !SMP
-       default "8192" if MAXSMP
-       default "32" if SMP && X86_BIGSMP
-       default "8" if SMP && X86_32
-       default "64" if SMP
+       range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END
+       default NR_CPUS_DEFAULT
        ---help---
          This allows you to specify the maximum number of CPUs which this
          kernel will support.  If CPUMASK_OFFSTACK is enabled, the maximum
          supported value is 8192, otherwise the maximum value is 512.  The
          minimum value which makes sense is 2.
 
-         This is purely to save memory - each supported CPU adds
-         approximately eight kilobytes to the kernel image.
+         This is purely to save memory: each supported CPU adds about 8KB
+         to the kernel image.
 
 config SCHED_SMT
        bool "SMT (Hyperthreading) scheduler support"
@@ -1363,7 +1405,7 @@ config HIGHMEM4G
 
 config HIGHMEM64G
        bool "64GB"
-       depends on !M486
+       depends on !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
        select X86_PAE
        ---help---
          Select this if you have a 32-bit processor and more than 4
@@ -2265,7 +2307,7 @@ choice
          it can be used to assist security vulnerability exploitation.
 
          This setting can be changed at boot time via the kernel command
-         line parameter vsyscall=[native|emulate|none].
+         line parameter vsyscall=[emulate|none].
 
          On a system with recent enough glibc (2.14 or newer) and no
          static binaries, you can say None without a performance penalty
@@ -2273,15 +2315,6 @@ choice
 
          If unsure, select "Emulate".
 
-       config LEGACY_VSYSCALL_NATIVE
-               bool "Native"
-               help
-                 Actual executable code is located in the fixed vsyscall
-                 address mapping, implementing time() efficiently. Since
-                 this makes the mapping executable, it can be used during
-                 security vulnerability exploitation (traditionally as
-                 ROP gadgets). This configuration is not recommended.
-
        config LEGACY_VSYSCALL_EMULATE
                bool "Emulate"
                help
index 65a9a4716e34f55394d057335629d0b32ec55ada..638411f22267aa34bd6ddda10eeccded1a1f6b48 100644 (file)
@@ -315,19 +315,6 @@ config X86_L1_CACHE_SHIFT
        default "4" if MELAN || M486 || MGEODEGX1
        default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 
-config X86_PPRO_FENCE
-       bool "PentiumPro memory ordering errata workaround"
-       depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
-       ---help---
-         Old PentiumPro multiprocessor systems had errata that could cause
-         memory operations to violate the x86 ordering standard in rare cases.
-         Enabling this option will attempt to work around some (but not all)
-         occurrences of this problem, at the cost of much heavier spinlock and
-         memory barrier operations.
-
-         If unsure, say n here. Even distro kernels should think twice before
-         enabling this: there are few systems, and an unlikely bug.
-
 config X86_F00F_BUG
        def_bool y
        depends on M586MMX || M586TSC || M586 || M486
@@ -374,7 +361,7 @@ config X86_TSC
 
 config X86_CMPXCHG64
        def_bool y
-       depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
+       depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8
 
 # this should be set for all -march=.. options where the compiler
 # generates cmov.
@@ -385,7 +372,7 @@ config X86_CMOV
 config X86_MINIMUM_CPU_FAMILY
        int
        default "64" if X86_64
-       default "6" if X86_32 && X86_P6_NOP
+       default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8)
        default "5" if X86_32 && X86_CMPXCHG64
        default "4"
 
index fad55160dcb94a28e60d537d3d69d471a1e10e2e..1c4d012550ec5fab1e2ae26b9cf8a67168da75fd 100644 (file)
@@ -223,6 +223,15 @@ KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr)
 
 LDFLAGS := -m elf_$(UTS_MACHINE)
 
+#
+# The 64-bit kernel must be aligned to 2MB.  Pass -z max-page-size=0x200000 to
+# the linker to force 2MB page size regardless of the default page size used
+# by the linker.
+#
+ifdef CONFIG_X86_64
+LDFLAGS += $(call ld-option, -z max-page-size=0x200000)
+endif
+
 # Speed up the build
 KBUILD_CFLAGS += -pipe
 # Workaround for a gcc prelease that unfortunately was shipped in a suse release
@@ -232,10 +241,9 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
 
 # Avoid indirect branches in kernel to deal with Spectre
 ifdef CONFIG_RETPOLINE
-    RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
-    ifneq ($(RETPOLINE_CFLAGS),)
-        KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE
-    endif
+ifneq ($(RETPOLINE_CFLAGS),)
+  KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE
+endif
 endif
 
 archscripts: scripts_basic
index 353e20c3f114f3132ef18dbc03e7a8110f4e22df..886a9115af6229d058cab4f0600ebd666fc9e6d3 100644 (file)
@@ -439,7 +439,7 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
        struct efi_uga_draw_protocol *uga = NULL, *first_uga;
        efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
        unsigned long nr_ugas;
-       u32 *handles = (u32 *)uga_handle;;
+       u32 *handles = (u32 *)uga_handle;
        efi_status_t status = EFI_INVALID_PARAMETER;
        int i;
 
@@ -484,7 +484,7 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)
        struct efi_uga_draw_protocol *uga = NULL, *first_uga;
        efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
        unsigned long nr_ugas;
-       u64 *handles = (u64 *)uga_handle;;
+       u64 *handles = (u64 *)uga_handle;
        efi_status_t status = EFI_INVALID_PARAMETER;
        int i;
 
index 98761a1576ceb5c21b2d8c7e98c1217fd48abb26..252fee32081662ce3bf21d71158969afc9c596b3 100644 (file)
@@ -309,6 +309,10 @@ static void parse_elf(void *output)
 
                switch (phdr->p_type) {
                case PT_LOAD:
+#ifdef CONFIG_X86_64
+                       if ((phdr->p_align % 0x200000) != 0)
+                               error("Alignment of LOAD segment isn't multiple of 2MB");
+#endif
 #ifdef CONFIG_RELOCATABLE
                        dest = output;
                        dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
index 36870b26067a73655b96d137c04977c8f392237d..d08805032f0193ab96dde00890a0502a9f2b24e6 100644 (file)
@@ -57,10 +57,12 @@ void sha512_mb_mgr_init_avx2(struct sha512_mb_mgr *state)
 {
        unsigned int j;
 
-       state->lens[0] = 0;
-       state->lens[1] = 1;
-       state->lens[2] = 2;
-       state->lens[3] = 3;
+       /* initially all lanes are unused */
+       state->lens[0] = 0xFFFFFFFF00000000;
+       state->lens[1] = 0xFFFFFFFF00000001;
+       state->lens[2] = 0xFFFFFFFF00000002;
+       state->lens[3] = 0xFFFFFFFF00000003;
+
        state->unused_lanes = 0xFF03020100;
        for (j = 0; j < 4; j++)
                state->ldata[j].job_in_lane = NULL;
index 3f48f695d5e6ac6546a009c734fcac517564b24d..be63330c551129cb6bf0fcf07d8bf6d4600cb098 100644 (file)
@@ -97,80 +97,78 @@ For 32-bit we have the following conventions - kernel is built with
 
 #define SIZEOF_PTREGS  21*8
 
-       .macro ALLOC_PT_GPREGS_ON_STACK
-       addq    $-(15*8), %rsp
-       .endm
-
-       .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1
-       .if \r11
-       movq %r11, 6*8+\offset(%rsp)
-       .endif
-       .if \r8910
-       movq %r10, 7*8+\offset(%rsp)
-       movq %r9,  8*8+\offset(%rsp)
-       movq %r8,  9*8+\offset(%rsp)
-       .endif
-       .if \rax
-       movq %rax, 10*8+\offset(%rsp)
+.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0
+       /*
+        * Push registers and sanitize registers of values that a
+        * speculation attack might otherwise want to exploit. The
+        * lower registers are likely clobbered well before they
+        * could be put to use in a speculative execution gadget.
+        * Interleave XOR with PUSH for better uop scheduling:
+        */
+       .if \save_ret
+       pushq   %rsi            /* pt_regs->si */
+       movq    8(%rsp), %rsi   /* temporarily store the return address in %rsi */
+       movq    %rdi, 8(%rsp)   /* pt_regs->di (overwriting original return address) */
+       .else
+       pushq   %rdi            /* pt_regs->di */
+       pushq   %rsi            /* pt_regs->si */
        .endif
-       .if \rcx
-       movq %rcx, 11*8+\offset(%rsp)
+       pushq   \rdx            /* pt_regs->dx */
+       pushq   %rcx            /* pt_regs->cx */
+       pushq   \rax            /* pt_regs->ax */
+       pushq   %r8             /* pt_regs->r8 */
+       xorl    %r8d, %r8d      /* nospec   r8 */
+       pushq   %r9             /* pt_regs->r9 */
+       xorl    %r9d, %r9d      /* nospec   r9 */
+       pushq   %r10            /* pt_regs->r10 */
+       xorl    %r10d, %r10d    /* nospec   r10 */
+       pushq   %r11            /* pt_regs->r11 */
+       xorl    %r11d, %r11d    /* nospec   r11*/
+       pushq   %rbx            /* pt_regs->rbx */
+       xorl    %ebx, %ebx      /* nospec   rbx*/
+       pushq   %rbp            /* pt_regs->rbp */
+       xorl    %ebp, %ebp      /* nospec   rbp*/
+       pushq   %r12            /* pt_regs->r12 */
+       xorl    %r12d, %r12d    /* nospec   r12*/
+       pushq   %r13            /* pt_regs->r13 */
+       xorl    %r13d, %r13d    /* nospec   r13*/
+       pushq   %r14            /* pt_regs->r14 */
+       xorl    %r14d, %r14d    /* nospec   r14*/
+       pushq   %r15            /* pt_regs->r15 */
+       xorl    %r15d, %r15d    /* nospec   r15*/
+       UNWIND_HINT_REGS
+       .if \save_ret
+       pushq   %rsi            /* return address on top of stack */
        .endif
-       movq %rdx, 12*8+\offset(%rsp)
-       movq %rsi, 13*8+\offset(%rsp)
-       movq %rdi, 14*8+\offset(%rsp)
-       UNWIND_HINT_REGS offset=\offset extra=0
-       .endm
-       .macro SAVE_C_REGS offset=0
-       SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1
-       .endm
-       .macro SAVE_C_REGS_EXCEPT_RAX_RCX offset=0
-       SAVE_C_REGS_HELPER \offset, 0, 0, 1, 1
-       .endm
-       .macro SAVE_C_REGS_EXCEPT_R891011
-       SAVE_C_REGS_HELPER 0, 1, 1, 0, 0
-       .endm
-       .macro SAVE_C_REGS_EXCEPT_RCX_R891011
-       SAVE_C_REGS_HELPER 0, 1, 0, 0, 0
-       .endm
-       .macro SAVE_C_REGS_EXCEPT_RAX_RCX_R11
-       SAVE_C_REGS_HELPER 0, 0, 0, 1, 0
-       .endm
-
-       .macro SAVE_EXTRA_REGS offset=0
-       movq %r15, 0*8+\offset(%rsp)
-       movq %r14, 1*8+\offset(%rsp)
-       movq %r13, 2*8+\offset(%rsp)
-       movq %r12, 3*8+\offset(%rsp)
-       movq %rbp, 4*8+\offset(%rsp)
-       movq %rbx, 5*8+\offset(%rsp)
-       UNWIND_HINT_REGS offset=\offset
-       .endm
-
-       .macro POP_EXTRA_REGS
+.endm
+
+.macro POP_REGS pop_rdi=1 skip_r11rcx=0
        popq %r15
        popq %r14
        popq %r13
        popq %r12
        popq %rbp
        popq %rbx
-       .endm
-
-       .macro POP_C_REGS
+       .if \skip_r11rcx
+       popq %rsi
+       .else
        popq %r11
+       .endif
        popq %r10
        popq %r9
        popq %r8
        popq %rax
+       .if \skip_r11rcx
+       popq %rsi
+       .else
        popq %rcx
+       .endif
        popq %rdx
        popq %rsi
+       .if \pop_rdi
        popq %rdi
-       .endm
-
-       .macro icebp
-       .byte 0xf1
-       .endm
+       .endif
+.endm
 
 /*
  * This is a sneaky trick to help the unwinder find pt_regs on the stack.  The
@@ -178,17 +176,12 @@ For 32-bit we have the following conventions - kernel is built with
  * is just setting the LSB, which makes it an invalid stack address and is also
  * a signal to the unwinder that it's a pt_regs pointer in disguise.
  *
- * NOTE: This macro must be used *after* SAVE_EXTRA_REGS because it corrupts
+ * NOTE: This macro must be used *after* PUSH_AND_CLEAR_REGS because it corrupts
  * the original rbp.
  */
 .macro ENCODE_FRAME_POINTER ptregs_offset=0
 #ifdef CONFIG_FRAME_POINTER
-       .if \ptregs_offset
-               leaq \ptregs_offset(%rsp), %rbp
-       .else
-               mov %rsp, %rbp
-       .endif
-       orq     $0x1, %rbp
+       leaq 1+\ptregs_offset(%rsp), %rbp
 #endif
 .endm
 
index 16c2c022540d42b9fc51ee7489383775bd319ac1..6ad064c8cf35e6fdfc9c384212a6f76c780ffd69 100644 (file)
@@ -252,8 +252,7 @@ ENTRY(__switch_to_asm)
         * exist, overwrite the RSB with entries which capture
         * speculative execution to prevent attack.
         */
-       /* Clobbers %ebx */
-       FILL_RETURN_BUFFER RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW
+       FILL_RETURN_BUFFER %ebx, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW
 #endif
 
        /* restore callee-saved registers */
index 30c8c5344c4a5dcfeb96d0711a322e50de33d324..18ed349b4f8379257daf9b31861912df9b411fec 100644 (file)
@@ -55,7 +55,7 @@ END(native_usergs_sysret64)
 
 .macro TRACE_IRQS_FLAGS flags:req
 #ifdef CONFIG_TRACE_IRQFLAGS
-       bt      $9, \flags              /* interrupts off? */
+       btl     $9, \flags              /* interrupts off? */
        jnc     1f
        TRACE_IRQS_ON
 1:
@@ -213,7 +213,7 @@ ENTRY(entry_SYSCALL_64)
 
        swapgs
        /*
-        * This path is not taken when PAGE_TABLE_ISOLATION is disabled so it
+        * This path is only taken when PAGE_TABLE_ISOLATION is disabled so it
         * is not required to switch CR3.
         */
        movq    %rsp, PER_CPU_VAR(rsp_scratch)
@@ -227,22 +227,8 @@ ENTRY(entry_SYSCALL_64)
        pushq   %rcx                            /* pt_regs->ip */
 GLOBAL(entry_SYSCALL_64_after_hwframe)
        pushq   %rax                            /* pt_regs->orig_ax */
-       pushq   %rdi                            /* pt_regs->di */
-       pushq   %rsi                            /* pt_regs->si */
-       pushq   %rdx                            /* pt_regs->dx */
-       pushq   %rcx                            /* pt_regs->cx */
-       pushq   $-ENOSYS                        /* pt_regs->ax */
-       pushq   %r8                             /* pt_regs->r8 */
-       pushq   %r9                             /* pt_regs->r9 */
-       pushq   %r10                            /* pt_regs->r10 */
-       pushq   %r11                            /* pt_regs->r11 */
-       pushq   %rbx                            /* pt_regs->rbx */
-       pushq   %rbp                            /* pt_regs->rbp */
-       pushq   %r12                            /* pt_regs->r12 */
-       pushq   %r13                            /* pt_regs->r13 */
-       pushq   %r14                            /* pt_regs->r14 */
-       pushq   %r15                            /* pt_regs->r15 */
-       UNWIND_HINT_REGS
+
+       PUSH_AND_CLEAR_REGS rax=$-ENOSYS
 
        TRACE_IRQS_OFF
 
@@ -321,15 +307,7 @@ GLOBAL(entry_SYSCALL_64_after_hwframe)
 syscall_return_via_sysret:
        /* rcx and r11 are already restored (see code above) */
        UNWIND_HINT_EMPTY
-       POP_EXTRA_REGS
-       popq    %rsi    /* skip r11 */
-       popq    %r10
-       popq    %r9
-       popq    %r8
-       popq    %rax
-       popq    %rsi    /* skip rcx */
-       popq    %rdx
-       popq    %rsi
+       POP_REGS pop_rdi=0 skip_r11rcx=1
 
        /*
         * Now all regs are restored except RSP and RDI.
@@ -386,8 +364,7 @@ ENTRY(__switch_to_asm)
         * exist, overwrite the RSB with entries which capture
         * speculative execution to prevent attack.
         */
-       /* Clobbers %rbx */
-       FILL_RETURN_BUFFER RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW
+       FILL_RETURN_BUFFER %r12, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW
 #endif
 
        /* restore callee-saved registers */
@@ -471,9 +448,19 @@ END(irq_entries_start)
  *
  * The invariant is that, if irq_count != -1, then the IRQ stack is in use.
  */
-.macro ENTER_IRQ_STACK regs=1 old_rsp
+.macro ENTER_IRQ_STACK regs=1 old_rsp save_ret=0
        DEBUG_ENTRY_ASSERT_IRQS_OFF
+
+       .if \save_ret
+       /*
+        * If save_ret is set, the original stack contains one additional
+        * entry -- the return address. Therefore, move the address one
+        * entry below %rsp to \old_rsp.
+        */
+       leaq    8(%rsp), \old_rsp
+       .else
        movq    %rsp, \old_rsp
+       .endif
 
        .if \regs
        UNWIND_HINT_REGS base=\old_rsp
@@ -519,6 +506,15 @@ END(irq_entries_start)
        .if \regs
        UNWIND_HINT_REGS indirect=1
        .endif
+
+       .if \save_ret
+       /*
+        * Push the return address to the stack. This return address can
+        * be found at the "real" original RSP, which was offset by 8 at
+        * the beginning of this macro.
+        */
+       pushq   -8(\old_rsp)
+       .endif
 .endm
 
 /*
@@ -542,29 +538,65 @@ END(irq_entries_start)
 .endm
 
 /*
- * Interrupt entry/exit.
- *
- * Interrupt entry points save only callee clobbered registers in fast path.
+ * Interrupt entry helper function.
  *
- * Entry runs with interrupts off.
+ * Entry runs with interrupts off. Stack layout at entry:
+ * +----------------------------------------------------+
+ * | regs->ss                                          |
+ * | regs->rsp                                         |
+ * | regs->eflags                                      |
+ * | regs->cs                                          |
+ * | regs->ip                                          |
+ * +----------------------------------------------------+
+ * | regs->orig_ax = ~(interrupt number)               |
+ * +----------------------------------------------------+
+ * | return address                                    |
+ * +----------------------------------------------------+
  */
-
-/* 0(%rsp): ~(interrupt number) */
-       .macro interrupt func
+ENTRY(interrupt_entry)
+       UNWIND_HINT_FUNC
+       ASM_CLAC
        cld
 
-       testb   $3, CS-ORIG_RAX(%rsp)
+       testb   $3, CS-ORIG_RAX+8(%rsp)
        jz      1f
        SWAPGS
-       call    switch_to_thread_stack
+
+       /*
+        * Switch to the thread stack. The IRET frame and orig_ax are
+        * on the stack, as well as the return address. RDI..R12 are
+        * not (yet) on the stack and space has not (yet) been
+        * allocated for them.
+        */
+       pushq   %rdi
+
+       /* Need to switch before accessing the thread stack. */
+       SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+       movq    %rsp, %rdi
+       movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+
+        /*
+         * We have RDI, return address, and orig_ax on the stack on
+         * top of the IRET frame. That means offset=24
+         */
+       UNWIND_HINT_IRET_REGS base=%rdi offset=24
+
+       pushq   7*8(%rdi)               /* regs->ss */
+       pushq   6*8(%rdi)               /* regs->rsp */
+       pushq   5*8(%rdi)               /* regs->eflags */
+       pushq   4*8(%rdi)               /* regs->cs */
+       pushq   3*8(%rdi)               /* regs->ip */
+       pushq   2*8(%rdi)               /* regs->orig_ax */
+       pushq   8(%rdi)                 /* return address */
+       UNWIND_HINT_FUNC
+
+       movq    (%rdi), %rdi
 1:
 
-       ALLOC_PT_GPREGS_ON_STACK
-       SAVE_C_REGS
-       SAVE_EXTRA_REGS
-       ENCODE_FRAME_POINTER
+       PUSH_AND_CLEAR_REGS save_ret=1
+       ENCODE_FRAME_POINTER 8
 
-       testb   $3, CS(%rsp)
+       testb   $3, CS+8(%rsp)
        jz      1f
 
        /*
@@ -572,7 +604,7 @@ END(irq_entries_start)
         *
         * We need to tell lockdep that IRQs are off.  We can't do this until
         * we fix gsbase, and we should do it before enter_from_user_mode
-        * (which can take locks).  Since TRACE_IRQS_OFF idempotent,
+        * (which can take locks).  Since TRACE_IRQS_OFF is idempotent,
         * the simplest way to handle it is to just call it twice if
         * we enter from user mode.  There's no reason to optimize this since
         * TRACE_IRQS_OFF is a no-op if lockdep is off.
@@ -582,12 +614,15 @@ END(irq_entries_start)
        CALL_enter_from_user_mode
 
 1:
-       ENTER_IRQ_STACK old_rsp=%rdi
+       ENTER_IRQ_STACK old_rsp=%rdi save_ret=1
        /* We entered an interrupt context - irqs are off: */
        TRACE_IRQS_OFF
 
-       call    \func   /* rdi points to pt_regs */
-       .endm
+       ret
+END(interrupt_entry)
+
+
+/* Interrupt entry/exit. */
 
        /*
         * The interrupt stubs push (~vector+0x80) onto the stack and
@@ -595,9 +630,10 @@ END(irq_entries_start)
         */
        .p2align CONFIG_X86_L1_CACHE_SHIFT
 common_interrupt:
-       ASM_CLAC
        addq    $-0x80, (%rsp)                  /* Adjust vector to [-256, -1] range */
-       interrupt do_IRQ
+       call    interrupt_entry
+       UNWIND_HINT_REGS indirect=1
+       call    do_IRQ  /* rdi points to pt_regs */
        /* 0(%rsp): old RSP */
 ret_from_intr:
        DISABLE_INTERRUPTS(CLBR_ANY)
@@ -622,15 +658,7 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode)
        ud2
 1:
 #endif
-       POP_EXTRA_REGS
-       popq    %r11
-       popq    %r10
-       popq    %r9
-       popq    %r8
-       popq    %rax
-       popq    %rcx
-       popq    %rdx
-       popq    %rsi
+       POP_REGS pop_rdi=0
 
        /*
         * The stack is now user RDI, orig_ax, RIP, CS, EFLAGS, RSP, SS.
@@ -688,8 +716,7 @@ GLOBAL(restore_regs_and_return_to_kernel)
        ud2
 1:
 #endif
-       POP_EXTRA_REGS
-       POP_C_REGS
+       POP_REGS
        addq    $8, %rsp        /* skip regs->orig_ax */
        /*
         * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
@@ -799,10 +826,11 @@ END(common_interrupt)
 .macro apicinterrupt3 num sym do_sym
 ENTRY(\sym)
        UNWIND_HINT_IRET_REGS
-       ASM_CLAC
        pushq   $~(\num)
 .Lcommon_\sym:
-       interrupt \do_sym
+       call    interrupt_entry
+       UNWIND_HINT_REGS indirect=1
+       call    \do_sym /* rdi points to pt_regs */
        jmp     ret_from_intr
 END(\sym)
 .endm
@@ -865,34 +893,6 @@ apicinterrupt IRQ_WORK_VECTOR                      irq_work_interrupt              smp_irq_work_interrupt
  */
 #define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
 
-/*
- * Switch to the thread stack.  This is called with the IRET frame and
- * orig_ax on the stack.  (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
- */
-ENTRY(switch_to_thread_stack)
-       UNWIND_HINT_FUNC
-
-       pushq   %rdi
-       /* Need to switch before accessing the thread stack. */
-       SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
-       movq    %rsp, %rdi
-       movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
-       UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
-
-       pushq   7*8(%rdi)               /* regs->ss */
-       pushq   6*8(%rdi)               /* regs->rsp */
-       pushq   5*8(%rdi)               /* regs->eflags */
-       pushq   4*8(%rdi)               /* regs->cs */
-       pushq   3*8(%rdi)               /* regs->ip */
-       pushq   2*8(%rdi)               /* regs->orig_ax */
-       pushq   8(%rdi)                 /* return address */
-       UNWIND_HINT_FUNC
-
-       movq    (%rdi), %rdi
-       ret
-END(switch_to_thread_stack)
-
 .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
 ENTRY(\sym)
        UNWIND_HINT_IRET_REGS offset=\has_error_code*8
@@ -908,10 +908,8 @@ ENTRY(\sym)
        pushq   $-1                             /* ORIG_RAX: no syscall to restart */
        .endif
 
-       ALLOC_PT_GPREGS_ON_STACK
-
        .if \paranoid < 2
-       testb   $3, CS(%rsp)                    /* If coming from userspace, switch stacks */
+       testb   $3, CS-ORIG_RAX(%rsp)           /* If coming from userspace, switch stacks */
        jnz     .Lfrom_usermode_switch_stack_\@
        .endif
 
@@ -1121,9 +1119,7 @@ ENTRY(xen_failsafe_callback)
        addq    $0x30, %rsp
        UNWIND_HINT_IRET_REGS
        pushq   $-1 /* orig_ax = -1 => not a system call */
-       ALLOC_PT_GPREGS_ON_STACK
-       SAVE_C_REGS
-       SAVE_EXTRA_REGS
+       PUSH_AND_CLEAR_REGS
        ENCODE_FRAME_POINTER
        jmp     error_exit
 END(xen_failsafe_callback)
@@ -1142,7 +1138,7 @@ apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \
 #endif /* CONFIG_HYPERV */
 
 idtentry debug                 do_debug                has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
-idtentry int3                  do_int3                 has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
+idtentry int3                  do_int3                 has_error_code=0
 idtentry stack_segment         do_stack_segment        has_error_code=1
 
 #ifdef CONFIG_XEN
@@ -1170,8 +1166,7 @@ idtentry machine_check            do_mce                  has_error_code=0        paranoid=1
 ENTRY(paranoid_entry)
        UNWIND_HINT_FUNC
        cld
-       SAVE_C_REGS 8
-       SAVE_EXTRA_REGS 8
+       PUSH_AND_CLEAR_REGS save_ret=1
        ENCODE_FRAME_POINTER 8
        movl    $1, %ebx
        movl    $MSR_GS_BASE, %ecx
@@ -1211,21 +1206,20 @@ ENTRY(paranoid_exit)
        jmp     .Lparanoid_exit_restore
 .Lparanoid_exit_no_swapgs:
        TRACE_IRQS_IRETQ_DEBUG
+       RESTORE_CR3     scratch_reg=%rbx save_reg=%r14
 .Lparanoid_exit_restore:
        jmp restore_regs_and_return_to_kernel
 END(paranoid_exit)
 
 /*
- * Save all registers in pt_regs, and switch gs if needed.
+ * Save all registers in pt_regs, and switch GS if needed.
  * Return: EBX=0: came from user mode; EBX=1: otherwise
  */
 ENTRY(error_entry)
        UNWIND_HINT_FUNC
        cld
-       SAVE_C_REGS 8
-       SAVE_EXTRA_REGS 8
+       PUSH_AND_CLEAR_REGS save_ret=1
        ENCODE_FRAME_POINTER 8
-       xorl    %ebx, %ebx
        testb   $3, CS+8(%rsp)
        jz      .Lerror_kernelspace
 
@@ -1406,22 +1400,7 @@ ENTRY(nmi)
        pushq   1*8(%rdx)       /* pt_regs->rip */
        UNWIND_HINT_IRET_REGS
        pushq   $-1             /* pt_regs->orig_ax */
-       pushq   %rdi            /* pt_regs->di */
-       pushq   %rsi            /* pt_regs->si */
-       pushq   (%rdx)          /* pt_regs->dx */
-       pushq   %rcx            /* pt_regs->cx */
-       pushq   %rax            /* pt_regs->ax */
-       pushq   %r8             /* pt_regs->r8 */
-       pushq   %r9             /* pt_regs->r9 */
-       pushq   %r10            /* pt_regs->r10 */
-       pushq   %r11            /* pt_regs->r11 */
-       pushq   %rbx            /* pt_regs->rbx */
-       pushq   %rbp            /* pt_regs->rbp */
-       pushq   %r12            /* pt_regs->r12 */
-       pushq   %r13            /* pt_regs->r13 */
-       pushq   %r14            /* pt_regs->r14 */
-       pushq   %r15            /* pt_regs->r15 */
-       UNWIND_HINT_REGS
+       PUSH_AND_CLEAR_REGS rdx=(%rdx)
        ENCODE_FRAME_POINTER
 
        /*
@@ -1631,7 +1610,6 @@ end_repeat_nmi:
         * frame to point back to repeat_nmi.
         */
        pushq   $-1                             /* ORIG_RAX: no syscall to restart */
-       ALLOC_PT_GPREGS_ON_STACK
 
        /*
         * Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit
@@ -1655,8 +1633,7 @@ end_repeat_nmi:
 nmi_swapgs:
        SWAPGS_UNSAFE_STACK
 nmi_restore:
-       POP_EXTRA_REGS
-       POP_C_REGS
+       POP_REGS
 
        /*
         * Skip orig_ax and the "outermost" frame to point RSP at the "iret"
index 98d5358e4041a7e144ec566f7db19ff054cedbcc..08425c42f8b7c726e0daa70bb4e112582a513c20 100644 (file)
@@ -85,15 +85,25 @@ ENTRY(entry_SYSENTER_compat)
        pushq   %rcx                    /* pt_regs->cx */
        pushq   $-ENOSYS                /* pt_regs->ax */
        pushq   $0                      /* pt_regs->r8  = 0 */
+       xorl    %r8d, %r8d              /* nospec   r8 */
        pushq   $0                      /* pt_regs->r9  = 0 */
+       xorl    %r9d, %r9d              /* nospec   r9 */
        pushq   $0                      /* pt_regs->r10 = 0 */
+       xorl    %r10d, %r10d            /* nospec   r10 */
        pushq   $0                      /* pt_regs->r11 = 0 */
+       xorl    %r11d, %r11d            /* nospec   r11 */
        pushq   %rbx                    /* pt_regs->rbx */
+       xorl    %ebx, %ebx              /* nospec   rbx */
        pushq   %rbp                    /* pt_regs->rbp (will be overwritten) */
+       xorl    %ebp, %ebp              /* nospec   rbp */
        pushq   $0                      /* pt_regs->r12 = 0 */
+       xorl    %r12d, %r12d            /* nospec   r12 */
        pushq   $0                      /* pt_regs->r13 = 0 */
+       xorl    %r13d, %r13d            /* nospec   r13 */
        pushq   $0                      /* pt_regs->r14 = 0 */
+       xorl    %r14d, %r14d            /* nospec   r14 */
        pushq   $0                      /* pt_regs->r15 = 0 */
+       xorl    %r15d, %r15d            /* nospec   r15 */
        cld
 
        /*
@@ -214,15 +224,25 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe)
        pushq   %rbp                    /* pt_regs->cx (stashed in bp) */
        pushq   $-ENOSYS                /* pt_regs->ax */
        pushq   $0                      /* pt_regs->r8  = 0 */
+       xorl    %r8d, %r8d              /* nospec   r8 */
        pushq   $0                      /* pt_regs->r9  = 0 */
+       xorl    %r9d, %r9d              /* nospec   r9 */
        pushq   $0                      /* pt_regs->r10 = 0 */
+       xorl    %r10d, %r10d            /* nospec   r10 */
        pushq   $0                      /* pt_regs->r11 = 0 */
+       xorl    %r11d, %r11d            /* nospec   r11 */
        pushq   %rbx                    /* pt_regs->rbx */
+       xorl    %ebx, %ebx              /* nospec   rbx */
        pushq   %rbp                    /* pt_regs->rbp (will be overwritten) */
+       xorl    %ebp, %ebp              /* nospec   rbp */
        pushq   $0                      /* pt_regs->r12 = 0 */
+       xorl    %r12d, %r12d            /* nospec   r12 */
        pushq   $0                      /* pt_regs->r13 = 0 */
+       xorl    %r13d, %r13d            /* nospec   r13 */
        pushq   $0                      /* pt_regs->r14 = 0 */
+       xorl    %r14d, %r14d            /* nospec   r14 */
        pushq   $0                      /* pt_regs->r15 = 0 */
+       xorl    %r15d, %r15d            /* nospec   r15 */
 
        /*
         * User mode is traced as though IRQs are on, and SYSENTER
@@ -278,9 +298,9 @@ sysret32_from_system_call:
         */
        SWITCH_TO_USER_CR3_NOSTACK scratch_reg=%r8 scratch_reg2=%r9
 
-       xorq    %r8, %r8
-       xorq    %r9, %r9
-       xorq    %r10, %r10
+       xorl    %r8d, %r8d
+       xorl    %r9d, %r9d
+       xorl    %r10d, %r10d
        swapgs
        sysretl
 END(entry_SYSCALL_compat)
@@ -327,26 +347,47 @@ ENTRY(entry_INT80_compat)
         */
        movl    %eax, %eax
 
+       /* switch to thread stack expects orig_ax and rdi to be pushed */
        pushq   %rax                    /* pt_regs->orig_ax */
+       pushq   %rdi                    /* pt_regs->di */
 
-       /* switch to thread stack expects orig_ax to be pushed */
-       call    switch_to_thread_stack
+       /* Need to switch before accessing the thread stack. */
+       SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+       movq    %rsp, %rdi
+       movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 
-       pushq   %rdi                    /* pt_regs->di */
+       pushq   6*8(%rdi)               /* regs->ss */
+       pushq   5*8(%rdi)               /* regs->rsp */
+       pushq   4*8(%rdi)               /* regs->eflags */
+       pushq   3*8(%rdi)               /* regs->cs */
+       pushq   2*8(%rdi)               /* regs->ip */
+       pushq   1*8(%rdi)               /* regs->orig_ax */
+
+       pushq   (%rdi)                  /* pt_regs->di */
        pushq   %rsi                    /* pt_regs->si */
        pushq   %rdx                    /* pt_regs->dx */
        pushq   %rcx                    /* pt_regs->cx */
        pushq   $-ENOSYS                /* pt_regs->ax */
        pushq   $0                      /* pt_regs->r8  = 0 */
+       xorl    %r8d, %r8d              /* nospec   r8 */
        pushq   $0                      /* pt_regs->r9  = 0 */
+       xorl    %r9d, %r9d              /* nospec   r9 */
        pushq   $0                      /* pt_regs->r10 = 0 */
+       xorl    %r10d, %r10d            /* nospec   r10 */
        pushq   $0                      /* pt_regs->r11 = 0 */
+       xorl    %r11d, %r11d            /* nospec   r11 */
        pushq   %rbx                    /* pt_regs->rbx */
+       xorl    %ebx, %ebx              /* nospec   rbx */
        pushq   %rbp                    /* pt_regs->rbp */
+       xorl    %ebp, %ebp              /* nospec   rbp */
        pushq   %r12                    /* pt_regs->r12 */
+       xorl    %r12d, %r12d            /* nospec   r12 */
        pushq   %r13                    /* pt_regs->r13 */
+       xorl    %r13d, %r13d            /* nospec   r13 */
        pushq   %r14                    /* pt_regs->r14 */
+       xorl    %r14d, %r14d            /* nospec   r14 */
        pushq   %r15                    /* pt_regs->r15 */
+       xorl    %r15d, %r15d            /* nospec   r15 */
        cld
 
        /*
@@ -363,15 +404,3 @@ ENTRY(entry_INT80_compat)
        TRACE_IRQS_ON
        jmp     swapgs_restore_regs_and_return_to_usermode
 END(entry_INT80_compat)
-
-ENTRY(stub32_clone)
-       /*
-        * The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).
-        * The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val).
-        *
-        * The native 64-bit kernel's sys_clone() implements the latter,
-        * so we need to swap arguments here before calling it:
-        */
-       xchg    %r8, %rcx
-       jmp     sys_clone
-ENDPROC(stub32_clone)
index 448ac2161112b7fd05c4388ff1327294499884f5..2a5e99cff8597278412685867f512858254f2b0c 100644 (file)
@@ -8,12 +8,12 @@
 #
 0      i386    restart_syscall         sys_restart_syscall
 1      i386    exit                    sys_exit
-2      i386    fork                    sys_fork                        sys_fork
+2      i386    fork                    sys_fork
 3      i386    read                    sys_read
 4      i386    write                   sys_write
 5      i386    open                    sys_open                        compat_sys_open
 6      i386    close                   sys_close
-7      i386    waitpid                 sys_waitpid                     sys32_waitpid
+7      i386    waitpid                 sys_waitpid                     compat_sys_x86_waitpid
 8      i386    creat                   sys_creat
 9      i386    link                    sys_link
 10     i386    unlink                  sys_unlink
@@ -78,7 +78,7 @@
 69     i386    ssetmask                sys_ssetmask
 70     i386    setreuid                sys_setreuid16
 71     i386    setregid                sys_setregid16
-72     i386    sigsuspend              sys_sigsuspend                  sys_sigsuspend
+72     i386    sigsuspend              sys_sigsuspend
 73     i386    sigpending              sys_sigpending                  compat_sys_sigpending
 74     i386    sethostname             sys_sethostname
 75     i386    setrlimit               sys_setrlimit                   compat_sys_setrlimit
@@ -96,7 +96,7 @@
 87     i386    swapon                  sys_swapon
 88     i386    reboot                  sys_reboot
 89     i386    readdir                 sys_old_readdir                 compat_sys_old_readdir
-90     i386    mmap                    sys_old_mmap                    sys32_mmap
+90     i386    mmap                    sys_old_mmap                    compat_sys_x86_mmap
 91     i386    munmap                  sys_munmap
 92     i386    truncate                sys_truncate                    compat_sys_truncate
 93     i386    ftruncate               sys_ftruncate                   compat_sys_ftruncate
 117    i386    ipc                     sys_ipc                         compat_sys_ipc
 118    i386    fsync                   sys_fsync
 119    i386    sigreturn               sys_sigreturn                   sys32_sigreturn
-120    i386    clone                   sys_clone                       stub32_clone
+120    i386    clone                   sys_clone                       compat_sys_x86_clone
 121    i386    setdomainname           sys_setdomainname
 122    i386    uname                   sys_newuname
 123    i386    modify_ldt              sys_modify_ldt
 177    i386    rt_sigtimedwait         sys_rt_sigtimedwait             compat_sys_rt_sigtimedwait
 178    i386    rt_sigqueueinfo         sys_rt_sigqueueinfo             compat_sys_rt_sigqueueinfo
 179    i386    rt_sigsuspend           sys_rt_sigsuspend
-180    i386    pread64                 sys_pread64                     sys32_pread
-181    i386    pwrite64                sys_pwrite64                    sys32_pwrite
+180    i386    pread64                 sys_pread64                     compat_sys_x86_pread
+181    i386    pwrite64                sys_pwrite64                    compat_sys_x86_pwrite
 182    i386    chown                   sys_chown16
 183    i386    getcwd                  sys_getcwd
 184    i386    capget                  sys_capget
 187    i386    sendfile                sys_sendfile                    compat_sys_sendfile
 188    i386    getpmsg
 189    i386    putpmsg
-190    i386    vfork                   sys_vfork                       sys_vfork
+190    i386    vfork                   sys_vfork
 191    i386    ugetrlimit              sys_getrlimit                   compat_sys_getrlimit
 192    i386    mmap2                   sys_mmap_pgoff
-193    i386    truncate64              sys_truncate64                  sys32_truncate64
-194    i386    ftruncate64             sys_ftruncate64                 sys32_ftruncate64
-195    i386    stat64                  sys_stat64                      sys32_stat64
-196    i386    lstat64                 sys_lstat64                     sys32_lstat64
-197    i386    fstat64                 sys_fstat64                     sys32_fstat64
+193    i386    truncate64              sys_truncate64                  compat_sys_x86_truncate64
+194    i386    ftruncate64             sys_ftruncate64                 compat_sys_x86_ftruncate64
+195    i386    stat64                  sys_stat64                      compat_sys_x86_stat64
+196    i386    lstat64                 sys_lstat64                     compat_sys_x86_lstat64
+197    i386    fstat64                 sys_fstat64                     compat_sys_x86_fstat64
 198    i386    lchown32                sys_lchown
 199    i386    getuid32                sys_getuid
 200    i386    getgid32                sys_getgid
 # 222 is unused
 # 223 is unused
 224    i386    gettid                  sys_gettid
-225    i386    readahead               sys_readahead                   sys32_readahead
+225    i386    readahead               sys_readahead                   compat_sys_x86_readahead
 226    i386    setxattr                sys_setxattr
 227    i386    lsetxattr               sys_lsetxattr
 228    i386    fsetxattr               sys_fsetxattr
 247    i386    io_getevents            sys_io_getevents                compat_sys_io_getevents
 248    i386    io_submit               sys_io_submit                   compat_sys_io_submit
 249    i386    io_cancel               sys_io_cancel
-250    i386    fadvise64               sys_fadvise64                   sys32_fadvise64
+250    i386    fadvise64               sys_fadvise64                   compat_sys_x86_fadvise64
 # 251 is available for reuse (was briefly sys_set_zone_reclaim)
 252    i386    exit_group              sys_exit_group
 253    i386    lookup_dcookie          sys_lookup_dcookie              compat_sys_lookup_dcookie
 269    i386    fstatfs64               sys_fstatfs64                   compat_sys_fstatfs64
 270    i386    tgkill                  sys_tgkill
 271    i386    utimes                  sys_utimes                      compat_sys_utimes
-272    i386    fadvise64_64            sys_fadvise64_64                sys32_fadvise64_64
+272    i386    fadvise64_64            sys_fadvise64_64                compat_sys_x86_fadvise64_64
 273    i386    vserver
 274    i386    mbind                   sys_mbind
 275    i386    get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
 297    i386    mknodat                 sys_mknodat
 298    i386    fchownat                sys_fchownat
 299    i386    futimesat               sys_futimesat                   compat_sys_futimesat
-300    i386    fstatat64               sys_fstatat64                   sys32_fstatat
+300    i386    fstatat64               sys_fstatat64                   compat_sys_x86_fstatat
 301    i386    unlinkat                sys_unlinkat
 302    i386    renameat                sys_renameat
 303    i386    linkat                  sys_linkat
 311    i386    set_robust_list         sys_set_robust_list             compat_sys_set_robust_list
 312    i386    get_robust_list         sys_get_robust_list             compat_sys_get_robust_list
 313    i386    splice                  sys_splice
-314    i386    sync_file_range         sys_sync_file_range             sys32_sync_file_range
+314    i386    sync_file_range         sys_sync_file_range             compat_sys_x86_sync_file_range
 315    i386    tee                     sys_tee
 316    i386    vmsplice                sys_vmsplice                    compat_sys_vmsplice
 317    i386    move_pages              sys_move_pages                  compat_sys_move_pages
 321    i386    signalfd                sys_signalfd                    compat_sys_signalfd
 322    i386    timerfd_create          sys_timerfd_create
 323    i386    eventfd                 sys_eventfd
-324    i386    fallocate               sys_fallocate                   sys32_fallocate
+324    i386    fallocate               sys_fallocate                   compat_sys_x86_fallocate
 325    i386    timerfd_settime         sys_timerfd_settime             compat_sys_timerfd_settime
 326    i386    timerfd_gettime         sys_timerfd_gettime             compat_sys_timerfd_gettime
 327    i386    signalfd4               sys_signalfd4                   compat_sys_signalfd4
index 7780bbfb06ef2da78c6a82d4978ac467899873d2..9242b28418d58d11373a81d6aa0403f8eddae2b4 100644 (file)
@@ -5,8 +5,6 @@
 #undef CONFIG_OPTIMIZE_INLINING
 #endif
 
-#undef CONFIG_X86_PPRO_FENCE
-
 #ifdef CONFIG_X86_64
 
 /*
index 577fa8adb785baf5ea1c993a2bbc88adf43fbbcc..317be365bce3a459b9d2b60dad6ad864868b1366 100644 (file)
 #define CREATE_TRACE_POINTS
 #include "vsyscall_trace.h"
 
-static enum { EMULATE, NATIVE, NONE } vsyscall_mode =
-#if defined(CONFIG_LEGACY_VSYSCALL_NATIVE)
-       NATIVE;
-#elif defined(CONFIG_LEGACY_VSYSCALL_NONE)
+static enum { EMULATE, NONE } vsyscall_mode =
+#ifdef CONFIG_LEGACY_VSYSCALL_NONE
        NONE;
 #else
        EMULATE;
@@ -56,8 +54,6 @@ static int __init vsyscall_setup(char *str)
        if (str) {
                if (!strcmp("emulate", str))
                        vsyscall_mode = EMULATE;
-               else if (!strcmp("native", str))
-                       vsyscall_mode = NATIVE;
                else if (!strcmp("none", str))
                        vsyscall_mode = NONE;
                else
@@ -139,10 +135,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 
        WARN_ON_ONCE(address != regs->ip);
 
-       /* This should be unreachable in NATIVE mode. */
-       if (WARN_ON(vsyscall_mode == NATIVE))
-               return false;
-
        if (vsyscall_mode == NONE) {
                warn_bad_vsyscall(KERN_INFO, regs,
                                  "vsyscall attempted with vsyscall=none");
@@ -355,7 +347,7 @@ void __init set_vsyscall_pgtable_user_bits(pgd_t *root)
        set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER));
        p4d = p4d_offset(pgd, VSYSCALL_ADDR);
 #if CONFIG_PGTABLE_LEVELS >= 5
-       p4d->p4d |= _PAGE_USER;
+       set_p4d(p4d, __p4d(p4d_val(*p4d) | _PAGE_USER));
 #endif
        pud = pud_offset(p4d, VSYSCALL_ADDR);
        set_pud(pud, __pud(pud_val(*pud) | _PAGE_USER));
@@ -370,9 +362,7 @@ void __init map_vsyscall(void)
 
        if (vsyscall_mode != NONE) {
                __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
-                            vsyscall_mode == NATIVE
-                            ? PAGE_KERNEL_VSYSCALL
-                            : PAGE_KERNEL_VVAR);
+                            PAGE_KERNEL_VVAR);
                set_vsyscall_pgtable_user_bits(swapper_pg_dir);
        }
 
index 140d33288e78e8ef72138a3ec247520f66b158a2..88797c80b3e09487868d93ad3ce1b1864e1e4f2d 100644 (file)
@@ -2118,7 +2118,8 @@ static int x86_pmu_event_init(struct perf_event *event)
                        event->destroy(event);
        }
 
-       if (READ_ONCE(x86_pmu.attr_rdpmc))
+       if (READ_ONCE(x86_pmu.attr_rdpmc) &&
+           !(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS))
                event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
 
        return err;
index 731153a4681e73f761dea8c0c15ce6757b89860e..1e41d7508d99cbe68694c7100ec87e061e66176a 100644 (file)
@@ -2952,9 +2952,9 @@ static void intel_pebs_aliases_skl(struct perf_event *event)
        return intel_pebs_aliases_precdist(event);
 }
 
-static unsigned long intel_pmu_free_running_flags(struct perf_event *event)
+static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event)
 {
-       unsigned long flags = x86_pmu.free_running_flags;
+       unsigned long flags = x86_pmu.large_pebs_flags;
 
        if (event->attr.use_clockid)
                flags &= ~PERF_SAMPLE_TIME;
@@ -2976,8 +2976,8 @@ static int intel_pmu_hw_config(struct perf_event *event)
                if (!event->attr.freq) {
                        event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
                        if (!(event->attr.sample_type &
-                             ~intel_pmu_free_running_flags(event)))
-                               event->hw.flags |= PERF_X86_EVENT_FREERUNNING;
+                             ~intel_pmu_large_pebs_flags(event)))
+                               event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS;
                }
                if (x86_pmu.pebs_aliases)
                        x86_pmu.pebs_aliases(event);
@@ -3194,7 +3194,7 @@ static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
                        X86_CONFIG(.event=0xc0, .umask=0x01)) {
                if (left < 128)
                        left = 128;
-               left &= ~0x3fu;
+               left &= ~0x3fULL;
        }
        return left;
 }
@@ -3460,7 +3460,7 @@ static __initconst const struct x86_pmu core_pmu = {
        .event_map              = intel_pmu_event_map,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
-       .free_running_flags     = PEBS_FREERUNNING_FLAGS,
+       .large_pebs_flags       = LARGE_PEBS_FLAGS,
 
        /*
         * Intel PMCs cannot be accessed sanely above 32-bit width,
@@ -3502,7 +3502,7 @@ static __initconst const struct x86_pmu intel_pmu = {
        .event_map              = intel_pmu_event_map,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
-       .free_running_flags     = PEBS_FREERUNNING_FLAGS,
+       .large_pebs_flags       = LARGE_PEBS_FLAGS,
        /*
         * Intel PMCs cannot be accessed sanely above 32 bit width,
         * so we install an artificial 1<<31 period regardless of
@@ -3559,7 +3559,7 @@ static int intel_snb_pebs_broken(int cpu)
                break;
 
        case INTEL_FAM6_SANDYBRIDGE_X:
-               switch (cpu_data(cpu).x86_mask) {
+               switch (cpu_data(cpu).x86_stepping) {
                case 6: rev = 0x618; break;
                case 7: rev = 0x70c; break;
                }
index 18c25ab2855744142d836f311e0b1a9279f2ed06..d8015235ba765b03c6ace2d73413e18bfd1cdbda 100644 (file)
@@ -935,7 +935,7 @@ void intel_pmu_pebs_add(struct perf_event *event)
        bool needed_cb = pebs_needs_sched_cb(cpuc);
 
        cpuc->n_pebs++;
-       if (hwc->flags & PERF_X86_EVENT_FREERUNNING)
+       if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
                cpuc->n_large_pebs++;
 
        pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
@@ -975,7 +975,7 @@ void intel_pmu_pebs_del(struct perf_event *event)
        bool needed_cb = pebs_needs_sched_cb(cpuc);
 
        cpuc->n_pebs--;
-       if (hwc->flags & PERF_X86_EVENT_FREERUNNING)
+       if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
                cpuc->n_large_pebs--;
 
        pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
@@ -1530,7 +1530,7 @@ void __init intel_ds_init(void)
                        x86_pmu.pebs_record_size =
                                                sizeof(struct pebs_record_skl);
                        x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
-                       x86_pmu.free_running_flags |= PERF_SAMPLE_TIME;
+                       x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
                        break;
 
                default:
index ae64d0b69729dbb23c436d6c3bbf360a3cafb53b..cf372b90557ed4e8a788c8f97b515ac956d2512e 100644 (file)
@@ -1186,7 +1186,7 @@ void __init intel_pmu_lbr_init_atom(void)
         * on PMU interrupt
         */
        if (boot_cpu_data.x86_model == 28
-           && boot_cpu_data.x86_mask < 10) {
+           && boot_cpu_data.x86_stepping < 10) {
                pr_cont("LBR disabled due to erratum");
                return;
        }
index a5604c3529308b7cfc1dc336a8d53496d531659b..408879b0c0d4e41c56906d2464734279c9360f7e 100644 (file)
@@ -234,7 +234,7 @@ static __initconst const struct x86_pmu p6_pmu = {
 
 static __init void p6_pmu_rdpmc_quirk(void)
 {
-       if (boot_cpu_data.x86_mask < 9) {
+       if (boot_cpu_data.x86_stepping < 9) {
                /*
                 * PPro erratum 26; fixed in stepping 9 and above.
                 */
index 6d8044ab10607b6c668bfee0d6366266401e7e2f..c98b943e58b4fca0a5144a20342229b013fe1ee1 100644 (file)
@@ -3343,6 +3343,7 @@ static struct extra_reg skx_uncore_cha_extra_regs[] = {
        SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
        SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
        SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3),
        EVENT_EXTRA_END
 };
 
@@ -3562,24 +3563,27 @@ static struct intel_uncore_type *skx_msr_uncores[] = {
        NULL,
 };
 
+/*
+ * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
+ * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
+ */
+#define SKX_CAPID6             0x9c
+#define SKX_CHA_BIT_MASK       GENMASK(27, 0)
+
 static int skx_count_chabox(void)
 {
-       struct pci_dev *chabox_dev = NULL;
-       int bus, count = 0;
+       struct pci_dev *dev = NULL;
+       u32 val = 0;
 
-       while (1) {
-               chabox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x208d, chabox_dev);
-               if (!chabox_dev)
-                       break;
-               if (count == 0)
-                       bus = chabox_dev->bus->number;
-               if (bus != chabox_dev->bus->number)
-                       break;
-               count++;
-       }
+       dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
+       if (!dev)
+               goto out;
 
-       pci_dev_put(chabox_dev);
-       return count;
+       pci_read_config_dword(dev, SKX_CAPID6, &val);
+       val &= SKX_CHA_BIT_MASK;
+out:
+       pci_dev_put(dev);
+       return hweight32(val);
 }
 
 void skx_uncore_cpu_init(void)
@@ -3606,7 +3610,7 @@ static struct intel_uncore_type skx_uncore_imc = {
 };
 
 static struct attribute *skx_upi_uncore_formats_attr[] = {
-       &format_attr_event_ext.attr,
+       &format_attr_event.attr,
        &format_attr_umask_ext.attr,
        &format_attr_edge.attr,
        &format_attr_inv.attr,
index 78f91ec1056ea2032cc36fbd5dc71b5dea4853cc..39cd0615f04fb09c83a8c81d282da755e9286b08 100644 (file)
@@ -69,7 +69,7 @@ struct event_constraint {
 #define PERF_X86_EVENT_RDPMC_ALLOWED   0x0100 /* grant rdpmc permission */
 #define PERF_X86_EVENT_EXCL_ACCT       0x0200 /* accounted EXCL event */
 #define PERF_X86_EVENT_AUTO_RELOAD     0x0400 /* use PEBS auto-reload */
-#define PERF_X86_EVENT_FREERUNNING     0x0800 /* use freerunning PEBS */
+#define PERF_X86_EVENT_LARGE_PEBS      0x0800 /* use large PEBS */
 
 
 struct amd_nb {
@@ -88,7 +88,7 @@ struct amd_nb {
  * REGS_USER can be handled for events limited to ring 3.
  *
  */
-#define PEBS_FREERUNNING_FLAGS \
+#define LARGE_PEBS_FLAGS \
        (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
        PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
        PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
@@ -608,7 +608,7 @@ struct x86_pmu {
        struct event_constraint *pebs_constraints;
        void            (*pebs_aliases)(struct perf_event *event);
        int             max_pebs_events;
-       unsigned long   free_running_flags;
+       unsigned long   large_pebs_flags;
 
        /*
         * Intel LBR
index 96cd33bbfc85494f52e4131f50b37129393d3b8a..6512498bbef69ced1f98c72afb5b11ade91ef4a5 100644 (file)
 #define AA(__x)                ((unsigned long)(__x))
 
 
-asmlinkage long sys32_truncate64(const char __user *filename,
-                                unsigned long offset_low,
-                                unsigned long offset_high)
+COMPAT_SYSCALL_DEFINE3(x86_truncate64, const char __user *, filename,
+                      unsigned long, offset_low, unsigned long, offset_high)
 {
        return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low);
 }
 
-asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long offset_low,
-                                 unsigned long offset_high)
+COMPAT_SYSCALL_DEFINE3(x86_ftruncate64, unsigned int, fd,
+                      unsigned long, offset_low, unsigned long, offset_high)
 {
        return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
 }
@@ -96,8 +95,8 @@ static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
        return 0;
 }
 
-asmlinkage long sys32_stat64(const char __user *filename,
-                            struct stat64 __user *statbuf)
+COMPAT_SYSCALL_DEFINE2(x86_stat64, const char __user *, filename,
+                      struct stat64 __user *, statbuf)
 {
        struct kstat stat;
        int ret = vfs_stat(filename, &stat);
@@ -107,8 +106,8 @@ asmlinkage long sys32_stat64(const char __user *filename,
        return ret;
 }
 
-asmlinkage long sys32_lstat64(const char __user *filename,
-                             struct stat64 __user *statbuf)
+COMPAT_SYSCALL_DEFINE2(x86_lstat64, const char __user *, filename,
+                      struct stat64 __user *, statbuf)
 {
        struct kstat stat;
        int ret = vfs_lstat(filename, &stat);
@@ -117,7 +116,8 @@ asmlinkage long sys32_lstat64(const char __user *filename,
        return ret;
 }
 
-asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
+COMPAT_SYSCALL_DEFINE2(x86_fstat64, unsigned int, fd,
+                      struct stat64 __user *, statbuf)
 {
        struct kstat stat;
        int ret = vfs_fstat(fd, &stat);
@@ -126,8 +126,9 @@ asmlinkage long sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
        return ret;
 }
 
-asmlinkage long sys32_fstatat(unsigned int dfd, const char __user *filename,
-                             struct stat64 __user *statbuf, int flag)
+COMPAT_SYSCALL_DEFINE4(x86_fstatat, unsigned int, dfd,
+                      const char __user *, filename,
+                      struct stat64 __user *, statbuf, int, flag)
 {
        struct kstat stat;
        int error;
@@ -153,7 +154,7 @@ struct mmap_arg_struct32 {
        unsigned int offset;
 };
 
-asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg)
+COMPAT_SYSCALL_DEFINE1(x86_mmap, struct mmap_arg_struct32 __user *, arg)
 {
        struct mmap_arg_struct32 a;
 
@@ -167,22 +168,22 @@ asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *arg)
                               a.offset>>PAGE_SHIFT);
 }
 
-asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int __user *stat_addr,
-                             int options)
+COMPAT_SYSCALL_DEFINE3(x86_waitpid, compat_pid_t, pid, unsigned int __user *,
+                      stat_addr, int, options)
 {
        return compat_sys_wait4(pid, stat_addr, options, NULL);
 }
 
 /* warning: next two assume little endian */
-asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count,
-                           u32 poslo, u32 poshi)
+COMPAT_SYSCALL_DEFINE5(x86_pread, unsigned int, fd, char __user *, ubuf,
+                      u32, count, u32, poslo, u32, poshi)
 {
        return sys_pread64(fd, ubuf, count,
                         ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage long sys32_pwrite(unsigned int fd, const char __user *ubuf,
-                            u32 count, u32 poslo, u32 poshi)
+COMPAT_SYSCALL_DEFINE5(x86_pwrite, unsigned int, fd, const char __user *, ubuf,
+                      u32, count, u32, poslo, u32, poshi)
 {
        return sys_pwrite64(fd, ubuf, count,
                          ((loff_t)AA(poshi) << 32) | AA(poslo));
@@ -193,8 +194,9 @@ asmlinkage long sys32_pwrite(unsigned int fd, const char __user *ubuf,
  * Some system calls that need sign extended arguments. This could be
  * done by a generic wrapper.
  */
-long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high,
-                       __u32 len_low, __u32 len_high, int advice)
+COMPAT_SYSCALL_DEFINE6(x86_fadvise64_64, int, fd, __u32, offset_low,
+                      __u32, offset_high, __u32, len_low, __u32, len_high,
+                      int, advice)
 {
        return sys_fadvise64_64(fd,
                               (((u64)offset_high)<<32) | offset_low,
@@ -202,31 +204,43 @@ long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high,
                                advice);
 }
 
-asmlinkage ssize_t sys32_readahead(int fd, unsigned off_lo, unsigned off_hi,
-                                  size_t count)
+COMPAT_SYSCALL_DEFINE4(x86_readahead, int, fd, unsigned int, off_lo,
+                      unsigned int, off_hi, size_t, count)
 {
        return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count);
 }
 
-asmlinkage long sys32_sync_file_range(int fd, unsigned off_low, unsigned off_hi,
-                                     unsigned n_low, unsigned n_hi,  int flags)
+COMPAT_SYSCALL_DEFINE6(x86_sync_file_range, int, fd, unsigned int, off_low,
+                      unsigned int, off_hi, unsigned int, n_low,
+                      unsigned int, n_hi, int, flags)
 {
        return sys_sync_file_range(fd,
                                   ((u64)off_hi << 32) | off_low,
                                   ((u64)n_hi << 32) | n_low, flags);
 }
 
-asmlinkage long sys32_fadvise64(int fd, unsigned offset_lo, unsigned offset_hi,
-                               size_t len, int advice)
+COMPAT_SYSCALL_DEFINE5(x86_fadvise64, int, fd, unsigned int, offset_lo,
+                      unsigned int, offset_hi, size_t, len, int, advice)
 {
        return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo,
                                len, advice);
 }
 
-asmlinkage long sys32_fallocate(int fd, int mode, unsigned offset_lo,
-                               unsigned offset_hi, unsigned len_lo,
-                               unsigned len_hi)
+COMPAT_SYSCALL_DEFINE6(x86_fallocate, int, fd, int, mode,
+                      unsigned int, offset_lo, unsigned int, offset_hi,
+                      unsigned int, len_lo, unsigned int, len_hi)
 {
        return sys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo,
                             ((u64)len_hi << 32) | len_lo);
 }
+
+/*
+ * The 32-bit clone ABI is CONFIG_CLONE_BACKWARDS
+ */
+COMPAT_SYSCALL_DEFINE5(x86_clone, unsigned long, clone_flags,
+                      unsigned long, newsp, int __user *, parent_tidptr,
+                      unsigned long, tls_val, int __user *, child_tidptr)
+{
+       return sys_clone(clone_flags, newsp, parent_tidptr, child_tidptr,
+                       tls_val);
+}
index 44f5d79d51056b036e7ef4536d7bfe340dae9747..11881726ed37290128f9bca07b9944aa2d818677 100644 (file)
@@ -94,7 +94,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
        if (boot_cpu_data.x86 == 0x0F &&
            boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
            boot_cpu_data.x86_model <= 0x05 &&
-           boot_cpu_data.x86_mask < 0x0A)
+           boot_cpu_data.x86_stepping < 0x0A)
                return 1;
        else if (boot_cpu_has(X86_BUG_AMD_APIC_C1E))
                return 1;
index 4d4015ddcf2633e9e8388216f9e9c8639e2eced8..c356098b6fb92b8ff7d42b2fd813c2a8551d3db1 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef _ASM_X86_MACH_DEFAULT_APM_H
 #define _ASM_X86_MACH_DEFAULT_APM_H
 
+#include <asm/nospec-branch.h>
+
 #ifdef APM_ZERO_SEGS
 #      define APM_DO_ZERO_SEGS \
                "pushl %%ds\n\t" \
@@ -32,6 +34,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
         * N.B. We do NOT need a cld after the BIOS call
         * because we always save and restore the flags.
         */
+       firmware_restrict_branch_speculation_start();
        __asm__ __volatile__(APM_DO_ZERO_SEGS
                "pushl %%edi\n\t"
                "pushl %%ebp\n\t"
@@ -44,6 +47,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,
                  "=S" (*esi)
                : "a" (func), "b" (ebx_in), "c" (ecx_in)
                : "memory", "cc");
+       firmware_restrict_branch_speculation_end();
 }
 
 static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in,
@@ -56,6 +60,7 @@ static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in,
         * N.B. We do NOT need a cld after the BIOS call
         * because we always save and restore the flags.
         */
+       firmware_restrict_branch_speculation_start();
        __asm__ __volatile__(APM_DO_ZERO_SEGS
                "pushl %%edi\n\t"
                "pushl %%ebp\n\t"
@@ -68,6 +73,7 @@ static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in,
                  "=S" (si)
                : "a" (func), "b" (ebx_in), "c" (ecx_in)
                : "memory", "cc");
+       firmware_restrict_branch_speculation_end();
        return error;
 }
 
index 4d111616524b2ee3c8d929ec98dd329b332811aa..1908214b91257f1d2442e2e6fc08b2f4c4f5bf65 100644 (file)
@@ -38,7 +38,4 @@ INDIRECT_THUNK(dx)
 INDIRECT_THUNK(si)
 INDIRECT_THUNK(di)
 INDIRECT_THUNK(bp)
-asmlinkage void __fill_rsb(void);
-asmlinkage void __clear_rsb(void);
-
 #endif /* CONFIG_RETPOLINE */
index 30d40614601641b9fc2dbd5ce734ff86d0cdd731..042b5e892ed1063769b253bdf35e31171eb55c4d 100644 (file)
@@ -40,7 +40,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
 
        asm ("cmp %1,%2; sbb %0,%0;"
                        :"=r" (mask)
-                       :"r"(size),"r" (index)
+                       :"g"(size),"r" (index)
                        :"cc");
        return mask;
 }
@@ -52,11 +52,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
 #define barrier_nospec() alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC, \
                                           "lfence", X86_FEATURE_LFENCE_RDTSC)
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()      rmb()
-#else
 #define dma_rmb()      barrier()
-#endif
 #define dma_wmb()      barrier()
 
 #ifdef CONFIG_X86_32
@@ -68,30 +64,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
 #define __smp_wmb()    barrier()
 #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
-#if defined(CONFIG_X86_PPRO_FENCE)
-
-/*
- * For this option x86 doesn't have a strong TSO memory
- * model and we should fall back to full barriers.
- */
-
-#define __smp_store_release(p, v)                                      \
-do {                                                                   \
-       compiletime_assert_atomic_type(*p);                             \
-       __smp_mb();                                                     \
-       WRITE_ONCE(*p, v);                                              \
-} while (0)
-
-#define __smp_load_acquire(p)                                          \
-({                                                                     \
-       typeof(*p) ___p1 = READ_ONCE(*p);                               \
-       compiletime_assert_atomic_type(*p);                             \
-       __smp_mb();                                                     \
-       ___p1;                                                          \
-})
-
-#else /* regular x86 TSO memory ordering */
-
 #define __smp_store_release(p, v)                                      \
 do {                                                                   \
        compiletime_assert_atomic_type(*p);                             \
@@ -107,8 +79,6 @@ do {                                                                 \
        ___p1;                                                          \
 })
 
-#endif
-
 /* Atomic operations are already serializing on x86 */
 #define __smp_mb__before_atomic()      barrier()
 #define __smp_mb__after_atomic()       barrier()
index 3fa039855b8f70aa2738468e33bef882b0a398cb..9f645ba57dbb263822600aae5d82138316c8f6e3 100644 (file)
@@ -78,7 +78,7 @@ set_bit(long nr, volatile unsigned long *addr)
                        : "iq" ((u8)CONST_MASK(nr))
                        : "memory");
        } else {
-               asm volatile(LOCK_PREFIX "bts %1,%0"
+               asm volatile(LOCK_PREFIX __ASM_SIZE(bts) " %1,%0"
                        : BITOP_ADDR(addr) : "Ir" (nr) : "memory");
        }
 }
@@ -94,7 +94,7 @@ set_bit(long nr, volatile unsigned long *addr)
  */
 static __always_inline void __set_bit(long nr, volatile unsigned long *addr)
 {
-       asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
+       asm volatile(__ASM_SIZE(bts) " %1,%0" : ADDR : "Ir" (nr) : "memory");
 }
 
 /**
@@ -115,7 +115,7 @@ clear_bit(long nr, volatile unsigned long *addr)
                        : CONST_MASK_ADDR(nr, addr)
                        : "iq" ((u8)~CONST_MASK(nr)));
        } else {
-               asm volatile(LOCK_PREFIX "btr %1,%0"
+               asm volatile(LOCK_PREFIX __ASM_SIZE(btr) " %1,%0"
                        : BITOP_ADDR(addr)
                        : "Ir" (nr));
        }
@@ -137,7 +137,7 @@ static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *ad
 
 static __always_inline void __clear_bit(long nr, volatile unsigned long *addr)
 {
-       asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
+       asm volatile(__ASM_SIZE(btr) " %1,%0" : ADDR : "Ir" (nr));
 }
 
 static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
@@ -182,7 +182,7 @@ static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *
  */
 static __always_inline void __change_bit(long nr, volatile unsigned long *addr)
 {
-       asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
+       asm volatile(__ASM_SIZE(btc) " %1,%0" : ADDR : "Ir" (nr));
 }
 
 /**
@@ -201,7 +201,7 @@ static __always_inline void change_bit(long nr, volatile unsigned long *addr)
                        : CONST_MASK_ADDR(nr, addr)
                        : "iq" ((u8)CONST_MASK(nr)));
        } else {
-               asm volatile(LOCK_PREFIX "btc %1,%0"
+               asm volatile(LOCK_PREFIX __ASM_SIZE(btc) " %1,%0"
                        : BITOP_ADDR(addr)
                        : "Ir" (nr));
        }
@@ -217,7 +217,8 @@ static __always_inline void change_bit(long nr, volatile unsigned long *addr)
  */
 static __always_inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
 {
-       GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", c);
+       GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(bts),
+                        *addr, "Ir", nr, "%0", c);
 }
 
 /**
@@ -246,7 +247,7 @@ static __always_inline bool __test_and_set_bit(long nr, volatile unsigned long *
 {
        bool oldbit;
 
-       asm("bts %2,%1"
+       asm(__ASM_SIZE(bts) " %2,%1"
            CC_SET(c)
            : CC_OUT(c) (oldbit), ADDR
            : "Ir" (nr));
@@ -263,7 +264,8 @@ static __always_inline bool __test_and_set_bit(long nr, volatile unsigned long *
  */
 static __always_inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
 {
-       GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", c);
+       GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btr),
+                        *addr, "Ir", nr, "%0", c);
 }
 
 /**
@@ -286,7 +288,7 @@ static __always_inline bool __test_and_clear_bit(long nr, volatile unsigned long
 {
        bool oldbit;
 
-       asm volatile("btr %2,%1"
+       asm volatile(__ASM_SIZE(btr) " %2,%1"
                     CC_SET(c)
                     : CC_OUT(c) (oldbit), ADDR
                     : "Ir" (nr));
@@ -298,7 +300,7 @@ static __always_inline bool __test_and_change_bit(long nr, volatile unsigned lon
 {
        bool oldbit;
 
-       asm volatile("btc %2,%1"
+       asm volatile(__ASM_SIZE(btc) " %2,%1"
                     CC_SET(c)
                     : CC_OUT(c) (oldbit), ADDR
                     : "Ir" (nr) : "memory");
@@ -316,7 +318,8 @@ static __always_inline bool __test_and_change_bit(long nr, volatile unsigned lon
  */
 static __always_inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
 {
-       GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", c);
+       GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btc),
+                        *addr, "Ir", nr, "%0", c);
 }
 
 static __always_inline bool constant_test_bit(long nr, const volatile unsigned long *addr)
@@ -329,7 +332,7 @@ static __always_inline bool variable_test_bit(long nr, volatile const unsigned l
 {
        bool oldbit;
 
-       asm volatile("bt %2,%1"
+       asm volatile(__ASM_SIZE(bt) " %2,%1"
                     CC_SET(c)
                     : CC_OUT(c) (oldbit)
                     : "m" (*(unsigned long *)addr), "Ir" (nr));
index 34d99af43994453e1cec89aa202cc17b052ee690..6804d66427673ec314659944e65052b5dfba273e 100644 (file)
@@ -5,23 +5,20 @@
 #include <linux/stringify.h>
 
 /*
- * Since some emulators terminate on UD2, we cannot use it for WARN.
- * Since various instruction decoders disagree on the length of UD1,
- * we cannot use it either. So use UD0 for WARN.
+ * Despite that some emulators terminate on UD2, we use it for WARN().
  *
- * (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas
- *  our kernel decoder thinks it takes a ModRM byte, which seems consistent
- *  with various things like the Intel SDM instruction encoding rules)
+ * Since various instruction decoders/specs disagree on the encoding of
+ * UD0/UD1.
  */
 
-#define ASM_UD0                ".byte 0x0f, 0xff"
+#define ASM_UD0                ".byte 0x0f, 0xff" /* + ModRM (for Intel) */
 #define ASM_UD1                ".byte 0x0f, 0xb9" /* + ModRM */
 #define ASM_UD2                ".byte 0x0f, 0x0b"
 
 #define INSN_UD0       0xff0f
 #define INSN_UD2       0x0b0f
 
-#define LEN_UD0                2
+#define LEN_UD2                2
 
 #ifdef CONFIG_GENERIC_BUG
 
@@ -77,7 +74,11 @@ do {                                                         \
        unreachable();                                          \
 } while (0)
 
-#define __WARN_FLAGS(flags)    _BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags))
+#define __WARN_FLAGS(flags)                                    \
+do {                                                           \
+       _BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags));           \
+       annotate_reachable();                                   \
+} while (0)
 
 #include <asm-generic/bug.h>
 
index 70eddb3922ff7b3e44fc27b9426da39aa4e2b6fa..736771c9822ef965233b7114fd0b1a025e8c3a46 100644 (file)
@@ -148,45 +148,46 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
  */
 static __always_inline __pure bool _static_cpu_has(u16 bit)
 {
-               asm_volatile_goto("1: jmp 6f\n"
-                        "2:\n"
-                        ".skip -(((5f-4f) - (2b-1b)) > 0) * "
-                                "((5f-4f) - (2b-1b)),0x90\n"
-                        "3:\n"
-                        ".section .altinstructions,\"a\"\n"
-                        " .long 1b - .\n"              /* src offset */
-                        " .long 4f - .\n"              /* repl offset */
-                        " .word %P1\n"                 /* always replace */
-                        " .byte 3b - 1b\n"             /* src len */
-                        " .byte 5f - 4f\n"             /* repl len */
-                        " .byte 3b - 2b\n"             /* pad len */
-                        ".previous\n"
-                        ".section .altinstr_replacement,\"ax\"\n"
-                        "4: jmp %l[t_no]\n"
-                        "5:\n"
-                        ".previous\n"
-                        ".section .altinstructions,\"a\"\n"
-                        " .long 1b - .\n"              /* src offset */
-                        " .long 0\n"                   /* no replacement */
-                        " .word %P0\n"                 /* feature bit */
-                        " .byte 3b - 1b\n"             /* src len */
-                        " .byte 0\n"                   /* repl len */
-                        " .byte 0\n"                   /* pad len */
-                        ".previous\n"
-                        ".section .altinstr_aux,\"ax\"\n"
-                        "6:\n"
-                        " testb %[bitnum],%[cap_byte]\n"
-                        " jnz %l[t_yes]\n"
-                        " jmp %l[t_no]\n"
-                        ".previous\n"
-                        : : "i" (bit), "i" (X86_FEATURE_ALWAYS),
-                            [bitnum] "i" (1 << (bit & 7)),
-                            [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
-                        : : t_yes, t_no);
-       t_yes:
-               return true;
-       t_no:
-               return false;
+       asm_volatile_goto("1: jmp 6f\n"
+                "2:\n"
+                ".skip -(((5f-4f) - (2b-1b)) > 0) * "
+                        "((5f-4f) - (2b-1b)),0x90\n"
+                "3:\n"
+                ".section .altinstructions,\"a\"\n"
+                " .long 1b - .\n"              /* src offset */
+                " .long 4f - .\n"              /* repl offset */
+                " .word %P[always]\n"          /* always replace */
+                " .byte 3b - 1b\n"             /* src len */
+                " .byte 5f - 4f\n"             /* repl len */
+                " .byte 3b - 2b\n"             /* pad len */
+                ".previous\n"
+                ".section .altinstr_replacement,\"ax\"\n"
+                "4: jmp %l[t_no]\n"
+                "5:\n"
+                ".previous\n"
+                ".section .altinstructions,\"a\"\n"
+                " .long 1b - .\n"              /* src offset */
+                " .long 0\n"                   /* no replacement */
+                " .word %P[feature]\n"         /* feature bit */
+                " .byte 3b - 1b\n"             /* src len */
+                " .byte 0\n"                   /* repl len */
+                " .byte 0\n"                   /* pad len */
+                ".previous\n"
+                ".section .altinstr_aux,\"ax\"\n"
+                "6:\n"
+                " testb %[bitnum],%[cap_byte]\n"
+                " jnz %l[t_yes]\n"
+                " jmp %l[t_no]\n"
+                ".previous\n"
+                : : [feature]  "i" (bit),
+                    [always]   "i" (X86_FEATURE_ALWAYS),
+                    [bitnum]   "i" (1 << (bit & 7)),
+                    [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
+                : : t_yes, t_no);
+t_yes:
+       return true;
+t_no:
+       return false;
 }
 
 #define static_cpu_has(bit)                                    \
index 0dfe4d3f74e24d6655fc40f0460b9e489fb9ef69..d554c11e01ff46742d53148df0ffb9c3476e8d6e 100644 (file)
 #define X86_FEATURE_SEV                        ( 7*32+20) /* AMD Secure Encrypted Virtualization */
 
 #define X86_FEATURE_USE_IBPB           ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
+#define X86_FEATURE_USE_IBRS_FW                ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW         ( 8*32+ 0) /* Intel TPR Shadow */
 #define X86_FEATURE_VPCLMULQDQ         (16*32+10) /* Carry-Less Multiplication Double Quadword */
 #define X86_FEATURE_AVX512_VNNI                (16*32+11) /* Vector Neural Network Instructions */
 #define X86_FEATURE_AVX512_BITALG      (16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */
+#define X86_FEATURE_TME                        (16*32+13) /* Intel Total Memory Encryption */
 #define X86_FEATURE_AVX512_VPOPCNTDQ   (16*32+14) /* POPCNT for vectors of DW/QW */
 #define X86_FEATURE_LA57               (16*32+16) /* 5-level page tables */
 #define X86_FEATURE_RDPID              (16*32+22) /* RDPID instruction */
 /* 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_PCONFIG            (18*32+18) /* Intel PCONFIG */
 #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) */
index 85f6ccb80b91771029f347f1875f7a6d923ef184..a399c1ebf6f0e6d974da0b773248b9c0cfe811a9 100644 (file)
@@ -6,6 +6,7 @@
 #include <asm/pgtable.h>
 #include <asm/processor-flags.h>
 #include <asm/tlb.h>
+#include <asm/nospec-branch.h>
 
 /*
  * We map the EFI regions needed for runtime services non-contiguously,
 
 extern asmlinkage unsigned long efi_call_phys(void *, ...);
 
-#define arch_efi_call_virt_setup()     kernel_fpu_begin()
-#define arch_efi_call_virt_teardown()  kernel_fpu_end()
+#define arch_efi_call_virt_setup()                                     \
+({                                                                     \
+       kernel_fpu_begin();                                             \
+       firmware_restrict_branch_speculation_start();                   \
+})
+
+#define arch_efi_call_virt_teardown()                                  \
+({                                                                     \
+       firmware_restrict_branch_speculation_end();                     \
+       kernel_fpu_end();                                               \
+})
+
 
 /*
  * Wrap all the virtual calls in a way that forces the parameters on the stack.
@@ -73,6 +84,7 @@ struct efi_scratch {
        efi_sync_low_kernel_mappings();                                 \
        preempt_disable();                                              \
        __kernel_fpu_begin();                                           \
+       firmware_restrict_branch_speculation_start();                   \
                                                                        \
        if (efi_scratch.use_pgd) {                                      \
                efi_scratch.prev_cr3 = __read_cr3();                    \
@@ -91,6 +103,7 @@ struct efi_scratch {
                __flush_tlb_all();                                      \
        }                                                               \
                                                                        \
+       firmware_restrict_branch_speculation_end();                     \
        __kernel_fpu_end();                                             \
        preempt_enable();                                               \
 })
index 95e948627fd04878883041543c3b5f13703ceaa9..f6e5b9375d8c324644e1f8ddb221fa625e063f3b 100644 (file)
@@ -232,21 +232,6 @@ extern void set_iounmap_nonlazy(void);
  */
 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
 
-/*
- *     Cache management
- *
- *     This needed for two cases
- *     1. Out of order aware processors
- *     2. Accidentally out of order processors (PPro errata #51)
- */
-
-static inline void flush_write_buffers(void)
-{
-#if defined(CONFIG_X86_PPRO_FENCE)
-       asm volatile("lock; addl $0,0(%%esp)": : :"memory");
-#endif
-}
-
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
index dd6f57a54a2626c080c8505cd670ef8c54c7bf56..b605a5b6a30c38f1bdcf647be241516b5e1310b8 100644 (file)
@@ -507,6 +507,7 @@ struct kvm_vcpu_arch {
        u64 smi_count;
        bool tpr_access_reporting;
        u64 ia32_xss;
+       u64 microcode_version;
 
        /*
         * Paging state of the vcpu
@@ -1095,6 +1096,8 @@ struct kvm_x86_ops {
        int (*mem_enc_op)(struct kvm *kvm, void __user *argp);
        int (*mem_enc_reg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
        int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region *argp);
+
+       int (*get_msr_feature)(struct kvm_msr_entry *entry);
 };
 
 struct kvm_arch_async_pf {
@@ -1464,7 +1467,4 @@ static inline int kvm_cpu_get_apicid(int mps_cpu)
 #define put_smstate(type, buf, offset, val)                      \
        *(type *)((buf) + (offset) - 0x7e00) = val
 
-void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
-               unsigned long start, unsigned long end);
-
 #endif /* _ASM_X86_KVM_HOST_H */
index 55520cec8b27d69727092e6fd81d3a0c0f4db252..6cf0e4cb7b9763a7d4d10438017a73aac737720b 100644 (file)
@@ -37,7 +37,13 @@ struct cpu_signature {
 
 struct device;
 
-enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND };
+enum ucode_state {
+       UCODE_OK        = 0,
+       UCODE_NEW,
+       UCODE_UPDATED,
+       UCODE_NFOUND,
+       UCODE_ERROR,
+};
 
 struct microcode_ops {
        enum ucode_state (*request_microcode_user) (int cpu,
@@ -54,7 +60,7 @@ struct microcode_ops {
         * are being called.
         * See also the "Synchronization" section in microcode_core.c.
         */
-       int (*apply_microcode) (int cpu);
+       enum ucode_state (*apply_microcode) (int cpu);
        int (*collect_cpu_info) (int cpu, struct cpu_signature *csig);
 };
 
index c931b88982a0ff59e3b67947cc606e452f327dc0..1de72ce514cd5561dbafea43996d909f449f8766 100644 (file)
@@ -74,6 +74,7 @@ static inline void *ldt_slot_va(int slot)
        return (void *)(LDT_BASE_ADDR + LDT_SLOT_STRIDE * slot);
 #else
        BUG();
+       return (void *)fix_to_virt(FIX_HOLE);
 #endif
 }
 
index 4d57894635f242da061e6a10acccaec70ae1dbc0..f928ad9b143fedea1085dedc508658fa745b4ceb 100644 (file)
@@ -6,6 +6,51 @@
 #include <asm/alternative.h>
 #include <asm/alternative-asm.h>
 #include <asm/cpufeatures.h>
+#include <asm/msr-index.h>
+
+/*
+ * Fill the CPU return stack buffer.
+ *
+ * Each entry in the RSB, if used for a speculative 'ret', contains an
+ * infinite 'pause; lfence; jmp' loop to capture speculative execution.
+ *
+ * This is required in various cases for retpoline and IBRS-based
+ * mitigations for the Spectre variant 2 vulnerability. Sometimes to
+ * eliminate potentially bogus entries from the RSB, and sometimes
+ * purely to ensure that it doesn't get empty, which on some CPUs would
+ * allow predictions from other (unwanted!) sources to be used.
+ *
+ * We define a CPP macro such that it can be used from both .S files and
+ * inline assembly. It's possible to do a .macro and then include that
+ * from C via asm(".include <asm/nospec-branch.h>") but let's not go there.
+ */
+
+#define RSB_CLEAR_LOOPS                32      /* To forcibly overwrite all entries */
+#define RSB_FILL_LOOPS         16      /* To avoid underflow */
+
+/*
+ * Google experimented with loop-unrolling and this turned out to be
+ * the optimal version â€” two calls, each with their own speculation
+ * trap should their return address end up getting used, in a loop.
+ */
+#define __FILL_RETURN_BUFFER(reg, nr, sp)      \
+       mov     $(nr/2), reg;                   \
+771:                                           \
+       call    772f;                           \
+773:   /* speculation trap */                  \
+       pause;                                  \
+       lfence;                                 \
+       jmp     773b;                           \
+772:                                           \
+       call    774f;                           \
+775:   /* speculation trap */                  \
+       pause;                                  \
+       lfence;                                 \
+       jmp     775b;                           \
+774:                                           \
+       dec     reg;                            \
+       jnz     771b;                           \
+       add     $(BITS_PER_LONG/8) * nr, sp;
 
 #ifdef __ASSEMBLY__
 
        .popsection
 .endm
 
+/*
+ * This should be used immediately before an indirect jump/call. It tells
+ * objtool the subsequent indirect jump/call is vouched safe for retpoline
+ * builds.
+ */
+.macro ANNOTATE_RETPOLINE_SAFE
+       .Lannotate_\@:
+       .pushsection .discard.retpoline_safe
+       _ASM_PTR .Lannotate_\@
+       .popsection
+.endm
+
 /*
  * These are the bare retpoline primitives for indirect jmp and call.
  * Do not use these directly; they only exist to make the ALTERNATIVE
 .macro JMP_NOSPEC reg:req
 #ifdef CONFIG_RETPOLINE
        ANNOTATE_NOSPEC_ALTERNATIVE
-       ALTERNATIVE_2 __stringify(jmp *\reg),                           \
+       ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg),  \
                __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \
-               __stringify(lfence; jmp *\reg), X86_FEATURE_RETPOLINE_AMD
+               __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD
 #else
        jmp     *\reg
 #endif
 .macro CALL_NOSPEC reg:req
 #ifdef CONFIG_RETPOLINE
        ANNOTATE_NOSPEC_ALTERNATIVE
-       ALTERNATIVE_2 __stringify(call *\reg),                          \
+       ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg), \
                __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\
-               __stringify(lfence; call *\reg), X86_FEATURE_RETPOLINE_AMD
+               __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD
 #else
        call    *\reg
 #endif
 .endm
 
-/* This clobbers the BX register */
-.macro FILL_RETURN_BUFFER nr:req ftr:req
+ /*
+  * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
+  * monstrosity above, manually.
+  */
+.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req
 #ifdef CONFIG_RETPOLINE
-       ALTERNATIVE "", "call __clear_rsb", \ftr
+       ANNOTATE_NOSPEC_ALTERNATIVE
+       ALTERNATIVE "jmp .Lskip_rsb_\@",                                \
+               __stringify(__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP))    \
+               \ftr
+.Lskip_rsb_\@:
 #endif
 .endm
 
        ".long 999b - .\n\t"                                    \
        ".popsection\n\t"
 
+#define ANNOTATE_RETPOLINE_SAFE                                        \
+       "999:\n\t"                                              \
+       ".pushsection .discard.retpoline_safe\n\t"              \
+       _ASM_PTR " 999b\n\t"                                    \
+       ".popsection\n\t"
+
 #if defined(CONFIG_X86_64) && defined(RETPOLINE)
 
 /*
 # define CALL_NOSPEC                                           \
        ANNOTATE_NOSPEC_ALTERNATIVE                             \
        ALTERNATIVE(                                            \
+       ANNOTATE_RETPOLINE_SAFE                                 \
        "call *%[thunk_target]\n",                              \
        "call __x86_indirect_thunk_%V[thunk_target]\n",         \
        X86_FEATURE_RETPOLINE)
  * otherwise we'll run out of registers. We don't care about CET
  * here, anyway.
  */
-# define CALL_NOSPEC ALTERNATIVE("call *%[thunk_target]\n",    \
+# define CALL_NOSPEC                                           \
+       ALTERNATIVE(                                            \
+       ANNOTATE_RETPOLINE_SAFE                                 \
+       "call *%[thunk_target]\n",                              \
        "       jmp    904f;\n"                                 \
        "       .align 16\n"                                    \
        "901:   call   903f;\n"                                 \
@@ -155,20 +229,90 @@ extern char __indirect_thunk_end[];
 static inline void vmexit_fill_RSB(void)
 {
 #ifdef CONFIG_RETPOLINE
-       alternative_input("",
-                         "call __fill_rsb",
-                         X86_FEATURE_RETPOLINE,
-                         ASM_NO_INPUT_CLOBBER(_ASM_BX, "memory"));
+       unsigned long loops;
+
+       asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE
+                     ALTERNATIVE("jmp 910f",
+                                 __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)),
+                                 X86_FEATURE_RETPOLINE)
+                     "910:"
+                     : "=r" (loops), ASM_CALL_CONSTRAINT
+                     : : "memory" );
 #endif
 }
 
+#define alternative_msr_write(_msr, _val, _feature)            \
+       asm volatile(ALTERNATIVE("",                            \
+                                "movl %[msr], %%ecx\n\t"       \
+                                "movl %[val], %%eax\n\t"       \
+                                "movl $0, %%edx\n\t"           \
+                                "wrmsr",                       \
+                                _feature)                      \
+                    : : [msr] "i" (_msr), [val] "i" (_val)     \
+                    : "eax", "ecx", "edx", "memory")
+
 static inline void indirect_branch_prediction_barrier(void)
 {
-       alternative_input("",
-                         "call __ibp_barrier",
-                         X86_FEATURE_USE_IBPB,
-                         ASM_NO_INPUT_CLOBBER("eax", "ecx", "edx", "memory"));
+       alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB,
+                             X86_FEATURE_USE_IBPB);
 }
 
+/*
+ * With retpoline, we must use IBRS to restrict branch prediction
+ * before calling into firmware.
+ *
+ * (Implemented as CPP macros due to header hell.)
+ */
+#define firmware_restrict_branch_speculation_start()                   \
+do {                                                                   \
+       preempt_disable();                                              \
+       alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS,       \
+                             X86_FEATURE_USE_IBRS_FW);                 \
+} while (0)
+
+#define firmware_restrict_branch_speculation_end()                     \
+do {                                                                   \
+       alternative_msr_write(MSR_IA32_SPEC_CTRL, 0,                    \
+                             X86_FEATURE_USE_IBRS_FW);                 \
+       preempt_enable();                                               \
+} while (0)
+
 #endif /* __ASSEMBLY__ */
+
+/*
+ * Below is used in the eBPF JIT compiler and emits the byte sequence
+ * for the following assembly:
+ *
+ * With retpolines configured:
+ *
+ *    callq do_rop
+ *  spec_trap:
+ *    pause
+ *    lfence
+ *    jmp spec_trap
+ *  do_rop:
+ *    mov %rax,(%rsp)
+ *    retq
+ *
+ * Without retpolines configured:
+ *
+ *    jmp *%rax
+ */
+#ifdef CONFIG_RETPOLINE
+# define RETPOLINE_RAX_BPF_JIT_SIZE    17
+# define RETPOLINE_RAX_BPF_JIT()                               \
+       EMIT1_off32(0xE8, 7);    /* callq do_rop */             \
+       /* spec_trap: */                                        \
+       EMIT2(0xF3, 0x90);       /* pause */                    \
+       EMIT3(0x0F, 0xAE, 0xE8); /* lfence */                   \
+       EMIT2(0xEB, 0xF9);       /* jmp spec_trap */            \
+       /* do_rop: */                                           \
+       EMIT4(0x48, 0x89, 0x04, 0x24); /* mov %rax,(%rsp) */    \
+       EMIT1(0xC3);             /* retq */
+#else
+# define RETPOLINE_RAX_BPF_JIT_SIZE    2
+# define RETPOLINE_RAX_BPF_JIT()                               \
+       EMIT2(0xFF, 0xE0);       /* jmp *%rax */
+#endif
+
 #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */
index 4baa6bceb2325e6dd056ca682e1eeeb435693a26..d652a38080659775ef145d089291bde353ffe97a 100644 (file)
@@ -52,10 +52,6 @@ static inline void clear_page(void *page)
 
 void copy_page(void *to, void *from);
 
-#ifdef CONFIG_X86_MCE
-#define arch_unmap_kpfn arch_unmap_kpfn
-#endif
-
 #endif /* !__ASSEMBLY__ */
 
 #ifdef CONFIG_X86_VSYSCALL_EMULATION
index 892df375b6155a51f584760efb9f9e77c3f732e8..c83a2f418cea097bb2c5a9545409c5e6efcbbc50 100644 (file)
@@ -7,6 +7,7 @@
 #ifdef CONFIG_PARAVIRT
 #include <asm/pgtable_types.h>
 #include <asm/asm.h>
+#include <asm/nospec-branch.h>
 
 #include <asm/paravirt_types.h>
 
@@ -297,9 +298,9 @@ static inline void __flush_tlb_global(void)
 {
        PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel);
 }
-static inline void __flush_tlb_single(unsigned long addr)
+static inline void __flush_tlb_one_user(unsigned long addr)
 {
-       PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr);
+       PVOP_VCALL1(pv_mmu_ops.flush_tlb_one_user, addr);
 }
 
 static inline void flush_tlb_others(const struct cpumask *cpumask,
@@ -879,23 +880,27 @@ extern void default_banner(void);
 
 #define INTERRUPT_RETURN                                               \
        PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE,       \
-                 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret))
+                 ANNOTATE_RETPOLINE_SAFE;                                      \
+                 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret);)
 
 #define DISABLE_INTERRUPTS(clobbers)                                   \
        PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
                  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);            \
+                 ANNOTATE_RETPOLINE_SAFE;                                      \
                  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable);    \
                  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 
 #define ENABLE_INTERRUPTS(clobbers)                                    \
        PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers,  \
                  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);            \
+                 ANNOTATE_RETPOLINE_SAFE;                                      \
                  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable);     \
                  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 
 #ifdef CONFIG_X86_32
 #define GET_CR0_INTO_EAX                               \
        push %ecx; push %edx;                           \
+       ANNOTATE_RETPOLINE_SAFE;                                \
        call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
        pop %edx; pop %ecx
 #else  /* !CONFIG_X86_32 */
@@ -917,21 +922,25 @@ extern void default_banner(void);
  */
 #define SWAPGS                                                         \
        PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,     \
-                 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs)          \
+                 ANNOTATE_RETPOLINE_SAFE;                                      \
+                 call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs);         \
                 )
 
 #define GET_CR2_INTO_RAX                               \
-       call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2)
+       ANNOTATE_RETPOLINE_SAFE;                                \
+       call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2);
 
 #define USERGS_SYSRET64                                                        \
        PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64),       \
                  CLBR_NONE,                                            \
-                 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64))
+                 ANNOTATE_RETPOLINE_SAFE;                                      \
+                 jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64);)
 
 #ifdef CONFIG_DEBUG_ENTRY
 #define SAVE_FLAGS(clobbers)                                        \
        PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_save_fl), clobbers, \
                  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);        \
+                 ANNOTATE_RETPOLINE_SAFE;                                  \
                  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_save_fl);    \
                  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
 #endif
index 6ec54d01972dcf7d79e75bcfbecc84a1f2da80ea..180bc0bff0fbd98195b8e81ce9aa7232dde06ee2 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/desc_defs.h>
 #include <asm/kmap_types.h>
 #include <asm/pgtable_types.h>
+#include <asm/nospec-branch.h>
 
 struct page;
 struct thread_struct;
@@ -217,7 +218,7 @@ struct pv_mmu_ops {
        /* TLB operations */
        void (*flush_tlb_user)(void);
        void (*flush_tlb_kernel)(void);
-       void (*flush_tlb_single)(unsigned long addr);
+       void (*flush_tlb_one_user)(unsigned long addr);
        void (*flush_tlb_others)(const struct cpumask *cpus,
                                 const struct flush_tlb_info *info);
 
@@ -392,7 +393,9 @@ int paravirt_disable_iospace(void);
  * offset into the paravirt_patch_template structure, and can therefore be
  * freely converted back into a structure offset.
  */
-#define PARAVIRT_CALL  "call *%c[paravirt_opptr];"
+#define PARAVIRT_CALL                                  \
+       ANNOTATE_RETPOLINE_SAFE                         \
+       "call *%c[paravirt_opptr];"
 
 /*
  * These macros are intended to wrap calls through one of the paravirt
index ba3c523aaf1618fdf6dfb35ade4c643799deec29..a06b07399d172c06b428936dc14e033ae9697298 100644 (file)
@@ -526,7 +526,7 @@ static inline bool x86_this_cpu_variable_test_bit(int nr,
 {
        bool oldbit;
 
-       asm volatile("bt "__percpu_arg(2)",%1"
+       asm volatile("btl "__percpu_arg(2)",%1"
                        CC_SET(c)
                        : CC_OUT(c) (oldbit)
                        : "m" (*(unsigned long __percpu *)addr), "Ir" (nr));
index 63c2552b6b6547b71bd7aa0934bc3c8c2cb54dc1..b444d83cfc952fc121d77599a938bbcc6c0d864b 100644 (file)
@@ -350,14 +350,14 @@ static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
 {
        pmdval_t v = native_pmd_val(pmd);
 
-       return __pmd(v | set);
+       return native_make_pmd(v | set);
 }
 
 static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear)
 {
        pmdval_t v = native_pmd_val(pmd);
 
-       return __pmd(v & ~clear);
+       return native_make_pmd(v & ~clear);
 }
 
 static inline pmd_t pmd_mkold(pmd_t pmd)
@@ -409,14 +409,14 @@ static inline pud_t pud_set_flags(pud_t pud, pudval_t set)
 {
        pudval_t v = native_pud_val(pud);
 
-       return __pud(v | set);
+       return native_make_pud(v | set);
 }
 
 static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear)
 {
        pudval_t v = native_pud_val(pud);
 
-       return __pud(v & ~clear);
+       return native_make_pud(v & ~clear);
 }
 
 static inline pud_t pud_mkold(pud_t pud)
index e67c0620aec2a268537b46d1da80ce6d0ef174a5..b3ec519e39827e58eaeb8a567303e37a6bc2e919 100644 (file)
@@ -32,6 +32,7 @@ extern pmd_t initial_pg_pmd[];
 static inline void pgtable_cache_init(void) { }
 static inline void check_pgt_cache(void) { }
 void paging_init(void);
+void sync_initial_page_table(void);
 
 /*
  * Define this if things work differently on an i386 and an i486:
@@ -61,7 +62,7 @@ void paging_init(void);
 #define kpte_clear_flush(ptep, vaddr)          \
 do {                                           \
        pte_clear(&init_mm, (vaddr), (ptep));   \
-       __flush_tlb_one((vaddr));               \
+       __flush_tlb_one_kernel((vaddr));                \
 } while (0)
 
 #endif /* !__ASSEMBLY__ */
index 81462e9a34f6af49645a08f55c7d67e0144dbb77..1149d2112b2e17347e8f85c4cae355f4522cc40a 100644 (file)
@@ -28,6 +28,7 @@ extern pgd_t init_top_pgt[];
 #define swapper_pg_dir init_top_pgt
 
 extern void paging_init(void);
+static inline void sync_initial_page_table(void) { }
 
 #define pte_ERROR(e)                                   \
        pr_err("%s:%d: bad pte %p(%016lx)\n",           \
index 3696398a9475fe78500c8c0a62922620d975453c..acfe755562a6aa85ecd74294fa1d063093223976 100644 (file)
@@ -174,7 +174,6 @@ enum page_cache_mode {
 #define __PAGE_KERNEL_RO               (__PAGE_KERNEL & ~_PAGE_RW)
 #define __PAGE_KERNEL_RX               (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
 #define __PAGE_KERNEL_NOCACHE          (__PAGE_KERNEL | _PAGE_NOCACHE)
-#define __PAGE_KERNEL_VSYSCALL         (__PAGE_KERNEL_RX | _PAGE_USER)
 #define __PAGE_KERNEL_VVAR             (__PAGE_KERNEL_RO | _PAGE_USER)
 #define __PAGE_KERNEL_LARGE            (__PAGE_KERNEL | _PAGE_PSE)
 #define __PAGE_KERNEL_LARGE_EXEC       (__PAGE_KERNEL_EXEC | _PAGE_PSE)
@@ -206,7 +205,6 @@ enum page_cache_mode {
 #define PAGE_KERNEL_NOCACHE    __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC)
 #define PAGE_KERNEL_LARGE      __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC)
 #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC)
-#define PAGE_KERNEL_VSYSCALL   __pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC)
 #define PAGE_KERNEL_VVAR       __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC)
 
 #define PAGE_KERNEL_IO         __pgprot(__PAGE_KERNEL_IO)
@@ -323,6 +321,11 @@ static inline pudval_t native_pud_val(pud_t pud)
 #else
 #include <asm-generic/pgtable-nopud.h>
 
+static inline pud_t native_make_pud(pudval_t val)
+{
+       return (pud_t) { .p4d.pgd = native_make_pgd(val) };
+}
+
 static inline pudval_t native_pud_val(pud_t pud)
 {
        return native_pgd_val(pud.p4d.pgd);
@@ -344,6 +347,11 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
 #else
 #include <asm-generic/pgtable-nopmd.h>
 
+static inline pmd_t native_make_pmd(pmdval_t val)
+{
+       return (pmd_t) { .pud.p4d.pgd = native_make_pgd(val) };
+}
+
 static inline pmdval_t native_pmd_val(pmd_t pmd)
 {
        return native_pgd_val(pmd.pud.p4d.pgd);
index 5973a2f3db3d709dabc0c88171aecf6f65c4466a..059823bb8af77ad4eb46f10017a0f0aa7ae68689 100644 (file)
@@ -135,6 +135,7 @@ struct sst_platform_info {
        const struct sst_res_info *res_info;
        const struct sst_lib_dnld_info *lib_info;
        const char *platform;
+       bool streams_lost_on_suspend;
 };
 int add_sst_platform_device(void);
 #endif
index 793bae7e7ce36bd36e728a8a6fe7f8e17b9920db..b0ccd4847a58ab671476f412905a1df912029f1a 100644 (file)
@@ -91,7 +91,7 @@ struct cpuinfo_x86 {
        __u8                    x86;            /* CPU family */
        __u8                    x86_vendor;     /* CPU vendor */
        __u8                    x86_model;
-       __u8                    x86_mask;
+       __u8                    x86_stepping;
 #ifdef CONFIG_X86_64
        /* Number of 4K pages in DTLB/ITLB combined(in pages): */
        int                     x86_tlbsize;
@@ -109,7 +109,7 @@ struct cpuinfo_x86 {
        char                    x86_vendor_id[16];
        char                    x86_model_id[64];
        /* in KB - valid for CPUS which support this call: */
-       int                     x86_cache_size;
+       unsigned int            x86_cache_size;
        int                     x86_cache_alignment;    /* In bytes */
        /* Cache QoS architectural values: */
        int                     x86_cache_max_rmid;     /* max index */
@@ -977,7 +977,5 @@ bool xen_set_default_idle(void);
 
 void stop_this_cpu(void *dummy);
 void df_debug(struct pt_regs *regs, long error_code);
-
-void __ibp_barrier(void);
-
+void microcode_check(void);
 #endif /* _ASM_X86_PROCESSOR_H */
index 4e44250e7d0d75c6db385dbf151583b31d3e8c19..4cf11d88d3b35f48b89fc0413d6db70ec9877075 100644 (file)
@@ -17,7 +17,7 @@
 #define _REFCOUNT_EXCEPTION                            \
        ".pushsection .text..refcount\n"                \
        "111:\tlea %[counter], %%" _ASM_CX "\n"         \
-       "112:\t" ASM_UD0 "\n"                           \
+       "112:\t" ASM_UD2 "\n"                           \
        ASM_UNREACHABLE                                 \
        ".popsection\n"                                 \
        "113:\n"                                        \
@@ -67,13 +67,13 @@ static __always_inline __must_check
 bool refcount_sub_and_test(unsigned int i, refcount_t *r)
 {
        GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", REFCOUNT_CHECK_LT_ZERO,
-                                 r->refs.counter, "er", i, "%0", e);
+                                 r->refs.counter, "er", i, "%0", e, "cx");
 }
 
 static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r)
 {
        GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", REFCOUNT_CHECK_LT_ZERO,
-                                r->refs.counter, "%0", e);
+                                r->refs.counter, "%0", e, "cx");
 }
 
 static __always_inline __must_check
index f91c365e57c36d2454806ff21a2d336dae5c6863..4914a3e7c8035538a167c0dc23a2a33afd4a1ca2 100644 (file)
@@ -2,8 +2,7 @@
 #ifndef _ASM_X86_RMWcc
 #define _ASM_X86_RMWcc
 
-#define __CLOBBERS_MEM         "memory"
-#define __CLOBBERS_MEM_CC_CX   "memory", "cc", "cx"
+#define __CLOBBERS_MEM(clb...) "memory", ## clb
 
 #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO)
 
@@ -40,18 +39,19 @@ do {                                                                        \
 #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */
 
 #define GEN_UNARY_RMWcc(op, var, arg0, cc)                             \
-       __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM)
+       __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM())
 
-#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc)            \
+#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc, clobbers...)\
        __GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc,                 \
-                   __CLOBBERS_MEM_CC_CX)
+                   __CLOBBERS_MEM(clobbers))
 
 #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)                 \
        __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc,                \
-                   __CLOBBERS_MEM, vcon (val))
+                   __CLOBBERS_MEM(), vcon (val))
 
-#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc)        \
+#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc,        \
+                                 clobbers...)                          \
        __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc,  \
-                   __CLOBBERS_MEM_CC_CX, vcon (val))
+                   __CLOBBERS_MEM(clobbers), vcon (val))
 
 #endif /* _ASM_X86_RMWcc */
index d6baf23782bcc23811c12bac8a6a181c2a6cdb5b..5c019d23d06b1168da0ea965d7c35bebd4d02307 100644 (file)
@@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[];
 
 #if defined(CONFIG_X86_64)
 extern char __end_rodata_hpage_align[];
+extern char __entry_trampoline_start[], __entry_trampoline_end[];
 #endif
 
 #endif /* _ASM_X86_SECTIONS_H */
index 461f53d27708ae8b80622753122c1a4927537ee2..a4189762b2667016e1e07a0942ff9eaecab9ba51 100644 (file)
@@ -129,6 +129,7 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 void cpu_disable_common(void);
 void native_smp_prepare_boot_cpu(void);
 void native_smp_prepare_cpus(unsigned int max_cpus);
+void calculate_max_logical_packages(void);
 void native_smp_cpus_done(unsigned int max_cpus);
 void common_cpu_up(unsigned int cpunum, struct task_struct *tidle);
 int native_cpu_up(unsigned int cpunum, struct task_struct *tidle);
index 82c34ee25a651760c9950ce6c54625896fd9ea2f..906794aa034e732ec57d32a8be0ef77085a553a6 100644 (file)
 #include <asm/ia32.h>
 
 /* ia32/sys_ia32.c */
-asmlinkage long sys32_truncate64(const char __user *, unsigned long, unsigned long);
-asmlinkage long sys32_ftruncate64(unsigned int, unsigned long, unsigned long);
+asmlinkage long compat_sys_x86_truncate64(const char __user *, unsigned long,
+                                         unsigned long);
+asmlinkage long compat_sys_x86_ftruncate64(unsigned int, unsigned long,
+                                          unsigned long);
 
-asmlinkage long sys32_stat64(const char __user *, struct stat64 __user *);
-asmlinkage long sys32_lstat64(const char __user *, struct stat64 __user *);
-asmlinkage long sys32_fstat64(unsigned int, struct stat64 __user *);
-asmlinkage long sys32_fstatat(unsigned int, const char __user *,
+asmlinkage long compat_sys_x86_stat64(const char __user *,
+                                     struct stat64 __user *);
+asmlinkage long compat_sys_x86_lstat64(const char __user *,
+                                      struct stat64 __user *);
+asmlinkage long compat_sys_x86_fstat64(unsigned int, struct stat64 __user *);
+asmlinkage long compat_sys_x86_fstatat(unsigned int, const char __user *,
                              struct stat64 __user *, int);
 struct mmap_arg_struct32;
-asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *);
+asmlinkage long compat_sys_x86_mmap(struct mmap_arg_struct32 __user *);
 
-asmlinkage long sys32_waitpid(compat_pid_t, unsigned int __user *, int);
+asmlinkage long compat_sys_x86_waitpid(compat_pid_t, unsigned int __user *,
+                                      int);
 
-asmlinkage long sys32_pread(unsigned int, char __user *, u32, u32, u32);
-asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32);
+asmlinkage long compat_sys_x86_pread(unsigned int, char __user *, u32, u32,
+                                    u32);
+asmlinkage long compat_sys_x86_pwrite(unsigned int, const char __user *, u32,
+                                     u32, u32);
 
-long sys32_fadvise64_64(int, __u32, __u32, __u32, __u32, int);
-long sys32_vm86_warning(void);
+asmlinkage long compat_sys_x86_fadvise64_64(int, __u32, __u32, __u32, __u32,
+                                           int);
 
-asmlinkage ssize_t sys32_readahead(int, unsigned, unsigned, size_t);
-asmlinkage long sys32_sync_file_range(int, unsigned, unsigned,
-                                     unsigned, unsigned, int);
-asmlinkage long sys32_fadvise64(int, unsigned, unsigned, size_t, int);
-asmlinkage long sys32_fallocate(int, int, unsigned,
-                               unsigned, unsigned, unsigned);
+asmlinkage ssize_t compat_sys_x86_readahead(int, unsigned int, unsigned int,
+                                           size_t);
+asmlinkage long compat_sys_x86_sync_file_range(int, unsigned int, unsigned int,
+                                              unsigned int, unsigned int,
+                                              int);
+asmlinkage long compat_sys_x86_fadvise64(int, unsigned int, unsigned int,
+                                        size_t, int);
+asmlinkage long compat_sys_x86_fallocate(int, int, unsigned int, unsigned int,
+                                        unsigned int, unsigned int);
+asmlinkage long compat_sys_x86_clone(unsigned long, unsigned long, int __user *,
+                                    unsigned long, int __user *);
 
 /* ia32/ia32_signal.c */
 asmlinkage long sys32_sigreturn(void);
index 2b8f18ca58747ae40b515c2bf674f8faced147e8..84137c22fdfade9bc8224c317808b311ec6f3007 100644 (file)
@@ -140,7 +140,7 @@ static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
 #else
 #define __flush_tlb() __native_flush_tlb()
 #define __flush_tlb_global() __native_flush_tlb_global()
-#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
+#define __flush_tlb_one_user(addr) __native_flush_tlb_one_user(addr)
 #endif
 
 static inline bool tlb_defer_switch_to_init_mm(void)
@@ -400,7 +400,7 @@ static inline void __native_flush_tlb_global(void)
 /*
  * flush one page in the user mapping
  */
-static inline void __native_flush_tlb_single(unsigned long addr)
+static inline void __native_flush_tlb_one_user(unsigned long addr)
 {
        u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
 
@@ -437,18 +437,31 @@ static inline void __flush_tlb_all(void)
 /*
  * flush one page in the kernel mapping
  */
-static inline void __flush_tlb_one(unsigned long addr)
+static inline void __flush_tlb_one_kernel(unsigned long addr)
 {
        count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE);
-       __flush_tlb_single(addr);
+
+       /*
+        * If PTI is off, then __flush_tlb_one_user() is just INVLPG or its
+        * paravirt equivalent.  Even with PCID, this is sufficient: we only
+        * use PCID if we also use global PTEs for the kernel mapping, and
+        * INVLPG flushes global translations across all address spaces.
+        *
+        * If PTI is on, then the kernel is mapped with non-global PTEs, and
+        * __flush_tlb_one_user() will flush the given address for the current
+        * kernel address space and for its usermode counterpart, but it does
+        * not flush it for other address spaces.
+        */
+       __flush_tlb_one_user(addr);
 
        if (!static_cpu_has(X86_FEATURE_PTI))
                return;
 
        /*
-        * __flush_tlb_single() will have cleared the TLB entry for this ASID,
-        * but since kernel space is replicated across all, we must also
-        * invalidate all others.
+        * See above.  We need to propagate the flush to all other address
+        * spaces.  In principle, we only need to propagate it to kernelmode
+        * address spaces, but the extra bookkeeping we would need is not
+        * worth it.
         */
        invalidate_other_asid();
 }
index 8b67807511329eae2eff2ced3733f68fcf8392c1..5db8b0b1076649fa287ad8ebfe2ba9853cd949d8 100644 (file)
@@ -352,6 +352,7 @@ enum vmcs_field {
 #define INTR_TYPE_NMI_INTR             (2 << 8) /* NMI */
 #define INTR_TYPE_HARD_EXCEPTION       (3 << 8) /* processor exception */
 #define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */
+#define INTR_TYPE_PRIV_SW_EXCEPTION    (5 << 8) /* ICE breakpoint - undocumented */
 #define INTR_TYPE_SOFT_EXCEPTION       (6 << 8) /* software exception */
 
 /* GUEST_INTERRUPTIBILITY_INFO flags. */
index 197c2e6c73765c364e519d8c70a1fa953d7d5053..099414345865d588e6c55b63078f8b168fc8e907 100644 (file)
 #define HV_X64_MSR_REENLIGHTENMENT_CONTROL     0x40000106
 
 struct hv_reenlightenment_control {
-       u64 vector:8;
-       u64 reserved1:8;
-       u64 enabled:1;
-       u64 reserved2:15;
-       u64 target_vp:32;
+       __u64 vector:8;
+       __u64 reserved1:8;
+       __u64 enabled:1;
+       __u64 reserved2:15;
+       __u64 target_vp:32;
 };
 
 #define HV_X64_MSR_TSC_EMULATION_CONTROL       0x40000107
 #define HV_X64_MSR_TSC_EMULATION_STATUS                0x40000108
 
 struct hv_tsc_emulation_control {
-       u64 enabled:1;
-       u64 reserved:63;
+       __u64 enabled:1;
+       __u64 reserved:63;
 };
 
 struct hv_tsc_emulation_status {
-       u64 inprogress:1;
-       u64 reserved:63;
+       __u64 inprogress:1;
+       __u64 reserved:63;
 };
 
 #define HV_X64_MSR_HYPERCALL_ENABLE            0x00000001
index 7a2ade4aa235380a8c28af6934d30566bb24de73..6cfa9c8cb7d650bef22010de0eca622a86364a73 100644 (file)
@@ -26,6 +26,7 @@
 #define KVM_FEATURE_PV_EOI             6
 #define KVM_FEATURE_PV_UNHALT          7
 #define KVM_FEATURE_PV_TLB_FLUSH       9
+#define KVM_FEATURE_ASYNC_PF_VMEXIT    10
 
 /* The last 8 bits are used to indicate how to interpret the flags field
  * in pvclock structure. If no bits are set, all flags are ignored.
index 91723461dc1feb0d63352c653fe0dafe625af379..435db58a7badec77e38e3d9e7f6ead5954efc4cc 100644 (file)
@@ -30,6 +30,7 @@ struct mce {
        __u64 synd;     /* MCA_SYND MSR: only valid on SMCA systems */
        __u64 ipid;     /* MCA_IPID MSR: only valid on SMCA systems */
        __u64 ppin;     /* Protected Processor Inventory Number */
+       __u32 microcode;/* Microcode revision */
 };
 
 #define MCE_GET_RECORD_LEN   _IOR('M', 1, int)
index 6db28f17ff2884e01122f2689b117e8ae63f9ec4..c88e0b127810f22b15b53eb150d11e9584201885 100644 (file)
@@ -235,7 +235,7 @@ int amd_cache_northbridges(void)
        if (boot_cpu_data.x86 == 0x10 &&
            boot_cpu_data.x86_model >= 0x8 &&
            (boot_cpu_data.x86_model > 0x9 ||
-            boot_cpu_data.x86_mask >= 0x1))
+            boot_cpu_data.x86_stepping >= 0x1))
                amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
 
        if (boot_cpu_data.x86 == 0x15)
index 25ddf02598d20a89cb1da2243aba687e6eee7657..b203af0855b57618fc398e29425ef96755c95552 100644 (file)
@@ -546,7 +546,7 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
 
 static u32 hsx_deadline_rev(void)
 {
-       switch (boot_cpu_data.x86_mask) {
+       switch (boot_cpu_data.x86_stepping) {
        case 0x02: return 0x3a; /* EP */
        case 0x04: return 0x0f; /* EX */
        }
@@ -556,7 +556,7 @@ static u32 hsx_deadline_rev(void)
 
 static u32 bdx_deadline_rev(void)
 {
-       switch (boot_cpu_data.x86_mask) {
+       switch (boot_cpu_data.x86_stepping) {
        case 0x02: return 0x00000011;
        case 0x03: return 0x0700000e;
        case 0x04: return 0x0f00000c;
@@ -568,7 +568,7 @@ static u32 bdx_deadline_rev(void)
 
 static u32 skx_deadline_rev(void)
 {
-       switch (boot_cpu_data.x86_mask) {
+       switch (boot_cpu_data.x86_stepping) {
        case 0x03: return 0x01000136;
        case 0x04: return 0x02000014;
        }
index 8ad2e410974f2d4b71a44f033e8c046671b89622..7c5538769f7e43f7bac9c8ff9a30b6a26ac89433 100644 (file)
@@ -1603,7 +1603,7 @@ static void __init delay_with_tsc(void)
        do {
                rep_nop();
                now = rdtsc();
-       } while ((now - start) < 40000000000UL / HZ &&
+       } while ((now - start) < 40000000000ULL / HZ &&
                time_before_eq(jiffies, end));
 }
 
index 3cc471beb50b499d89148bbdee37c697c596f743..bb6f7a2148d7781f64836a14f6f9884bd7955740 100644 (file)
@@ -134,21 +134,40 @@ static void apic_update_vector(struct irq_data *irqd, unsigned int newvec,
 {
        struct apic_chip_data *apicd = apic_chip_data(irqd);
        struct irq_desc *desc = irq_data_to_desc(irqd);
+       bool managed = irqd_affinity_is_managed(irqd);
 
        lockdep_assert_held(&vector_lock);
 
        trace_vector_update(irqd->irq, newvec, newcpu, apicd->vector,
                            apicd->cpu);
 
-       /* Setup the vector move, if required  */
-       if (apicd->vector && cpu_online(apicd->cpu)) {
+       /*
+        * If there is no vector associated or if the associated vector is
+        * the shutdown vector, which is associated to make PCI/MSI
+        * shutdown mode work, then there is nothing to release. Clear out
+        * prev_vector for this and the offlined target case.
+        */
+       apicd->prev_vector = 0;
+       if (!apicd->vector || apicd->vector == MANAGED_IRQ_SHUTDOWN_VECTOR)
+               goto setnew;
+       /*
+        * If the target CPU of the previous vector is online, then mark
+        * the vector as move in progress and store it for cleanup when the
+        * first interrupt on the new vector arrives. If the target CPU is
+        * offline then the regular release mechanism via the cleanup
+        * vector is not possible and the vector can be immediately freed
+        * in the underlying matrix allocator.
+        */
+       if (cpu_online(apicd->cpu)) {
                apicd->move_in_progress = true;
                apicd->prev_vector = apicd->vector;
                apicd->prev_cpu = apicd->cpu;
        } else {
-               apicd->prev_vector = 0;
+               irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector,
+                               managed);
        }
 
+setnew:
        apicd->vector = newvec;
        apicd->cpu = newcpu;
        BUG_ON(!IS_ERR_OR_NULL(per_cpu(vector_irq, newcpu)[newvec]));
index 46b675aaf20b8a1f30f1eee2cf63717e299c5367..f11910b44638c84995848a5acdecbb296ddb5636 100644 (file)
@@ -1176,16 +1176,25 @@ static void __init decode_gam_rng_tbl(unsigned long ptr)
 
        uv_gre_table = gre;
        for (; gre->type != UV_GAM_RANGE_TYPE_UNUSED; gre++) {
+               unsigned long size = ((unsigned long)(gre->limit - lgre)
+                                       << UV_GAM_RANGE_SHFT);
+               int order = 0;
+               char suffix[] = " KMGTPE";
+
+               while (size > 9999 && order < sizeof(suffix)) {
+                       size /= 1024;
+                       order++;
+               }
+
                if (!index) {
                        pr_info("UV: GAM Range Table...\n");
                        pr_info("UV:  # %20s %14s %5s %4s %5s %3s %2s\n", "Range", "", "Size", "Type", "NASID", "SID", "PN");
                }
-               pr_info("UV: %2d: 0x%014lx-0x%014lx %5luG %3d   %04x  %02x %02x\n",
+               pr_info("UV: %2d: 0x%014lx-0x%014lx %5lu%c %3d   %04x  %02x %02x\n",
                        index++,
                        (unsigned long)lgre << UV_GAM_RANGE_SHFT,
                        (unsigned long)gre->limit << UV_GAM_RANGE_SHFT,
-                       ((unsigned long)(gre->limit - lgre)) >>
-                               (30 - UV_GAM_RANGE_SHFT), /* 64M -> 1G */
+                       size, suffix[order],
                        gre->type, gre->nasid, gre->sockid, gre->pnode);
 
                lgre = gre->limit;
index fa1261eefa16e73cedf27aadb878753be693f919..f91ba53e06c8b90f9d5557a2713896a1a50100f0 100644 (file)
@@ -18,7 +18,7 @@ void foo(void)
        OFFSET(CPUINFO_x86, cpuinfo_x86, x86);
        OFFSET(CPUINFO_x86_vendor, cpuinfo_x86, x86_vendor);
        OFFSET(CPUINFO_x86_model, cpuinfo_x86, x86_model);
-       OFFSET(CPUINFO_x86_mask, cpuinfo_x86, x86_mask);
+       OFFSET(CPUINFO_x86_stepping, cpuinfo_x86, x86_stepping);
        OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level);
        OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability);
        OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
index 5bddbdcbc4a3cf722cd960c032e8ec400369e17a..f0e6456ca7d3cd482893a7d1953aec5d79c4caad 100644 (file)
@@ -119,7 +119,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
                return;
        }
 
-       if (c->x86_model == 6 && c->x86_mask == 1) {
+       if (c->x86_model == 6 && c->x86_stepping == 1) {
                const int K6_BUG_LOOP = 1000000;
                int n;
                void (*f_vide)(void);
@@ -149,7 +149,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
 
        /* K6 with old style WHCR */
        if (c->x86_model < 8 ||
-          (c->x86_model == 8 && c->x86_mask < 8)) {
+          (c->x86_model == 8 && c->x86_stepping < 8)) {
                /* We can only write allocate on the low 508Mb */
                if (mbytes > 508)
                        mbytes = 508;
@@ -168,7 +168,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
                return;
        }
 
-       if ((c->x86_model == 8 && c->x86_mask > 7) ||
+       if ((c->x86_model == 8 && c->x86_stepping > 7) ||
             c->x86_model == 9 || c->x86_model == 13) {
                /* The more serious chips .. */
 
@@ -221,7 +221,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
         * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx
         * As per AMD technical note 27212 0.2
         */
-       if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
+       if ((c->x86_model == 8 && c->x86_stepping >= 1) || (c->x86_model > 8)) {
                rdmsr(MSR_K7_CLK_CTL, l, h);
                if ((l & 0xfff00000) != 0x20000000) {
                        pr_info("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
@@ -241,12 +241,12 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
         * but they are not certified as MP capable.
         */
        /* Athlon 660/661 is valid. */
-       if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
-           (c->x86_mask == 1)))
+       if ((c->x86_model == 6) && ((c->x86_stepping == 0) ||
+           (c->x86_stepping == 1)))
                return;
 
        /* Duron 670 is valid */
-       if ((c->x86_model == 7) && (c->x86_mask == 0))
+       if ((c->x86_model == 7) && (c->x86_stepping == 0))
                return;
 
        /*
@@ -256,8 +256,8 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
         * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
         * more.
         */
-       if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
-           ((c->x86_model == 7) && (c->x86_mask >= 1)) ||
+       if (((c->x86_model == 6) && (c->x86_stepping >= 2)) ||
+           ((c->x86_model == 7) && (c->x86_stepping >= 1)) ||
             (c->x86_model > 7))
                if (cpu_has(c, X86_FEATURE_MP))
                        return;
@@ -628,7 +628,7 @@ static void early_init_amd(struct cpuinfo_x86 *c)
        /*  Set MTRR capability flag if appropriate */
        if (c->x86 == 5)
                if (c->x86_model == 13 || c->x86_model == 9 ||
-                   (c->x86_model == 8 && c->x86_mask >= 8))
+                   (c->x86_model == 8 && c->x86_stepping >= 8))
                        set_cpu_cap(c, X86_FEATURE_K6_MTRR);
 #endif
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
@@ -795,7 +795,7 @@ static void init_amd_zn(struct cpuinfo_x86 *c)
         * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects
         * all up to and including B1.
         */
-       if (c->x86_model <= 1 && c->x86_mask <= 1)
+       if (c->x86_model <= 1 && c->x86_stepping <= 1)
                set_cpu_cap(c, X86_FEATURE_CPB);
 }
 
@@ -906,11 +906,11 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
        /* AMD errata T13 (order #21922) */
        if ((c->x86 == 6)) {
                /* Duron Rev A0 */
-               if (c->x86_model == 3 && c->x86_mask == 0)
+               if (c->x86_model == 3 && c->x86_stepping == 0)
                        size = 64;
                /* Tbird rev A1/A2 */
                if (c->x86_model == 4 &&
-                       (c->x86_mask == 0 || c->x86_mask == 1))
+                       (c->x86_stepping == 0 || c->x86_stepping == 1))
                        size = 256;
        }
        return size;
@@ -1047,7 +1047,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
        }
 
        /* OSVW unavailable or ID unknown, match family-model-stepping range */
-       ms = (cpu->x86_model << 4) | cpu->x86_mask;
+       ms = (cpu->x86_model << 4) | cpu->x86_stepping;
        while ((range = *erratum++))
                if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
                    (ms >= AMD_MODEL_RANGE_START(range)) &&
index 71949bf2de5ad378e8184566010e4aaa6aa2307d..bfca937bdcc36ce8d9523f03dcc92e93d3c39d5c 100644 (file)
@@ -162,8 +162,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
        if (cmdline_find_option_bool(boot_command_line, "nospectre_v2"))
                return SPECTRE_V2_CMD_NONE;
        else {
-               ret = cmdline_find_option(boot_command_line, "spectre_v2", arg,
-                                         sizeof(arg));
+               ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg));
                if (ret < 0)
                        return SPECTRE_V2_CMD_AUTO;
 
@@ -175,8 +174,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
                }
 
                if (i >= ARRAY_SIZE(mitigation_options)) {
-                       pr_err("unknown option (%s). Switching to AUTO select\n",
-                              mitigation_options[i].option);
+                       pr_err("unknown option (%s). Switching to AUTO select\n", arg);
                        return SPECTRE_V2_CMD_AUTO;
                }
        }
@@ -185,8 +183,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
             cmd == SPECTRE_V2_CMD_RETPOLINE_AMD ||
             cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) &&
            !IS_ENABLED(CONFIG_RETPOLINE)) {
-               pr_err("%s selected but not compiled in. Switching to AUTO select\n",
-                      mitigation_options[i].option);
+               pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option);
                return SPECTRE_V2_CMD_AUTO;
        }
 
@@ -256,14 +253,14 @@ static void __init spectre_v2_select_mitigation(void)
                        goto retpoline_auto;
                break;
        }
-       pr_err("kernel not compiled with retpoline; no mitigation available!");
+       pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!");
        return;
 
 retpoline_auto:
        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
        retpoline_amd:
                if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
-                       pr_err("LFENCE not serializing. Switching to generic retpoline\n");
+                       pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n");
                        goto retpoline_generic;
                }
                mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD :
@@ -281,7 +278,7 @@ retpoline_auto:
        pr_info("%s\n", spectre_v2_strings[mode]);
 
        /*
-        * If neither SMEP or KPTI are available, there is a risk of
+        * If neither SMEP nor PTI are available, there is a risk of
         * hitting userspace addresses in the RSB after a context switch
         * from a shallow call stack to a deeper one. To prevent this fill
         * the entire RSB, even when using IBRS.
@@ -295,21 +292,29 @@ retpoline_auto:
        if ((!boot_cpu_has(X86_FEATURE_PTI) &&
             !boot_cpu_has(X86_FEATURE_SMEP)) || is_skylake_era()) {
                setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
-               pr_info("Filling RSB on context switch\n");
+               pr_info("Spectre v2 mitigation: Filling RSB on context switch\n");
        }
 
        /* Initialize Indirect Branch Prediction Barrier if supported */
        if (boot_cpu_has(X86_FEATURE_IBPB)) {
                setup_force_cpu_cap(X86_FEATURE_USE_IBPB);
-               pr_info("Enabling Indirect Branch Prediction Barrier\n");
+               pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n");
+       }
+
+       /*
+        * Retpoline means the kernel is safe because it has no indirect
+        * branches. But firmware isn't, so use IBRS to protect that.
+        */
+       if (boot_cpu_has(X86_FEATURE_IBRS)) {
+               setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
+               pr_info("Enabling Restricted Speculation for firmware calls\n");
        }
 }
 
 #undef pr_fmt
 
 #ifdef CONFIG_SYSFS
-ssize_t cpu_show_meltdown(struct device *dev,
-                         struct device_attribute *attr, char *buf)
+ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
 {
        if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN))
                return sprintf(buf, "Not affected\n");
@@ -318,28 +323,21 @@ ssize_t cpu_show_meltdown(struct device *dev,
        return sprintf(buf, "Vulnerable\n");
 }
 
-ssize_t cpu_show_spectre_v1(struct device *dev,
-                           struct device_attribute *attr, char *buf)
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
 {
        if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1))
                return sprintf(buf, "Not affected\n");
        return sprintf(buf, "Mitigation: __user pointer sanitization\n");
 }
 
-ssize_t cpu_show_spectre_v2(struct device *dev,
-                           struct device_attribute *attr, char *buf)
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
 {
        if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
                return sprintf(buf, "Not affected\n");
 
-       return sprintf(buf, "%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
+       return sprintf(buf, "%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
                       boot_cpu_has(X86_FEATURE_USE_IBPB) ? ", IBPB" : "",
+                      boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
                       spectre_v2_module_string());
 }
 #endif
-
-void __ibp_barrier(void)
-{
-       __wrmsr(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, 0);
-}
-EXPORT_SYMBOL_GPL(__ibp_barrier);
index c578cd29c2d2c47bd8c03268bc8809c28785d43c..e5ec0f11c0de7c06a0975d852822b2033d914185 100644 (file)
@@ -140,7 +140,7 @@ static void init_centaur(struct cpuinfo_x86 *c)
                        clear_cpu_cap(c, X86_FEATURE_TSC);
                        break;
                case 8:
-                       switch (c->x86_mask) {
+                       switch (c->x86_stepping) {
                        default:
                        name = "2";
                                break;
@@ -215,7 +215,7 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
         *  - Note, it seems this may only be in engineering samples.
         */
        if ((c->x86 == 6) && (c->x86_model == 9) &&
-                               (c->x86_mask == 1) && (size == 65))
+                               (c->x86_stepping == 1) && (size == 65))
                size -= 1;
        return size;
 }
index d63f4b5706e4d76271da40fe14c6ef4ba41fe999..348cf48212405077bd731e25cf7a41de585ba61d 100644 (file)
@@ -731,7 +731,7 @@ void cpu_detect(struct cpuinfo_x86 *c)
                cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
                c->x86          = x86_family(tfms);
                c->x86_model    = x86_model(tfms);
-               c->x86_mask     = x86_stepping(tfms);
+               c->x86_stepping = x86_stepping(tfms);
 
                if (cap0 & (1<<19)) {
                        c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
@@ -1184,9 +1184,9 @@ static void identify_cpu(struct cpuinfo_x86 *c)
        int i;
 
        c->loops_per_jiffy = loops_per_jiffy;
-       c->x86_cache_size = -1;
+       c->x86_cache_size = 0;
        c->x86_vendor = X86_VENDOR_UNKNOWN;
-       c->x86_model = c->x86_mask = 0; /* So far unknown... */
+       c->x86_model = c->x86_stepping = 0;     /* So far unknown... */
        c->x86_vendor_id[0] = '\0'; /* Unset */
        c->x86_model_id[0] = '\0';  /* Unset */
        c->x86_max_cores = 1;
@@ -1378,8 +1378,8 @@ void print_cpu_info(struct cpuinfo_x86 *c)
 
        pr_cont(" (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
 
-       if (c->x86_mask || c->cpuid_level >= 0)
-               pr_cont(", stepping: 0x%x)\n", c->x86_mask);
+       if (c->x86_stepping || c->cpuid_level >= 0)
+               pr_cont(", stepping: 0x%x)\n", c->x86_stepping);
        else
                pr_cont(")\n");
 }
@@ -1749,3 +1749,33 @@ static int __init init_cpu_syscore(void)
        return 0;
 }
 core_initcall(init_cpu_syscore);
+
+/*
+ * The microcode loader calls this upon late microcode load to recheck features,
+ * only when microcode has been updated. Caller holds microcode_mutex and CPU
+ * hotplug lock.
+ */
+void microcode_check(void)
+{
+       struct cpuinfo_x86 info;
+
+       perf_check_microcode();
+
+       /* Reload CPUID max function as it might've changed. */
+       info.cpuid_level = cpuid_eax(0);
+
+       /*
+        * Copy all capability leafs to pick up the synthetic ones so that
+        * memcmp() below doesn't fail on that. The ones coming from CPUID will
+        * get overwritten in get_cpu_cap().
+        */
+       memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
+
+       get_cpu_cap(&info);
+
+       if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability)))
+               return;
+
+       pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
+       pr_warn("x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update.\n");
+}
index 6b4bb335641f3f039c7cff50190ad38b5cf9de66..8949b7ae6d92536c1bbff659d7463588d2bdfb06 100644 (file)
@@ -215,7 +215,7 @@ static void init_cyrix(struct cpuinfo_x86 *c)
 
        /* common case step number/rev -- exceptions handled below */
        c->x86_model = (dir1 >> 4) + 1;
-       c->x86_mask = dir1 & 0xf;
+       c->x86_stepping = dir1 & 0xf;
 
        /* Now cook; the original recipe is by Channing Corn, from Cyrix.
         * We do the same thing for each generation: we work out
index 319bf989fad1e1f3d7ed2234090a51c55a0067c6..c3af167d0a70c8e0220d3ae81383b8f8dee046de 100644 (file)
@@ -105,7 +105,7 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c)
 /*
  * Early microcode releases for the Spectre v2 mitigation were broken.
  * Information taken from;
- * - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/microcode-update-guidance.pdf
+ * - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/03/microcode-update-guidance.pdf
  * - https://kb.vmware.com/s/article/52345
  * - Microcode revisions observed in the wild
  * - Release note from 20180108 microcode release
@@ -116,15 +116,13 @@ struct sku_microcode {
        u32 microcode;
 };
 static const struct sku_microcode spectre_bad_microcodes[] = {
-       { INTEL_FAM6_KABYLAKE_DESKTOP,  0x0B,   0x84 },
-       { INTEL_FAM6_KABYLAKE_DESKTOP,  0x0A,   0x84 },
-       { INTEL_FAM6_KABYLAKE_DESKTOP,  0x09,   0x84 },
-       { INTEL_FAM6_KABYLAKE_MOBILE,   0x0A,   0x84 },
-       { INTEL_FAM6_KABYLAKE_MOBILE,   0x09,   0x84 },
+       { INTEL_FAM6_KABYLAKE_DESKTOP,  0x0B,   0x80 },
+       { INTEL_FAM6_KABYLAKE_DESKTOP,  0x0A,   0x80 },
+       { INTEL_FAM6_KABYLAKE_DESKTOP,  0x09,   0x80 },
+       { INTEL_FAM6_KABYLAKE_MOBILE,   0x0A,   0x80 },
+       { INTEL_FAM6_KABYLAKE_MOBILE,   0x09,   0x80 },
        { INTEL_FAM6_SKYLAKE_X,         0x03,   0x0100013e },
        { INTEL_FAM6_SKYLAKE_X,         0x04,   0x0200003c },
-       { INTEL_FAM6_SKYLAKE_MOBILE,    0x03,   0xc2 },
-       { INTEL_FAM6_SKYLAKE_DESKTOP,   0x03,   0xc2 },
        { INTEL_FAM6_BROADWELL_CORE,    0x04,   0x28 },
        { INTEL_FAM6_BROADWELL_GT3E,    0x01,   0x1b },
        { INTEL_FAM6_BROADWELL_XEON_D,  0x02,   0x14 },
@@ -136,8 +134,6 @@ static const struct sku_microcode spectre_bad_microcodes[] = {
        { INTEL_FAM6_HASWELL_X,         0x02,   0x3b },
        { INTEL_FAM6_HASWELL_X,         0x04,   0x10 },
        { INTEL_FAM6_IVYBRIDGE_X,       0x04,   0x42a },
-       /* Updated in the 20180108 release; blacklist until we know otherwise */
-       { INTEL_FAM6_ATOM_GEMINI_LAKE,  0x01,   0x22 },
        /* Observed in the wild */
        { INTEL_FAM6_SANDYBRIDGE_X,     0x06,   0x61b },
        { INTEL_FAM6_SANDYBRIDGE_X,     0x07,   0x712 },
@@ -147,9 +143,16 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
 {
        int i;
 
+       /*
+        * We know that the hypervisor lie to us on the microcode version so
+        * we may as well hope that it is running the correct version.
+        */
+       if (cpu_has(c, X86_FEATURE_HYPERVISOR))
+               return false;
+
        for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
                if (c->x86_model == spectre_bad_microcodes[i].model &&
-                   c->x86_mask == spectre_bad_microcodes[i].stepping)
+                   c->x86_stepping == spectre_bad_microcodes[i].stepping)
                        return (c->microcode <= spectre_bad_microcodes[i].microcode);
        }
        return false;
@@ -196,7 +199,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
         * need the microcode to have already been loaded... so if it is
         * not, recommend a BIOS update and disable large pages.
         */
-       if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2 &&
+       if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_stepping <= 2 &&
            c->microcode < 0x20e) {
                pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n");
                clear_cpu_cap(c, X86_FEATURE_PSE);
@@ -212,7 +215,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
 
        /* CPUID workaround for 0F33/0F34 CPU */
        if (c->x86 == 0xF && c->x86_model == 0x3
-           && (c->x86_mask == 0x3 || c->x86_mask == 0x4))
+           && (c->x86_stepping == 0x3 || c->x86_stepping == 0x4))
                c->x86_phys_bits = 36;
 
        /*
@@ -310,7 +313,7 @@ int ppro_with_ram_bug(void)
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
            boot_cpu_data.x86 == 6 &&
            boot_cpu_data.x86_model == 1 &&
-           boot_cpu_data.x86_mask < 8) {
+           boot_cpu_data.x86_stepping < 8) {
                pr_info("Pentium Pro with Errata#50 detected. Taking evasive action.\n");
                return 1;
        }
@@ -327,7 +330,7 @@ static void intel_smp_check(struct cpuinfo_x86 *c)
         * Mask B, Pentium, but not Pentium MMX
         */
        if (c->x86 == 5 &&
-           c->x86_mask >= 1 && c->x86_mask <= 4 &&
+           c->x86_stepping >= 1 && c->x86_stepping <= 4 &&
            c->x86_model <= 3) {
                /*
                 * Remember we have B step Pentia with bugs
@@ -370,7 +373,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
         * SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until
         * model 3 mask 3
         */
-       if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
+       if ((c->x86<<8 | c->x86_model<<4 | c->x86_stepping) < 0x633)
                clear_cpu_cap(c, X86_FEATURE_SEP);
 
        /*
@@ -388,7 +391,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
         * P4 Xeon erratum 037 workaround.
         * Hardware prefetcher may cause stale data to be loaded into the cache.
         */
-       if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
+       if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_stepping == 1)) {
                if (msr_set_bit(MSR_IA32_MISC_ENABLE,
                                MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT) > 0) {
                        pr_info("CPU: C0 stepping P4 Xeon detected.\n");
@@ -403,7 +406,7 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
         * Specification Update").
         */
        if (boot_cpu_has(X86_FEATURE_APIC) && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
-           (c->x86_mask < 0x6 || c->x86_mask == 0xb))
+           (c->x86_stepping < 0x6 || c->x86_stepping == 0xb))
                set_cpu_bug(c, X86_BUG_11AP);
 
 
@@ -650,7 +653,7 @@ static void init_intel(struct cpuinfo_x86 *c)
                case 6:
                        if (l2 == 128)
                                p = "Celeron (Mendocino)";
-                       else if (c->x86_mask == 0 || c->x86_mask == 5)
+                       else if (c->x86_stepping == 0 || c->x86_stepping == 5)
                                p = "Celeron-A";
                        break;
 
index 410629f10ad377176787b1b93ddb36625de2be36..589b948e6e01f01d7388cca456fbecd6019dbca4 100644 (file)
@@ -819,7 +819,7 @@ static __init void rdt_quirks(void)
                        cache_alloc_hsw_probe();
                break;
        case INTEL_FAM6_SKYLAKE_X:
-               if (boot_cpu_data.x86_mask <= 4)
+               if (boot_cpu_data.x86_stepping <= 4)
                        set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat");
        }
 }
index bdab7d2f51af4c2a32d18d891f54b5bc60f60bd4..fca759d272a1783e76d86dfa38e213d167f39ade 100644 (file)
@@ -1804,6 +1804,7 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
                goto out_common_fail;
        }
        closid = ret;
+       ret = 0;
 
        rdtgrp->closid = closid;
        list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
index aa0d5df9dc60e710b22ab7172f0e5fd6e05db2c9..e956eb26706191d27447bc9feec2e9fbde5310c7 100644 (file)
@@ -115,4 +115,19 @@ static inline void mce_unregister_injector_chain(struct notifier_block *nb)        { }
 
 extern struct mca_config mca_cfg;
 
+#ifndef CONFIG_X86_64
+/*
+ * On 32-bit systems it would be difficult to safely unmap a poison page
+ * from the kernel 1:1 map because there are no non-canonical addresses that
+ * we can use to refer to the address without risking a speculative access.
+ * However, this isn't much of an issue because:
+ * 1) Few unmappable pages are in the 1:1 map. Most are in HIGHMEM which
+ *    are only mapped into the kernel as needed
+ * 2) Few people would run a 32-bit kernel on a machine that supports
+ *    recoverable errors because they have too much memory to boot 32-bit.
+ */
+static inline void mce_unmap_kpfn(unsigned long pfn) {}
+#define mce_unmap_kpfn mce_unmap_kpfn
+#endif
+
 #endif /* __X86_MCE_INTERNAL_H__ */
index 3a8e88a611ebf99d70c2cacf2d866343f01a4a1a..466f47301334ba0c8e64c17fd8fa5b7903cca44f 100644 (file)
@@ -56,6 +56,9 @@
 
 static DEFINE_MUTEX(mce_log_mutex);
 
+/* sysfs synchronization */
+static DEFINE_MUTEX(mce_sysfs_mutex);
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/mce.h>
 
@@ -105,6 +108,10 @@ static struct irq_work mce_irq_work;
 
 static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
 
+#ifndef mce_unmap_kpfn
+static void mce_unmap_kpfn(unsigned long pfn);
+#endif
+
 /*
  * CPU/chipset specific EDAC code can register a notifier call here to print
  * MCE errors in a human-readable form.
@@ -126,6 +133,8 @@ void mce_setup(struct mce *m)
 
        if (this_cpu_has(X86_FEATURE_INTEL_PPIN))
                rdmsrl(MSR_PPIN, m->ppin);
+
+       m->microcode = boot_cpu_data.microcode;
 }
 
 DEFINE_PER_CPU(struct mce, injectm);
@@ -234,7 +243,7 @@ static void __print_mce(struct mce *m)
                        m->cs, m->ip);
 
                if (m->cs == __KERNEL_CS)
-                       pr_cont("{%pS}", (void *)m->ip);
+                       pr_cont("{%pS}", (void *)(unsigned long)m->ip);
                pr_cont("\n");
        }
 
@@ -258,7 +267,7 @@ static void __print_mce(struct mce *m)
         */
        pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n",
                m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid,
-               cpu_data(m->extcpu).microcode);
+               m->microcode);
 }
 
 static void print_mce(struct mce *m)
@@ -590,7 +599,8 @@ static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
 
        if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) {
                pfn = mce->addr >> PAGE_SHIFT;
-               memory_failure(pfn, 0);
+               if (!memory_failure(pfn, 0))
+                       mce_unmap_kpfn(pfn);
        }
 
        return NOTIFY_OK;
@@ -1057,12 +1067,13 @@ static int do_memory_failure(struct mce *m)
        ret = memory_failure(m->addr >> PAGE_SHIFT, flags);
        if (ret)
                pr_err("Memory error not recovered");
+       else
+               mce_unmap_kpfn(m->addr >> PAGE_SHIFT);
        return ret;
 }
 
-#if defined(arch_unmap_kpfn) && defined(CONFIG_MEMORY_FAILURE)
-
-void arch_unmap_kpfn(unsigned long pfn)
+#ifndef mce_unmap_kpfn
+static void mce_unmap_kpfn(unsigned long pfn)
 {
        unsigned long decoy_addr;
 
@@ -1073,7 +1084,7 @@ void arch_unmap_kpfn(unsigned long pfn)
         * We would like to just call:
         *      set_memory_np((unsigned long)pfn_to_kaddr(pfn), 1);
         * but doing that would radically increase the odds of a
-        * speculative access to the posion page because we'd have
+        * speculative access to the poison page because we'd have
         * the virtual address of the kernel 1:1 mapping sitting
         * around in registers.
         * Instead we get tricky.  We create a non-canonical address
@@ -1098,7 +1109,6 @@ void arch_unmap_kpfn(unsigned long pfn)
 
        if (set_memory_np(decoy_addr, 1))
                pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
-
 }
 #endif
 
@@ -2081,6 +2091,7 @@ static ssize_t set_ignore_ce(struct device *s,
        if (kstrtou64(buf, 0, &new) < 0)
                return -EINVAL;
 
+       mutex_lock(&mce_sysfs_mutex);
        if (mca_cfg.ignore_ce ^ !!new) {
                if (new) {
                        /* disable ce features */
@@ -2093,6 +2104,8 @@ static ssize_t set_ignore_ce(struct device *s,
                        on_each_cpu(mce_enable_ce, (void *)1, 1);
                }
        }
+       mutex_unlock(&mce_sysfs_mutex);
+
        return size;
 }
 
@@ -2105,6 +2118,7 @@ static ssize_t set_cmci_disabled(struct device *s,
        if (kstrtou64(buf, 0, &new) < 0)
                return -EINVAL;
 
+       mutex_lock(&mce_sysfs_mutex);
        if (mca_cfg.cmci_disabled ^ !!new) {
                if (new) {
                        /* disable cmci */
@@ -2116,6 +2130,8 @@ static ssize_t set_cmci_disabled(struct device *s,
                        on_each_cpu(mce_enable_ce, NULL, 1);
                }
        }
+       mutex_unlock(&mce_sysfs_mutex);
+
        return size;
 }
 
@@ -2123,8 +2139,19 @@ static ssize_t store_int_with_restart(struct device *s,
                                      struct device_attribute *attr,
                                      const char *buf, size_t size)
 {
-       ssize_t ret = device_store_int(s, attr, buf, size);
+       unsigned long old_check_interval = check_interval;
+       ssize_t ret = device_store_ulong(s, attr, buf, size);
+
+       if (check_interval == old_check_interval)
+               return ret;
+
+       if (check_interval < 1)
+               check_interval = 1;
+
+       mutex_lock(&mce_sysfs_mutex);
        mce_restart();
+       mutex_unlock(&mce_sysfs_mutex);
+
        return ret;
 }
 
index 330b8462d426faad0dccdc480f34eec34cd8b92f..48179928ff38cf12476ce27cd096383aee1feb93 100644 (file)
@@ -339,7 +339,7 @@ int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax)
                return -EINVAL;
 
        ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size);
-       if (ret != UCODE_OK)
+       if (ret > UCODE_UPDATED)
                return -EINVAL;
 
        return 0;
@@ -498,7 +498,7 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
        return patch_size;
 }
 
-static int apply_microcode_amd(int cpu)
+static enum ucode_state apply_microcode_amd(int cpu)
 {
        struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct microcode_amd *mc_amd;
@@ -512,7 +512,7 @@ static int apply_microcode_amd(int cpu)
 
        p = find_patch(cpu);
        if (!p)
-               return 0;
+               return UCODE_NFOUND;
 
        mc_amd  = p->data;
        uci->mc = p->data;
@@ -523,13 +523,13 @@ static int apply_microcode_amd(int cpu)
        if (rev >= mc_amd->hdr.patch_id) {
                c->microcode = rev;
                uci->cpu_sig.rev = rev;
-               return 0;
+               return UCODE_OK;
        }
 
        if (__apply_microcode_amd(mc_amd)) {
                pr_err("CPU%d: update failed for patch_level=0x%08x\n",
                        cpu, mc_amd->hdr.patch_id);
-               return -1;
+               return UCODE_ERROR;
        }
        pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
                mc_amd->hdr.patch_id);
@@ -537,7 +537,7 @@ static int apply_microcode_amd(int cpu)
        uci->cpu_sig.rev = mc_amd->hdr.patch_id;
        c->microcode = mc_amd->hdr.patch_id;
 
-       return 0;
+       return UCODE_UPDATED;
 }
 
 static int install_equiv_cpu_table(const u8 *buf)
@@ -683,27 +683,35 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
 static enum ucode_state
 load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
 {
+       struct ucode_patch *p;
        enum ucode_state ret;
 
        /* free old equiv table */
        free_equiv_cpu_table();
 
        ret = __load_microcode_amd(family, data, size);
-
-       if (ret != UCODE_OK)
+       if (ret != UCODE_OK) {
                cleanup();
+               return ret;
+       }
 
-#ifdef CONFIG_X86_32
-       /* save BSP's matching patch for early load */
-       if (save) {
-               struct ucode_patch *p = find_patch(0);
-               if (p) {
-                       memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
-                       memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data),
-                                                              PATCH_MAX_SIZE));
-               }
+       p = find_patch(0);
+       if (!p) {
+               return ret;
+       } else {
+               if (boot_cpu_data.microcode == p->patch_id)
+                       return ret;
+
+               ret = UCODE_NEW;
        }
-#endif
+
+       /* save BSP's matching patch for early load */
+       if (!save)
+               return ret;
+
+       memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
+       memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE));
+
        return ret;
 }
 
index 319dd65f98a25530d3a55cb6ea1cf61f6c2004bc..10c4fc2c91f8ed1dd6879c8b0b8aa24d7275cd3b 100644 (file)
 #define pr_fmt(fmt) "microcode: " fmt
 
 #include <linux/platform_device.h>
+#include <linux/stop_machine.h>
 #include <linux/syscore_ops.h>
 #include <linux/miscdevice.h>
 #include <linux/capability.h>
 #include <linux/firmware.h>
 #include <linux/kernel.h>
+#include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/cpu.h>
+#include <linux/nmi.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 
@@ -64,6 +67,11 @@ LIST_HEAD(microcode_cache);
  */
 static DEFINE_MUTEX(microcode_mutex);
 
+/*
+ * Serialize late loading so that CPUs get updated one-by-one.
+ */
+static DEFINE_SPINLOCK(update_lock);
+
 struct ucode_cpu_info          ucode_cpu_info[NR_CPUS];
 
 struct cpu_info_ctx {
@@ -373,26 +381,23 @@ static int collect_cpu_info(int cpu)
        return ret;
 }
 
-struct apply_microcode_ctx {
-       int err;
-};
-
 static void apply_microcode_local(void *arg)
 {
-       struct apply_microcode_ctx *ctx = arg;
+       enum ucode_state *err = arg;
 
-       ctx->err = microcode_ops->apply_microcode(smp_processor_id());
+       *err = microcode_ops->apply_microcode(smp_processor_id());
 }
 
 static int apply_microcode_on_target(int cpu)
 {
-       struct apply_microcode_ctx ctx = { .err = 0 };
+       enum ucode_state err;
        int ret;
 
-       ret = smp_call_function_single(cpu, apply_microcode_local, &ctx, 1);
-       if (!ret)
-               ret = ctx.err;
-
+       ret = smp_call_function_single(cpu, apply_microcode_local, &err, 1);
+       if (!ret) {
+               if (err == UCODE_ERROR)
+                       ret = 1;
+       }
        return ret;
 }
 
@@ -489,31 +494,124 @@ static void __exit microcode_dev_exit(void)
 /* fake device for request_firmware */
 static struct platform_device  *microcode_pdev;
 
-static int reload_for_cpu(int cpu)
+/*
+ * Late loading dance. Why the heavy-handed stomp_machine effort?
+ *
+ * - HT siblings must be idle and not execute other code while the other sibling
+ *   is loading microcode in order to avoid any negative interactions caused by
+ *   the loading.
+ *
+ * - In addition, microcode update on the cores must be serialized until this
+ *   requirement can be relaxed in the future. Right now, this is conservative
+ *   and good.
+ */
+#define SPINUNIT 100 /* 100 nsec */
+
+static int check_online_cpus(void)
 {
-       struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-       enum ucode_state ustate;
-       int err = 0;
+       if (num_online_cpus() == num_present_cpus())
+               return 0;
 
-       if (!uci->valid)
-               return err;
+       pr_err("Not all CPUs online, aborting microcode update.\n");
 
-       ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, true);
-       if (ustate == UCODE_OK)
-               apply_microcode_on_target(cpu);
-       else
-               if (ustate == UCODE_ERROR)
-                       err = -EINVAL;
-       return err;
+       return -EINVAL;
+}
+
+static atomic_t late_cpus_in;
+static atomic_t late_cpus_out;
+
+static int __wait_for_cpus(atomic_t *t, long long timeout)
+{
+       int all_cpus = num_online_cpus();
+
+       atomic_inc(t);
+
+       while (atomic_read(t) < all_cpus) {
+               if (timeout < SPINUNIT) {
+                       pr_err("Timeout while waiting for CPUs rendezvous, remaining: %d\n",
+                               all_cpus - atomic_read(t));
+                       return 1;
+               }
+
+               ndelay(SPINUNIT);
+               timeout -= SPINUNIT;
+
+               touch_nmi_watchdog();
+       }
+       return 0;
+}
+
+/*
+ * Returns:
+ * < 0 - on error
+ *   0 - no update done
+ *   1 - microcode was updated
+ */
+static int __reload_late(void *info)
+{
+       int cpu = smp_processor_id();
+       enum ucode_state err;
+       int ret = 0;
+
+       /*
+        * Wait for all CPUs to arrive. A load will not be attempted unless all
+        * CPUs show up.
+        * */
+       if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC))
+               return -1;
+
+       spin_lock(&update_lock);
+       apply_microcode_local(&err);
+       spin_unlock(&update_lock);
+
+       if (err > UCODE_NFOUND) {
+               pr_warn("Error reloading microcode on CPU %d\n", cpu);
+               return -1;
+       /* siblings return UCODE_OK because their engine got updated already */
+       } else if (err == UCODE_UPDATED || err == UCODE_OK) {
+               ret = 1;
+       } else {
+               return ret;
+       }
+
+       /*
+        * Increase the wait timeout to a safe value here since we're
+        * serializing the microcode update and that could take a while on a
+        * large number of CPUs. And that is fine as the *actual* timeout will
+        * be determined by the last CPU finished updating and thus cut short.
+        */
+       if (__wait_for_cpus(&late_cpus_out, NSEC_PER_SEC * num_online_cpus()))
+               panic("Timeout during microcode update!\n");
+
+       return ret;
+}
+
+/*
+ * Reload microcode late on all CPUs. Wait for a sec until they
+ * all gather together.
+ */
+static int microcode_reload_late(void)
+{
+       int ret;
+
+       atomic_set(&late_cpus_in,  0);
+       atomic_set(&late_cpus_out, 0);
+
+       ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
+       if (ret > 0)
+               microcode_check();
+
+       return ret;
 }
 
 static ssize_t reload_store(struct device *dev,
                            struct device_attribute *attr,
                            const char *buf, size_t size)
 {
+       enum ucode_state tmp_ret = UCODE_OK;
+       int bsp = boot_cpu_data.cpu_index;
        unsigned long val;
-       int cpu;
-       ssize_t ret = 0, tmp_ret;
+       ssize_t ret = 0;
 
        ret = kstrtoul(buf, 0, &val);
        if (ret)
@@ -522,23 +620,24 @@ static ssize_t reload_store(struct device *dev,
        if (val != 1)
                return size;
 
+       tmp_ret = microcode_ops->request_microcode_fw(bsp, &microcode_pdev->dev, true);
+       if (tmp_ret != UCODE_NEW)
+               return size;
+
        get_online_cpus();
-       mutex_lock(&microcode_mutex);
-       for_each_online_cpu(cpu) {
-               tmp_ret = reload_for_cpu(cpu);
-               if (tmp_ret != 0)
-                       pr_warn("Error reloading microcode on CPU %d\n", cpu);
 
-               /* save retval of the first encountered reload error */
-               if (!ret)
-                       ret = tmp_ret;
-       }
-       if (!ret)
-               perf_check_microcode();
+       ret = check_online_cpus();
+       if (ret)
+               goto put;
+
+       mutex_lock(&microcode_mutex);
+       ret = microcode_reload_late();
        mutex_unlock(&microcode_mutex);
+
+put:
        put_online_cpus();
 
-       if (!ret)
+       if (ret >= 0)
                ret = size;
 
        return ret;
@@ -606,10 +705,8 @@ static enum ucode_state microcode_init_cpu(int cpu, bool refresh_fw)
        if (system_state != SYSTEM_RUNNING)
                return UCODE_NFOUND;
 
-       ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev,
-                                                    refresh_fw);
-
-       if (ustate == UCODE_OK) {
+       ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev, refresh_fw);
+       if (ustate == UCODE_NEW) {
                pr_debug("CPU%d updated upon init\n", cpu);
                apply_microcode_on_target(cpu);
        }
index f7c55b0e753ad038332307b2c7347abd1dcbc670..32b8e5724f966abbc67153065dd17b5ddcfd6d70 100644 (file)
@@ -589,6 +589,23 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)
        if (!mc)
                return 0;
 
+       /*
+        * Save us the MSR write below - which is a particular expensive
+        * operation - when the other hyperthread has updated the microcode
+        * already.
+        */
+       rev = intel_get_microcode_revision();
+       if (rev >= mc->hdr.rev) {
+               uci->cpu_sig.rev = rev;
+               return UCODE_OK;
+       }
+
+       /*
+        * Writeback and invalidate caches before updating microcode to avoid
+        * internal issues depending on what the microcode is updating.
+        */
+       native_wbinvd();
+
        /* write microcode via MSR 0x79 */
        native_wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
 
@@ -772,27 +789,44 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
        return 0;
 }
 
-static int apply_microcode_intel(int cpu)
+static enum ucode_state apply_microcode_intel(int cpu)
 {
+       struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct microcode_intel *mc;
-       struct ucode_cpu_info *uci;
-       struct cpuinfo_x86 *c;
        static int prev_rev;
        u32 rev;
 
        /* We should bind the task to the CPU */
        if (WARN_ON(raw_smp_processor_id() != cpu))
-               return -1;
+               return UCODE_ERROR;
 
-       uci = ucode_cpu_info + cpu;
-       mc = uci->mc;
+       /* Look for a newer patch in our cache: */
+       mc = find_patch(uci);
        if (!mc) {
-               /* Look for a newer patch in our cache: */
-               mc = find_patch(uci);
+               mc = uci->mc;
                if (!mc)
-                       return 0;
+                       return UCODE_NFOUND;
        }
 
+       /*
+        * Save us the MSR write below - which is a particular expensive
+        * operation - when the other hyperthread has updated the microcode
+        * already.
+        */
+       rev = intel_get_microcode_revision();
+       if (rev >= mc->hdr.rev) {
+               uci->cpu_sig.rev = rev;
+               c->microcode = rev;
+               return UCODE_OK;
+       }
+
+       /*
+        * Writeback and invalidate caches before updating microcode to avoid
+        * internal issues depending on what the microcode is updating.
+        */
+       native_wbinvd();
+
        /* write microcode via MSR 0x79 */
        wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc->bits);
 
@@ -801,7 +835,7 @@ static int apply_microcode_intel(int cpu)
        if (rev != mc->hdr.rev) {
                pr_err("CPU%d update to revision 0x%x failed\n",
                       cpu, mc->hdr.rev);
-               return -1;
+               return UCODE_ERROR;
        }
 
        if (rev != prev_rev) {
@@ -813,12 +847,10 @@ static int apply_microcode_intel(int cpu)
                prev_rev = rev;
        }
 
-       c = &cpu_data(cpu);
-
        uci->cpu_sig.rev = rev;
        c->microcode = rev;
 
-       return 0;
+       return UCODE_UPDATED;
 }
 
 static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
@@ -830,6 +862,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
        unsigned int leftover = size;
        unsigned int curr_mc_size = 0, new_mc_size = 0;
        unsigned int csig, cpf;
+       enum ucode_state ret = UCODE_OK;
 
        while (leftover) {
                struct microcode_header_intel mc_header;
@@ -871,6 +904,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                        new_mc  = mc;
                        new_mc_size = mc_size;
                        mc = NULL;      /* trigger new vmalloc */
+                       ret = UCODE_NEW;
                }
 
                ucode_ptr += mc_size;
@@ -900,7 +934,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
        pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
                 cpu, new_rev, uci->cpu_sig.rev);
 
-       return UCODE_OK;
+       return ret;
 }
 
 static int get_ucode_fw(void *to, const void *from, size_t n)
@@ -921,7 +955,7 @@ static bool is_blacklisted(unsigned int cpu)
         */
        if (c->x86 == 6 &&
            c->x86_model == INTEL_FAM6_BROADWELL_X &&
-           c->x86_mask == 0x01 &&
+           c->x86_stepping == 0x01 &&
            llc_size_per_core > 2621440 &&
            c->microcode < 0x0b000021) {
                pr_err_once("Erratum BDF90: late loading with revision < 0x0b000021 (0x%x) disabled.\n", c->microcode);
@@ -944,7 +978,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device,
                return UCODE_NFOUND;
 
        sprintf(name, "intel-ucode/%02x-%02x-%02x",
-               c->x86, c->x86_model, c->x86_mask);
+               c->x86, c->x86_model, c->x86_stepping);
 
        if (request_firmware_direct(&firmware, name, device)) {
                pr_debug("data file %s load failed\n", name);
@@ -982,7 +1016,7 @@ static struct microcode_ops microcode_intel_ops = {
 
 static int __init calc_llc_size_per_core(struct cpuinfo_x86 *c)
 {
-       u64 llc_size = c->x86_cache_size * 1024;
+       u64 llc_size = c->x86_cache_size * 1024ULL;
 
        do_div(llc_size, c->x86_max_cores);
 
index fdc55215d44d08b8c170767f94e68c4e60c09079..e12ee86906c6250faa05b13ae9bb9c3dc545558f 100644 (file)
@@ -859,7 +859,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size,
         */
        if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 &&
            boot_cpu_data.x86_model == 1 &&
-           boot_cpu_data.x86_mask <= 7) {
+           boot_cpu_data.x86_stepping <= 7) {
                if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
                        pr_warn("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
                        return -EINVAL;
index 40d5a8a752125ed5d26a7605d5eabad572879bfc..7468de4290873ad4664a5575e6cc0f4d74a26ae6 100644 (file)
@@ -711,8 +711,8 @@ void __init mtrr_bp_init(void)
                        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
                            boot_cpu_data.x86 == 0xF &&
                            boot_cpu_data.x86_model == 0x3 &&
-                           (boot_cpu_data.x86_mask == 0x3 ||
-                            boot_cpu_data.x86_mask == 0x4))
+                           (boot_cpu_data.x86_stepping == 0x3 ||
+                            boot_cpu_data.x86_stepping == 0x4))
                                phys_addr = 36;
 
                        size_or_mask = SIZE_OR_MASK_BITS(phys_addr);
index e7ecedafa1c8f7b033eccbdcf24198089933b386..2c8522a39ed5dbc388bada821ed144f2435adac2 100644 (file)
@@ -72,8 +72,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                   c->x86_model,
                   c->x86_model_id[0] ? c->x86_model_id : "unknown");
 
-       if (c->x86_mask || c->cpuid_level >= 0)
-               seq_printf(m, "stepping\t: %d\n", c->x86_mask);
+       if (c->x86_stepping || c->cpuid_level >= 0)
+               seq_printf(m, "stepping\t: %d\n", c->x86_stepping);
        else
                seq_puts(m, "stepping\t: unknown\n");
        if (c->microcode)
@@ -91,8 +91,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        }
 
        /* Cache size */
-       if (c->x86_cache_size >= 0)
-               seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
+       if (c->x86_cache_size)
+               seq_printf(m, "cache size\t: %u KB\n", c->x86_cache_size);
 
        show_cpuinfo_core(m, c, cpu);
        show_cpuinfo_misc(m, c);
index c29020907886a32d1ca40e9beb858c32dfdefd0f..b59e4fb40fd9986c0cc6b629b4c7a3a18a6d23b4 100644 (file)
@@ -37,7 +37,7 @@
 #define X86            new_cpu_data+CPUINFO_x86
 #define X86_VENDOR     new_cpu_data+CPUINFO_x86_vendor
 #define X86_MODEL      new_cpu_data+CPUINFO_x86_model
-#define X86_MASK       new_cpu_data+CPUINFO_x86_mask
+#define X86_STEPPING   new_cpu_data+CPUINFO_x86_stepping
 #define X86_HARD_MATH  new_cpu_data+CPUINFO_hard_math
 #define X86_CPUID      new_cpu_data+CPUINFO_cpuid_level
 #define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability
@@ -332,7 +332,7 @@ ENTRY(startup_32_smp)
        shrb $4,%al
        movb %al,X86_MODEL
        andb $0x0f,%cl          # mask mask revision
-       movb %cl,X86_MASK
+       movb %cl,X86_STEPPING
        movl %edx,X86_CAPABILITY
 
 .Lis486:
index 04a625f0fcda322dab7c9d8459a19ee56b71c936..0f545b3cf926787bd986d763c843498540ef530d 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/nops.h>
 #include "../entry/calling.h"
 #include <asm/export.h>
+#include <asm/nospec-branch.h>
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/asm-offsets.h>
@@ -134,6 +135,7 @@ ENTRY(secondary_startup_64)
 
        /* Ensure I am executing from virtual addresses */
        movq    $1f, %rax
+       ANNOTATE_RETPOLINE_SAFE
        jmp     *%rax
 1:
        UNWIND_HINT_EMPTY
index 56d99be3706a23b600a50d2ae366b3a8fde251ed..50bee5fe114013622ee858e4a3b7b16d1ffa8a05 100644 (file)
@@ -160,7 +160,6 @@ static const __initconst struct idt_data early_pf_idts[] = {
  */
 static const __initconst struct idt_data dbg_idts[] = {
        INTG(X86_TRAP_DB,       debug),
-       INTG(X86_TRAP_BP,       int3),
 };
 #endif
 
@@ -183,7 +182,6 @@ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;
 static const __initconst struct idt_data ist_idts[] = {
        ISTG(X86_TRAP_DB,       debug,          DEBUG_STACK),
        ISTG(X86_TRAP_NMI,      nmi,            NMI_STACK),
-       SISTG(X86_TRAP_BP,      int3,           DEBUG_STACK),
        ISTG(X86_TRAP_DF,       double_fault,   DOUBLEFAULT_STACK),
 #ifdef CONFIG_X86_MCE
        ISTG(X86_TRAP_MC,       &machine_check, MCE_STACK),
index 2f723301eb58fc5ad0d6796b342446ae2ee0c9e6..38deafebb21b726227fb2a12a7386f49603189fe 100644 (file)
@@ -23,7 +23,7 @@
 /*
  * this changes the io permissions bitmap in the current task.
  */
-asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
+SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
 {
        struct thread_struct *t = &current->thread;
        struct tss_struct *tss;
index bd36f3c33cd0f96f47b61034b02c205301fe87d1..0715f827607c4a2742e140f8d9a656ed4514d226 100644 (file)
@@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler);
 
 bool arch_within_kprobe_blacklist(unsigned long addr)
 {
+       bool is_in_entry_trampoline_section = false;
+
+#ifdef CONFIG_X86_64
+       is_in_entry_trampoline_section =
+               (addr >= (unsigned long)__entry_trampoline_start &&
+                addr < (unsigned long)__entry_trampoline_end);
+#endif
        return  (addr >= (unsigned long)__kprobes_text_start &&
                 addr < (unsigned long)__kprobes_text_end) ||
                (addr >= (unsigned long)__entry_text_start &&
-                addr < (unsigned long)__entry_text_end);
+                addr < (unsigned long)__entry_text_end) ||
+               is_in_entry_trampoline_section;
 }
 
 int __init arch_init_kprobes(void)
index 4e37d1a851a62df3f9f841f3bbd66827af0c1920..bc1a27280c4bf77899afad4b85bf53212d385cab 100644 (file)
@@ -49,7 +49,7 @@
 
 static int kvmapf = 1;
 
-static int parse_no_kvmapf(char *arg)
+static int __init parse_no_kvmapf(char *arg)
 {
         kvmapf = 0;
         return 0;
@@ -58,7 +58,7 @@ static int parse_no_kvmapf(char *arg)
 early_param("no-kvmapf", parse_no_kvmapf);
 
 static int steal_acc = 1;
-static int parse_no_stealacc(char *arg)
+static int __init parse_no_stealacc(char *arg)
 {
         steal_acc = 0;
         return 0;
@@ -67,7 +67,7 @@ static int parse_no_stealacc(char *arg)
 early_param("no-steal-acc", parse_no_stealacc);
 
 static int kvmclock_vsyscall = 1;
-static int parse_no_kvmclock_vsyscall(char *arg)
+static int __init parse_no_kvmclock_vsyscall(char *arg)
 {
         kvmclock_vsyscall = 0;
         return 0;
@@ -341,10 +341,10 @@ static void kvm_guest_cpu_init(void)
 #endif
                pa |= KVM_ASYNC_PF_ENABLED;
 
-               /* Async page fault support for L1 hypervisor is optional */
-               if (wrmsr_safe(MSR_KVM_ASYNC_PF_EN,
-                       (pa | KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT) & 0xffffffff, pa >> 32) < 0)
-                       wrmsrl(MSR_KVM_ASYNC_PF_EN, pa);
+               if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF_VMEXIT))
+                       pa |= KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT;
+
+               wrmsrl(MSR_KVM_ASYNC_PF_EN, pa);
                __this_cpu_write(apf_reason.enabled, 1);
                printk(KERN_INFO"KVM setup async PF for cpu %d\n",
                       smp_processor_id());
@@ -545,7 +545,8 @@ static void __init kvm_guest_init(void)
                pv_time_ops.steal_clock = kvm_steal_clock;
        }
 
-       if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH))
+       if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
+           !kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
                pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
 
        if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
@@ -633,7 +634,8 @@ static __init int kvm_setup_pv_tlb_flush(void)
 {
        int cpu;
 
-       if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH)) {
+       if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
+           !kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
                for_each_possible_cpu(cpu) {
                        zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu),
                                GFP_KERNEL, cpu_to_node(cpu));
index 1f790cf9d38fe0e10e46eaf9b5bef945d25a9370..3b7427aa7d850675905aaf636590b34107132874 100644 (file)
@@ -542,6 +542,7 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
                                goto overflow;
                        break;
                case R_X86_64_PC32:
+               case R_X86_64_PLT32:
                        value -= (u64)address;
                        *(u32 *)location = value;
                        break;
index da0c160e558905c2164bf1d3879bd1a1cf368f34..f58336af095c9d3050e85c5dea79a164b275e420 100644 (file)
@@ -191,6 +191,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
                                goto overflow;
                        break;
                case R_X86_64_PC32:
+               case R_X86_64_PLT32:
                        if (*(u32 *)loc != 0)
                                goto invalid_relocation;
                        val -= (u64)loc;
index 27d0a1712663673ac9993a6ddd055cb075b265fa..f1c5eb99d445407a9fc134e76a8010d17a61d780 100644 (file)
@@ -410,7 +410,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
        processor.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
        processor.cpuflag = CPU_ENABLED;
        processor.cpufeature = (boot_cpu_data.x86 << 8) |
-           (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
+           (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_stepping;
        processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX];
        processor.reserved[0] = 0;
        processor.reserved[1] = 0;
index 041096bdef860d356d58873e3e0483384ee98301..99dc79e76bdc5497c8e07c6ee32e74ffe04ff492 100644 (file)
@@ -200,9 +200,9 @@ static void native_flush_tlb_global(void)
        __native_flush_tlb_global();
 }
 
-static void native_flush_tlb_single(unsigned long addr)
+static void native_flush_tlb_one_user(unsigned long addr)
 {
-       __native_flush_tlb_single(addr);
+       __native_flush_tlb_one_user(addr);
 }
 
 struct static_key paravirt_steal_enabled;
@@ -401,7 +401,7 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = {
 
        .flush_tlb_user = native_flush_tlb,
        .flush_tlb_kernel = native_flush_tlb_global,
-       .flush_tlb_single = native_flush_tlb_single,
+       .flush_tlb_one_user = native_flush_tlb_one_user,
        .flush_tlb_others = native_flush_tlb_others,
 
        .pgd_alloc = __paravirt_pgd_alloc,
index 618285e475c622bc9f0a9fa8356794ed70da8e02..ac7ea3a8242fee683916cba35854655affaf0e45 100644 (file)
@@ -37,7 +37,6 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
        WARN_ON(size == 0);
        if (!check_addr("map_single", dev, bus, size))
                return NOMMU_MAPPING_ERROR;
-       flush_write_buffers();
        return bus;
 }
 
@@ -72,25 +71,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
                        return 0;
                s->dma_length = s->length;
        }
-       flush_write_buffers();
        return nents;
 }
 
-static void nommu_sync_single_for_device(struct device *dev,
-                       dma_addr_t addr, size_t size,
-                       enum dma_data_direction dir)
-{
-       flush_write_buffers();
-}
-
-
-static void nommu_sync_sg_for_device(struct device *dev,
-                       struct scatterlist *sg, int nelems,
-                       enum dma_data_direction dir)
-{
-       flush_write_buffers();
-}
-
 static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        return dma_addr == NOMMU_MAPPING_ERROR;
@@ -101,8 +84,6 @@ const struct dma_map_ops nommu_dma_ops = {
        .free                   = dma_generic_free_coherent,
        .map_sg                 = nommu_map_sg,
        .map_page               = nommu_map_page,
-       .sync_single_for_device = nommu_sync_single_for_device,
-       .sync_sg_for_device     = nommu_sync_sg_for_device,
        .is_phys                = 1,
        .mapping_error          = nommu_mapping_error,
        .dma_supported          = x86_dma_supported,
index 1ae67e982af70b193498c8186f65ff27788acd9f..4c616be28506fe100f88092474e193521fa81f78 100644 (file)
@@ -1204,20 +1204,13 @@ void __init setup_arch(char **cmdline_p)
 
        kasan_init();
 
-#ifdef CONFIG_X86_32
-       /* sync back kernel address range */
-       clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
-                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
-                       KERNEL_PGD_PTRS);
-
        /*
-        * sync back low identity map too.  It is used for example
-        * in the 32-bit EFI stub.
+        * Sync back kernel address range.
+        *
+        * FIXME: Can the later sync in setup_cpu_entry_areas() replace
+        * this call?
         */
-       clone_pgd_range(initial_page_table,
-                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
-                       min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
-#endif
+       sync_initial_page_table();
 
        tboot_probe();
 
index 497aa766fab38e21e5d1c24048e65a1e9c5b1e22..ea554f812ee18e46289bb1fc9b65cc7408189a74 100644 (file)
@@ -287,24 +287,15 @@ void __init setup_per_cpu_areas(void)
        /* Setup cpu initialized, callin, callout masks */
        setup_cpu_local_masks();
 
-#ifdef CONFIG_X86_32
        /*
         * Sync back kernel address range again.  We already did this in
         * setup_arch(), but percpu data also needs to be available in
         * the smpboot asm.  We can't reliably pick up percpu mappings
         * using vmalloc_fault(), because exception dispatch needs
         * percpu data.
+        *
+        * FIXME: Can the later sync in setup_cpu_entry_areas() replace
+        * this call?
         */
-       clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
-                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
-                       KERNEL_PGD_PTRS);
-
-       /*
-        * sync back low identity map too.  It is used for example
-        * in the 32-bit EFI stub.
-        */
-       clone_pgd_range(initial_page_table,
-                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
-                       min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
-#endif
+       sync_initial_page_table();
 }
index ac057f9b076360168704438f9f808d152a2dce8d..0d930d8987cc7c88454ff96acc671222583ac1c5 100644 (file)
@@ -43,6 +43,13 @@ static inline void signal_compat_build_tests(void)
        BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int));
 #define CHECK_CSI_OFFSET(name)   BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name))
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_code)  != 8);
+
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_signo) != 0);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_errno) != 4);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_code)  != 8);
         /*
         * Ensure that the size of each si_field never changes.
         * If it does, it is a sign that the
@@ -63,36 +70,94 @@ static inline void signal_compat_build_tests(void)
        CHECK_CSI_SIZE  (_kill, 2*sizeof(int));
        CHECK_SI_SIZE   (_kill, 2*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0xC);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);
+
        CHECK_CSI_OFFSET(_timer);
        CHECK_CSI_SIZE  (_timer, 3*sizeof(int));
        CHECK_SI_SIZE   (_timer, 6*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_tid)     != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x14);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_value)   != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_tid)     != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_overrun) != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value)   != 0x14);
+
        CHECK_CSI_OFFSET(_rt);
        CHECK_CSI_SIZE  (_rt, 3*sizeof(int));
        CHECK_SI_SIZE   (_rt, 4*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pid)   != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_uid)   != 0x14);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)   != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)   != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14);
+
        CHECK_CSI_OFFSET(_sigchld);
        CHECK_CSI_SIZE  (_sigchld, 5*sizeof(int));
        CHECK_SI_SIZE   (_sigchld, 8*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pid)    != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_uid)    != 0x14);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x18);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_utime)  != 0x20);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_stime)  != 0x28);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)    != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)    != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_status) != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_utime)  != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_stime)  != 0x1C);
+
 #ifdef CONFIG_X86_X32_ABI
        CHECK_CSI_OFFSET(_sigchld_x32);
        CHECK_CSI_SIZE  (_sigchld_x32, 7*sizeof(int));
        /* no _sigchld_x32 in the generic siginfo_t */
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime)  != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime)  != 0x20);
 #endif
 
        CHECK_CSI_OFFSET(_sigfault);
        CHECK_CSI_SIZE  (_sigfault, 4*sizeof(int));
        CHECK_SI_SIZE   (_sigfault, 8*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);
+
+       BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
+
+       BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18);
+
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
+
        CHECK_CSI_OFFSET(_sigpoll);
        CHECK_CSI_SIZE  (_sigpoll, 2*sizeof(int));
        CHECK_SI_SIZE   (_sigpoll, 4*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_fd)     != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd)   != 0x10);
+
        CHECK_CSI_OFFSET(_sigsys);
        CHECK_CSI_SIZE  (_sigsys, 3*sizeof(int));
        CHECK_SI_SIZE   (_sigsys, 4*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_syscall)   != 0x18);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_arch)      != 0x1C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall)   != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch)      != 0x14);
+
        /* any new si_fields should be added here */
 }
 
index 6f27facbaa9b03bd32da7f0c5edca4f1014aa320..ff99e2b6fc541a0faf8afaa17328679533b7838a 100644 (file)
@@ -1281,11 +1281,10 @@ void __init native_smp_prepare_boot_cpu(void)
        cpu_set_state_online(me);
 }
 
-void __init native_smp_cpus_done(unsigned int max_cpus)
+void __init calculate_max_logical_packages(void)
 {
        int ncpus;
 
-       pr_debug("Boot done\n");
        /*
         * Today neither Intel nor AMD support heterogenous systems so
         * extrapolate the boot cpu's data to all packages.
@@ -1293,6 +1292,13 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
        ncpus = cpu_data(0).booted_cores * topology_max_smt_threads();
        __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus);
        pr_info("Max logical packages: %u\n", __max_logical_packages);
+}
+
+void __init native_smp_cpus_done(unsigned int max_cpus)
+{
+       pr_debug("Boot done\n");
+
+       calculate_max_logical_packages();
 
        if (x86_has_numa_in_package)
                set_sched_topology(x86_numa_in_package_topology);
@@ -1430,8 +1436,8 @@ static void remove_siblinginfo(int cpu)
        cpumask_clear(cpu_llc_shared_mask(cpu));
        cpumask_clear(topology_sibling_cpumask(cpu));
        cpumask_clear(topology_core_cpumask(cpu));
-       c->phys_proc_id = 0;
        c->cpu_core_id = 0;
+       c->booted_cores = 0;
        cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
        recompute_smt_state();
 }
index 446c9ef8cfc32b68d77d4429128b3c794b3fc069..03f3d7695daccae1af7265f2aab221da81573ce5 100644 (file)
@@ -181,7 +181,7 @@ int fixup_bug(struct pt_regs *regs, int trapnr)
                break;
 
        case BUG_TRAP_TYPE_WARN:
-               regs->ip += LEN_UD0;
+               regs->ip += LEN_UD2;
                return 1;
        }
 
@@ -577,7 +577,6 @@ do_general_protection(struct pt_regs *regs, long error_code)
 }
 NOKPROBE_SYMBOL(do_general_protection);
 
-/* May run on IST stack. */
 dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 {
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -592,6 +591,13 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
        if (poke_int3_handler(regs))
                return;
 
+       /*
+        * Use ist_enter despite the fact that we don't use an IST stack.
+        * We can be called from a kprobe in non-CONTEXT_KERNEL kernel
+        * mode or even during context tracking state changes.
+        *
+        * This means that we can't schedule.  That's okay.
+        */
        ist_enter(regs);
        RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@@ -609,15 +615,10 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
                        SIGTRAP) == NOTIFY_STOP)
                goto exit;
 
-       /*
-        * Let others (NMI) know that the debug stack is in use
-        * as we may switch to the interrupt stack.
-        */
-       debug_stack_usage_inc();
        cond_local_irq_enable(regs);
        do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
        cond_local_irq_disable(regs);
-       debug_stack_usage_dec();
+
 exit:
        ist_exit(regs);
 }
index 1f9188f5357cb38e45295c07ba5f2e902563257e..feb28fee6cea7f9fbad1a4b06ee9932ac8690d75 100644 (file)
@@ -5,7 +5,6 @@
 #include <asm/unwind.h>
 #include <asm/orc_types.h>
 #include <asm/orc_lookup.h>
-#include <asm/sections.h>
 
 #define orc_warn(fmt, ...) \
        printk_deferred_once(KERN_WARNING pr_fmt("WARNING: " fmt), ##__VA_ARGS__)
@@ -148,7 +147,7 @@ static struct orc_entry *orc_find(unsigned long ip)
        }
 
        /* vmlinux .init slow lookup: */
-       if (ip >= (unsigned long)_sinittext && ip < (unsigned long)_einittext)
+       if (init_kernel_text(ip))
                return __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
                                  __stop_orc_unwind_ip - __start_orc_unwind_ip, ip);
 
index 5edb27f1a2c407ff8173161fb87cbd9130b76e8e..9d0b5af7db915c60adf23389ac47c3312dd3683a 100644 (file)
@@ -727,7 +727,8 @@ void handle_vm86_fault(struct kernel_vm86_regs *regs, long error_code)
        return;
 
 check_vip:
-       if (VEFLAGS & X86_EFLAGS_VIP) {
+       if ((VEFLAGS & (X86_EFLAGS_VIP | X86_EFLAGS_VIF)) ==
+           (X86_EFLAGS_VIP | X86_EFLAGS_VIF)) {
                save_v86_state(regs, VM86_STI);
                return;
        }
index 9b138a06c1a468e6a6d3fe41748abef3a436ace3..b854ebf5851b7c8fb6225b53e7d3a81b16ec43db 100644 (file)
@@ -118,9 +118,11 @@ SECTIONS
 
 #ifdef CONFIG_X86_64
                . = ALIGN(PAGE_SIZE);
+               VMLINUX_SYMBOL(__entry_trampoline_start) = .;
                _entry_trampoline = .;
                *(.entry_trampoline)
                . = ALIGN(PAGE_SIZE);
+               VMLINUX_SYMBOL(__entry_trampoline_end) = .;
                ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big");
 #endif
 
index a0c5a69bc7c4a324078db14ad27753443d65aa85..b671fc2d0422717f06ca6291b2a76742ee45537a 100644 (file)
@@ -607,7 +607,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
                             (1 << KVM_FEATURE_PV_EOI) |
                             (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
                             (1 << KVM_FEATURE_PV_UNHALT) |
-                            (1 << KVM_FEATURE_PV_TLB_FLUSH);
+                            (1 << KVM_FEATURE_PV_TLB_FLUSH) |
+                            (1 << KVM_FEATURE_ASYNC_PF_VMEXIT);
 
                if (sched_info_on())
                        entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
index 924ac8ce9d5004f9db4126a81f178c2bf0e6ff40..391dda8d43b7a44d3cedd0b41edbb51ba7171bf4 100644 (file)
@@ -2002,14 +2002,13 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
 
 void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
 {
-       struct kvm_lapic *apic;
+       struct kvm_lapic *apic = vcpu->arch.apic;
        int i;
 
-       apic_debug("%s\n", __func__);
+       if (!apic)
+               return;
 
-       ASSERT(vcpu);
-       apic = vcpu->arch.apic;
-       ASSERT(apic != NULL);
+       apic_debug("%s\n", __func__);
 
        /* Stop the timer in case it's a reset to an active apic */
        hrtimer_cancel(&apic->lapic_timer.timer);
@@ -2165,7 +2164,6 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
         */
        vcpu->arch.apic_base = MSR_IA32_APICBASE_ENABLE;
        static_key_slow_inc(&apic_sw_disabled.key); /* sw disabled at reset */
-       kvm_lapic_reset(vcpu, false);
        kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
 
        return 0;
@@ -2569,7 +2567,6 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
 
        pe = xchg(&apic->pending_events, 0);
        if (test_bit(KVM_APIC_INIT, &pe)) {
-               kvm_lapic_reset(vcpu, true);
                kvm_vcpu_reset(vcpu, true);
                if (kvm_vcpu_is_bsp(apic->vcpu))
                        vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
index 8eca1d04aeb86d309d7242ec2baf6c0153f79068..763bb3bade63f38df3f3f92cc2727499a3ed160f 100644 (file)
@@ -2770,8 +2770,10 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
        else
                pte_access &= ~ACC_WRITE_MASK;
 
+       if (!kvm_is_mmio_pfn(pfn))
+               spte |= shadow_me_mask;
+
        spte |= (u64)pfn << PAGE_SHIFT;
-       spte |= shadow_me_mask;
 
        if (pte_access & ACC_WRITE_MASK) {
 
@@ -3029,7 +3031,7 @@ static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn)
                return RET_PF_RETRY;
        }
 
-       return -EFAULT;
+       return RET_PF_EMULATE;
 }
 
 static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu,
@@ -5080,7 +5082,7 @@ void kvm_mmu_uninit_vm(struct kvm *kvm)
 typedef bool (*slot_level_handler) (struct kvm *kvm, struct kvm_rmap_head *rmap_head);
 
 /* The caller should hold mmu-lock before calling this function. */
-static bool
+static __always_inline bool
 slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot,
                        slot_level_handler fn, int start_level, int end_level,
                        gfn_t start_gfn, gfn_t end_gfn, bool lock_flush_tlb)
@@ -5110,7 +5112,7 @@ slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot,
        return flush;
 }
 
-static bool
+static __always_inline bool
 slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
                  slot_level_handler fn, int start_level, int end_level,
                  bool lock_flush_tlb)
@@ -5121,7 +5123,7 @@ slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
                        lock_flush_tlb);
 }
 
-static bool
+static __always_inline bool
 slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
                      slot_level_handler fn, bool lock_flush_tlb)
 {
@@ -5129,7 +5131,7 @@ slot_handle_all_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
                                 PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb);
 }
 
-static bool
+static __always_inline bool
 slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
                        slot_level_handler fn, bool lock_flush_tlb)
 {
@@ -5137,7 +5139,7 @@ slot_handle_large_level(struct kvm *kvm, struct kvm_memory_slot *memslot,
                                 PT_MAX_HUGEPAGE_LEVEL, lock_flush_tlb);
 }
 
-static bool
+static __always_inline bool
 slot_handle_leaf(struct kvm *kvm, struct kvm_memory_slot *memslot,
                 slot_level_handler fn, bool lock_flush_tlb)
 {
index b3e488a748281aa5f3d319861ae2ab4bfca3e65c..be9c839e2c89967d689485dbb8e51763980dd151 100644 (file)
@@ -49,6 +49,7 @@
 #include <asm/debugreg.h>
 #include <asm/kvm_para.h>
 #include <asm/irq_remapping.h>
+#include <asm/microcode.h>
 #include <asm/nospec-branch.h>
 
 #include <asm/virtext.h>
@@ -178,6 +179,8 @@ struct vcpu_svm {
        uint64_t sysenter_eip;
        uint64_t tsc_aux;
 
+       u64 msr_decfg;
+
        u64 next_rip;
 
        u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
@@ -300,6 +303,8 @@ module_param(vgif, int, 0444);
 static int sev = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT);
 module_param(sev, int, 0444);
 
+static u8 rsm_ins_bytes[] = "\x0f\xaa";
+
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
 static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 static void svm_complete_interrupts(struct vcpu_svm *svm);
@@ -1383,6 +1388,7 @@ static void init_vmcb(struct vcpu_svm *svm)
        set_intercept(svm, INTERCEPT_SKINIT);
        set_intercept(svm, INTERCEPT_WBINVD);
        set_intercept(svm, INTERCEPT_XSETBV);
+       set_intercept(svm, INTERCEPT_RSM);
 
        if (!kvm_mwait_in_guest()) {
                set_intercept(svm, INTERCEPT_MONITOR);
@@ -1902,6 +1908,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
        u32 dummy;
        u32 eax = 1;
 
+       vcpu->arch.microcode_version = 0x01000065;
        svm->spec_ctrl = 0;
 
        if (!init_event) {
@@ -3699,6 +3706,12 @@ static int emulate_on_interception(struct vcpu_svm *svm)
        return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 }
 
+static int rsm_interception(struct vcpu_svm *svm)
+{
+       return x86_emulate_instruction(&svm->vcpu, 0, 0,
+                                      rsm_ins_bytes, 2) == EMULATE_DONE;
+}
+
 static int rdpmc_interception(struct vcpu_svm *svm)
 {
        int err;
@@ -3860,6 +3873,22 @@ static int cr8_write_interception(struct vcpu_svm *svm)
        return 0;
 }
 
+static int svm_get_msr_feature(struct kvm_msr_entry *msr)
+{
+       msr->data = 0;
+
+       switch (msr->index) {
+       case MSR_F10H_DECFG:
+               if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC))
+                       msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE;
+               break;
+       default:
+               return 1;
+       }
+
+       return 0;
+}
+
 static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -3935,9 +3964,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
                msr_info->data = svm->spec_ctrl;
                break;
-       case MSR_IA32_UCODE_REV:
-               msr_info->data = 0x01000065;
-               break;
        case MSR_F15H_IC_CFG: {
 
                int family, model;
@@ -3955,6 +3981,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        msr_info->data = 0x1E;
                }
                break;
+       case MSR_F10H_DECFG:
+               msr_info->data = svm->msr_decfg;
+               break;
        default:
                return kvm_get_msr_common(vcpu, msr_info);
        }
@@ -4133,6 +4162,24 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
        case MSR_VM_IGNNE:
                vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
                break;
+       case MSR_F10H_DECFG: {
+               struct kvm_msr_entry msr_entry;
+
+               msr_entry.index = msr->index;
+               if (svm_get_msr_feature(&msr_entry))
+                       return 1;
+
+               /* Check the supported bits */
+               if (data & ~msr_entry.data)
+                       return 1;
+
+               /* Don't allow the guest to change a bit, #GP */
+               if (!msr->host_initiated && (data ^ msr_entry.data))
+                       return 1;
+
+               svm->msr_decfg = data;
+               break;
+       }
        case MSR_IA32_APICBASE:
                if (kvm_vcpu_apicv_active(vcpu))
                        avic_update_vapic_bar(to_svm(vcpu), data);
@@ -4541,7 +4588,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
        [SVM_EXIT_MWAIT]                        = mwait_interception,
        [SVM_EXIT_XSETBV]                       = xsetbv_interception,
        [SVM_EXIT_NPF]                          = npf_interception,
-       [SVM_EXIT_RSM]                          = emulate_on_interception,
+       [SVM_EXIT_RSM]                          = rsm_interception,
        [SVM_EXIT_AVIC_INCOMPLETE_IPI]          = avic_incomplete_ipi_interception,
        [SVM_EXIT_AVIC_UNACCELERATED_ACCESS]    = avic_unaccelerated_access_interception,
 };
@@ -5355,7 +5402,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
         * being speculatively taken.
         */
        if (svm->spec_ctrl)
-               wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
+               native_wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
 
        asm volatile (
                "push %%" _ASM_BP "; \n\t"
@@ -5464,11 +5511,11 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
         * If the L02 MSR bitmap does not intercept the MSR, then we need to
         * save it.
         */
-       if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
-               rdmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
+       if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
+               svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
 
        if (svm->spec_ctrl)
-               wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+               native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
 
        /* Eliminate branch target predictions from guest mode */
        vmexit_fill_RSB();
@@ -6236,16 +6283,18 @@ e_free:
 
 static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
 {
+       void __user *measure = (void __user *)(uintptr_t)argp->data;
        struct kvm_sev_info *sev = &kvm->arch.sev_info;
        struct sev_data_launch_measure *data;
        struct kvm_sev_launch_measure params;
+       void __user *p = NULL;
        void *blob = NULL;
        int ret;
 
        if (!sev_guest(kvm))
                return -ENOTTY;
 
-       if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+       if (copy_from_user(&params, measure, sizeof(params)))
                return -EFAULT;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -6256,17 +6305,13 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
        if (!params.len)
                goto cmd;
 
-       if (params.uaddr) {
+       p = (void __user *)(uintptr_t)params.uaddr;
+       if (p) {
                if (params.len > SEV_FW_BLOB_MAX_SIZE) {
                        ret = -EINVAL;
                        goto e_free;
                }
 
-               if (!access_ok(VERIFY_WRITE, params.uaddr, params.len)) {
-                       ret = -EFAULT;
-                       goto e_free;
-               }
-
                ret = -ENOMEM;
                blob = kmalloc(params.len, GFP_KERNEL);
                if (!blob)
@@ -6290,13 +6335,13 @@ cmd:
                goto e_free_blob;
 
        if (blob) {
-               if (copy_to_user((void __user *)(uintptr_t)params.uaddr, blob, params.len))
+               if (copy_to_user(p, blob, params.len))
                        ret = -EFAULT;
        }
 
 done:
        params.len = data->len;
-       if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
+       if (copy_to_user(measure, &params, sizeof(params)))
                ret = -EFAULT;
 e_free_blob:
        kfree(blob);
@@ -6597,7 +6642,7 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
        struct page **pages;
        void *blob, *hdr;
        unsigned long n;
-       int ret;
+       int ret, offset;
 
        if (!sev_guest(kvm))
                return -ENOTTY;
@@ -6623,6 +6668,10 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
        if (!data)
                goto e_unpin_memory;
 
+       offset = params.guest_uaddr & (PAGE_SIZE - 1);
+       data->guest_address = __sme_page_pa(pages[0]) + offset;
+       data->guest_len = params.guest_len;
+
        blob = psp_copy_user_blob(params.trans_uaddr, params.trans_len);
        if (IS_ERR(blob)) {
                ret = PTR_ERR(blob);
@@ -6637,8 +6686,8 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
                ret = PTR_ERR(hdr);
                goto e_free_blob;
        }
-       data->trans_address = __psp_pa(blob);
-       data->trans_len = params.trans_len;
+       data->hdr_address = __psp_pa(hdr);
+       data->hdr_len = params.hdr_len;
 
        data->handle = sev->handle;
        ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_UPDATE_SECRET, data, &argp->error);
@@ -6821,6 +6870,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .vcpu_unblocking = svm_vcpu_unblocking,
 
        .update_bp_intercept = update_bp_intercept,
+       .get_msr_feature = svm_get_msr_feature,
        .get_msr = svm_get_msr,
        .set_msr = svm_set_msr,
        .get_segment_base = svm_get_segment_base,
index f427723dc7db34fab153b4faecbbb767b48f7e06..2d87603f91795b29c5ea0f84703d316a49c0573d 100644 (file)
@@ -51,6 +51,7 @@
 #include <asm/apic.h>
 #include <asm/irq_remapping.h>
 #include <asm/mmu_context.h>
+#include <asm/microcode.h>
 #include <asm/nospec-branch.h>
 
 #include "trace.h"
@@ -1044,6 +1045,13 @@ static inline bool is_machine_check(u32 intr_info)
                (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK);
 }
 
+/* Undocumented: icebp/int1 */
+static inline bool is_icebp(u32 intr_info)
+{
+       return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
+               == (INTR_TYPE_PRIV_SW_EXCEPTION | INTR_INFO_VALID_MASK);
+}
+
 static inline bool cpu_has_vmx_msr_bitmap(void)
 {
        return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
@@ -3226,6 +3234,11 @@ static inline bool vmx_feature_control_msr_valid(struct kvm_vcpu *vcpu,
        return !(val & ~valid_bits);
 }
 
+static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
+{
+       return 1;
+}
+
 /*
  * Reads an msr value (of 'msr_index') into 'pdata'.
  * Returns 0 on success, non-0 otherwise.
@@ -4485,7 +4498,8 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
                vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
                              SECONDARY_EXEC_DESC);
                hw_cr4 &= ~X86_CR4_UMIP;
-       } else
+       } else if (!is_guest_mode(vcpu) ||
+                  !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC))
                vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
                                SECONDARY_EXEC_DESC);
 
@@ -5765,6 +5779,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
        vmx->rmode.vm86_active = 0;
        vmx->spec_ctrl = 0;
 
+       vcpu->arch.microcode_version = 0x100000000ULL;
        vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
        kvm_set_cr8(vcpu, 0);
 
@@ -6171,7 +6186,7 @@ static int handle_exception(struct kvm_vcpu *vcpu)
                      (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
                        vcpu->arch.dr6 &= ~15;
                        vcpu->arch.dr6 |= dr6 | DR6_RTM;
-                       if (!(dr6 & ~DR6_RESERVED)) /* icebp */
+                       if (is_icebp(intr_info))
                                skip_emulated_instruction(vcpu);
 
                        kvm_queue_exception(vcpu, DB_VECTOR);
@@ -9452,7 +9467,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
         * being speculatively taken.
         */
        if (vmx->spec_ctrl)
-               wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+               native_wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
 
        vmx->__launched = vmx->loaded_vmcs->launched;
        asm(
@@ -9587,11 +9602,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
         * If the L02 MSR bitmap does not intercept the MSR, then we need to
         * save it.
         */
-       if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
-               rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+       if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
+               vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
 
        if (vmx->spec_ctrl)
-               wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+               native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
 
        /* Eliminate branch target predictions from guest mode */
        vmexit_fill_RSB();
@@ -10136,7 +10151,10 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu,
                        (unsigned long)(vmcs12->posted_intr_desc_addr &
                        (PAGE_SIZE - 1)));
        }
-       if (!nested_vmx_prepare_msr_bitmap(vcpu, vmcs12))
+       if (nested_vmx_prepare_msr_bitmap(vcpu, vmcs12))
+               vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL,
+                             CPU_BASED_USE_MSR_BITMAPS);
+       else
                vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL,
                                CPU_BASED_USE_MSR_BITMAPS);
 }
@@ -10224,8 +10242,8 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
         *    updated to reflect this when L1 (or its L2s) actually write to
         *    the MSR.
         */
-       bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
-       bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
+       bool pred_cmd = !msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
+       bool spec_ctrl = !msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
 
        /* Nothing to do if the MSR bitmap is not in use.  */
        if (!cpu_has_vmx_msr_bitmap() ||
@@ -11196,7 +11214,12 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
        if (ret)
                return ret;
 
-       if (vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT)
+       /*
+        * If we're entering a halted L2 vcpu and the L2 vcpu won't be woken
+        * by event injection, halt vcpu.
+        */
+       if ((vmcs12->guest_activity_state == GUEST_ACTIVITY_HLT) &&
+           !(vmcs12->vm_entry_intr_info_field & INTR_INFO_VALID_MASK))
                return kvm_vcpu_halt(vcpu);
 
        vmx->nested.nested_run_pending = 1;
@@ -12287,6 +12310,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .vcpu_put = vmx_vcpu_put,
 
        .update_bp_intercept = update_exception_bitmap,
+       .get_msr_feature = vmx_get_msr_feature,
        .get_msr = vmx_get_msr,
        .set_msr = vmx_set_msr,
        .get_segment_base = vmx_get_segment_base,
index c8a0b545ac20c71a464738a1dd0cd7e1c3df388e..18b5ca7a31974757f0dfdd43f5d7e0805f4f3aaa 100644 (file)
@@ -1049,6 +1049,45 @@ static u32 emulated_msrs[] = {
 
 static unsigned num_emulated_msrs;
 
+/*
+ * List of msr numbers which are used to expose MSR-based features that
+ * can be used by a hypervisor to validate requested CPU features.
+ */
+static u32 msr_based_features[] = {
+       MSR_F10H_DECFG,
+       MSR_IA32_UCODE_REV,
+};
+
+static unsigned int num_msr_based_features;
+
+static int kvm_get_msr_feature(struct kvm_msr_entry *msr)
+{
+       switch (msr->index) {
+       case MSR_IA32_UCODE_REV:
+               rdmsrl(msr->index, msr->data);
+               break;
+       default:
+               if (kvm_x86_ops->get_msr_feature(msr))
+                       return 1;
+       }
+       return 0;
+}
+
+static int do_get_msr_feature(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
+{
+       struct kvm_msr_entry msr;
+       int r;
+
+       msr.index = index;
+       r = kvm_get_msr_feature(&msr);
+       if (r)
+               return r;
+
+       *data = msr.data;
+
+       return 0;
+}
+
 bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
        if (efer & efer_reserved_bits)
@@ -2222,7 +2261,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
        switch (msr) {
        case MSR_AMD64_NB_CFG:
-       case MSR_IA32_UCODE_REV:
        case MSR_IA32_UCODE_WRITE:
        case MSR_VM_HSAVE_PA:
        case MSR_AMD64_PATCH_LOADER:
@@ -2230,6 +2268,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_AMD64_DC_CFG:
                break;
 
+       case MSR_IA32_UCODE_REV:
+               if (msr_info->host_initiated)
+                       vcpu->arch.microcode_version = data;
+               break;
        case MSR_EFER:
                return set_efer(vcpu, data);
        case MSR_K7_HWCR:
@@ -2525,7 +2567,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                msr_info->data = 0;
                break;
        case MSR_IA32_UCODE_REV:
-               msr_info->data = 0x100000000ULL;
+               msr_info->data = vcpu->arch.microcode_version;
                break;
        case MSR_MTRRcap:
        case 0x200 ... 0x2ff:
@@ -2680,13 +2722,11 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
                    int (*do_msr)(struct kvm_vcpu *vcpu,
                                  unsigned index, u64 *data))
 {
-       int i, idx;
+       int i;
 
-       idx = srcu_read_lock(&vcpu->kvm->srcu);
        for (i = 0; i < msrs->nmsrs; ++i)
                if (do_msr(vcpu, entries[i].index, &entries[i].data))
                        break;
-       srcu_read_unlock(&vcpu->kvm->srcu, idx);
 
        return i;
 }
@@ -2785,6 +2825,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_SET_BOOT_CPU_ID:
        case KVM_CAP_SPLIT_IRQCHIP:
        case KVM_CAP_IMMEDIATE_EXIT:
+       case KVM_CAP_GET_MSR_FEATURES:
                r = 1;
                break;
        case KVM_CAP_ADJUST_CLOCK:
@@ -2899,6 +2940,31 @@ long kvm_arch_dev_ioctl(struct file *filp,
                        goto out;
                r = 0;
                break;
+       case KVM_GET_MSR_FEATURE_INDEX_LIST: {
+               struct kvm_msr_list __user *user_msr_list = argp;
+               struct kvm_msr_list msr_list;
+               unsigned int n;
+
+               r = -EFAULT;
+               if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list)))
+                       goto out;
+               n = msr_list.nmsrs;
+               msr_list.nmsrs = num_msr_based_features;
+               if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list)))
+                       goto out;
+               r = -E2BIG;
+               if (n < msr_list.nmsrs)
+                       goto out;
+               r = -EFAULT;
+               if (copy_to_user(user_msr_list->indices, &msr_based_features,
+                                num_msr_based_features * sizeof(u32)))
+                       goto out;
+               r = 0;
+               break;
+       }
+       case KVM_GET_MSRS:
+               r = msr_io(NULL, argp, do_get_msr_feature, 1);
+               break;
        }
        default:
                r = -EINVAL;
@@ -3636,12 +3702,18 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                r = 0;
                break;
        }
-       case KVM_GET_MSRS:
+       case KVM_GET_MSRS: {
+               int idx = srcu_read_lock(&vcpu->kvm->srcu);
                r = msr_io(vcpu, argp, do_get_msr, 1);
+               srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
-       case KVM_SET_MSRS:
+       }
+       case KVM_SET_MSRS: {
+               int idx = srcu_read_lock(&vcpu->kvm->srcu);
                r = msr_io(vcpu, argp, do_set_msr, 0);
+               srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
+       }
        case KVM_TPR_ACCESS_REPORTING: {
                struct kvm_tpr_access_ctl tac;
 
@@ -4464,6 +4536,19 @@ static void kvm_init_msr_list(void)
                j++;
        }
        num_emulated_msrs = j;
+
+       for (i = j = 0; i < ARRAY_SIZE(msr_based_features); i++) {
+               struct kvm_msr_entry msr;
+
+               msr.index = msr_based_features[i];
+               if (kvm_get_msr_feature(&msr))
+                       continue;
+
+               if (j < i)
+                       msr_based_features[j] = msr_based_features[i];
+               j++;
+       }
+       num_msr_based_features = j;
 }
 
 static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
@@ -8017,6 +8102,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 
 void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 {
+       kvm_lapic_reset(vcpu, init_event);
+
        vcpu->arch.hflags = 0;
 
        vcpu->arch.smi_pending = 0;
@@ -8460,10 +8547,8 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
                        return r;
        }
 
-       if (!size) {
-               r = vm_munmap(old.userspace_addr, old.npages * PAGE_SIZE);
-               WARN_ON(r < 0);
-       }
+       if (!size)
+               vm_munmap(old.userspace_addr, old.npages * PAGE_SIZE);
 
        return 0;
 }
index 91e9700cc6dcd2152f7488740ad3f9a6e1b766c4..25a972c61b0ae9816a817eb9681f4cd374e9e32a 100644 (file)
@@ -28,7 +28,6 @@ lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o
 lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
 lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 lib-$(CONFIG_RETPOLINE) += retpoline.o
-OBJECT_FILES_NON_STANDARD_retpoline.o :=y
 
 obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
 
index d6f848d1211d4b2deaf193fca80fb4834310dff4..2dd1fe13a37b36aacfeca12733178f62a89ba309 100644 (file)
@@ -18,7 +18,7 @@ unsigned int x86_model(unsigned int sig)
 {
        unsigned int fam, model;
 
-        fam = x86_family(sig);
+       fam = x86_family(sig);
 
        model = (sig >> 4) & 0xf;
 
index 7b881d03d0ddd934f674343519159be1fe48a2cc..3cdf06128d13c11b60ca2aa7cadf32af03703020 100644 (file)
@@ -7,6 +7,7 @@ asmlinkage void just_return_func(void);
 
 asm(
        ".type just_return_func, @function\n"
+       ".globl just_return_func\n"
        "just_return_func:\n"
        "       ret\n"
        ".size just_return_func, .-just_return_func\n"
index 480edc3a5e03002dd6f0a0316477cbd7b0971cc8..c909961e678a594bd3812cb14936bdf035af2bb9 100644 (file)
@@ -7,7 +7,6 @@
 #include <asm/alternative-asm.h>
 #include <asm/export.h>
 #include <asm/nospec-branch.h>
-#include <asm/bitsperlong.h>
 
 .macro THUNK reg
        .section .text.__x86.indirect_thunk
@@ -47,58 +46,3 @@ GENERATE_THUNK(r13)
 GENERATE_THUNK(r14)
 GENERATE_THUNK(r15)
 #endif
-
-/*
- * Fill the CPU return stack buffer.
- *
- * Each entry in the RSB, if used for a speculative 'ret', contains an
- * infinite 'pause; lfence; jmp' loop to capture speculative execution.
- *
- * This is required in various cases for retpoline and IBRS-based
- * mitigations for the Spectre variant 2 vulnerability. Sometimes to
- * eliminate potentially bogus entries from the RSB, and sometimes
- * purely to ensure that it doesn't get empty, which on some CPUs would
- * allow predictions from other (unwanted!) sources to be used.
- *
- * Google experimented with loop-unrolling and this turned out to be
- * the optimal version - two calls, each with their own speculation
- * trap should their return address end up getting used, in a loop.
- */
-.macro STUFF_RSB nr:req sp:req
-       mov     $(\nr / 2), %_ASM_BX
-       .align 16
-771:
-       call    772f
-773:                                           /* speculation trap */
-       pause
-       lfence
-       jmp     773b
-       .align 16
-772:
-       call    774f
-775:                                           /* speculation trap */
-       pause
-       lfence
-       jmp     775b
-       .align 16
-774:
-       dec     %_ASM_BX
-       jnz     771b
-       add     $((BITS_PER_LONG/8) * \nr), \sp
-.endm
-
-#define RSB_FILL_LOOPS         16      /* To avoid underflow */
-
-ENTRY(__fill_rsb)
-       STUFF_RSB RSB_FILL_LOOPS, %_ASM_SP
-       ret
-END(__fill_rsb)
-EXPORT_SYMBOL_GPL(__fill_rsb)
-
-#define RSB_CLEAR_LOOPS                32      /* To forcibly overwrite all entries */
-
-ENTRY(__clear_rsb)
-       STUFF_RSB RSB_CLEAR_LOOPS, %_ASM_SP
-       ret
-END(__clear_rsb)
-EXPORT_SYMBOL_GPL(__clear_rsb)
index b9283cc276220db667ab091a3358eb5741813f7f..476d810639a87a5ba5a24528b4de5dd34b6e59f6 100644 (file)
@@ -163,4 +163,10 @@ void __init setup_cpu_entry_areas(void)
 
        for_each_possible_cpu(cpu)
                setup_cpu_entry_area(cpu);
+
+       /*
+        * This is the last essential update to swapper_pgdir which needs
+        * to be synchronized to initial_page_table on 32bit.
+        */
+       sync_initial_page_table();
 }
index 800de815519cd1061c090e70fab09bd62bbd8ddd..25a30b5d6582f2cd7937ed1beb51de989db24280 100644 (file)
@@ -330,7 +330,7 @@ static noinline int vmalloc_fault(unsigned long address)
        if (!pmd_k)
                return -1;
 
-       if (pmd_huge(*pmd_k))
+       if (pmd_large(*pmd_k))
                return 0;
 
        pte_k = pte_offset_kernel(pmd_k, address);
@@ -475,7 +475,7 @@ static noinline int vmalloc_fault(unsigned long address)
        if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
                BUG();
 
-       if (pud_huge(*pud))
+       if (pud_large(*pud))
                return 0;
 
        pmd = pmd_offset(pud, address);
@@ -486,7 +486,7 @@ static noinline int vmalloc_fault(unsigned long address)
        if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
                BUG();
 
-       if (pmd_huge(*pmd))
+       if (pmd_large(*pmd))
                return 0;
 
        pte_ref = pte_offset_kernel(pmd_ref, address);
@@ -1248,10 +1248,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
        tsk = current;
        mm = tsk->mm;
 
-       /*
-        * Detect and handle instructions that would cause a page fault for
-        * both a tracked kernel page and a userspace page.
-        */
        prefetchw(&mm->mmap_sem);
 
        if (unlikely(kmmio_fault(regs, address)))
index 79cb066f40c0d4a4607a7b7aa4e5524a203b5e10..396e1f0151ac1973de4339a8946653f95aecb66d 100644 (file)
@@ -453,6 +453,21 @@ static inline void permanent_kmaps_init(pgd_t *pgd_base)
 }
 #endif /* CONFIG_HIGHMEM */
 
+void __init sync_initial_page_table(void)
+{
+       clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
+                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       KERNEL_PGD_PTRS);
+
+       /*
+        * sync back low identity map too.  It is used for example
+        * in the 32-bit EFI stub.
+        */
+       clone_pgd_range(initial_page_table,
+                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       min(KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
+}
+
 void __init native_pagetable_init(void)
 {
        unsigned long pfn, va;
index 1ab42c8520693c9999e4b19d04eb565528404ed7..af11a2890235584a5f07cfe7f83a00ea71fc47f9 100644 (file)
@@ -256,7 +256,7 @@ static void __set_pte_vaddr(pud_t *pud, unsigned long vaddr, pte_t new_pte)
         * It's enough to flush this one mapping.
         * (PGE mappings get flushed as well)
         */
-       __flush_tlb_one(vaddr);
+       __flush_tlb_one_kernel(vaddr);
 }
 
 void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte)
@@ -800,17 +800,11 @@ int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
 
 #define PAGE_INUSE 0xFD
 
-static void __meminit free_pagetable(struct page *page, int order,
-               struct vmem_altmap *altmap)
+static void __meminit free_pagetable(struct page *page, int order)
 {
        unsigned long magic;
        unsigned int nr_pages = 1 << order;
 
-       if (altmap) {
-               vmem_altmap_free(altmap, nr_pages);
-               return;
-       }
-
        /* bootmem page has reserved flag */
        if (PageReserved(page)) {
                __ClearPageReserved(page);
@@ -826,8 +820,16 @@ 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_hugepage_table(struct page *page,
                struct vmem_altmap *altmap)
+{
+       if (altmap)
+               vmem_altmap_free(altmap, PMD_SIZE / PAGE_SIZE);
+       else
+               free_pagetable(page, get_order(PMD_SIZE));
+}
+
+static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
 {
        pte_t *pte;
        int i;
@@ -839,14 +841,13 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd,
        }
 
        /* free a pte talbe */
-       free_pagetable(pmd_page(*pmd), 0, altmap);
+       free_pagetable(pmd_page(*pmd), 0);
        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,
-               struct vmem_altmap *altmap)
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
 {
        pmd_t *pmd;
        int i;
@@ -858,14 +859,13 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud,
        }
 
        /* free a pmd talbe */
-       free_pagetable(pud_page(*pud), 0, altmap);
+       free_pagetable(pud_page(*pud), 0);
        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,
-               struct vmem_altmap *altmap)
+static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
 {
        pud_t *pud;
        int i;
@@ -877,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, altmap);
+       free_pagetable(p4d_page(*p4d), 0);
        spin_lock(&init_mm.page_table_lock);
        p4d_clear(p4d);
        spin_unlock(&init_mm.page_table_lock);
@@ -885,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,
-                struct vmem_altmap *altmap, bool direct)
+                bool direct)
 {
        unsigned long next, pages = 0;
        pte_t *pte;
@@ -916,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, altmap);
+                               free_pagetable(pte_page(*pte), 0);
 
                        spin_lock(&init_mm.page_table_lock);
                        pte_clear(&init_mm, addr, pte);
@@ -939,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, altmap);
+                               free_pagetable(pte_page(*pte), 0);
 
                                spin_lock(&init_mm.page_table_lock);
                                pte_clear(&init_mm, addr, pte);
@@ -974,9 +974,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
                        if (IS_ALIGNED(addr, PMD_SIZE) &&
                            IS_ALIGNED(next, PMD_SIZE)) {
                                if (!direct)
-                                       free_pagetable(pmd_page(*pmd),
-                                                      get_order(PMD_SIZE),
-                                                      altmap);
+                                       free_hugepage_table(pmd_page(*pmd),
+                                                           altmap);
 
                                spin_lock(&init_mm.page_table_lock);
                                pmd_clear(pmd);
@@ -989,9 +988,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
                                page_addr = page_address(pmd_page(*pmd));
                                if (!memchr_inv(page_addr, PAGE_INUSE,
                                                PMD_SIZE)) {
-                                       free_pagetable(pmd_page(*pmd),
-                                                      get_order(PMD_SIZE),
-                                                      altmap);
+                                       free_hugepage_table(pmd_page(*pmd),
+                                                           altmap);
 
                                        spin_lock(&init_mm.page_table_lock);
                                        pmd_clear(pmd);
@@ -1003,8 +1001,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, altmap, direct);
-               free_pte_table(pte_base, pmd, altmap);
+               remove_pte_table(pte_base, addr, next, direct);
+               free_pte_table(pte_base, pmd);
        }
 
        /* Call free_pmd_table() in remove_pud_table(). */
@@ -1033,8 +1031,7 @@ 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),
-                                                      altmap);
+                                                      get_order(PUD_SIZE));
 
                                spin_lock(&init_mm.page_table_lock);
                                pud_clear(pud);
@@ -1048,8 +1045,7 @@ 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),
-                                                      altmap);
+                                                      get_order(PUD_SIZE));
 
                                        spin_lock(&init_mm.page_table_lock);
                                        pud_clear(pud);
@@ -1062,7 +1058,7 @@ 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, altmap);
-               free_pmd_table(pmd_base, pud, altmap);
+               free_pmd_table(pmd_base, pud);
        }
 
        if (direct)
@@ -1094,7 +1090,7 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
                 * to adapt for boot-time switching between 4 and 5 level page tables.
                 */
                if (CONFIG_PGTABLE_LEVELS == 5)
-                       free_pud_table(pud_base, p4d, altmap);
+                       free_pud_table(pud_base, p4d);
        }
 
        if (direct)
@@ -1193,8 +1189,8 @@ void __init mem_init(void)
        register_page_bootmem_info();
 
        /* Register memory areas for /proc/kcore */
-       kclist_add(&kcore_vsyscall, (void *)VSYSCALL_ADDR,
-                        PAGE_SIZE, KCORE_OTHER);
+       if (get_gate_vma(&init_mm))
+               kclist_add(&kcore_vsyscall, (void *)VSYSCALL_ADDR, PAGE_SIZE, KCORE_USER);
 
        mem_init_print_info(NULL);
 }
index c45b6ec5357bcd2e9f6626bd738c700cccd0a173..e2db83bebc3b71a7842404b938f3bb1c2f1e7fae 100644 (file)
@@ -820,5 +820,5 @@ void __init __early_set_fixmap(enum fixed_addresses idx,
                set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
        else
                pte_clear(&init_mm, addr, pte);
-       __flush_tlb_one(addr);
+       __flush_tlb_one_kernel(addr);
 }
index 58477ec3d66d08acf07c1bc21bb9a55a78fcaa28..7c868670963617865d2e9fb494a08b04a82b49cb 100644 (file)
@@ -168,7 +168,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
                return -1;
        }
 
-       __flush_tlb_one(f->addr);
+       __flush_tlb_one_kernel(f->addr);
        return 0;
 }
 
index 01f682cf77a8b36bff9a2b45a8f8beb734b4b6c4..40a6085063d6fe87958f260bf9cbc1be3b647424 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/page.h>
 #include <asm/processor-flags.h>
 #include <asm/msr-index.h>
+#include <asm/nospec-branch.h>
 
        .text
        .code64
@@ -59,6 +60,7 @@ ENTRY(sme_encrypt_execute)
        movq    %rax, %r8               /* Workarea encryption routine */
        addq    $PAGE_SIZE, %r8         /* Workarea intermediate copy buffer */
 
+       ANNOTATE_RETPOLINE_SAFE
        call    *%rax                   /* Call the encryption routine */
 
        pop     %r12
index 004abf9ebf1222c169448090f7f1c570635bce41..34cda7e0551b4a8809bb4a1a9fedef22ce4a4e28 100644 (file)
@@ -702,4 +702,52 @@ int pmd_clear_huge(pmd_t *pmd)
 
        return 0;
 }
+
+/**
+ * pud_free_pmd_page - Clear pud entry and free pmd page.
+ * @pud: Pointer to a PUD.
+ *
+ * Context: The pud range has been unmaped and TLB purged.
+ * Return: 1 if clearing the entry succeeded. 0 otherwise.
+ */
+int pud_free_pmd_page(pud_t *pud)
+{
+       pmd_t *pmd;
+       int i;
+
+       if (pud_none(*pud))
+               return 1;
+
+       pmd = (pmd_t *)pud_page_vaddr(*pud);
+
+       for (i = 0; i < PTRS_PER_PMD; i++)
+               if (!pmd_free_pte_page(&pmd[i]))
+                       return 0;
+
+       pud_clear(pud);
+       free_page((unsigned long)pmd);
+
+       return 1;
+}
+
+/**
+ * pmd_free_pte_page - Clear pmd entry and free pte page.
+ * @pmd: Pointer to a PMD.
+ *
+ * Context: The pmd range has been unmaped and TLB purged.
+ * Return: 1 if clearing the entry succeeded. 0 otherwise.
+ */
+int pmd_free_pte_page(pmd_t *pmd)
+{
+       pte_t *pte;
+
+       if (pmd_none(*pmd))
+               return 1;
+
+       pte = (pte_t *)pmd_page_vaddr(*pmd);
+       pmd_clear(pmd);
+       free_page((unsigned long)pte);
+
+       return 1;
+}
 #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
index c3c5274410a908e762aed936406006d63c3116ac..9bb7f0ab9fe625b77c64bec89b2a0ff9cac222bf 100644 (file)
@@ -63,7 +63,7 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
         * It's enough to flush this one mapping.
         * (PGE mappings get flushed as well)
         */
-       __flush_tlb_one(vaddr);
+       __flush_tlb_one_kernel(vaddr);
 }
 
 unsigned long __FIXADDR_TOP = 0xfffff000;
index ce38f165489b5a13d92091c8671879f30ce44e20..631507f0c1980cc03367c161b7164a16c40de496 100644 (file)
@@ -332,7 +332,7 @@ static void __init pti_clone_user_shared(void)
 }
 
 /*
- * Clone the ESPFIX P4D into the user space visinble page table
+ * Clone the ESPFIX P4D into the user space visible page table
  */
 static void __init pti_setup_espfix64(void)
 {
index 8dcc0607f80584748f92fe43aba9a32685fc6f9b..7f1a51399674b1da34cac674b94b66043f11a1ea 100644 (file)
@@ -498,7 +498,7 @@ static void flush_tlb_func_common(const struct flush_tlb_info *f,
         *    flush that changes context.tlb_gen from 2 to 3.  If they get
         *    processed on this CPU in reverse order, we'll see
         *     local_tlb_gen == 1, mm_tlb_gen == 3, and end != TLB_FLUSH_ALL.
-        *    If we were to use __flush_tlb_single() and set local_tlb_gen to
+        *    If we were to use __flush_tlb_one_user() and set local_tlb_gen to
         *    3, we'd be break the invariant: we'd update local_tlb_gen above
         *    1 without the full flush that's needed for tlb_gen 2.
         *
@@ -519,7 +519,7 @@ static void flush_tlb_func_common(const struct flush_tlb_info *f,
 
                addr = f->start;
                while (addr < f->end) {
-                       __flush_tlb_single(addr);
+                       __flush_tlb_one_user(addr);
                        addr += PAGE_SIZE;
                }
                if (local)
@@ -666,7 +666,7 @@ static void do_kernel_range_flush(void *info)
 
        /* flush range by one by one 'invlpg' */
        for (addr = f->start; addr < f->end; addr += PAGE_SIZE)
-               __flush_tlb_one(addr);
+               __flush_tlb_one_kernel(addr);
 }
 
 void flush_tlb_kernel_range(unsigned long start, unsigned long end)
index 4923d92f918d58fa3daddd915f49b383533a161e..ce5b2ebd57015db862192c598a5886776c30faac 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/if_vlan.h>
 #include <asm/cacheflush.h>
 #include <asm/set_memory.h>
+#include <asm/nospec-branch.h>
 #include <linux/bpf.h>
 
 /*
@@ -290,7 +291,7 @@ static void emit_bpf_tail_call(u8 **pprog)
        EMIT2(0x89, 0xD2);                        /* mov edx, edx */
        EMIT3(0x39, 0x56,                         /* cmp dword ptr [rsi + 16], edx */
              offsetof(struct bpf_array, map.max_entries));
-#define OFFSET1 43 /* number of bytes to jump */
+#define OFFSET1 (41 + RETPOLINE_RAX_BPF_JIT_SIZE) /* number of bytes to jump */
        EMIT2(X86_JBE, OFFSET1);                  /* jbe out */
        label1 = cnt;
 
@@ -299,7 +300,7 @@ static void emit_bpf_tail_call(u8 **pprog)
         */
        EMIT2_off32(0x8B, 0x85, 36);              /* mov eax, dword ptr [rbp + 36] */
        EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT);     /* cmp eax, MAX_TAIL_CALL_CNT */
-#define OFFSET2 32
+#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE)
        EMIT2(X86_JA, OFFSET2);                   /* ja out */
        label2 = cnt;
        EMIT3(0x83, 0xC0, 0x01);                  /* add eax, 1 */
@@ -313,7 +314,7 @@ static void emit_bpf_tail_call(u8 **pprog)
         *   goto out;
         */
        EMIT3(0x48, 0x85, 0xC0);                  /* test rax,rax */
-#define OFFSET3 10
+#define OFFSET3 (8 + RETPOLINE_RAX_BPF_JIT_SIZE)
        EMIT2(X86_JE, OFFSET3);                   /* je out */
        label3 = cnt;
 
@@ -326,7 +327,7 @@ static void emit_bpf_tail_call(u8 **pprog)
         * rdi == ctx (1st arg)
         * rax == prog->bpf_func + prologue_size
         */
-       EMIT2(0xFF, 0xE0);                        /* jmp rax */
+       RETPOLINE_RAX_BPF_JIT();
 
        /* out: */
        BUILD_BUG_ON(cnt - label1 != OFFSET1);
@@ -1187,7 +1188,7 @@ skip_init_addrs:
         * may converge on the last pass. In such case do one more
         * pass to emit the final image
         */
-       for (pass = 0; pass < 10 || image; pass++) {
+       for (pass = 0; pass < 20 || image; pass++) {
                proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
                if (proglen <= 0) {
                        image = NULL;
@@ -1214,6 +1215,7 @@ skip_init_addrs:
                        }
                }
                oldproglen = proglen;
+               cond_resched();
        }
 
        if (bpf_jit_enable > 1)
index 174c59774cc935430583160c6c158d5de363c7ef..a7a7677265b6f73779d486da8bb5ae0b83e48062 100644 (file)
@@ -460,7 +460,7 @@ static int nmi_setup(void)
                goto fail;
 
        for_each_possible_cpu(cpu) {
-               if (!cpu)
+               if (!IS_ENABLED(CONFIG_SMP) || !cpu)
                        continue;
 
                memcpy(per_cpu(cpu_msrs, cpu).counters,
index c310a82843589c6df238e72061b037de42b22867..f9cfbc0d1f337e63b9a744cdb423ba2ecd6712f8 100644 (file)
@@ -227,7 +227,7 @@ int __init efi_alloc_page_tables(void)
        if (!pud) {
                if (CONFIG_PGTABLE_LEVELS > 4)
                        free_page((unsigned long) pgd_page_vaddr(*pgd));
-               free_page((unsigned long)efi_pgd);
+               free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER);
                return -ENOMEM;
        }
 
index 2c67bae6bb53e033b823e0146f3f1a0b2901eba0..fb1df9488e98b843f89155b3afbfe5958128a306 100644 (file)
@@ -79,7 +79,7 @@ static void intel_mid_power_off(void)
 
 static void intel_mid_reboot(void)
 {
-       intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
+       intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
 }
 
 static unsigned long __init intel_mid_calibrate_tsc(void)
index c2e9285d1bf11539ce7efe9c3a683467368c9cbb..db77e087adaf874f6556f5f1d0cb5bdcaf54c42f 100644 (file)
@@ -299,7 +299,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp,
                local_flush_tlb();
                stat->d_alltlb++;
        } else {
-               __flush_tlb_single(msg->address);
+               __flush_tlb_one_user(msg->address);
                stat->d_onetlb++;
        }
        stat->d_requestee++;
index de53bd15df5a865589e7eda181a1771fbe7297e4..24bb7598774e6aa94203e601f41329d31308692e 100644 (file)
@@ -102,7 +102,7 @@ ENTRY(startup_32)
         * don't we'll eventually crash trying to execute encrypted
         * instructions.
         */
-       bt      $TH_FLAGS_SME_ACTIVE_BIT, pa_tr_flags
+       btl     $TH_FLAGS_SME_ACTIVE_BIT, pa_tr_flags
        jnc     .Ldone
        movl    $MSR_K8_SYSCFG, %ecx
        rdmsr
index 5d73c443e778b3a0e2fd79b4bf0f301cd1c8d878..220e97841e494c41e21b242a053b9ffcefeb2b4a 100644 (file)
@@ -770,9 +770,12 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
                break;
 
        case R_X86_64_PC32:
+       case R_X86_64_PLT32:
                /*
                 * PC relative relocations don't need to be adjusted unless
                 * referencing a percpu symbol.
+                *
+                * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
                 */
                if (is_percpu_sym(sym, symname))
                        add_reloc(&relocs32neg, offset);
index b7d73400ea29aa095acd58c5e8502a6524aff04f..f31e5d9031617b21df04416feef5aff3f85e9b59 100644 (file)
 
 #endif /* CONFIG_X86_32 */
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()      rmb()
-#else /* CONFIG_X86_PPRO_FENCE */
 #define dma_rmb()      barrier()
-#endif /* CONFIG_X86_PPRO_FENCE */
 #define dma_wmb()      barrier()
 
 #include <asm-generic/barrier.h>
index c047f42552e1a61ed0a5787d904681974cc05af1..3c2c2530737efc717c9945ee1e2990e5b5bfd4c5 100644 (file)
@@ -1376,8 +1376,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
        if (!xen_initial_domain()) {
                add_preferred_console("xenboot", 0, NULL);
-               add_preferred_console("tty", 0, NULL);
-               add_preferred_console("hvc", 0, NULL);
                if (pci_xen)
                        x86_init.pci.arch_init = pci_xen_init;
        } else {
@@ -1410,6 +1408,10 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
                xen_boot_params_init_edd();
        }
+
+       add_preferred_console("tty", 0, NULL);
+       add_preferred_console("hvc", 0, NULL);
+
 #ifdef CONFIG_PCI
        /* PCI BIOS service won't work from a PV guest. */
        pci_probe &= ~PCI_PROBE_BIOS;
index d85076223a696d0b00bee7c22a9e28b1e66dc975..aae88fec9941a6dd4183ff2e85f43036e0c2aa88 100644 (file)
@@ -1300,12 +1300,12 @@ static void xen_flush_tlb(void)
        preempt_enable();
 }
 
-static void xen_flush_tlb_single(unsigned long addr)
+static void xen_flush_tlb_one_user(unsigned long addr)
 {
        struct mmuext_op *op;
        struct multicall_space mcs;
 
-       trace_xen_mmu_flush_tlb_single(addr);
+       trace_xen_mmu_flush_tlb_one_user(addr);
 
        preempt_disable();
 
@@ -2370,7 +2370,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
 
        .flush_tlb_user = xen_flush_tlb,
        .flush_tlb_kernel = xen_flush_tlb,
-       .flush_tlb_single = xen_flush_tlb_single,
+       .flush_tlb_one_user = xen_flush_tlb_one_user,
        .flush_tlb_others = xen_flush_tlb_others,
 
        .pgd_alloc = xen_pgd_alloc,
index 77c959cf81e7c3fb573066513067c47f2698fedc..7a43b2ae19f1228b247e57fe453d21ab15e116f7 100644 (file)
@@ -122,6 +122,8 @@ void __init xen_smp_cpus_done(unsigned int max_cpus)
 
        if (xen_hvm_domain())
                native_smp_cpus_done(max_cpus);
+       else
+               calculate_max_logical_packages();
 
        if (xen_have_vcpu_info_placement)
                return;
index d9f96cc5d74367932020edfe71424d7940fa77a3..1d83152c761bcb1f74929006fbe52d450d68b81c 100644 (file)
@@ -1,12 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/types.h>
 #include <linux/tick.h>
+#include <linux/percpu-defs.h>
 
 #include <xen/xen.h>
 #include <xen/interface/xen.h>
 #include <xen/grant_table.h>
 #include <xen/events.h>
 
+#include <asm/cpufeatures.h>
+#include <asm/msr-index.h>
 #include <asm/xen/hypercall.h>
 #include <asm/xen/page.h>
 #include <asm/fixmap.h>
@@ -15,6 +18,8 @@
 #include "mmu.h"
 #include "pmu.h"
 
+static DEFINE_PER_CPU(u64, spec_ctrl);
+
 void xen_arch_pre_suspend(void)
 {
        xen_save_time_memory_area();
@@ -35,6 +40,9 @@ void xen_arch_post_suspend(int cancelled)
 
 static void xen_vcpu_notify_restore(void *data)
 {
+       if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL))
+               wrmsrl(MSR_IA32_SPEC_CTRL, this_cpu_read(spec_ctrl));
+
        /* Boot processor notified via generic timekeeping_resume() */
        if (smp_processor_id() == 0)
                return;
@@ -44,7 +52,15 @@ static void xen_vcpu_notify_restore(void *data)
 
 static void xen_vcpu_notify_suspend(void *data)
 {
+       u64 tmp;
+
        tick_suspend_local();
+
+       if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) {
+               rdmsrl(MSR_IA32_SPEC_CTRL, tmp);
+               this_cpu_write(spec_ctrl, tmp);
+               wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+       }
 }
 
 void xen_arch_resume(void)
index 623720a111432f68e8f8c080e4085d5cab151565..732631ce250fcab756d7e4d8d39ee054cf7a4de9 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <linux/dma-contiguous.h>
+#include <linux/dma-direct.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
 #include <linux/mm.h>
@@ -123,7 +124,7 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size,
                              unsigned long attrs)
 {
        unsigned long ret;
-       unsigned long uncached = 0;
+       unsigned long uncached;
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
        struct page *page = NULL;
 
@@ -144,15 +145,27 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size,
        if (!page)
                return NULL;
 
-       ret = (unsigned long)page_address(page);
+       *handle = phys_to_dma(dev, page_to_phys(page));
 
-       /* We currently don't support coherent memory outside KSEG */
+#ifdef CONFIG_MMU
+       if (PageHighMem(page)) {
+               void *p;
 
+               p = dma_common_contiguous_remap(page, size, VM_MAP,
+                                               pgprot_noncached(PAGE_KERNEL),
+                                               __builtin_return_address(0));
+               if (!p) {
+                       if (!dma_release_from_contiguous(dev, page, count))
+                               __free_pages(page, get_order(size));
+               }
+               return p;
+       }
+#endif
+       ret = (unsigned long)page_address(page);
        BUG_ON(ret < XCHAL_KSEG_CACHED_VADDR ||
               ret > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1);
 
        uncached = ret + XCHAL_KSEG_BYPASS_VADDR - XCHAL_KSEG_CACHED_VADDR;
-       *handle = virt_to_bus((void *)ret);
        __invalidate_dcache_range(ret, size);
 
        return (void *)uncached;
@@ -161,13 +174,20 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size,
 static void xtensa_dma_free(struct device *dev, size_t size, void *vaddr,
                            dma_addr_t dma_handle, unsigned long attrs)
 {
-       unsigned long addr = (unsigned long)vaddr +
-               XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR;
-       struct page *page = virt_to_page(addr);
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-
-       BUG_ON(addr < XCHAL_KSEG_CACHED_VADDR ||
-              addr > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1);
+       unsigned long addr = (unsigned long)vaddr;
+       struct page *page;
+
+       if (addr >= XCHAL_KSEG_BYPASS_VADDR &&
+           addr - XCHAL_KSEG_BYPASS_VADDR < XCHAL_KSEG_SIZE) {
+               addr += XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR;
+               page = virt_to_page(addr);
+       } else {
+#ifdef CONFIG_MMU
+               dma_common_free_remap(vaddr, size, VM_MAP);
+#endif
+               page = pfn_to_page(PHYS_PFN(dma_to_phys(dev, dma_handle)));
+       }
 
        if (!dma_release_from_contiguous(dev, page, count))
                __free_pages(page, get_order(size));
index d776ec0d7b22d375c4df5121a3a18f95babca749..34aead7dcb4878bf18f48cc2087fd93b5bee95ca 100644 (file)
@@ -79,19 +79,75 @@ void __init zones_init(void)
        free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
 }
 
+#ifdef CONFIG_HIGHMEM
+static void __init free_area_high(unsigned long pfn, unsigned long end)
+{
+       for (; pfn < end; pfn++)
+               free_highmem_page(pfn_to_page(pfn));
+}
+
+static void __init free_highpages(void)
+{
+       unsigned long max_low = max_low_pfn;
+       struct memblock_region *mem, *res;
+
+       reset_all_zones_managed_pages();
+       /* set highmem page free */
+       for_each_memblock(memory, mem) {
+               unsigned long start = memblock_region_memory_base_pfn(mem);
+               unsigned long end = memblock_region_memory_end_pfn(mem);
+
+               /* Ignore complete lowmem entries */
+               if (end <= max_low)
+                       continue;
+
+               if (memblock_is_nomap(mem))
+                       continue;
+
+               /* Truncate partial highmem entries */
+               if (start < max_low)
+                       start = max_low;
+
+               /* Find and exclude any reserved regions */
+               for_each_memblock(reserved, res) {
+                       unsigned long res_start, res_end;
+
+                       res_start = memblock_region_reserved_base_pfn(res);
+                       res_end = memblock_region_reserved_end_pfn(res);
+
+                       if (res_end < start)
+                               continue;
+                       if (res_start < start)
+                               res_start = start;
+                       if (res_start > end)
+                               res_start = end;
+                       if (res_end > end)
+                               res_end = end;
+                       if (res_start != start)
+                               free_area_high(start, res_start);
+                       start = res_end;
+                       if (start == end)
+                               break;
+               }
+
+               /* And now free anything which remains */
+               if (start < end)
+                       free_area_high(start, end);
+       }
+}
+#else
+static void __init free_highpages(void)
+{
+}
+#endif
+
 /*
  * Initialize memory pages.
  */
 
 void __init mem_init(void)
 {
-#ifdef CONFIG_HIGHMEM
-       unsigned long tmp;
-
-       reset_all_zones_managed_pages();
-       for (tmp = max_low_pfn; tmp < max_pfn; tmp++)
-               free_highmem_page(pfn_to_page(tmp));
-#endif
+       free_highpages();
 
        max_mapnr = max_pfn - ARCH_PFN_OFFSET;
        high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
index 4117524ca45bc76cceb163c42f752ffd8d7e1659..c2033a232a443a3b54def7e9d88b646a7ac950d5 100644 (file)
@@ -812,7 +812,6 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
        struct gendisk *disk;
        struct request_queue *q;
        struct blkcg_gq *blkg;
-       struct module *owner;
        unsigned int major, minor;
        int key_len, part, ret;
        char *body;
@@ -904,9 +903,7 @@ fail_unlock:
        spin_unlock_irq(q->queue_lock);
        rcu_read_unlock();
 fail:
-       owner = disk->fops->owner;
-       put_disk(disk);
-       module_put(owner);
+       put_disk_and_module(disk);
        /*
         * If queue was bypassing, we should retry.  Do so after a
         * short msleep().  It isn't strictly necessary but queue
@@ -931,13 +928,9 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
 void blkg_conf_finish(struct blkg_conf_ctx *ctx)
        __releases(ctx->disk->queue->queue_lock) __releases(rcu)
 {
-       struct module *owner;
-
        spin_unlock_irq(ctx->disk->queue->queue_lock);
        rcu_read_unlock();
-       owner = ctx->disk->fops->owner;
-       put_disk(ctx->disk);
-       module_put(owner);
+       put_disk_and_module(ctx->disk);
 }
 EXPORT_SYMBOL_GPL(blkg_conf_finish);
 
index 2d1a7bbe063437bfacfca43ad479c305fccf56c7..6d82c4f7fadd9466f84a2405352f8296597eaa09 100644 (file)
@@ -2434,7 +2434,7 @@ blk_qc_t submit_bio(struct bio *bio)
                unsigned int count;
 
                if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
-                       count = queue_logical_block_size(bio->bi_disk->queue);
+                       count = queue_logical_block_size(bio->bi_disk->queue) >> 9;
                else
                        count = bio_sectors(bio);
 
index df93102e21494dc7f98456e4376ce7c83fca56ab..16e83e6df404a24fd1a59baeb77b9c7b7cc9890c 100644 (file)
@@ -712,7 +712,6 @@ static void __blk_mq_requeue_request(struct request *rq)
 
        trace_block_rq_requeue(q, rq);
        wbt_requeue(q->rq_wb, &rq->issue_stat);
-       blk_mq_sched_requeue_request(rq);
 
        if (blk_mq_rq_state(rq) != MQ_RQ_IDLE) {
                blk_mq_rq_update_state(rq, MQ_RQ_IDLE);
@@ -725,6 +724,9 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list)
 {
        __blk_mq_requeue_request(rq);
 
+       /* this request will be re-inserted to io scheduler queue */
+       blk_mq_sched_requeue_request(rq);
+
        BUG_ON(blk_queued_rq(rq));
        blk_mq_add_to_requeue_list(rq, true, kick_requeue_list);
 }
@@ -3164,6 +3166,7 @@ static bool __blk_mq_poll(struct blk_mq_hw_ctx *hctx, struct request *rq)
                cpu_relax();
        }
 
+       __set_current_state(TASK_RUNNING);
        return false;
 }
 
index 88a53c188cb7338e74a9a55a44d8d0e5a2a758da..9656f9e9f99e20af13f1e175aba15f9447d9ef87 100644 (file)
@@ -547,7 +547,7 @@ static int exact_lock(dev_t devt, void *data)
 {
        struct gendisk *p = data;
 
-       if (!get_disk(p))
+       if (!get_disk_and_module(p))
                return -1;
        return 0;
 }
@@ -717,6 +717,11 @@ void del_gendisk(struct gendisk *disk)
        blk_integrity_del(disk);
        disk_del_events(disk);
 
+       /*
+        * Block lookups of the disk until all bdevs are unhashed and the
+        * disk is marked as dead (GENHD_FL_UP cleared).
+        */
+       down_write(&disk->lookup_sem);
        /* invalidate stuff */
        disk_part_iter_init(&piter, disk,
                             DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
@@ -731,6 +736,7 @@ void del_gendisk(struct gendisk *disk)
        bdev_unhash_inode(disk_devt(disk));
        set_capacity(disk, 0);
        disk->flags &= ~GENHD_FL_UP;
+       up_write(&disk->lookup_sem);
 
        if (!(disk->flags & GENHD_FL_HIDDEN))
                sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
@@ -809,16 +815,28 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
 
                spin_lock_bh(&ext_devt_lock);
                part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
-               if (part && get_disk(part_to_disk(part))) {
+               if (part && get_disk_and_module(part_to_disk(part))) {
                        *partno = part->partno;
                        disk = part_to_disk(part);
                }
                spin_unlock_bh(&ext_devt_lock);
        }
 
-       if (disk && unlikely(disk->flags & GENHD_FL_HIDDEN)) {
-               put_disk(disk);
+       if (!disk)
+               return NULL;
+
+       /*
+        * Synchronize with del_gendisk() to not return disk that is being
+        * destroyed.
+        */
+       down_read(&disk->lookup_sem);
+       if (unlikely((disk->flags & GENHD_FL_HIDDEN) ||
+                    !(disk->flags & GENHD_FL_UP))) {
+               up_read(&disk->lookup_sem);
+               put_disk_and_module(disk);
                disk = NULL;
+       } else {
+               up_read(&disk->lookup_sem);
        }
        return disk;
 }
@@ -1418,6 +1436,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
                        kfree(disk);
                        return NULL;
                }
+               init_rwsem(&disk->lookup_sem);
                disk->node_id = node_id;
                if (disk_expand_part_tbl(disk, 0)) {
                        free_part_stats(&disk->part0);
@@ -1453,7 +1472,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
 }
 EXPORT_SYMBOL(__alloc_disk_node);
 
-struct kobject *get_disk(struct gendisk *disk)
+struct kobject *get_disk_and_module(struct gendisk *disk)
 {
        struct module *owner;
        struct kobject *kobj;
@@ -1471,17 +1490,30 @@ struct kobject *get_disk(struct gendisk *disk)
        return kobj;
 
 }
-
-EXPORT_SYMBOL(get_disk);
+EXPORT_SYMBOL(get_disk_and_module);
 
 void put_disk(struct gendisk *disk)
 {
        if (disk)
                kobject_put(&disk_to_dev(disk)->kobj);
 }
-
 EXPORT_SYMBOL(put_disk);
 
+/*
+ * This is a counterpart of get_disk_and_module() and thus also of
+ * get_gendisk().
+ */
+void put_disk_and_module(struct gendisk *disk)
+{
+       if (disk) {
+               struct module *owner = disk->fops->owner;
+
+               put_disk(disk);
+               module_put(owner);
+       }
+}
+EXPORT_SYMBOL(put_disk_and_module);
+
 static void set_disk_ro_uevent(struct gendisk *gd, int ro)
 {
        char event[] = "DISK_RO=1";
index 1668506d8ed80607b6e3c279fa22195fb73571de..3884d810efd27fc73bb07659b91296ea46265252 100644 (file)
@@ -225,7 +225,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
 
        if (start + len > i_size_read(bdev->bd_inode))
                return -EINVAL;
-       truncate_inode_pages_range(mapping, start, start + len);
+       truncate_inode_pages_range(mapping, start, start + len - 1);
        return blkdev_issue_discard(bdev, start >> 9, len >> 9,
                                    GFP_KERNEL, flags);
 }
index f95c60774ce8ca613417d3ccf54bee52010752ee..0d6d25e32e1f44fda0049bb3e213b85a3debfa1f 100644 (file)
@@ -833,6 +833,7 @@ static struct elevator_type kyber_sched = {
                .limit_depth = kyber_limit_depth,
                .prepare_request = kyber_prepare_request,
                .finish_request = kyber_finish_request,
+               .requeue_request = kyber_finish_request,
                .completed_request = kyber_completed_request,
                .dispatch_request = kyber_dispatch_request,
                .has_work = kyber_has_work,
index c56f211c84400662f3e18c137b51c3f5406e20fd..8ec0ba9f538619f177eef3416711689323161a65 100644 (file)
@@ -535,13 +535,22 @@ static void dd_insert_requests(struct blk_mq_hw_ctx *hctx,
        spin_unlock(&dd->lock);
 }
 
+/*
+ * Nothing to do here. This is defined only to ensure that .finish_request
+ * method is called upon request completion.
+ */
+static void dd_prepare_request(struct request *rq, struct bio *bio)
+{
+}
+
 /*
  * For zoned block devices, write unlock the target zone of
  * completed write requests. Do this while holding the zone lock
  * spinlock so that the zone is never unlocked while deadline_fifo_request()
- * while deadline_next_request() are executing.
+ * or deadline_next_request() are executing. This function is called for
+ * all requests, whether or not these requests complete successfully.
  */
-static void dd_completed_request(struct request *rq)
+static void dd_finish_request(struct request *rq)
 {
        struct request_queue *q = rq->q;
 
@@ -756,7 +765,8 @@ static struct elevator_type mq_deadline = {
        .ops.mq = {
                .insert_requests        = dd_insert_requests,
                .dispatch_request       = dd_dispatch_request,
-               .completed_request      = dd_completed_request,
+               .prepare_request        = dd_prepare_request,
+               .finish_request         = dd_finish_request,
                .next_request           = elv_rb_latter_request,
                .former_request         = elv_rb_former_request,
                .bio_merge              = dd_bio_merge,
index 91622db9aedffd997947642a5872802312346869..08dabcd8b6aefc6844bbb9d9e9c001e6ff71fb33 100644 (file)
@@ -51,6 +51,12 @@ const char *bdevname(struct block_device *bdev, char *buf)
 
 EXPORT_SYMBOL(bdevname);
 
+const char *bio_devname(struct bio *bio, char *buf)
+{
+       return disk_name(bio->bi_disk, bio->bi_partno, buf);
+}
+EXPORT_SYMBOL(bio_devname);
+
 /*
  * There's very little reason to use this, you should really
  * have a struct block_device just about everywhere and use
index 9ed51d0c6b1d171fc2eab785ef854b64f93721fe..e4929eec547fc4141a6b078e79d5fe2688a20198 100644 (file)
@@ -490,7 +490,7 @@ static int opal_discovery0_end(struct opal_dev *dev)
 
        if (!found_com_id) {
                pr_debug("Could not find OPAL comid for device. Returning early\n");
-               return -EOPNOTSUPP;;
+               return -EOPNOTSUPP;
        }
 
        dev->comid = comid;
index 73fd99098ad7ce5f4eb12eef6111500f4a89063e..753b703ef0ef8d711e04150467e5fb3643bce799 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "blacklist.h"
 
-const char __initdata *const blacklist_hashes[] = {
+const char __initconst *const blacklist_hashes[] = {
        NULL
 };
index 1f4e25f10049c2645c2a421b07bb21fdaf1c0857..598906b1e28d37e264058276a2dfd3d9263af4b1 100644 (file)
@@ -106,6 +106,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
                pr_devel("sinfo %u: Direct signer is key %x\n",
                         sinfo->index, key_serial(key));
                x509 = NULL;
+               sig = sinfo->sig;
                goto matched;
        }
        if (PTR_ERR(key) != -ENOKEY)
index 39e6de0c2761fb03efab8f144fa1d1693e7cb035..97c77f66b20d680f9fc40dfcd6154881ef983a62 100644 (file)
@@ -270,7 +270,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
                                sinfo->index);
                        return 0;
                }
-               ret = public_key_verify_signature(p->pub, p->sig);
+               ret = public_key_verify_signature(p->pub, x509->sig);
                if (ret < 0)
                        return ret;
                x509->signer = p;
@@ -366,8 +366,7 @@ static int pkcs7_verify_one(struct pkcs7_message *pkcs7,
  *
  *  (*) -EBADMSG if some part of the message was invalid, or:
  *
- *  (*) 0 if no signature chains were found to be blacklisted or to contain
- *     unsupported crypto, or:
+ *  (*) 0 if a signature chain passed verification, or:
  *
  *  (*) -EKEYREJECTED if a blacklisted key was encountered, or:
  *
@@ -423,8 +422,11 @@ int pkcs7_verify(struct pkcs7_message *pkcs7,
 
        for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
                ret = pkcs7_verify_one(pkcs7, sinfo);
-               if (sinfo->blacklisted && actual_ret == -ENOPKG)
-                       actual_ret = -EKEYREJECTED;
+               if (sinfo->blacklisted) {
+                       if (actual_ret == -ENOPKG)
+                               actual_ret = -EKEYREJECTED;
+                       continue;
+               }
                if (ret < 0) {
                        if (ret == -ENOPKG) {
                                sinfo->unsupported_crypto = true;
index de996586762a83c0b3214aaf5fa561bde92f65c0..e929fe1e4106c7dfaff7c2bcf3186952f449b764 100644 (file)
@@ -79,9 +79,11 @@ int public_key_verify_signature(const struct public_key *pkey,
 
        BUG_ON(!pkey);
        BUG_ON(!sig);
-       BUG_ON(!sig->digest);
        BUG_ON(!sig->s);
 
+       if (!sig->digest)
+               return -ENOPKG;
+
        alg_name = sig->pkey_algo;
        if (strcmp(sig->pkey_algo, "rsa") == 0) {
                /* The data wangled by the RSA algorithm is typically padded
index 86fb6850895283d28659127f6934b8611bcef636..7c93c7728454a224c7348cfd36df868ba5067722 100644 (file)
@@ -67,8 +67,9 @@ __setup("ca_keys=", ca_keys_setup);
  *
  * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
  * matching parent certificate in the trusted list, -EKEYREJECTED if the
- * signature check fails or the key is blacklisted and some other error if
- * there is a matching certificate but the signature check cannot be performed.
+ * signature check fails or the key is blacklisted, -ENOPKG if the signature
+ * uses unsupported crypto, or some other error if there is a matching
+ * certificate but the signature check cannot be performed.
  */
 int restrict_link_by_signature(struct key *dest_keyring,
                               const struct key_type *type,
@@ -88,6 +89,8 @@ int restrict_link_by_signature(struct key *dest_keyring,
                return -EOPNOTSUPP;
 
        sig = payload->data[asym_auth];
+       if (!sig)
+               return -ENOPKG;
        if (!sig->auth_ids[0] && !sig->auth_ids[1])
                return -ENOKEY;
 
@@ -139,6 +142,8 @@ static int key_or_keyring_common(struct key *dest_keyring,
                return -EOPNOTSUPP;
 
        sig = payload->data[asym_auth];
+       if (!sig)
+               return -ENOPKG;
        if (!sig->auth_ids[0] && !sig->auth_ids[1])
                return -ENOKEY;
 
@@ -222,9 +227,9 @@ static int key_or_keyring_common(struct key *dest_keyring,
  *
  * Returns 0 if the new certificate was accepted, -ENOKEY if we
  * couldn't find a matching parent certificate in the trusted list,
- * -EKEYREJECTED if the signature check fails, and some other error if
- * there is a matching certificate but the signature check cannot be
- * performed.
+ * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
+ * unsupported crypto, or some other error if there is a matching certificate
+ * but the signature check cannot be performed.
  */
 int restrict_link_by_key_or_keyring(struct key *dest_keyring,
                                    const struct key_type *type,
@@ -249,9 +254,9 @@ int restrict_link_by_key_or_keyring(struct key *dest_keyring,
  *
  * Returns 0 if the new certificate was accepted, -ENOKEY if we
  * couldn't find a matching parent certificate in the trusted list,
- * -EKEYREJECTED if the signature check fails, and some other error if
- * there is a matching certificate but the signature check cannot be
- * performed.
+ * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
+ * unsupported crypto, or some other error if there is a matching certificate
+ * but the signature check cannot be performed.
  */
 int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
                                          const struct key_type *type,
index a965b9d8055983af4353ae39fe676b7789c8f93f..ded1487833033a602b7736ca6d78967517153dae 100644 (file)
 #include <crypto/sha3.h>
 #include <asm/unaligned.h>
 
+/*
+ * On some 32-bit architectures (mn10300 and h8300), GCC ends up using
+ * over 1 KB of stack if we inline the round calculation into the loop
+ * in keccakf(). On the other hand, on 64-bit architectures with plenty
+ * of [64-bit wide] general purpose registers, not inlining it severely
+ * hurts performance. So let's use 64-bitness as a heuristic to decide
+ * whether to inline or not.
+ */
+#ifdef CONFIG_64BIT
+#define SHA3_INLINE    inline
+#else
+#define SHA3_INLINE    noinline
+#endif
+
 #define KECCAK_ROUNDS 24
 
 static const u64 keccakf_rndc[24] = {
@@ -35,111 +49,115 @@ static const u64 keccakf_rndc[24] = {
 
 /* update the state with given number of rounds */
 
-static void __attribute__((__optimize__("O3"))) keccakf(u64 st[25])
+static SHA3_INLINE void keccakf_round(u64 st[25])
 {
        u64 t[5], tt, bc[5];
-       int round;
 
-       for (round = 0; round < KECCAK_ROUNDS; round++) {
+       /* Theta */
+       bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
+       bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
+       bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
+       bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
+       bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
+
+       t[0] = bc[4] ^ rol64(bc[1], 1);
+       t[1] = bc[0] ^ rol64(bc[2], 1);
+       t[2] = bc[1] ^ rol64(bc[3], 1);
+       t[3] = bc[2] ^ rol64(bc[4], 1);
+       t[4] = bc[3] ^ rol64(bc[0], 1);
+
+       st[0] ^= t[0];
+
+       /* Rho Pi */
+       tt = st[1];
+       st[ 1] = rol64(st[ 6] ^ t[1], 44);
+       st[ 6] = rol64(st[ 9] ^ t[4], 20);
+       st[ 9] = rol64(st[22] ^ t[2], 61);
+       st[22] = rol64(st[14] ^ t[4], 39);
+       st[14] = rol64(st[20] ^ t[0], 18);
+       st[20] = rol64(st[ 2] ^ t[2], 62);
+       st[ 2] = rol64(st[12] ^ t[2], 43);
+       st[12] = rol64(st[13] ^ t[3], 25);
+       st[13] = rol64(st[19] ^ t[4],  8);
+       st[19] = rol64(st[23] ^ t[3], 56);
+       st[23] = rol64(st[15] ^ t[0], 41);
+       st[15] = rol64(st[ 4] ^ t[4], 27);
+       st[ 4] = rol64(st[24] ^ t[4], 14);
+       st[24] = rol64(st[21] ^ t[1],  2);
+       st[21] = rol64(st[ 8] ^ t[3], 55);
+       st[ 8] = rol64(st[16] ^ t[1], 45);
+       st[16] = rol64(st[ 5] ^ t[0], 36);
+       st[ 5] = rol64(st[ 3] ^ t[3], 28);
+       st[ 3] = rol64(st[18] ^ t[3], 21);
+       st[18] = rol64(st[17] ^ t[2], 15);
+       st[17] = rol64(st[11] ^ t[1], 10);
+       st[11] = rol64(st[ 7] ^ t[2],  6);
+       st[ 7] = rol64(st[10] ^ t[0],  3);
+       st[10] = rol64(    tt ^ t[1],  1);
+
+       /* Chi */
+       bc[ 0] = ~st[ 1] & st[ 2];
+       bc[ 1] = ~st[ 2] & st[ 3];
+       bc[ 2] = ~st[ 3] & st[ 4];
+       bc[ 3] = ~st[ 4] & st[ 0];
+       bc[ 4] = ~st[ 0] & st[ 1];
+       st[ 0] ^= bc[ 0];
+       st[ 1] ^= bc[ 1];
+       st[ 2] ^= bc[ 2];
+       st[ 3] ^= bc[ 3];
+       st[ 4] ^= bc[ 4];
+
+       bc[ 0] = ~st[ 6] & st[ 7];
+       bc[ 1] = ~st[ 7] & st[ 8];
+       bc[ 2] = ~st[ 8] & st[ 9];
+       bc[ 3] = ~st[ 9] & st[ 5];
+       bc[ 4] = ~st[ 5] & st[ 6];
+       st[ 5] ^= bc[ 0];
+       st[ 6] ^= bc[ 1];
+       st[ 7] ^= bc[ 2];
+       st[ 8] ^= bc[ 3];
+       st[ 9] ^= bc[ 4];
+
+       bc[ 0] = ~st[11] & st[12];
+       bc[ 1] = ~st[12] & st[13];
+       bc[ 2] = ~st[13] & st[14];
+       bc[ 3] = ~st[14] & st[10];
+       bc[ 4] = ~st[10] & st[11];
+       st[10] ^= bc[ 0];
+       st[11] ^= bc[ 1];
+       st[12] ^= bc[ 2];
+       st[13] ^= bc[ 3];
+       st[14] ^= bc[ 4];
+
+       bc[ 0] = ~st[16] & st[17];
+       bc[ 1] = ~st[17] & st[18];
+       bc[ 2] = ~st[18] & st[19];
+       bc[ 3] = ~st[19] & st[15];
+       bc[ 4] = ~st[15] & st[16];
+       st[15] ^= bc[ 0];
+       st[16] ^= bc[ 1];
+       st[17] ^= bc[ 2];
+       st[18] ^= bc[ 3];
+       st[19] ^= bc[ 4];
+
+       bc[ 0] = ~st[21] & st[22];
+       bc[ 1] = ~st[22] & st[23];
+       bc[ 2] = ~st[23] & st[24];
+       bc[ 3] = ~st[24] & st[20];
+       bc[ 4] = ~st[20] & st[21];
+       st[20] ^= bc[ 0];
+       st[21] ^= bc[ 1];
+       st[22] ^= bc[ 2];
+       st[23] ^= bc[ 3];
+       st[24] ^= bc[ 4];
+}
 
-               /* Theta */
-               bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
-               bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
-               bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
-               bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
-               bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
-
-               t[0] = bc[4] ^ rol64(bc[1], 1);
-               t[1] = bc[0] ^ rol64(bc[2], 1);
-               t[2] = bc[1] ^ rol64(bc[3], 1);
-               t[3] = bc[2] ^ rol64(bc[4], 1);
-               t[4] = bc[3] ^ rol64(bc[0], 1);
-
-               st[0] ^= t[0];
-
-               /* Rho Pi */
-               tt = st[1];
-               st[ 1] = rol64(st[ 6] ^ t[1], 44);
-               st[ 6] = rol64(st[ 9] ^ t[4], 20);
-               st[ 9] = rol64(st[22] ^ t[2], 61);
-               st[22] = rol64(st[14] ^ t[4], 39);
-               st[14] = rol64(st[20] ^ t[0], 18);
-               st[20] = rol64(st[ 2] ^ t[2], 62);
-               st[ 2] = rol64(st[12] ^ t[2], 43);
-               st[12] = rol64(st[13] ^ t[3], 25);
-               st[13] = rol64(st[19] ^ t[4],  8);
-               st[19] = rol64(st[23] ^ t[3], 56);
-               st[23] = rol64(st[15] ^ t[0], 41);
-               st[15] = rol64(st[ 4] ^ t[4], 27);
-               st[ 4] = rol64(st[24] ^ t[4], 14);
-               st[24] = rol64(st[21] ^ t[1],  2);
-               st[21] = rol64(st[ 8] ^ t[3], 55);
-               st[ 8] = rol64(st[16] ^ t[1], 45);
-               st[16] = rol64(st[ 5] ^ t[0], 36);
-               st[ 5] = rol64(st[ 3] ^ t[3], 28);
-               st[ 3] = rol64(st[18] ^ t[3], 21);
-               st[18] = rol64(st[17] ^ t[2], 15);
-               st[17] = rol64(st[11] ^ t[1], 10);
-               st[11] = rol64(st[ 7] ^ t[2],  6);
-               st[ 7] = rol64(st[10] ^ t[0],  3);
-               st[10] = rol64(    tt ^ t[1],  1);
-
-               /* Chi */
-               bc[ 0] = ~st[ 1] & st[ 2];
-               bc[ 1] = ~st[ 2] & st[ 3];
-               bc[ 2] = ~st[ 3] & st[ 4];
-               bc[ 3] = ~st[ 4] & st[ 0];
-               bc[ 4] = ~st[ 0] & st[ 1];
-               st[ 0] ^= bc[ 0];
-               st[ 1] ^= bc[ 1];
-               st[ 2] ^= bc[ 2];
-               st[ 3] ^= bc[ 3];
-               st[ 4] ^= bc[ 4];
-
-               bc[ 0] = ~st[ 6] & st[ 7];
-               bc[ 1] = ~st[ 7] & st[ 8];
-               bc[ 2] = ~st[ 8] & st[ 9];
-               bc[ 3] = ~st[ 9] & st[ 5];
-               bc[ 4] = ~st[ 5] & st[ 6];
-               st[ 5] ^= bc[ 0];
-               st[ 6] ^= bc[ 1];
-               st[ 7] ^= bc[ 2];
-               st[ 8] ^= bc[ 3];
-               st[ 9] ^= bc[ 4];
-
-               bc[ 0] = ~st[11] & st[12];
-               bc[ 1] = ~st[12] & st[13];
-               bc[ 2] = ~st[13] & st[14];
-               bc[ 3] = ~st[14] & st[10];
-               bc[ 4] = ~st[10] & st[11];
-               st[10] ^= bc[ 0];
-               st[11] ^= bc[ 1];
-               st[12] ^= bc[ 2];
-               st[13] ^= bc[ 3];
-               st[14] ^= bc[ 4];
-
-               bc[ 0] = ~st[16] & st[17];
-               bc[ 1] = ~st[17] & st[18];
-               bc[ 2] = ~st[18] & st[19];
-               bc[ 3] = ~st[19] & st[15];
-               bc[ 4] = ~st[15] & st[16];
-               st[15] ^= bc[ 0];
-               st[16] ^= bc[ 1];
-               st[17] ^= bc[ 2];
-               st[18] ^= bc[ 3];
-               st[19] ^= bc[ 4];
-
-               bc[ 0] = ~st[21] & st[22];
-               bc[ 1] = ~st[22] & st[23];
-               bc[ 2] = ~st[23] & st[24];
-               bc[ 3] = ~st[24] & st[20];
-               bc[ 4] = ~st[20] & st[21];
-               st[20] ^= bc[ 0];
-               st[21] ^= bc[ 1];
-               st[22] ^= bc[ 2];
-               st[23] ^= bc[ 3];
-               st[24] ^= bc[ 4];
+static void __optimize("O3") keccakf(u64 st[25])
+{
+       int round;
 
+       for (round = 0; round < KECCAK_ROUNDS; round++) {
+               keccakf_round(st);
                /* Iota */
                st[0] ^= keccakf_rndc[round];
        }
index 11b113f8e36741aeb00e921ee64a5ae871f8d55f..ebb626ffb5fa2d38c853ddcbbe7227aa09c7f7dd 100644 (file)
@@ -74,10 +74,10 @@ void __init acpi_watchdog_init(void)
                res.start = gas->address;
                if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
                        res.flags = IORESOURCE_MEM;
-                       res.end = res.start + ALIGN(gas->access_width, 4);
+                       res.end = res.start + ALIGN(gas->access_width, 4) - 1;
                } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
                        res.flags = IORESOURCE_IO;
-                       res.end = res.start + gas->access_width;
+                       res.end = res.start + gas->access_width - 1;
                } else {
                        pr_warn("Unsupported address space: %u\n",
                                gas->space_id);
index 7128488a3a728ff54f00fc1085c45afb5152f089..f2eb6c37ea0aa9aed03f562883634add68078f55 100644 (file)
@@ -70,7 +70,6 @@ static async_cookie_t async_cookie;
 static bool battery_driver_registered;
 static int battery_bix_broken_package;
 static int battery_notification_delay_ms;
-static int battery_full_discharging;
 static unsigned int cache_time = 1000;
 module_param(cache_time, uint, 0644);
 MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
@@ -215,12 +214,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
                return -ENODEV;
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
-               if (battery->state & ACPI_BATTERY_STATE_DISCHARGING) {
-                       if (battery_full_discharging && battery->rate_now == 0)
-                               val->intval = POWER_SUPPLY_STATUS_FULL;
-                       else
-                               val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-               } else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
+               if (battery->state & ACPI_BATTERY_STATE_DISCHARGING)
+                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               else if (battery->state & ACPI_BATTERY_STATE_CHARGING)
                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
                else if (acpi_battery_is_charged(battery))
                        val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -1170,12 +1166,6 @@ battery_notification_delay_quirk(const struct dmi_system_id *d)
        return 0;
 }
 
-static int __init battery_full_discharging_quirk(const struct dmi_system_id *d)
-{
-       battery_full_discharging = 1;
-       return 0;
-}
-
 static const struct dmi_system_id bat_dmi_table[] __initconst = {
        {
                .callback = battery_bix_broken_package_quirk,
@@ -1193,38 +1183,6 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-573G"),
                },
        },
-       {
-               .callback = battery_full_discharging_quirk,
-               .ident = "ASUS GL502VSK",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "GL502VSK"),
-               },
-       },
-       {
-               .callback = battery_full_discharging_quirk,
-               .ident = "ASUS UX305LA",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "UX305LA"),
-               },
-       },
-       {
-               .callback = battery_full_discharging_quirk,
-               .ident = "ASUS UX360UA",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "UX360UA"),
-               },
-       },
-       {
-               .callback = battery_full_discharging_quirk,
-               .ident = "ASUS UX410UAK",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "UX410UAK"),
-               },
-       },
        {},
 };
 
index 676c9788e1c8287b5e16311fa3159342702ae637..0dad0bd9327b5ac2338f0c8b1e4c021532a47196 100644 (file)
@@ -660,13 +660,15 @@ struct acpi_device *acpi_companion_match(const struct device *dev)
  * acpi_of_match_device - Match device object using the "compatible" property.
  * @adev: ACPI device object to match.
  * @of_match_table: List of device IDs to match against.
+ * @of_id: OF ID if matched
  *
  * If @dev has an ACPI companion which has ACPI_DT_NAMESPACE_HID in its list of
  * identifiers and a _DSD object with the "compatible" property, use that
  * property to match against the given list of identifiers.
  */
 static bool acpi_of_match_device(struct acpi_device *adev,
-                                const struct of_device_id *of_match_table)
+                                const struct of_device_id *of_match_table,
+                                const struct of_device_id **of_id)
 {
        const union acpi_object *of_compatible, *obj;
        int i, nval;
@@ -690,8 +692,11 @@ static bool acpi_of_match_device(struct acpi_device *adev,
                const struct of_device_id *id;
 
                for (id = of_match_table; id->compatible[0]; id++)
-                       if (!strcasecmp(obj->string.pointer, id->compatible))
+                       if (!strcasecmp(obj->string.pointer, id->compatible)) {
+                               if (of_id)
+                                       *of_id = id;
                                return true;
+                       }
        }
 
        return false;
@@ -762,10 +767,11 @@ static bool __acpi_match_device_cls(const struct acpi_device_id *id,
        return true;
 }
 
-static const struct acpi_device_id *__acpi_match_device(
-       struct acpi_device *device,
-       const struct acpi_device_id *ids,
-       const struct of_device_id *of_ids)
+static bool __acpi_match_device(struct acpi_device *device,
+                               const struct acpi_device_id *acpi_ids,
+                               const struct of_device_id *of_ids,
+                               const struct acpi_device_id **acpi_id,
+                               const struct of_device_id **of_id)
 {
        const struct acpi_device_id *id;
        struct acpi_hardware_id *hwid;
@@ -775,30 +781,32 @@ static const struct acpi_device_id *__acpi_match_device(
         * driver for it.
         */
        if (!device || !device->status.present)
-               return NULL;
+               return false;
 
        list_for_each_entry(hwid, &device->pnp.ids, list) {
                /* First, check the ACPI/PNP IDs provided by the caller. */
-               for (id = ids; id->id[0] || id->cls; id++) {
-                       if (id->id[0] && !strcmp((char *) id->id, hwid->id))
-                               return id;
-                       else if (id->cls && __acpi_match_device_cls(id, hwid))
-                               return id;
+               if (acpi_ids) {
+                       for (id = acpi_ids; id->id[0] || id->cls; id++) {
+                               if (id->id[0] && !strcmp((char *)id->id, hwid->id))
+                                       goto out_acpi_match;
+                               if (id->cls && __acpi_match_device_cls(id, hwid))
+                                       goto out_acpi_match;
+                       }
                }
 
                /*
                 * Next, check ACPI_DT_NAMESPACE_HID and try to match the
                 * "compatible" property if found.
-                *
-                * The id returned by the below is not valid, but the only
-                * caller passing non-NULL of_ids here is only interested in
-                * whether or not the return value is NULL.
                 */
-               if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)
-                   && acpi_of_match_device(device, of_ids))
-                       return id;
+               if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id))
+                       return acpi_of_match_device(device, of_ids, of_id);
        }
-       return NULL;
+       return false;
+
+out_acpi_match:
+       if (acpi_id)
+               *acpi_id = id;
+       return true;
 }
 
 /**
@@ -815,32 +823,29 @@ static const struct acpi_device_id *__acpi_match_device(
 const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
                                               const struct device *dev)
 {
-       return __acpi_match_device(acpi_companion_match(dev), ids, NULL);
+       const struct acpi_device_id *id = NULL;
+
+       __acpi_match_device(acpi_companion_match(dev), ids, NULL, &id, NULL);
+       return id;
 }
 EXPORT_SYMBOL_GPL(acpi_match_device);
 
-void *acpi_get_match_data(const struct device *dev)
+const void *acpi_device_get_match_data(const struct device *dev)
 {
        const struct acpi_device_id *match;
 
-       if (!dev->driver)
-               return NULL;
-
-       if (!dev->driver->acpi_match_table)
-               return NULL;
-
        match = acpi_match_device(dev->driver->acpi_match_table, dev);
        if (!match)
                return NULL;
 
-       return (void *)match->driver_data;
+       return (const void *)match->driver_data;
 }
-EXPORT_SYMBOL_GPL(acpi_get_match_data);
+EXPORT_SYMBOL_GPL(acpi_device_get_match_data);
 
 int acpi_match_device_ids(struct acpi_device *device,
                          const struct acpi_device_id *ids)
 {
-       return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT;
+       return __acpi_match_device(device, ids, NULL, NULL, NULL) ? 0 : -ENOENT;
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
@@ -849,10 +854,12 @@ bool acpi_driver_match_device(struct device *dev,
 {
        if (!drv->acpi_match_table)
                return acpi_of_match_device(ACPI_COMPANION(dev),
-                                           drv->of_match_table);
+                                           drv->of_match_table,
+                                           NULL);
 
-       return !!__acpi_match_device(acpi_companion_match(dev),
-                                    drv->acpi_match_table, drv->of_match_table);
+       return __acpi_match_device(acpi_companion_match(dev),
+                                  drv->acpi_match_table, drv->of_match_table,
+                                  NULL, NULL);
 }
 EXPORT_SYMBOL_GPL(acpi_driver_match_device);
 
index d9f38c645e4a1dc776b783dc1eae7aeb28418873..30a5729565575f83cb02700ac2050f35abab5e5d 100644 (file)
@@ -1927,6 +1927,9 @@ static int acpi_ec_suspend_noirq(struct device *dev)
            ec->reference_count >= 1)
                acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
 
+       if (acpi_sleep_no_ec_events())
+               acpi_ec_enter_noirq(ec);
+
        return 0;
 }
 
@@ -1934,6 +1937,9 @@ static int acpi_ec_resume_noirq(struct device *dev)
 {
        struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
 
+       if (acpi_sleep_no_ec_events())
+               acpi_ec_leave_noirq(ec);
+
        if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) &&
            ec->reference_count >= 1)
                acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
index bbe48ad20886c8530fe525ffe9f35725d1df1ddc..eb09ef55c38a2779c046241c337ea7be3cf75b79 100644 (file)
@@ -2675,10 +2675,14 @@ 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)
+       /*
+        * Persistence domain bits are hierarchical, if
+        * ACPI_NFIT_CAPABILITY_CACHE_FLUSH is set then
+        * ACPI_NFIT_CAPABILITY_MEM_FLUSH is implied.
+        */
+       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)
+       else 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) {
index 8ccaae3550d284be2070f7e06dd6794c5bc8c5b3..85167603b9c94318bcef7c260de689c13e4e4545 100644 (file)
@@ -103,25 +103,27 @@ int acpi_map_pxm_to_node(int pxm)
  */
 int acpi_map_pxm_to_online_node(int pxm)
 {
-       int node, n, dist, min_dist;
+       int node, min_node;
 
        node = acpi_map_pxm_to_node(pxm);
 
        if (node == NUMA_NO_NODE)
                node = 0;
 
+       min_node = node;
        if (!node_online(node)) {
-               min_dist = INT_MAX;
+               int min_dist = INT_MAX, dist, n;
+
                for_each_online_node(n) {
                        dist = node_distance(node, n);
                        if (dist < min_dist) {
                                min_dist = dist;
-                               node = n;
+                               min_node = n;
                        }
                }
        }
 
-       return node;
+       return min_node;
 }
 EXPORT_SYMBOL(acpi_map_pxm_to_online_node);
 
index 466d1503aba0e31f26b297df2532561a03c12ebd..5815356ea6ad3fb584a63e4ebf076d09fda635d8 100644 (file)
@@ -1271,11 +1271,11 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
        return 0;
 }
 
-static void *
+static const void *
 acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
                                  const struct device *dev)
 {
-       return acpi_get_match_data(dev);
+       return acpi_device_get_match_data(dev);
 }
 
 #define DECLARE_ACPI_FWNODE_OPS(ops) \
index 89e97d21a89ce26c7b8a0f5b53802618c871a927..9d52743080a4f65200ea6e33f0d0d2fefdb881ea 100644 (file)
@@ -115,6 +115,7 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
                        table->serial_port.access_width))) {
                default:
                        pr_err("Unexpected SPCR Access Width.  Defaulting to byte size\n");
+                       /* fall through */
                case 8:
                        iotype = "mmio";
                        break;
index 15e3d3c2260ddc915f49732f1076f3a7ee0f540e..764b63a5aadefe5c73ef849ee5b377b134e3841e 100644 (file)
@@ -1991,8 +1991,14 @@ static void binder_send_failed_reply(struct binder_transaction *t,
                                        &target_thread->reply_error.work);
                                wake_up_interruptible(&target_thread->wait);
                        } else {
-                               WARN(1, "Unexpected reply error: %u\n",
-                                               target_thread->reply_error.cmd);
+                               /*
+                                * Cannot get here for normal operation, but
+                                * we can if multiple synchronous transactions
+                                * are sent without blocking for responses.
+                                * Just ignore the 2nd error in this case.
+                                */
+                               pr_warn("Unexpected reply error: %u\n",
+                                       target_thread->reply_error.cmd);
                        }
                        binder_inner_proc_unlock(target_thread->proc);
                        binder_thread_dec_tmpref(target_thread);
@@ -2193,7 +2199,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
        int debug_id = buffer->debug_id;
 
        binder_debug(BINDER_DEBUG_TRANSACTION,
-                    "%d buffer release %d, size %zd-%zd, failed at %p\n",
+                    "%d buffer release %d, size %zd-%zd, failed at %pK\n",
                     proc->pid, buffer->debug_id,
                     buffer->data_size, buffer->offsets_size, failed_at);
 
@@ -3705,7 +3711,7 @@ static int binder_thread_write(struct binder_proc *proc,
                                }
                        }
                        binder_debug(BINDER_DEBUG_DEAD_BINDER,
-                                    "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n",
+                                    "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n",
                                     proc->pid, thread->pid, (u64)cookie,
                                     death);
                        if (death == NULL) {
@@ -4376,6 +4382,15 @@ static int binder_thread_release(struct binder_proc *proc,
 
        binder_inner_proc_unlock(thread->proc);
 
+       /*
+        * This is needed to avoid races between wake_up_poll() above and
+        * and ep_remove_waitqueue() called for other reasons (eg the epoll file
+        * descriptor being closed); ep_remove_waitqueue() holds an RCU read
+        * lock, so we can be sure it's done after calling synchronize_rcu().
+        */
+       if (thread->looper & BINDER_LOOPER_STATE_POLL)
+               synchronize_rcu();
+
        if (send_reply)
                binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
        binder_release_work(proc, &thread->todo);
@@ -4391,6 +4406,8 @@ static __poll_t binder_poll(struct file *filp,
        bool wait_for_proc_work;
 
        thread = binder_get_thread(proc);
+       if (!thread)
+               return POLLERR;
 
        binder_inner_proc_lock(thread->proc);
        thread->looper |= BINDER_LOOPER_STATE_POLL;
@@ -5034,7 +5051,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
        spin_lock(&t->lock);
        to_proc = t->to_proc;
        seq_printf(m,
-                  "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d",
+                  "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d",
                   prefix, t->debug_id, t,
                   t->from ? t->from->proc->pid : 0,
                   t->from ? t->from->pid : 0,
@@ -5058,7 +5075,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
        }
        if (buffer->target_node)
                seq_printf(m, " node %d", buffer->target_node->debug_id);
-       seq_printf(m, " size %zd:%zd data %p\n",
+       seq_printf(m, " size %zd:%zd data %pK\n",
                   buffer->data_size, buffer->offsets_size,
                   buffer->data);
 }
index 355a95a83a3405abd73a4b5d4ded9df48e8f0e38..1ff17799769d0b2372d2b9d385af57dab15acf10 100644 (file)
@@ -550,7 +550,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          .driver_data = board_ahci_yes_fbs },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
          .driver_data = board_ahci_yes_fbs },
-       { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
+       { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */
+         .driver_data = board_ahci_yes_fbs },
+       { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */
          .driver_data = board_ahci_yes_fbs },
 
        /* Promise */
index a0de7a38430c954b31c7b4e6e01a790ee98e85c2..7adcf3caabd00abbb08ef76c0e4e604f0ba8c97c 100644 (file)
@@ -665,6 +665,16 @@ int ahci_stop_engine(struct ata_port *ap)
        if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0)
                return 0;
 
+       /*
+        * Don't try to issue commands but return with ENODEV if the
+        * AHCI controller not available anymore (e.g. due to PCIe hot
+        * unplugging). Otherwise a 500ms delay for each port is added.
+        */
+       if (tmp == 0xffffffff) {
+               dev_err(ap->host->dev, "AHCI controller unavailable!\n");
+               return -ENODEV;
+       }
+
        /* setting HBA to idle */
        tmp &= ~PORT_CMD_START;
        writel(tmp, port_mmio + PORT_CMD);
index 341d0ef82cbddbf3c67d2b210ada2b45eebb8958..30cc8f1a31e1299f3cc68659a5be959492249382 100644 (file)
@@ -340,7 +340,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
  * 2) regulator for controlling the targets power (optional)
  * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  *    or for non devicetree enabled platforms a single clock
- *     4) phys (optional)
+ * 4) phys (optional)
  *
  * RETURNS:
  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
index 3c09122bf03825b6489a16b8f116bd05485aa1b4..7431ccd0331648d4ce64930901a440eb8bae2d70 100644 (file)
@@ -4530,6 +4530,25 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "PIONEER DVD-RW  DVR-212D",   NULL,   ATA_HORKAGE_NOSETXFER },
        { "PIONEER DVD-RW  DVR-216D",   NULL,   ATA_HORKAGE_NOSETXFER },
 
+       /* Crucial BX100 SSD 500GB has broken LPM support */
+       { "CT500BX100SSD1",             NULL,   ATA_HORKAGE_NOLPM },
+
+       /* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */
+       { "Crucial_CT512MX100*",        "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NOLPM, },
+       /* 512GB MX100 with newer firmware has only LPM issues */
+       { "Crucial_CT512MX100*",        NULL,   ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NOLPM, },
+
+       /* 480GB+ M500 SSDs have both queued TRIM and LPM issues */
+       { "Crucial_CT480M500*",         NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NOLPM, },
+       { "Crucial_CT960M500*",         NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NOLPM, },
+
        /* devices that don't properly handle queued TRIM commands */
        { "Micron_M500_*",              NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
@@ -4541,7 +4560,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
        { "Crucial_CT*MX100*",          "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
-       { "Samsung SSD 8*",             NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+       { "Samsung SSD 840*",           NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM, },
+       { "Samsung SSD 850*",           NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
        { "FCCT*M500*",                 NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
@@ -5401,8 +5422,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
         * We guarantee to LLDs that they will have at least one
         * non-zero sg if the command is a data command.
         */
-       if (WARN_ON_ONCE(ata_is_data(prot) &&
-                        (!qc->sg || !qc->n_elem || !qc->nbytes)))
+       if (ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes))
                goto sys_err;
 
        if (ata_is_dma(prot) || (ata_is_pio(prot) &&
index 11c3137d7b0af5dda9cc3c45364f7677d7fa892d..c016829a38fd21798e263cdc678517b3dbf728f7 100644 (file)
@@ -815,7 +815,8 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
 
        if (ap->pflags & ATA_PFLAG_LOADING)
                ap->pflags &= ~ATA_PFLAG_LOADING;
-       else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG)
+       else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) &&
+               !(ap->flags & ATA_FLAG_SAS_HOST))
                schedule_delayed_work(&ap->hotplug_task, 0);
 
        if (ap->pflags & ATA_PFLAG_RECOVERED)
index 66be961c93a4e3311a7d477ec666e3f17150397d..89a9d4a2efc8a56a76407611a30d4079363fdfe9 100644 (file)
@@ -3316,6 +3316,12 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                goto invalid_fld;
        }
 
+       /* We may not issue NCQ commands to devices not supporting NCQ */
+       if (ata_is_ncq(tf->protocol) && !ata_ncq_enabled(dev)) {
+               fp = 1;
+               goto invalid_fld;
+       }
+
        /* sanity check for pio multi commands */
        if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) {
                fp = 1;
@@ -4282,7 +4288,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
 #ifdef ATA_DEBUG
        struct scsi_device *scsidev = cmd->device;
 
-       DPRINTK("CDB (%u:%d,%d,%d) %9ph\n",
+       DPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
                ap->print_id,
                scsidev->channel, scsidev->id, scsidev->lun,
                cmd->cmnd);
@@ -4309,7 +4315,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
                if (likely((scsi_op != ATA_16) || !atapi_passthru16)) {
                        /* relay SCSI command to ATAPI device */
                        int len = COMMAND_SIZE(scsi_op);
-                       if (unlikely(len > scmd->cmd_len || len > dev->cdb_len))
+                       if (unlikely(len > scmd->cmd_len ||
+                                    len > dev->cdb_len ||
+                                    scmd->cmd_len > ATAPI_CDB_LEN))
                                goto bad_cdb_len;
 
                        xlat_func = atapi_xlat;
index 80ee2f2a50d02872a9b657e99d320ac7dfe2cc5a..6456e07db72a7ea4e5cf2bcb1110dec9db42e946 100644 (file)
 enum sata_rcar_type {
        RCAR_GEN1_SATA,
        RCAR_GEN2_SATA,
+       RCAR_GEN3_SATA,
        RCAR_R8A7790_ES1_SATA,
 };
 
@@ -784,26 +785,11 @@ static void sata_rcar_setup_port(struct ata_host *host)
        ioaddr->command_addr    = ioaddr->cmd_addr + (ATA_REG_CMD << 2);
 }
 
-static void sata_rcar_init_controller(struct ata_host *host)
+static void sata_rcar_init_module(struct sata_rcar_priv *priv)
 {
-       struct sata_rcar_priv *priv = host->private_data;
        void __iomem *base = priv->base;
        u32 val;
 
-       /* reset and setup phy */
-       switch (priv->type) {
-       case RCAR_GEN1_SATA:
-               sata_rcar_gen1_phy_init(priv);
-               break;
-       case RCAR_GEN2_SATA:
-       case RCAR_R8A7790_ES1_SATA:
-               sata_rcar_gen2_phy_init(priv);
-               break;
-       default:
-               dev_warn(host->dev, "SATA phy is not initialized\n");
-               break;
-       }
-
        /* SATA-IP reset state */
        val = ioread32(base + ATAPI_CONTROL1_REG);
        val |= ATAPI_CONTROL1_RESET;
@@ -824,10 +810,33 @@ static void sata_rcar_init_controller(struct ata_host *host)
        /* ack and mask */
        iowrite32(0, base + SATAINTSTAT_REG);
        iowrite32(0x7ff, base + SATAINTMASK_REG);
+
        /* enable interrupts */
        iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
 }
 
+static void sata_rcar_init_controller(struct ata_host *host)
+{
+       struct sata_rcar_priv *priv = host->private_data;
+
+       /* reset and setup phy */
+       switch (priv->type) {
+       case RCAR_GEN1_SATA:
+               sata_rcar_gen1_phy_init(priv);
+               break;
+       case RCAR_GEN2_SATA:
+       case RCAR_GEN3_SATA:
+       case RCAR_R8A7790_ES1_SATA:
+               sata_rcar_gen2_phy_init(priv);
+               break;
+       default:
+               dev_warn(host->dev, "SATA phy is not initialized\n");
+               break;
+       }
+
+       sata_rcar_init_module(priv);
+}
+
 static const struct of_device_id sata_rcar_match[] = {
        {
                /* Deprecated by "renesas,sata-r8a7779" */
@@ -856,7 +865,7 @@ static const struct of_device_id sata_rcar_match[] = {
        },
        {
                .compatible = "renesas,sata-r8a7795",
-               .data = (void *)RCAR_GEN2_SATA
+               .data = (void *)RCAR_GEN3_SATA
        },
        {
                .compatible = "renesas,rcar-gen2-sata",
@@ -864,7 +873,7 @@ static const struct of_device_id sata_rcar_match[] = {
        },
        {
                .compatible = "renesas,rcar-gen3-sata",
-               .data = (void *)RCAR_GEN2_SATA
+               .data = (void *)RCAR_GEN3_SATA
        },
        { },
 };
@@ -982,11 +991,18 @@ static int sata_rcar_resume(struct device *dev)
        if (ret)
                return ret;
 
-       /* ack and mask */
-       iowrite32(0, base + SATAINTSTAT_REG);
-       iowrite32(0x7ff, base + SATAINTMASK_REG);
-       /* enable interrupts */
-       iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
+       if (priv->type == RCAR_GEN3_SATA) {
+               sata_rcar_gen2_phy_init(priv);
+               sata_rcar_init_module(priv);
+       } else {
+               /* ack and mask */
+               iowrite32(0, base + SATAINTSTAT_REG);
+               iowrite32(0x7ff, base + SATAINTMASK_REG);
+
+               /* enable interrupts */
+               iowrite32(ATAPI_INT_ENABLE_SATAINT,
+                         base + ATAPI_INT_ENABLE_REG);
+       }
 
        ata_host_resume(host);
 
index 9180b9bd58216f780ab608cf75d868cb60e484b1..834509506ef643399a18ec3cb841d8827c6c70c5 100644 (file)
@@ -97,7 +97,7 @@ static struct img_ascii_lcd_config boston_config = {
 static void malta_update(struct img_ascii_lcd_ctx *ctx)
 {
        unsigned int i;
-       int err;
+       int err = 0;
 
        for (i = 0; i < ctx->cfg->num_chars; i++) {
                err = regmap_write(ctx->regmap,
@@ -180,7 +180,7 @@ static int sead3_wait_lcd_idle(struct img_ascii_lcd_ctx *ctx)
 static void sead3_update(struct img_ascii_lcd_ctx *ctx)
 {
        unsigned int i;
-       int err;
+       int err = 0;
 
        for (i = 0; i < ctx->cfg->num_chars; i++) {
                err = sead3_wait_lcd_idle(ctx);
@@ -224,7 +224,7 @@ MODULE_DEVICE_TABLE(of, img_ascii_lcd_matches);
 
 /**
  * img_ascii_lcd_scroll() - scroll the display by a character
- * @arg: really a pointer to the private data structure
+ * @t: really a pointer to the private data structure
  *
  * Scroll the current message along the LCD by one character, rearming the
  * timer if required.
index ea7869c0d7f9f638ffb33f61d7b2b7437cd3bf41..ec5e8800f8adf18ad0f645747d991abb518a2659 100644 (file)
@@ -1372,7 +1372,7 @@ static void panel_process_inputs(void)
                                break;
                        input->rise_timer = 0;
                        input->state = INPUT_ST_RISING;
-                       /* no break here, fall through */
+                       /* fall through */
                case INPUT_ST_RISING:
                        if ((phys_curr & input->mask) != input->value) {
                                input->state = INPUT_ST_LOW;
@@ -1385,11 +1385,11 @@ static void panel_process_inputs(void)
                        }
                        input->high_timer = 0;
                        input->state = INPUT_ST_HIGH;
-                       /* no break here, fall through */
+                       /* fall through */
                case INPUT_ST_HIGH:
                        if (input_state_high(input))
                                break;
-                       /* no break here, fall through */
+                       /* fall through */
                case INPUT_ST_FALLING:
                        input_state_falling(input);
                }
index b2261f92f2f1c1356b8e2f78e915cce9efff36ba..5847364f25d96721ea6ce13f81bd8ead83504cb7 100644 (file)
@@ -310,6 +310,9 @@ static void __device_link_del(struct device_link *link)
        dev_info(link->consumer, "Dropping the link to %s\n",
                 dev_name(link->supplier));
 
+       if (link->flags & DL_FLAG_PM_RUNTIME)
+               pm_runtime_drop_link(link->consumer);
+
        list_del(&link->s_node);
        list_del(&link->c_node);
        device_link_free(link);
index a8ac86e4d79e73f758301bdc8f690dddb795b671..6637fc319269ba9f93a4c7ae44422723656033c8 100644 (file)
@@ -321,7 +321,8 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq)
                return;
 
        if (device_may_wakeup(wirq->dev)) {
-               if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED)
+               if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
+                   !pm_runtime_status_suspended(wirq->dev))
                        enable_irq(wirq->irq);
 
                enable_irq_wake(wirq->irq);
@@ -343,7 +344,8 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
        if (device_may_wakeup(wirq->dev)) {
                disable_irq_wake(wirq->irq);
 
-               if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED)
+               if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
+                   !pm_runtime_status_suspended(wirq->dev))
                        disable_irq_nosync(wirq->irq);
        }
 }
index 302236281d83012c23334ff752c680328a16769a..8f205f6461ed8cb2907284d9840717afafb02844 100644 (file)
@@ -1410,9 +1410,8 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
 }
 EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
 
-void *device_get_match_data(struct device *dev)
+const void *device_get_match_data(struct device *dev)
 {
-       return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data,
-                                 dev);
+       return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
 }
 EXPORT_SYMBOL_GPL(device_get_match_data);
index e5aa62fcf5a8380d02866b7d9c31aa0a72f6573e..3aaf6af3ec23d7d54d5f45deb97ede64bec7d3db 100644 (file)
@@ -1758,7 +1758,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        if (unit[drive].type->code == FD_NODRIVE)
                return NULL;
        *part = 0;
-       return get_disk(unit[drive].gendisk);
+       return get_disk_and_module(unit[drive].gendisk);
 }
 
 static int __init amiga_floppy_probe(struct platform_device *pdev)
index 8bc3b9fd8dd2be0df64d166dbc4c2b65eef03305..dfb2c2622e5a64d77e85ca9d14059c25f1840878 100644 (file)
@@ -1917,7 +1917,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)
                return NULL;
        *part = 0;
-       return get_disk(unit[drive].disk);
+       return get_disk_and_module(unit[drive].disk);
 }
 
 static int __init atari_floppy_init (void)
index 8028a3a7e7fd63cabb8ce47c021e90e26d09a7ba..deea78e485da05e90436d78c334da2b40e9c6bce 100644 (file)
@@ -456,7 +456,7 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data)
 
        mutex_lock(&brd_devices_mutex);
        brd = brd_init_one(MINOR(dev) / max_part, &new);
-       kobj = brd ? get_disk(brd->brd_disk) : NULL;
+       kobj = brd ? get_disk_and_module(brd->brd_disk) : NULL;
        mutex_unlock(&brd_devices_mutex);
 
        if (new)
index eae484acfbbc1d4c8228b5524b4d30070793620a..8ec7235fc93be49c48291725aec29f2c36818ade 100644 (file)
@@ -4505,7 +4505,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
                return NULL;
        *part = 0;
-       return get_disk(disks[drive]);
+       return get_disk_and_module(disks[drive]);
 }
 
 static int __init do_floppy_init(void)
index d5fe720cf14940b668f8764de2bad6cf95549528..ee62d2d517bf4537c60cdd83c70363382403fc57 100644 (file)
@@ -266,7 +266,7 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
        struct iov_iter i;
        ssize_t bw;
 
-       iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len);
+       iov_iter_bvec(&i, ITER_BVEC | WRITE, bvec, 1, bvec->bv_len);
 
        file_start_write(file);
        bw = vfs_iter_write(file, &i, ppos, 0);
@@ -1922,7 +1922,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
        if (err < 0)
                kobj = NULL;
        else
-               kobj = get_disk(lo->lo_disk);
+               kobj = get_disk_and_module(lo->lo_disk);
        mutex_unlock(&loop_index_mutex);
 
        *part = 0;
index 5f2a4240a204d54fc6fe87e569dc6165d5190530..86258b00a1d4d1960a67fb021babc668884a72a7 100644 (file)
@@ -1591,7 +1591,7 @@ again:
                        if (new_index < 0) {
                                mutex_unlock(&nbd_index_mutex);
                                printk(KERN_ERR "nbd: failed to add new device\n");
-                               return ret;
+                               return new_index;
                        }
                        nbd = idr_find(&nbd_index_idr, new_index);
                }
index 531a0915066b313462d6208359ecea4102397215..c61d20c9f3f8092f3aed69d859f137e7d67aef33 100644 (file)
@@ -1122,7 +1122,7 @@ static int pkt_start_recovery(struct packet_data *pkt)
        pkt->sector = new_sector;
 
        bio_reset(pkt->bio);
-       bio_set_set(pkt->bio, pd->bdev);
+       bio_set_dev(pkt->bio, pd->bdev);
        bio_set_op_attrs(pkt->bio, REQ_OP_WRITE, 0);
        pkt->bio->bi_iter.bi_sector = new_sector;
        pkt->bio->bi_iter.bi_size = pkt->frames * CD_FRAMESIZE;
index 84434d3ea19b8f3a7500972219b952a6b84072a2..64e066eba72e03abec38d49036d0f3677aafb2a3 100644 (file)
@@ -799,7 +799,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
                return NULL;
 
        *part = 0;
-       return get_disk(swd->unit[drive].disk);
+       return get_disk_and_module(swd->unit[drive].disk);
 }
 
 static int swim_add_floppy(struct swim_priv *swd, enum drive_location location)
index e126e4cac2ca499566da91a6e3da01d0b1e4381e..92ec1bbece51d31c44f88eb6a2037333dd7a9f40 100644 (file)
@@ -262,6 +262,7 @@ static DEFINE_SPINLOCK(minor_lock);
 
 static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo);
 static void blkfront_gather_backend_features(struct blkfront_info *info);
+static int negotiate_mq(struct blkfront_info *info);
 
 static int get_id_from_freelist(struct blkfront_ring_info *rinfo)
 {
@@ -1774,11 +1775,18 @@ static int talk_to_blkback(struct xenbus_device *dev,
        unsigned int i, max_page_order;
        unsigned int ring_page_order;
 
+       if (!info)
+               return -ENODEV;
+
        max_page_order = xenbus_read_unsigned(info->xbdev->otherend,
                                              "max-ring-page-order", 0);
        ring_page_order = min(xen_blkif_max_ring_order, max_page_order);
        info->nr_ring_pages = 1 << ring_page_order;
 
+       err = negotiate_mq(info);
+       if (err)
+               goto destroy_blkring;
+
        for (i = 0; i < info->nr_rings; i++) {
                struct blkfront_ring_info *rinfo = &info->rinfo[i];
 
@@ -1978,11 +1986,6 @@ static int blkfront_probe(struct xenbus_device *dev,
        }
 
        info->xbdev = dev;
-       err = negotiate_mq(info);
-       if (err) {
-               kfree(info);
-               return err;
-       }
 
        mutex_init(&info->mutex);
        info->vdevice = vdevice;
@@ -2099,10 +2102,6 @@ static int blkfront_resume(struct xenbus_device *dev)
 
        blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
 
-       err = negotiate_mq(info);
-       if (err)
-               return err;
-
        err = talk_to_blkback(dev, info);
        if (!err)
                blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings);
index 41c95c9b2ab436e5917eb6f83f055b91ee521044..8f9130ab5887273d8feba518fabb76524fa7b579 100644 (file)
@@ -332,7 +332,7 @@ static const struct block_device_operations z2_fops =
 static struct kobject *z2_find(dev_t dev, int *part, void *data)
 {
        *part = 0;
-       return get_disk(z2ram_gendisk);
+       return get_disk_and_module(z2ram_gendisk);
 }
 
 static struct request_queue *z2_queue;
index 2a55380ad730713fa4f26807294e9a9a0b5fa1b5..366a49c7c08f22c00a22e9ecd6b202b166c1e83e 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 
+#include <linux/dmi.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/quirks.h>
@@ -230,7 +231,6 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
-       { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
@@ -263,6 +263,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
 
        /* QCA ROME chipset */
+       { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME },
        { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME },
        { USB_DEVICE(0x0cf3, 0xe009), .driver_info = BTUSB_QCA_ROME },
        { USB_DEVICE(0x0cf3, 0xe010), .driver_info = BTUSB_QCA_ROME },
@@ -379,6 +380,21 @@ static const struct usb_device_id blacklist_table[] = {
        { }     /* Terminating entry */
 };
 
+/* The Bluetooth USB module build into some devices needs to be reset on resume,
+ * this is a problem with the platform (likely shutting off all power) not with
+ * the module itself. So we use a DMI list to match known broken platforms.
+ */
+static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
+       {
+               /* Dell OptiPlex 3060 (QCA ROME device 0cf3:e007) */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 3060"),
+               },
+       },
+       {}
+};
+
 #define BTUSB_MAX_ISOC_FRAMES  10
 
 #define BTUSB_INTR_RUNNING     0
@@ -2945,6 +2961,9 @@ static int btusb_probe(struct usb_interface *intf,
        hdev->send   = btusb_send_frame;
        hdev->notify = btusb_notify;
 
+       if (dmi_check_system(btusb_needs_reset_resume_table))
+               interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
+
 #ifdef CONFIG_PM
        err = btusb_config_oob_wake(hdev);
        if (err)
@@ -3031,12 +3050,6 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info & BTUSB_QCA_ROME) {
                data->setup_on_usb = btusb_setup_qca;
                hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
-
-               /* QCA Rome devices lose their updated firmware over suspend,
-                * but the USB hub doesn't notice any status change.
-                * explicitly request a device reset on resume.
-                */
-               interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME;
        }
 
 #ifdef CONFIG_BT_HCIBTUSB_RTL
index 0438a64b8185ed85b60c28f5086141c7e7a7b769..40b9fb247010169d047f27b1532ef20e69ecab68 100644 (file)
@@ -244,7 +244,9 @@ static irqreturn_t bcm_host_wake(int irq, void *data)
 
        bt_dev_dbg(bdev, "Host wake IRQ");
 
-       pm_request_resume(bdev->dev);
+       pm_runtime_get(bdev->dev);
+       pm_runtime_mark_last_busy(bdev->dev);
+       pm_runtime_put_autosuspend(bdev->dev);
 
        return IRQ_HANDLED;
 }
@@ -301,7 +303,7 @@ static const struct bcm_set_sleep_mode default_sleep_params = {
        .usb_auto_sleep = 0,
        .usb_resume_timeout = 0,
        .break_to_host = 0,
-       .pulsed_host_wake = 0,
+       .pulsed_host_wake = 1,
 };
 
 static int bcm_setup_sleep(struct hci_uart *hu)
@@ -586,8 +588,11 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)
        } else if (!bcm->rx_skb) {
                /* Delay auto-suspend when receiving completed packet */
                mutex_lock(&bcm_device_lock);
-               if (bcm->dev && bcm_device_exists(bcm->dev))
-                       pm_request_resume(bcm->dev->dev);
+               if (bcm->dev && bcm_device_exists(bcm->dev)) {
+                       pm_runtime_get(bcm->dev->dev);
+                       pm_runtime_mark_last_busy(bcm->dev->dev);
+                       pm_runtime_put_autosuspend(bcm->dev->dev);
+               }
                mutex_unlock(&bcm_device_lock);
        }
 
@@ -922,12 +927,13 @@ static int bcm_get_resources(struct bcm_device *dev)
 
        dev->clk = devm_clk_get(dev->dev, NULL);
 
-       dev->device_wakeup = devm_gpiod_get(dev->dev, "device-wakeup",
-                                           GPIOD_OUT_LOW);
+       dev->device_wakeup = devm_gpiod_get_optional(dev->dev, "device-wakeup",
+                                                    GPIOD_OUT_LOW);
        if (IS_ERR(dev->device_wakeup))
                return PTR_ERR(dev->device_wakeup);
 
-       dev->shutdown = devm_gpiod_get(dev->dev, "shutdown", GPIOD_OUT_LOW);
+       dev->shutdown = devm_gpiod_get_optional(dev->dev, "shutdown",
+                                               GPIOD_OUT_LOW);
        if (IS_ERR(dev->shutdown))
                return PTR_ERR(dev->shutdown);
 
index 4d46003c46cfe5f4599a17cf726cb3d86fd8399c..cdaeeea7999cd20759dca0d5cd7f88a3ff431440 100644 (file)
@@ -630,7 +630,7 @@ static int sysc_init_dts_quirks(struct sysc *ddata)
        for (i = 0; i < ARRAY_SIZE(sysc_dts_quirks); i++) {
                prop = of_get_property(np, sysc_dts_quirks[i].name, &len);
                if (!prop)
-                       break;
+                       continue;
 
                ddata->cfg.quirks |= sysc_dts_quirks[i].mask;
        }
index d1f5bb534e0e363ba4750b7b7f9035de94cfc4ec..6e9df558325bea7d139a1b726858837a586cde51 100644 (file)
@@ -162,7 +162,7 @@ static int via_rng_init(struct hwrng *rng)
        /* Enable secondary noise source on CPUs where it is present. */
 
        /* Nehemiah stepping 8 and higher */
-       if ((c->x86_model == 9) && (c->x86_mask > 7))
+       if ((c->x86_model == 9) && (c->x86_stepping > 7))
                lo |= VIA_NOISESRC2;
 
        /* Esther */
index 4d1dc8b46877ca497a198a3d988d060b9235100a..f95b9c75175bcf27825b16891ca405886e51c379 100644 (file)
@@ -457,7 +457,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
                            size_t count)
 {
        int size = 0;
-       int expected;
+       u32 expected;
 
        if (!chip)
                return -EBUSY;
@@ -474,7 +474,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
        }
 
        expected = be32_to_cpu(*(__be32 *)(buf + 2));
-       if (expected > count) {
+       if (expected > count || expected < TPM_HEADER_SIZE) {
                size = -EIO;
                goto out;
        }
index 76df4fbcf089c2371b2ad8b08f31bf446b5c488b..9e80a953d6933ea05668636b6abcd444eff72b0a 100644 (file)
@@ -1190,6 +1190,10 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
                        break;
 
                recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
+               if (recd > num_bytes) {
+                       total = -EFAULT;
+                       break;
+               }
 
                rlength = be32_to_cpu(tpm_cmd.header.out.length);
                if (rlength < offsetof(struct tpm_getrandom_out, rng_data) +
index c17e75348a991e355236f2040f931e940541049f..a700f8f9ead797df39de4b5ef946fb5c2c65c95b 100644 (file)
@@ -683,6 +683,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
        if (!rc) {
                data_len = be16_to_cpup(
                        (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
+               if (data_len < MIN_KEY_SIZE ||  data_len > MAX_KEY_SIZE + 1) {
+                       rc = -EFAULT;
+                       goto out;
+               }
 
                rlength = be32_to_cpu(((struct tpm2_cmd *)&buf)
                                        ->header.out.length);
index c1dd39eaaeebb1f474d2d9f8b0d1e98e3559f27f..6116cd05e2287999c69ea4c5432098f159a44379 100644 (file)
@@ -473,7 +473,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        int size = 0;
-       int expected, status;
+       int status;
+       u32 expected;
 
        if (count < TPM_HEADER_SIZE) {
                size = -EIO;
@@ -488,7 +489,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
        }
 
        expected = be32_to_cpu(*(__be32 *)(buf + 2));
-       if ((size_t) expected > count) {
+       if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
                size = -EIO;
                goto out;
        }
index c6428771841f814a891719fab16e92d7e0723fc7..caa86b19c76dd7007a3975756dec8fe069a31db3 100644 (file)
@@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
        struct device *dev = chip->dev.parent;
        struct i2c_client *client = to_i2c_client(dev);
        s32 rc;
-       int expected, status, burst_count, retries, size = 0;
+       int status;
+       int burst_count;
+       int retries;
+       int size = 0;
+       u32 expected;
 
        if (count < TPM_HEADER_SIZE) {
                i2c_nuvoton_ready(chip);    /* return to idle */
@@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
                 * to machine native
                 */
                expected = be32_to_cpu(*(__be32 *) (buf + 2));
-               if (expected > count) {
+               if (expected > count || expected < size) {
                        dev_err(dev, "%s() expected > count\n", __func__);
                        size = -EIO;
                        continue;
index 183a5f54d875d072b98e7aead6563f3dd3d95a62..da074e3db19be5c895f80a403aabb992e9a14d29 100644 (file)
@@ -270,7 +270,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
        int size = 0;
-       int expected, status;
+       int status;
+       u32 expected;
 
        if (count < TPM_HEADER_SIZE) {
                size = -EIO;
@@ -285,7 +286,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
        }
 
        expected = be32_to_cpu(*(__be32 *) (buf + 2));
-       if (expected > count) {
+       if (expected > count || expected < TPM_HEADER_SIZE) {
                size = -EIO;
                goto out;
        }
index 44301a3d996333f37f4e6e1b9696f84f99563e71..a07f6451694ae3ff25b65fa02ddd5f78e1caec05 100644 (file)
@@ -449,17 +449,17 @@ struct bcm2835_pll_ana_bits {
 static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
        .mask0 = 0,
        .set0 = 0,
-       .mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
+       .mask1 = A2W_PLL_KI_MASK | A2W_PLL_KP_MASK,
        .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
-       .mask3 = (u32)~A2W_PLL_KA_MASK,
+       .mask3 = A2W_PLL_KA_MASK,
        .set3 = (2 << A2W_PLL_KA_SHIFT),
        .fb_prediv_mask = BIT(14),
 };
 
 static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
-       .mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
+       .mask0 = A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK,
        .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
-       .mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
+       .mask1 = A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK,
        .set1 = (6 << A2W_PLLH_KP_SHIFT),
        .mask3 = 0,
        .set3 = 0,
@@ -623,8 +623,10 @@ static int bcm2835_pll_on(struct clk_hw *hw)
                     ~A2W_PLL_CTRL_PWRDN);
 
        /* Take the PLL out of reset. */
+       spin_lock(&cprman->regs_lock);
        cprman_write(cprman, data->cm_ctrl_reg,
                     cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
+       spin_unlock(&cprman->regs_lock);
 
        /* Wait for the PLL to lock. */
        timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
@@ -701,9 +703,11 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
        }
 
        /* Unmask the reference clock from the oscillator. */
+       spin_lock(&cprman->regs_lock);
        cprman_write(cprman, A2W_XOSC_CTRL,
                     cprman_read(cprman, A2W_XOSC_CTRL) |
                     data->reference_enable_mask);
+       spin_unlock(&cprman->regs_lock);
 
        if (do_ana_setup_first)
                bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana);
index 9f7f931d6b2f717f786255bfcf74b6a74e212cde..5eb50c31e4553c114a6ce62d38a4afb0b158f9b6 100644 (file)
@@ -205,6 +205,18 @@ static const struct aspeed_clk_soc_data ast2400_data = {
        .calc_pll = aspeed_ast2400_calc_pll,
 };
 
+static int aspeed_clk_is_enabled(struct clk_hw *hw)
+{
+       struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
+       u32 clk = BIT(gate->clock_idx);
+       u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
+       u32 reg;
+
+       regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
+
+       return ((reg & clk) == enval) ? 1 : 0;
+}
+
 static int aspeed_clk_enable(struct clk_hw *hw)
 {
        struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
@@ -215,6 +227,11 @@ static int aspeed_clk_enable(struct clk_hw *hw)
 
        spin_lock_irqsave(gate->lock, flags);
 
+       if (aspeed_clk_is_enabled(hw)) {
+               spin_unlock_irqrestore(gate->lock, flags);
+               return 0;
+       }
+
        if (gate->reset_idx >= 0) {
                /* Put IP in reset */
                regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst);
@@ -255,17 +272,6 @@ static void aspeed_clk_disable(struct clk_hw *hw)
        spin_unlock_irqrestore(gate->lock, flags);
 }
 
-static int aspeed_clk_is_enabled(struct clk_hw *hw)
-{
-       struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
-       u32 clk = BIT(gate->clock_idx);
-       u32 reg;
-
-       regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);
-
-       return (reg & clk) ? 0 : 1;
-}
-
 static const struct clk_ops aspeed_clk_gate_ops = {
        .enable = aspeed_clk_enable,
        .disable = aspeed_clk_disable,
index 0f686a9dac3e78212b390ab985e1c571557c65f0..076d4244d6725228a12ed0c0daa5ee1c3b7e3c43 100644 (file)
@@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
 {
        lockdep_assert_held(&prepare_lock);
 
-       if (!core)
+       if (!core) {
+               req->rate = 0;
                return 0;
+       }
 
        clk_core_init_rate_req(core, req);
 
@@ -2309,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees)
 
        trace_clk_set_phase(core, degrees);
 
-       if (core->ops->set_phase)
+       if (core->ops->set_phase) {
                ret = core->ops->set_phase(core->hw, degrees);
+               if (!ret)
+                       core->phase = degrees;
+       }
 
        trace_clk_set_phase_complete(core, degrees);
 
@@ -2967,23 +2972,38 @@ static int __clk_core_init(struct clk_core *core)
                rate = 0;
        core->rate = core->req_rate = rate;
 
+       /*
+        * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
+        * don't get accidentally disabled when walking the orphan tree and
+        * reparenting clocks
+        */
+       if (core->flags & CLK_IS_CRITICAL) {
+               unsigned long flags;
+
+               clk_core_prepare(core);
+
+               flags = clk_enable_lock();
+               clk_core_enable(core);
+               clk_enable_unlock(flags);
+       }
+
        /*
         * walk the list of orphan clocks and reparent any that newly finds a
         * parent.
         */
        hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
                struct clk_core *parent = __clk_init_parent(orphan);
-               unsigned long flags;
 
                /*
-                * we could call __clk_set_parent, but that would result in a
-                * redundant call to the .set_rate op, if it exists
+                * We need to use __clk_set_parent_before() and _after() to
+                * to properly migrate any prepare/enable count of the orphan
+                * clock. This is important for CLK_IS_CRITICAL clocks, which
+                * are enabled during init but might not have a parent yet.
                 */
                if (parent) {
                        /* update the clk tree topology */
-                       flags = clk_enable_lock();
-                       clk_reparent(orphan, parent);
-                       clk_enable_unlock(flags);
+                       __clk_set_parent_before(orphan, parent);
+                       __clk_set_parent_after(orphan, parent, NULL);
                        __clk_recalc_accuracies(orphan);
                        __clk_recalc_rates(orphan, 0);
                }
@@ -3000,16 +3020,6 @@ static int __clk_core_init(struct clk_core *core)
        if (core->ops->init)
                core->ops->init(core->hw);
 
-       if (core->flags & CLK_IS_CRITICAL) {
-               unsigned long flags;
-
-               clk_core_prepare(core);
-
-               flags = clk_enable_lock();
-               clk_core_enable(core);
-               clk_enable_unlock(flags);
-       }
-
        kref_init(&core->ref);
 out:
        clk_pm_runtime_put(core);
index 9b6c72bbddf96712a004aab1ec37b2ebe2d423a6..e8b2c43b1bb86f17612b63534172a7332f44f6eb 100644 (file)
@@ -149,6 +149,8 @@ static int hi3660_stub_clk_probe(struct platform_device *pdev)
                return PTR_ERR(stub_clk_chan.mbox);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -EINVAL;
        freq_reg = devm_ioremap(dev, res->start, resource_size(res));
        if (!freq_reg)
                return -ENOMEM;
index c864992e6983f800abc030e233320af5406ce973..caa8bd40692c61be4feba9a37cc5f33a8046bfac 100644 (file)
@@ -131,7 +131,17 @@ static const char *ieee1588_sels[] = { "pll3_sw", "pll4_sw", "dummy" /* usbphy2_
 static struct clk *clk[IMX5_CLK_END];
 static struct clk_onecell_data clk_data;
 
-static struct clk ** const uart_clks[] __initconst = {
+static struct clk ** const uart_clks_mx51[] __initconst = {
+       &clk[IMX5_CLK_UART1_IPG_GATE],
+       &clk[IMX5_CLK_UART1_PER_GATE],
+       &clk[IMX5_CLK_UART2_IPG_GATE],
+       &clk[IMX5_CLK_UART2_PER_GATE],
+       &clk[IMX5_CLK_UART3_IPG_GATE],
+       &clk[IMX5_CLK_UART3_PER_GATE],
+       NULL
+};
+
+static struct clk ** const uart_clks_mx50_mx53[] __initconst = {
        &clk[IMX5_CLK_UART1_IPG_GATE],
        &clk[IMX5_CLK_UART1_PER_GATE],
        &clk[IMX5_CLK_UART2_IPG_GATE],
@@ -321,8 +331,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
        clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
        clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
        clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
-
-       imx_register_uart_clocks(uart_clks);
 }
 
 static void __init mx50_clocks_init(struct device_node *np)
@@ -388,6 +396,8 @@ static void __init mx50_clocks_init(struct device_node *np)
 
        r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
        clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
+
+       imx_register_uart_clocks(uart_clks_mx50_mx53);
 }
 CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
 
@@ -477,6 +487,8 @@ static void __init mx51_clocks_init(struct device_node *np)
        val = readl(MXC_CCM_CLPCR);
        val |= 1 << 23;
        writel(val, MXC_CCM_CLPCR);
+
+       imx_register_uart_clocks(uart_clks_mx51);
 }
 CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
 
@@ -606,5 +618,7 @@ static void __init mx53_clocks_init(struct device_node *np)
 
        r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
        clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
+
+       imx_register_uart_clocks(uart_clks_mx50_mx53);
 }
 CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);
index 246957f1a413513543db0e4c79573f0aba10b6b0..b1cc8dbcd3274a429f1e80884ce8c09f974ebc09 100644 (file)
@@ -49,11 +49,10 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
        struct clk_regmap_mux_div *a53cc;
        struct regmap *regmap;
        struct clk_init_data init = { };
-       int ret;
+       int ret = -ENODEV;
 
        regmap = dev_get_regmap(parent, NULL);
-       if (IS_ERR(regmap)) {
-               ret = PTR_ERR(regmap);
+       if (!regmap) {
                dev_err(dev, "failed to get regmap: %d\n", ret);
                return ret;
        }
index 72b16ed1012b1e78e272b0ca06fee32a8a49aed0..3b97f60540ad8cd29aeb06a69620dcf940a15213 100644 (file)
@@ -762,7 +762,7 @@ static struct ccu_mp out_a_clk = {
                .features       = CCU_FEATURE_FIXED_PREDIV,
                .hw.init        = CLK_HW_INIT_PARENTS("out-a",
                                                      clk_out_parents,
-                                                     &ccu_div_ops,
+                                                     &ccu_mp_ops,
                                                      0),
        },
 };
@@ -783,7 +783,7 @@ static struct ccu_mp out_b_clk = {
                .features       = CCU_FEATURE_FIXED_PREDIV,
                .hw.init        = CLK_HW_INIT_PARENTS("out-b",
                                                      clk_out_parents,
-                                                     &ccu_div_ops,
+                                                     &ccu_mp_ops,
                                                      0),
        },
 };
@@ -804,7 +804,7 @@ static struct ccu_mp out_c_clk = {
                .features       = CCU_FEATURE_FIXED_PREDIV,
                .hw.init        = CLK_HW_INIT_PARENTS("out-c",
                                                      clk_out_parents,
-                                                     &ccu_div_ops,
+                                                     &ccu_mp_ops,
                                                      0),
        },
 };
index 612491a260708ad19534ee17c94c63ee77e48b8a..12e0a2d1991124504c3ac9a0c5245b991b9921f4 100644 (file)
@@ -45,7 +45,7 @@ static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = {
 
 static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = {
        { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
-       { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP, "lcd_gclk", "lcdc_clkdm" },
+       { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" },
        { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" },
        { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" },
        { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" },
index 2b7c2e017665e20ded9d8a46b96f55e2ddb52c49..63c5ddb501876993f0584364f44ed56a28bc175d 100644 (file)
@@ -187,7 +187,7 @@ static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst
        { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
        { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" },
        { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" },
-       { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "disp_clk", "dss_clkdm" },
+       { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" },
        { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" },
        { 0 },
 };
index afa0d6bfc5c15643a3dd2e765aa1b29048744d90..421b0539222058354d94ae6c29347d03b02ddd93 100644 (file)
@@ -537,6 +537,8 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
                init.parent_names = &reg_data->parent;
                init.num_parents = 1;
                init.flags = 0;
+               if (reg_data->flags & CLKF_SET_RATE_PARENT)
+                       init.flags |= CLK_SET_RATE_PARENT;
                init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
                                      node->parent->name, node->name,
                                      reg_data->offset, 0);
index b3b4ed9b68742bfbb8219af9c24c9d542d6f02ec..d2e5382821a43621310994ea1611e2ad27e798a8 100644 (file)
@@ -386,6 +386,7 @@ config ATMEL_PIT
 
 config ATMEL_ST
        bool "Atmel ST timer support" if COMPILE_TEST
+       depends on HAS_IOMEM
        select TIMER_OF
        select MFD_SYSCON
        help
index 4927355f9cbe51e086db1a144190c0bda1944733..471b428d8034ce5af3e2fc8993fca63df27b68f9 100644 (file)
@@ -251,9 +251,14 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
        int irq_reenable = clockevent_state_periodic(evt);
 
        /*
-        * Any write to CTRL reg ACks the interrupt, we rewrite the
-        * Count when [N]ot [H]alted bit.
-        * And re-arm it if perioid by [I]nterrupt [E]nable bit
+        * 1. ACK the interrupt
+        *    - For ARC700, any write to CTRL reg ACKs it, so just rewrite
+        *      Count when [N]ot [H]alted bit.
+        *    - For HS3x, it is a bit subtle. On taken count-down interrupt,
+        *      IP bit [3] is set, which needs to be cleared for ACK'ing.
+        *      The write below can only update the other two bits, hence
+        *      explicitly clears IP bit
+        * 2. Re-arm interrupt if periodic by writing to IE bit [0]
         */
        write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH);
 
index 3ee7e6fea6212668d8a9a4d4c1e5c52aedab58fb..846d18daf893b03d926276ba454a5babca7cc75d 100644 (file)
@@ -281,7 +281,7 @@ static int __init __ftm_clk_init(struct device_node *np, char *cnt_name,
 
 static unsigned long __init ftm_clk_init(struct device_node *np)
 {
-       unsigned long freq;
+       long freq;
 
        freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt");
        if (freq <= 0)
index a04808a21d4ec9eef5d3c6d5e7ed140945d1001b..986b6796b631f77daa26e3b300d901c2ae00da22 100644 (file)
@@ -166,7 +166,7 @@ static int __init __gic_clocksource_init(void)
 
        /* Set clocksource mask. */
        count_width = read_gic_config() & GIC_CONFIG_COUNTBITS;
-       count_width >>= __fls(GIC_CONFIG_COUNTBITS);
+       count_width >>= __ffs(GIC_CONFIG_COUNTBITS);
        count_width *= 4;
        count_width += 32;
        gic_clocksource.mask = CLOCKSOURCE_MASK(count_width);
@@ -205,12 +205,12 @@ static int __init gic_clocksource_of_init(struct device_node *node)
        } else if (of_property_read_u32(node, "clock-frequency",
                                        &gic_frequency)) {
                pr_err("GIC frequency not specified.\n");
-               return -EINVAL;;
+               return -EINVAL;
        }
        gic_timer_irq = irq_of_parse_and_map(node, 0);
        if (!gic_timer_irq) {
                pr_err("GIC timer IRQ not specified.\n");
-               return -EINVAL;;
+               return -EINVAL;
        }
 
        ret = __gic_clocksource_init();
index 2a3fe83ec3377cc160570fc9ed6e0e5375f57f7a..3b56ea3f52afc8ee47ca21c38cd0c6aa7ec80021 100644 (file)
@@ -334,7 +334,7 @@ static int __init sun5i_timer_init(struct device_node *node)
        timer_base = of_io_request_and_map(node, 0, of_node_full_name(node));
        if (IS_ERR(timer_base)) {
                pr_err("Can't map registers\n");
-               return PTR_ERR(timer_base);;
+               return PTR_ERR(timer_base);
        }
 
        irq = irq_of_parse_and_map(node, 0);
index 3a88e33b0cfed86e487888bc203d9823fcdeb9c0..fb586e09682d84704a28748673cdc4c571c28105 100644 (file)
@@ -44,10 +44,10 @@ config ARM_DT_BL_CPUFREQ
 
 config ARM_SCPI_CPUFREQ
        tristate "SCPI based CPUfreq driver"
-       depends on ARM_BIG_LITTLE_CPUFREQ && ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
+       depends on ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI
        help
-         This adds the CPUfreq driver support for ARM big.LITTLE platforms
-         using SCPI protocol for CPU power management.
+         This adds the CPUfreq driver support for ARM platforms using SCPI
+         protocol for CPU power management.
 
          This driver uses SCPI Message Protocol driver to interact with the
          firmware providing the CPU DVFS functionality.
index 3a2ca0f79daf281c5940222f6b9da179b35f64f3..d0c34df0529c8a8ae425a9a1e845bab0672544ce 100644 (file)
@@ -629,7 +629,7 @@ static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
        if (c->x86_vendor == X86_VENDOR_INTEL) {
                if ((c->x86 == 15) &&
                    (c->x86_model == 6) &&
-                   (c->x86_mask == 8)) {
+                   (c->x86_stepping == 8)) {
                        pr_info("Intel(R) Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n");
                        return -ENODEV;
                    }
index 942632a27b50fb458f927ed69406eafab99511e3..f730b6528c185c8ab94393668afca956ee21eee7 100644 (file)
@@ -775,7 +775,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
                break;
 
        case 7:
-               switch (c->x86_mask) {
+               switch (c->x86_stepping) {
                case 0:
                        longhaul_version = TYPE_LONGHAUL_V1;
                        cpu_model = CPU_SAMUEL2;
@@ -787,7 +787,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
                        break;
                case 1 ... 15:
                        longhaul_version = TYPE_LONGHAUL_V2;
-                       if (c->x86_mask < 8) {
+                       if (c->x86_stepping < 8) {
                                cpu_model = CPU_SAMUEL2;
                                cpuname = "C3 'Samuel 2' [C5B]";
                        } else {
@@ -814,7 +814,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
                numscales = 32;
                memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
                memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
-               switch (c->x86_mask) {
+               switch (c->x86_stepping) {
                case 0 ... 1:
                        cpu_model = CPU_NEHEMIAH;
                        cpuname = "C3 'Nehemiah A' [C5XLOE]";
index fd77812313f3ecd2ef485b6298141de322ce4d80..a25741b1281b46c13d8af408413bed82634cbdab 100644 (file)
@@ -168,7 +168,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
 #endif
 
        /* Errata workaround */
-       cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask;
+       cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_stepping;
        switch (cpuid) {
        case 0x0f07:
        case 0x0f0a:
index 80ac313e6c59c13fa28e9bf62cd616e5d25f9448..302e9ce793a0171e491e0374eee3a7fc1dac63ac 100644 (file)
@@ -131,7 +131,7 @@ static int check_powernow(void)
                return 0;
        }
 
-       if ((c->x86_model == 6) && (c->x86_mask == 0)) {
+       if ((c->x86_model == 6) && (c->x86_stepping == 0)) {
                pr_info("K7 660[A0] core detected, enabling errata workarounds\n");
                have_a0 = 1;
        }
index 7b596fa38ad2de4b7d9cf075ce69a876b4f2e35f..6bebc1f9f55aa65dc1718e47ddea4c0439b42cb0 100644 (file)
@@ -351,7 +351,13 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
 static int s3c_cpufreq_init(struct cpufreq_policy *policy)
 {
        policy->clk = clk_arm;
-       return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency);
+
+       policy->cpuinfo.transition_latency = cpu_cur.info->latency;
+
+       if (ftab)
+               return cpufreq_table_validate_and_show(policy, ftab);
+
+       return 0;
 }
 
 static int __init s3c_cpufreq_initclks(void)
index c32a833e1b00542fd3f49bf758e96f57ee6fa478..d300a163945f53476b4a751f3c208d423717d55f 100644 (file)
@@ -51,15 +51,23 @@ static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
 static int
 scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
 {
+       unsigned long freq = policy->freq_table[index].frequency;
        struct scpi_data *priv = policy->driver_data;
-       u64 rate = policy->freq_table[index].frequency * 1000;
+       u64 rate = freq * 1000;
        int ret;
 
        ret = clk_set_rate(priv->clk, rate);
-       if (!ret && (clk_get_rate(priv->clk) != rate))
-               ret = -EIO;
 
-       return ret;
+       if (ret)
+               return ret;
+
+       if (clk_get_rate(priv->clk) != rate)
+               return -EIO;
+
+       arch_set_freq_scale(policy->related_cpus, freq,
+                           policy->cpuinfo.max_freq);
+
+       return 0;
 }
 
 static int
index 41bc5397f4bbb3d0a08bcab5c3a75ad976680554..4fa5adf16c7014817485784f47d0e650d95e3344 100644 (file)
@@ -37,7 +37,7 @@ struct cpu_id
 {
        __u8    x86;            /* CPU family */
        __u8    x86_model;      /* model */
-       __u8    x86_mask;       /* stepping */
+       __u8    x86_stepping;   /* stepping */
 };
 
 enum {
@@ -277,7 +277,7 @@ static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
 {
        if ((c->x86 == x->x86) &&
            (c->x86_model == x->x86_model) &&
-           (c->x86_mask == x->x86_mask))
+           (c->x86_stepping == x->x86_stepping))
                return 1;
        return 0;
 }
index 8085ec9000d19eb3c1ed3800844f4eeb12be8511..e3a9962ee4109b63f4815074211a232444298d8a 100644 (file)
@@ -272,9 +272,9 @@ unsigned int speedstep_detect_processor(void)
                ebx = cpuid_ebx(0x00000001);
                ebx &= 0x000000FF;
 
-               pr_debug("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);
+               pr_debug("ebx value is %x, x86_stepping is %x\n", ebx, c->x86_stepping);
 
-               switch (c->x86_mask) {
+               switch (c->x86_stepping) {
                case 4:
                        /*
                         * B-stepping [M-P4-M]
@@ -361,7 +361,7 @@ unsigned int speedstep_detect_processor(void)
                                msr_lo, msr_hi);
                if ((msr_hi & (1<<18)) &&
                    (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
-                       if (c->x86_mask == 0x01) {
+                       if (c->x86_stepping == 0x01) {
                                pr_debug("early PIII version\n");
                                return SPEEDSTEP_CPU_PIII_C_EARLY;
                        } else
index 75d280cb2dc057f20e26e20362aabd1d1d6bd7c8..e843cf410373681848d61c45ef63ca6a560ae7d1 100644 (file)
@@ -228,12 +228,16 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
                 * without any error (HW optimizations for later
                 * CAAM eras), then try again.
                 */
+               if (ret)
+                       break;
+
                rdsta_val = rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_IFMASK;
                if ((status && status != JRSTA_SSRC_JUMP_HALT_CC) ||
-                   !(rdsta_val & (1 << sh_idx)))
+                   !(rdsta_val & (1 << sh_idx))) {
                        ret = -EAGAIN;
-               if (ret)
                        break;
+               }
+
                dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
                /* Clear the contents before recreating the descriptor */
                memset(desc, 0x00, CAAM_CMD_SZ * 7);
index fcfa5b1eae6169b44398b20442d95532d924821c..b3afb6cc9d72278b35eadb239e280b5aa311c3f9 100644 (file)
@@ -211,7 +211,7 @@ static int __sev_platform_shutdown_locked(int *error)
 {
        int ret;
 
-       ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, 0, error);
+       ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
        if (ret)
                return ret;
 
@@ -271,7 +271,7 @@ static int sev_ioctl_do_reset(struct sev_issue_cmd *argp)
                        return rc;
        }
 
-       return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, 0, &argp->error);
+       return __sev_do_cmd_locked(SEV_CMD_FACTORY_RESET, NULL, &argp->error);
 }
 
 static int sev_ioctl_do_platform_status(struct sev_issue_cmd *argp)
@@ -299,7 +299,7 @@ static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp)
                        return rc;
        }
 
-       return __sev_do_cmd_locked(cmd, 0, &argp->error);
+       return __sev_do_cmd_locked(cmd, NULL, &argp->error);
 }
 
 static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp)
@@ -624,7 +624,7 @@ EXPORT_SYMBOL_GPL(sev_guest_decommission);
 
 int sev_guest_df_flush(int *error)
 {
-       return sev_do_cmd(SEV_CMD_DF_FLUSH, 0, error);
+       return sev_do_cmd(SEV_CMD_DF_FLUSH, NULL, error);
 }
 EXPORT_SYMBOL_GPL(sev_guest_df_flush);
 
index 4b6642a25df51e9315b816c9062791febdaf6d10..1c6cbda56afe9964c65f58e0cf43024b26b08ba3 100644 (file)
@@ -512,7 +512,7 @@ static int __init padlock_init(void)
 
        printk(KERN_NOTICE PFX "Using VIA PadLock ACE for AES algorithm.\n");
 
-       if (c->x86 == 6 && c->x86_model == 15 && c->x86_mask == 2) {
+       if (c->x86 == 6 && c->x86_model == 15 && c->x86_stepping == 2) {
                ecb_fetch_blocks = MAX_ECB_FETCH_BLOCKS;
                cbc_fetch_blocks = MAX_CBC_FETCH_BLOCKS;
                printk(KERN_NOTICE PFX "VIA Nano stepping 2 detected: enabling workaround.\n");
index 188f44b7eb27edd2f45977b4e59ca17f2cd3f997..5d64c08b7f47ef412916b804256716f6f8016779 100644 (file)
@@ -1922,15 +1922,21 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode)
        uint32_t aes_control;
        unsigned long flags;
        int err;
+       u8 *iv;
 
        aes_control = SSS_AES_KEY_CHANGE_MODE;
        if (mode & FLAGS_AES_DECRYPT)
                aes_control |= SSS_AES_MODE_DECRYPT;
 
-       if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC)
+       if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) {
                aes_control |= SSS_AES_CHAIN_MODE_CBC;
-       else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR)
+               iv = req->info;
+       } else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) {
                aes_control |= SSS_AES_CHAIN_MODE_CTR;
+               iv = req->info;
+       } else {
+               iv = NULL; /* AES_ECB */
+       }
 
        if (dev->ctx->keylen == AES_KEYSIZE_192)
                aes_control |= SSS_AES_KEY_SIZE_192;
@@ -1961,7 +1967,7 @@ static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode)
                goto outdata_error;
 
        SSS_AES_WRITE(dev, AES_CONTROL, aes_control);
-       s5p_set_aes(dev, dev->ctx->aes_key, req->info, dev->ctx->keylen);
+       s5p_set_aes(dev, dev->ctx->aes_key, iv, dev->ctx->keylen);
 
        s5p_set_dma_indata(dev,  dev->sg_src);
        s5p_set_dma_outdata(dev, dev->sg_dst);
index 0d01d16242527c919b99a284a48071fb5c61aa7b..63d636424161dccfbb5cdd12fd34b5db8e1915d1 100644 (file)
@@ -28,7 +28,7 @@ int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
        algt = container_of(alg, struct sun4i_ss_alg_template, alg.rng);
        ss = algt->ss;
 
-       spin_lock(&ss->slock);
+       spin_lock_bh(&ss->slock);
 
        writel(mode, ss->base + SS_CTL);
 
@@ -51,6 +51,6 @@ int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
        }
 
        writel(0, ss->base + SS_CTL);
-       spin_unlock(&ss->slock);
-       return dlen;
+       spin_unlock_bh(&ss->slock);
+       return 0;
 }
index 9c80e0cb16647035fbfeea22ea1b3c9e6bf0a1b1..6882fa2f8badd171ce5b843a05a878a8af0bc46e 100644 (file)
@@ -1138,6 +1138,10 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src,
        struct talitos_private *priv = dev_get_drvdata(dev);
        bool is_sec1 = has_ftr_sec1(priv);
 
+       if (!src) {
+               to_talitos_ptr(ptr, 0, 0, is_sec1);
+               return 1;
+       }
        if (sg_count == 1) {
                to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
                return sg_count;
index 473af694ad1cbee97db06646a715776a5d9e7889..ecdc292aa4e4d861552e4646cdf7bf6bd5c24ea6 100644 (file)
@@ -246,12 +246,6 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
 {
        long avail;
 
-       /*
-        * The device driver is allowed to sleep, in order to make the
-        * memory directly accessible.
-        */
-       might_sleep();
-
        if (!dax_dev)
                return -EOPNOTSUPP;
 
index f652a0e0f5a2a46d78bece1d41cd0895dfc5d593..3548caa9e9339f17208a62066ad055c842491e3b 100644 (file)
@@ -163,6 +163,7 @@ struct mv_xor_v2_device {
        void __iomem *dma_base;
        void __iomem *glob_base;
        struct clk *clk;
+       struct clk *reg_clk;
        struct tasklet_struct irq_tasklet;
        struct list_head free_sw_desc;
        struct dma_device dmadev;
@@ -749,13 +750,26 @@ static int mv_xor_v2_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       xor_dev->reg_clk = devm_clk_get(&pdev->dev, "reg");
+       if (PTR_ERR(xor_dev->reg_clk) != -ENOENT) {
+               if (!IS_ERR(xor_dev->reg_clk)) {
+                       ret = clk_prepare_enable(xor_dev->reg_clk);
+                       if (ret)
+                               return ret;
+               } else {
+                       return PTR_ERR(xor_dev->reg_clk);
+               }
+       }
+
        xor_dev->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER)
-               return -EPROBE_DEFER;
+       if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) {
+               ret = EPROBE_DEFER;
+               goto disable_reg_clk;
+       }
        if (!IS_ERR(xor_dev->clk)) {
                ret = clk_prepare_enable(xor_dev->clk);
                if (ret)
-                       return ret;
+                       goto disable_reg_clk;
        }
 
        ret = platform_msi_domain_alloc_irqs(&pdev->dev, 1,
@@ -866,8 +880,9 @@ free_hw_desq:
 free_msi_irqs:
        platform_msi_domain_free_irqs(&pdev->dev);
 disable_clk:
-       if (!IS_ERR(xor_dev->clk))
-               clk_disable_unprepare(xor_dev->clk);
+       clk_disable_unprepare(xor_dev->clk);
+disable_reg_clk:
+       clk_disable_unprepare(xor_dev->reg_clk);
        return ret;
 }
 
index e3ff162c03fc6a011cb0139a4ffbda2d2600fd32..d0cacdb0713eca47360e4f5ceedc8dc6428145bb 100644 (file)
@@ -917,7 +917,7 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl,
 
        rcar_dmac_chan_configure_desc(chan, desc);
 
-       max_chunk_size = (RCAR_DMATCR_MASK + 1) << desc->xfer_shift;
+       max_chunk_size = RCAR_DMATCR_MASK << desc->xfer_shift;
 
        /*
         * Allocate and fill the transfer chunk descriptors. We own the only
index 4dbb30cf94acb8462cd50b8123c64259a86f31c9..b922db90939a5d9643753bfdc313d9fdbdd2dc33 100644 (file)
@@ -118,14 +118,15 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
        spin_lock_irqsave(&dmamux->lock, flags);
        mux->chan_id = find_first_zero_bit(dmamux->dma_inuse,
                                           dmamux->dma_requests);
-       set_bit(mux->chan_id, dmamux->dma_inuse);
-       spin_unlock_irqrestore(&dmamux->lock, flags);
 
        if (mux->chan_id == dmamux->dma_requests) {
+               spin_unlock_irqrestore(&dmamux->lock, flags);
                dev_err(&pdev->dev, "Run out of free DMA requests\n");
                ret = -ENOMEM;
-               goto error;
+               goto error_chan_id;
        }
+       set_bit(mux->chan_id, dmamux->dma_inuse);
+       spin_unlock_irqrestore(&dmamux->lock, flags);
 
        /* Look for DMA Master */
        for (i = 1, min = 0, max = dmamux->dma_reqs[i];
@@ -173,6 +174,8 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
 
 error:
        clear_bit(mux->chan_id, dmamux->dma_inuse);
+
+error_chan_id:
        kfree(mux);
        return ERR_PTR(ret);
 }
index 8b16ec595fa7273f125d4d0f0bdfaa8a41999c17..329cb96f886fd136062707324680327a3083b763 100644 (file)
@@ -3147,7 +3147,7 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
        struct amd64_family_type *fam_type = NULL;
 
        pvt->ext_model  = boot_cpu_data.x86_model >> 4;
-       pvt->stepping   = boot_cpu_data.x86_mask;
+       pvt->stepping   = boot_cpu_data.x86_stepping;
        pvt->model      = boot_cpu_data.x86_model;
        pvt->fam        = boot_cpu_data.x86;
 
index f34430f99fd805414085fea26540f3c152dd6b0c..872100215ca00f0f4703c025b8e52e637c85c710 100644 (file)
@@ -279,7 +279,7 @@ static const u32 correrrthrsld[] = {
  * sbridge structs
  */
 
-#define NUM_CHANNELS           4       /* Max channels per MC */
+#define NUM_CHANNELS           6       /* Max channels per MC */
 #define MAX_DIMMS              3       /* Max DIMMS per channel */
 #define KNL_MAX_CHAS           38      /* KNL max num. of Cache Home Agents */
 #define KNL_MAX_CHANNELS       6       /* KNL max num. of PCI channels */
index 0a44d43802fe1221971d5e61fc0810e2090627cc..3ec4c715e24053c9cbe8ea770d0f4bdfbb69dffb 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver
  *
- * Copyright (C) 2016-2017 Hans de Goede <hdegoede@redhat.com>
  * Copyright (C) 2015 Intel Corporation
  * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
  *
@@ -98,15 +97,13 @@ struct axp288_extcon_info {
        struct device *dev;
        struct regmap *regmap;
        struct regmap_irq_chip_data *regmap_irqc;
-       struct delayed_work det_work;
        int irq[EXTCON_IRQ_END];
        struct extcon_dev *edev;
        unsigned int previous_cable;
-       bool first_detect_done;
 };
 
 /* Power up/down reason string array */
-static char *axp288_pwr_up_down_info[] = {
+static const char * const axp288_pwr_up_down_info[] = {
        "Last wake caused by user pressing the power button",
        "Last wake caused by a charger insertion",
        "Last wake caused by a battery insertion",
@@ -124,7 +121,7 @@ static char *axp288_pwr_up_down_info[] = {
  */
 static void axp288_extcon_log_rsi(struct axp288_extcon_info *info)
 {
-       char **rsi;
+       const char * const *rsi;
        unsigned int val, i, clear_mask = 0;
        int ret;
 
@@ -140,25 +137,6 @@ static void axp288_extcon_log_rsi(struct axp288_extcon_info *info)
        regmap_write(info->regmap, AXP288_PS_BOOT_REASON_REG, clear_mask);
 }
 
-static void axp288_chrg_detect_complete(struct axp288_extcon_info *info)
-{
-       /*
-        * We depend on other drivers to do things like mux the data lines,
-        * enable/disable vbus based on the id-pin, etc. Sometimes the BIOS has
-        * not set these things up correctly resulting in the initial charger
-        * cable type detection giving a wrong result and we end up not charging
-        * or charging at only 0.5A.
-        *
-        * So we schedule a second cable type detection after 2 seconds to
-        * give the other drivers time to load and do their thing.
-        */
-       if (!info->first_detect_done) {
-               queue_delayed_work(system_wq, &info->det_work,
-                                  msecs_to_jiffies(2000));
-               info->first_detect_done = true;
-       }
-}
-
 static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info)
 {
        int ret, stat, cfg, pwr_stat;
@@ -223,8 +201,6 @@ no_vbus:
                info->previous_cable = cable;
        }
 
-       axp288_chrg_detect_complete(info);
-
        return 0;
 
 dev_det_ret:
@@ -246,11 +222,8 @@ static irqreturn_t axp288_extcon_isr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static void axp288_extcon_det_work(struct work_struct *work)
+static void axp288_extcon_enable(struct axp288_extcon_info *info)
 {
-       struct axp288_extcon_info *info =
-               container_of(work, struct axp288_extcon_info, det_work.work);
-
        regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG,
                                                BC_GLOBAL_RUN, 0);
        /* Enable the charger detection logic */
@@ -272,7 +245,6 @@ static int axp288_extcon_probe(struct platform_device *pdev)
        info->regmap = axp20x->regmap;
        info->regmap_irqc = axp20x->regmap_irqc;
        info->previous_cable = EXTCON_NONE;
-       INIT_DELAYED_WORK(&info->det_work, axp288_extcon_det_work);
 
        platform_set_drvdata(pdev, info);
 
@@ -318,7 +290,7 @@ static int axp288_extcon_probe(struct platform_device *pdev)
        }
 
        /* Start charger cable type detection */
-       queue_delayed_work(system_wq, &info->det_work, 0);
+       axp288_extcon_enable(info);
 
        return 0;
 }
index c8691b5a9cb00c0c77f95d278db541fa97e4f42b..191e99f06a9a5d55a2433b3daa31978fa454e533 100644 (file)
@@ -153,8 +153,9 @@ static int int3496_probe(struct platform_device *pdev)
                return ret;
        }
 
-       /* queue initial processing of id-pin */
+       /* process id-pin so that we start with the right status */
        queue_delayed_work(system_wq, &data->work, 0);
+       flush_delayed_work(&data->work);
 
        platform_set_drvdata(pdev, data);
 
index c16600f30611849562386e25375947785f580463..0bdea60c65ddbff81742b5d1a5d22c25521cfa8f 100644 (file)
@@ -639,7 +639,7 @@ static void __exit dcdbas_exit(void)
        platform_driver_unregister(&dcdbas_driver);
 }
 
-module_init(dcdbas_init);
+subsys_initcall_sync(dcdbas_init);
 module_exit(dcdbas_exit);
 
 MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
index da661bf8cb96e3b683b04574667ec9e7a350376b..13c1edd37e9692155c1e127644715c433267e93b 100644 (file)
@@ -68,11 +68,11 @@ void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg)
        efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
        efi_status_t status;
        efi_physical_addr_t log_location, log_last_entry;
-       struct linux_efi_tpm_eventlog *log_tbl;
+       struct linux_efi_tpm_eventlog *log_tbl = NULL;
        unsigned long first_entry_addr, last_entry_addr;
        size_t log_size, last_entry_size;
        efi_bool_t truncated;
-       void *tcg2_protocol;
+       void *tcg2_protocol = NULL;
 
        status = efi_call_early(locate_protocol, &tcg2_guid, NULL,
                                &tcg2_protocol);
index e76de57dd617d7e2c918c057dcc0ced6636be7b2..ebaea8b1594b7fc4919a71fdac7ed9ef8418df7b 100644 (file)
@@ -14,7 +14,6 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
@@ -37,10 +36,9 @@ struct gpio_rcar_priv {
        struct platform_device *pdev;
        struct gpio_chip gpio_chip;
        struct irq_chip irq_chip;
-       struct clk *clk;
        unsigned int irq_parent;
+       atomic_t wakeup_path;
        bool has_both_edge_trigger;
-       bool needs_clk;
 };
 
 #define IOINTSEL 0x00  /* General IO/Interrupt Switching Register */
@@ -186,13 +184,10 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)
                }
        }
 
-       if (!p->clk)
-               return 0;
-
        if (on)
-               clk_enable(p->clk);
+               atomic_inc(&p->wakeup_path);
        else
-               clk_disable(p->clk);
+               atomic_dec(&p->wakeup_path);
 
        return 0;
 }
@@ -330,17 +325,14 @@ static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,
 
 struct gpio_rcar_info {
        bool has_both_edge_trigger;
-       bool needs_clk;
 };
 
 static const struct gpio_rcar_info gpio_rcar_info_gen1 = {
        .has_both_edge_trigger = false,
-       .needs_clk = false,
 };
 
 static const struct gpio_rcar_info gpio_rcar_info_gen2 = {
        .has_both_edge_trigger = true,
-       .needs_clk = true,
 };
 
 static const struct of_device_id gpio_rcar_of_table[] = {
@@ -403,7 +395,6 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins)
        ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args);
        *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;
        p->has_both_edge_trigger = info->has_both_edge_trigger;
-       p->needs_clk = info->needs_clk;
 
        if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {
                dev_warn(&p->pdev->dev,
@@ -440,16 +431,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, p);
 
-       p->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(p->clk)) {
-               if (p->needs_clk) {
-                       dev_err(dev, "unable to get clock\n");
-                       ret = PTR_ERR(p->clk);
-                       goto err0;
-               }
-               p->clk = NULL;
-       }
-
        pm_runtime_enable(dev);
 
        irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -531,11 +512,24 @@ static int gpio_rcar_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused gpio_rcar_suspend(struct device *dev)
+{
+       struct gpio_rcar_priv *p = dev_get_drvdata(dev);
+
+       if (atomic_read(&p->wakeup_path))
+               device_set_wakeup_path(dev);
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(gpio_rcar_pm_ops, gpio_rcar_suspend, NULL);
+
 static struct platform_driver gpio_rcar_device_driver = {
        .probe          = gpio_rcar_probe,
        .remove         = gpio_rcar_remove,
        .driver         = {
                .name   = "gpio_rcar",
+               .pm     = &gpio_rcar_pm_ops,
                .of_match_table = of_match_ptr(gpio_rcar_of_table),
        }
 };
index 564bb7a31da43b4e924daf7501c36ec9a4eb8fc2..84e5a9df234433b430fc950a04d80dc9cd43bad8 100644 (file)
@@ -241,6 +241,19 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 
                desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
                                                &of_flags);
+               /*
+                * -EPROBE_DEFER in our case means that we found a
+                * valid GPIO property, but no controller has been
+                * registered so far.
+                *
+                * This means we don't need to look any further for
+                * alternate name conventions, and we should really
+                * preserve the return code for our user to be able to
+                * retry probing later.
+                */
+               if (IS_ERR(desc) && PTR_ERR(desc) == -EPROBE_DEFER)
+                       return desc;
+
                if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
                        break;
        }
@@ -250,7 +263,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
                desc = of_find_spi_gpio(dev, con_id, &of_flags);
 
        /* Special handling for regulator GPIOs if used */
-       if (IS_ERR(desc))
+       if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
                desc = of_find_regulator_gpio(dev, con_id, &of_flags);
 
        if (IS_ERR(desc))
index d5a2eefd6c3e9c634597dba673a6ee25a60c830d..74edba18b1596504ab76a45e71146dc7084e6c13 100644 (file)
@@ -1156,7 +1156,7 @@ static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p,
 /*
  * Writeback
  */
-#define AMDGPU_MAX_WB 512      /* Reserve at most 512 WB slots for amdgpu-owned rings. */
+#define AMDGPU_MAX_WB 128      /* Reserve at most 128 WB slots for amdgpu-owned rings. */
 
 struct amdgpu_wb {
        struct amdgpu_bo        *wb_obj;
index 57afad79f55d086b673cd6c61c688d532620a033..8fa850a070e0fe8ea7a67823008ff7e543d8d1dc 100644 (file)
@@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
        size_t size;
        u32 retry = 3;
 
+       if (amdgpu_acpi_pcie_notify_device_ready(adev))
+               return -EINVAL;
+
        /* Get the device handle */
        handle = ACPI_HANDLE(&adev->pdev->dev);
        if (!handle)
index e2c3c5ec42d1557d58474441782bcfd788972a80..c53095b3b0fb9754bd248113eee2877130c9e066 100644 (file)
@@ -568,6 +568,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
        /* HG _PR3 doesn't seem to work on this A+A weston board */
        { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
+       { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0, 0, 0, 0, 0 },
 };
 
index 8ca3783f2debefbc32f1ad3d6bc475cfbc16b986..7a073ac5f9c61c1653414eb6e60b95f263f505d4 100644 (file)
@@ -69,25 +69,18 @@ void amdgpu_connector_hotplug(struct drm_connector *connector)
                /* don't do anything if sink is not display port, i.e.,
                 * passive dp->(dvi|hdmi) adaptor
                 */
-               if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
-                       int saved_dpms = connector->dpms;
-                       /* Only turn off the display if it's physically disconnected */
-                       if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {
-                               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
-                       } else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
-                               /* Don't try to start link training before we
-                                * have the dpcd */
-                               if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
-                                       return;
-
-                               /* set it to OFF so that drm_helper_connector_dpms()
-                                * won't return immediately since the current state
-                                * is ON at this point.
-                                */
-                               connector->dpms = DRM_MODE_DPMS_OFF;
-                               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
-                       }
-                       connector->dpms = saved_dpms;
+               if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
+                   amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd) &&
+                   amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
+                       /* Don't start link training before we have the DPCD */
+                       if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
+                               return;
+
+                       /* Turn the connector off and back on immediately, which
+                        * will trigger link training
+                        */
+                       drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+                       drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
                }
        }
 }
@@ -736,9 +729,11 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
        enum drm_connector_status ret = connector_status_disconnected;
        int r;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        if (encoder) {
                struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
@@ -757,8 +752,12 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
        /* check acpi lid status ??? */
 
        amdgpu_connector_update_scratch_regs(connector, ret);
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
+
        return ret;
 }
 
@@ -868,9 +867,11 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
        enum drm_connector_status ret = connector_status_disconnected;
        int r;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        encoder = amdgpu_connector_best_single_encoder(connector);
        if (!encoder)
@@ -924,8 +925,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
        amdgpu_connector_update_scratch_regs(connector, ret);
 
 out:
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return ret;
 }
@@ -988,9 +991,11 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
        enum drm_connector_status ret = connector_status_disconnected;
        bool dret = false, broken_edid = false;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
                ret = connector->status;
@@ -1115,8 +1120,10 @@ out:
        amdgpu_connector_update_scratch_regs(connector, ret);
 
 exit:
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return ret;
 }
@@ -1359,9 +1366,11 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
        struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
        int r;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
                ret = connector->status;
@@ -1429,8 +1438,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
 
        amdgpu_connector_update_scratch_regs(connector, ret);
 out:
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return ret;
 }
index 00a50cc5ec9a31a77b7476020e5f47089c83c5de..66cb10cdc7c3e4410eb2b130b8b4d02c1732cdd6 100644 (file)
@@ -492,7 +492,7 @@ static int amdgpu_device_wb_init(struct amdgpu_device *adev)
                memset(&adev->wb.used, 0, sizeof(adev->wb.used));
 
                /* clear wb memory */
-               memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t));
+               memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t) * 8);
        }
 
        return 0;
@@ -530,8 +530,9 @@ int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
  */
 void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
 {
+       wb >>= 3;
        if (wb < adev->wb.num_wb)
-               __clear_bit(wb >> 3, adev->wb.used);
+               __clear_bit(wb, adev->wb.used);
 }
 
 /**
@@ -1455,11 +1456,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
                if (!adev->ip_blocks[i].status.hw)
                        continue;
-               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
-                       amdgpu_free_static_csa(adev);
-                       amdgpu_device_wb_fini(adev);
-                       amdgpu_device_vram_scratch_fini(adev);
-               }
 
                if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
                        adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) {
@@ -1486,6 +1482,13 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
                if (!adev->ip_blocks[i].status.sw)
                        continue;
+
+               if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
+                       amdgpu_free_static_csa(adev);
+                       amdgpu_device_wb_fini(adev);
+                       amdgpu_device_vram_scratch_fini(adev);
+               }
+
                r = adev->ip_blocks[i].version->funcs->sw_fini((void *)adev);
                /* XXX handle errors */
                if (r) {
@@ -2060,9 +2063,12 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
 
        DRM_INFO("amdgpu: finishing device.\n");
        adev->shutdown = true;
-       if (adev->mode_info.mode_config_initialized)
-               drm_crtc_force_disable_all(adev->ddev);
-
+       if (adev->mode_info.mode_config_initialized){
+               if (!amdgpu_device_has_dc_support(adev))
+                       drm_crtc_force_disable_all(adev->ddev);
+               else
+                       drm_atomic_helper_shutdown(adev->ddev);
+       }
        amdgpu_ib_pool_fini(adev);
        amdgpu_fence_driver_fini(adev);
        amdgpu_fbdev_fini(adev);
@@ -2284,14 +2290,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
                                drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
                        }
                        drm_modeset_unlock_all(dev);
-               } else {
-                       /*
-                        * There is no equivalent atomic helper to turn on
-                        * display, so we defined our own function for this,
-                        * once suspend resume is supported by the atomic
-                        * framework this will be reworked
-                        */
-                       amdgpu_dm_display_resume(adev);
                }
        }
 
@@ -2726,7 +2724,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
        if (amdgpu_device_has_dc_support(adev)) {
                if (drm_atomic_helper_resume(adev->ddev, state))
                        dev_info(adev->dev, "drm resume failed:%d\n", r);
-               amdgpu_dm_display_resume(adev);
        } else {
                drm_helper_resume_force_mode(adev->ddev);
        }
index e48b4ec88c8c72b84599d8f85b38836c92c26523..ca6c931dabfab9c3248dc5a0460b8bdd15f1011b 100644 (file)
@@ -36,8 +36,6 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj)
        struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
 
        if (robj) {
-               if (robj->gem_base.import_attach)
-                       drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
                amdgpu_mn_unregister(robj);
                amdgpu_bo_unref(&robj);
        }
index e14ab34d8262418084abdafe4015ad5ddee5c0a7..7c2be32c5aea6fd55a5747fd22d80e913d356c1c 100644 (file)
@@ -75,7 +75,7 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,
 static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
 {
        struct amdgpu_gtt_mgr *mgr = man->priv;
-
+       spin_lock(&mgr->lock);
        drm_mm_takedown(&mgr->mm);
        spin_unlock(&mgr->lock);
        kfree(mgr);
index 56bcd59c3399a0a912ea1fa8f869c105b8827327..36483e0d3c9729e555163e9f9a0b1cfe7dc319a8 100644 (file)
@@ -257,7 +257,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
        r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq);
        if (r) {
                adev->irq.installed = false;
-               flush_work(&adev->hotplug_work);
+               if (!amdgpu_device_has_dc_support(adev))
+                       flush_work(&adev->hotplug_work);
                cancel_work_sync(&adev->reset_work);
                return r;
        }
@@ -282,7 +283,8 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
                adev->irq.installed = false;
                if (adev->irq.msi_enabled)
                        pci_disable_msi(adev->pdev);
-               flush_work(&adev->hotplug_work);
+               if (!amdgpu_device_has_dc_support(adev))
+                       flush_work(&adev->hotplug_work);
                cancel_work_sync(&adev->reset_work);
        }
 
index 54f06c959340923c36ca469dd558df968e5688d0..2264c5c97009333aa74c6a64ffdfd6d2d69bd4d0 100644 (file)
@@ -352,6 +352,7 @@ struct amdgpu_mode_info {
        u16 firmware_flags;
        /* pointer to backlight encoder */
        struct amdgpu_encoder *bl_encoder;
+       u8 bl_level; /* saved backlight level */
        struct amdgpu_audio     audio; /* audio stuff */
        int                     num_crtc; /* number of crtcs */
        int                     num_hpd; /* number of hpd pins */
index 5c4c3e0d527be64386dcab0951727642f64d73db..1220322c168092951aa424e79c83976d3b17e1c4 100644 (file)
@@ -56,6 +56,8 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
 
        amdgpu_bo_kunmap(bo);
 
+       if (bo->gem_base.import_attach)
+               drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg);
        drm_gem_object_release(&bo->gem_base);
        amdgpu_bo_unref(&bo->parent);
        if (!list_empty(&bo->shadow_list)) {
index 13044e66dcaf4e6ab0b79fab23aef8db987170db..561d3312af3280a56bccaee8c04dc7eab9017710 100644 (file)
@@ -481,7 +481,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
        result = 0;
 
        if (*pos < 12) {
-               early[0] = amdgpu_ring_get_rptr(ring);
+               early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask;
                early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask;
                early[2] = ring->wptr & ring->buf_mask;
                for (i = *pos / 4; i < 3 && size; i++) {
index b2eae86bf906abe6ed0bd7e89f67f2d9acbfa809..5c26a8e806b93dfe4a0aced5838f20b0fa234c80 100644 (file)
@@ -299,12 +299,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
 
        cancel_delayed_work_sync(&adev->uvd.idle_work);
 
-       for (i = 0; i < adev->uvd.max_handles; ++i)
-               if (atomic_read(&adev->uvd.handles[i]))
-                       break;
+       /* only valid for physical mode */
+       if (adev->asic_type < CHIP_POLARIS10) {
+               for (i = 0; i < adev->uvd.max_handles; ++i)
+                       if (atomic_read(&adev->uvd.handles[i]))
+                               break;
 
-       if (i == AMDGPU_MAX_UVD_HANDLES)
-               return 0;
+               if (i == adev->uvd.max_handles)
+                       return 0;
+       }
 
        size = amdgpu_bo_size(adev->uvd.vcpu_bo);
        ptr = adev->uvd.cpu_addr;
index 2af26d2da12779f8bfb38460ddaf67f03ccf41e3..d702fb8e342753f19f308c398bd2b0567d252ba2 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/backlight.h>
 #include "bif/bif_4_1_d.h"
 
-static u8
+u8
 amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev)
 {
        u8 backlight_level;
@@ -48,7 +48,7 @@ amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev)
        return backlight_level;
 }
 
-static void
+void
 amdgpu_atombios_encoder_set_backlight_level_to_reg(struct amdgpu_device *adev,
                                            u8 backlight_level)
 {
index 2bdec40515ce51e846c15dd625d89de649a4db8f..f77cbdef679e989281027242ff11328105d08bb1 100644 (file)
 #ifndef __ATOMBIOS_ENCODER_H__
 #define __ATOMBIOS_ENCODER_H__
 
+u8
+amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev);
+void
+amdgpu_atombios_encoder_set_backlight_level_to_reg(struct amdgpu_device *adev,
+                                                  u8 backlight_level);
 u8
 amdgpu_atombios_encoder_get_backlight_level(struct amdgpu_encoder *amdgpu_encoder);
 void
index f34bc68aadfb119380e5f6ff1a279a996d4f453a..022f303463fc83920fca4962101a343c1b557238 100644 (file)
@@ -2921,6 +2921,11 @@ static int dce_v10_0_hw_fini(void *handle)
 
 static int dce_v10_0_suspend(void *handle)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       adev->mode_info.bl_level =
+               amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
+
        return dce_v10_0_hw_fini(handle);
 }
 
@@ -2929,6 +2934,9 @@ static int dce_v10_0_resume(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        int ret;
 
+       amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
+                                                          adev->mode_info.bl_level);
+
        ret = dce_v10_0_hw_init(handle);
 
        /* turn on the BL */
index 26378bd6aba45a86e18e1d7ac122182a7730a811..800a9f36ab4faddbd5836de2c486e6550eff5a68 100644 (file)
@@ -3047,6 +3047,11 @@ static int dce_v11_0_hw_fini(void *handle)
 
 static int dce_v11_0_suspend(void *handle)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       adev->mode_info.bl_level =
+               amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
+
        return dce_v11_0_hw_fini(handle);
 }
 
@@ -3055,6 +3060,9 @@ static int dce_v11_0_resume(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        int ret;
 
+       amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
+                                                          adev->mode_info.bl_level);
+
        ret = dce_v11_0_hw_init(handle);
 
        /* turn on the BL */
index bd2c4f727df661866733d3b21254769220f7101c..b8368f69ce1fbbe17230ef7e7cd5b7e0d35e9d85 100644 (file)
@@ -2787,6 +2787,11 @@ static int dce_v6_0_hw_fini(void *handle)
 
 static int dce_v6_0_suspend(void *handle)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       adev->mode_info.bl_level =
+               amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
+
        return dce_v6_0_hw_fini(handle);
 }
 
@@ -2795,6 +2800,9 @@ static int dce_v6_0_resume(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        int ret;
 
+       amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
+                                                          adev->mode_info.bl_level);
+
        ret = dce_v6_0_hw_init(handle);
 
        /* turn on the BL */
@@ -3093,7 +3101,7 @@ static int dce_v6_0_hpd_irq(struct amdgpu_device *adev,
                tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK;
                WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);
                schedule_work(&adev->hotplug_work);
-               DRM_INFO("IH: HPD%d\n", hpd + 1);
+               DRM_DEBUG("IH: HPD%d\n", hpd + 1);
        }
 
        return 0;
index c008dc03068707de0bd2620679f2f74357d474b1..012e0a9ae0ffcd5e7dda1ce1925ae93d4e4e4b6f 100644 (file)
@@ -2819,6 +2819,11 @@ static int dce_v8_0_hw_fini(void *handle)
 
 static int dce_v8_0_suspend(void *handle)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+       adev->mode_info.bl_level =
+               amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);
+
        return dce_v8_0_hw_fini(handle);
 }
 
@@ -2827,6 +2832,9 @@ static int dce_v8_0_resume(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        int ret;
 
+       amdgpu_atombios_encoder_set_backlight_level_to_reg(adev,
+                                                          adev->mode_info.bl_level);
+
        ret = dce_v8_0_hw_init(handle);
 
        /* turn on the BL */
index a066c5eda135a782d8e01f730cfc10172210c7c9..a4309698e76c898fc038b362ed1d124a8e3d6806 100644 (file)
@@ -4384,34 +4384,8 @@ static void gfx_v7_0_gpu_early_init(struct amdgpu_device *adev)
        case CHIP_KAVERI:
                adev->gfx.config.max_shader_engines = 1;
                adev->gfx.config.max_tile_pipes = 4;
-               if ((adev->pdev->device == 0x1304) ||
-                   (adev->pdev->device == 0x1305) ||
-                   (adev->pdev->device == 0x130C) ||
-                   (adev->pdev->device == 0x130F) ||
-                   (adev->pdev->device == 0x1310) ||
-                   (adev->pdev->device == 0x1311) ||
-                   (adev->pdev->device == 0x131C)) {
-                       adev->gfx.config.max_cu_per_sh = 8;
-                       adev->gfx.config.max_backends_per_se = 2;
-               } else if ((adev->pdev->device == 0x1309) ||
-                          (adev->pdev->device == 0x130A) ||
-                          (adev->pdev->device == 0x130D) ||
-                          (adev->pdev->device == 0x1313) ||
-                          (adev->pdev->device == 0x131D)) {
-                       adev->gfx.config.max_cu_per_sh = 6;
-                       adev->gfx.config.max_backends_per_se = 2;
-               } else if ((adev->pdev->device == 0x1306) ||
-                          (adev->pdev->device == 0x1307) ||
-                          (adev->pdev->device == 0x130B) ||
-                          (adev->pdev->device == 0x130E) ||
-                          (adev->pdev->device == 0x1315) ||
-                          (adev->pdev->device == 0x131B)) {
-                       adev->gfx.config.max_cu_per_sh = 4;
-                       adev->gfx.config.max_backends_per_se = 1;
-               } else {
-                       adev->gfx.config.max_cu_per_sh = 3;
-                       adev->gfx.config.max_backends_per_se = 1;
-               }
+               adev->gfx.config.max_cu_per_sh = 8;
+               adev->gfx.config.max_backends_per_se = 2;
                adev->gfx.config.max_sh_per_se = 1;
                adev->gfx.config.max_texture_channel_caches = 4;
                adev->gfx.config.max_gprs = 256;
index 2719937e09d6bf00a4f78c47cd970ce5f5a51000..3b7e7af09ead1b8ea7ec8168b1252e71baaccb57 100644 (file)
@@ -634,7 +634,7 @@ static int gmc_v9_0_late_init(void *handle)
        for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i)
                BUG_ON(vm_inv_eng[i] > 16);
 
-       if (adev->asic_type == CHIP_VEGA10) {
+       if (adev->asic_type == CHIP_VEGA10 && !amdgpu_sriov_vf(adev)) {
                r = gmc_v9_0_ecc_available(adev);
                if (r == 1) {
                        DRM_INFO("ECC is active.\n");
@@ -682,7 +682,10 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
        adev->mc.vram_width = amdgpu_atomfirmware_get_vram_width(adev);
        if (!adev->mc.vram_width) {
                /* hbm memory channel size */
-               chansize = 128;
+               if (adev->flags & AMD_IS_APU)
+                       chansize = 64;
+               else
+                       chansize = 128;
 
                tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0);
                tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
index e92fb372bc99738dad957334ba40d3a138c57636..91cf95a8c39c832d50b378bf7464a99f19c839c8 100644 (file)
@@ -238,31 +238,27 @@ static uint64_t sdma_v4_0_ring_get_rptr(struct amdgpu_ring *ring)
 static uint64_t sdma_v4_0_ring_get_wptr(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
-       u64 *wptr = NULL;
-       uint64_t local_wptr = 0;
+       u64 wptr;
 
        if (ring->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
-               wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]);
-               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr);
-               *wptr = (*wptr) >> 2;
-               DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr);
+               wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs]));
+               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr);
        } else {
                u32 lowbit, highbit;
                int me = (ring == &adev->sdma.instance[0].ring) ? 0 : 1;
 
-               wptr = &local_wptr;
                lowbit = RREG32(sdma_v4_0_get_reg_offset(adev, me, mmSDMA0_GFX_RB_WPTR)) >> 2;
                highbit = RREG32(sdma_v4_0_get_reg_offset(adev, me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2;
 
                DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n",
                                me, highbit, lowbit);
-               *wptr = highbit;
-               *wptr = (*wptr) << 32;
-               *wptr |= lowbit;
+               wptr = highbit;
+               wptr = wptr << 32;
+               wptr |= lowbit;
        }
 
-       return *wptr;
+       return wptr >> 2;
 }
 
 /**
index 543101d5a5edd053c83beea6de7db5adbf9844eb..2095173aaabf864345c0643170a8975ef08866b4 100644 (file)
@@ -31,6 +31,7 @@
 #include "amdgpu_uvd.h"
 #include "amdgpu_vce.h"
 #include "atom.h"
+#include "amd_pcie.h"
 #include "amdgpu_powerplay.h"
 #include "sid.h"
 #include "si_ih.h"
@@ -1461,8 +1462,8 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
 {
        struct pci_dev *root = adev->pdev->bus->self;
        int bridge_pos, gpu_pos;
-       u32 speed_cntl, mask, current_data_rate;
-       int ret, i;
+       u32 speed_cntl, current_data_rate;
+       int i;
        u16 tmp16;
 
        if (pci_is_root_bus(adev->pdev->bus))
@@ -1474,23 +1475,20 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
        if (adev->flags & AMD_IS_APU)
                return;
 
-       ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-       if (ret != 0)
-               return;
-
-       if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
+       if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+                                       CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
                return;
 
        speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
        current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
                LC_CURRENT_DATA_RATE_SHIFT;
-       if (mask & DRM_PCIE_SPEED_80) {
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
                if (current_data_rate == 2) {
                        DRM_INFO("PCIE gen 3 link speeds already enabled\n");
                        return;
                }
                DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
-       } else if (mask & DRM_PCIE_SPEED_50) {
+       } else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) {
                if (current_data_rate == 1) {
                        DRM_INFO("PCIE gen 2 link speeds already enabled\n");
                        return;
@@ -1506,7 +1504,7 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
        if (!gpu_pos)
                return;
 
-       if (mask & DRM_PCIE_SPEED_80) {
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
                if (current_data_rate != 2) {
                        u16 bridge_cfg, gpu_cfg;
                        u16 bridge_cfg2, gpu_cfg2;
@@ -1589,9 +1587,9 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev)
 
        pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
        tmp16 &= ~0xf;
-       if (mask & DRM_PCIE_SPEED_80)
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
                tmp16 |= 3;
-       else if (mask & DRM_PCIE_SPEED_50)
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
                tmp16 |= 2;
        else
                tmp16 |= 1;
index ce675a7f179a6a0f3b9f7b254589694541aea3cd..22f0b7ff3ac9731d05643b9c6af9ce7ef2ee3208 100644 (file)
@@ -26,6 +26,7 @@
 #include "amdgpu_pm.h"
 #include "amdgpu_dpm.h"
 #include "amdgpu_atombios.h"
+#include "amd_pcie.h"
 #include "sid.h"
 #include "r600_dpm.h"
 #include "si_dpm.h"
@@ -3331,29 +3332,6 @@ static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev,
        }
 }
 
-static enum amdgpu_pcie_gen r600_get_pcie_gen_support(struct amdgpu_device *adev,
-                                              u32 sys_mask,
-                                              enum amdgpu_pcie_gen asic_gen,
-                                              enum amdgpu_pcie_gen default_gen)
-{
-       switch (asic_gen) {
-       case AMDGPU_PCIE_GEN1:
-               return AMDGPU_PCIE_GEN1;
-       case AMDGPU_PCIE_GEN2:
-               return AMDGPU_PCIE_GEN2;
-       case AMDGPU_PCIE_GEN3:
-               return AMDGPU_PCIE_GEN3;
-       default:
-               if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == AMDGPU_PCIE_GEN3))
-                       return AMDGPU_PCIE_GEN3;
-               else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == AMDGPU_PCIE_GEN2))
-                       return AMDGPU_PCIE_GEN2;
-               else
-                       return AMDGPU_PCIE_GEN1;
-       }
-       return AMDGPU_PCIE_GEN1;
-}
-
 static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
                            u32 *p, u32 *u)
 {
@@ -5028,10 +5006,11 @@ static int si_populate_smc_acpi_state(struct amdgpu_device *adev,
                                                              table->ACPIState.levels[0].vddc.index,
                                                              &table->ACPIState.levels[0].std_vddc);
                }
-               table->ACPIState.levels[0].gen2PCIE = (u8)r600_get_pcie_gen_support(adev,
-                                                                                   si_pi->sys_pcie_mask,
-                                                                                   si_pi->boot_pcie_gen,
-                                                                                   AMDGPU_PCIE_GEN1);
+               table->ACPIState.levels[0].gen2PCIE =
+                       (u8)amdgpu_get_pcie_gen_support(adev,
+                                                       si_pi->sys_pcie_mask,
+                                                       si_pi->boot_pcie_gen,
+                                                       AMDGPU_PCIE_GEN1);
 
                if (si_pi->vddc_phase_shed_control)
                        si_populate_phase_shedding_value(adev,
@@ -7168,10 +7147,10 @@ static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
        pl->vddc = le16_to_cpu(clock_info->si.usVDDC);
        pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);
        pl->flags = le32_to_cpu(clock_info->si.ulFlags);
-       pl->pcie_gen = r600_get_pcie_gen_support(adev,
-                                                si_pi->sys_pcie_mask,
-                                                si_pi->boot_pcie_gen,
-                                                clock_info->si.ucPCIEGen);
+       pl->pcie_gen = amdgpu_get_pcie_gen_support(adev,
+                                                  si_pi->sys_pcie_mask,
+                                                  si_pi->boot_pcie_gen,
+                                                  clock_info->si.ucPCIEGen);
 
        /* patch up vddc if necessary */
        ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc,
@@ -7326,7 +7305,6 @@ static int si_dpm_init(struct amdgpu_device *adev)
        struct si_power_info *si_pi;
        struct atom_clock_dividers dividers;
        int ret;
-       u32 mask;
 
        si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);
        if (si_pi == NULL)
@@ -7336,11 +7314,9 @@ static int si_dpm_init(struct amdgpu_device *adev)
        eg_pi = &ni_pi->eg;
        pi = &eg_pi->rv7xx;
 
-       ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-       if (ret)
-               si_pi->sys_pcie_mask = 0;
-       else
-               si_pi->sys_pcie_mask = mask;
+       si_pi->sys_pcie_mask =
+               (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK) >>
+               CAIL_PCIE_LINK_SPEED_SUPPORT_SHIFT;
        si_pi->force_pcie_gen = AMDGPU_PCIE_GEN_INVALID;
        si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev);
 
index b2bfedaf57f197b38e98dce034d12c1d3359ca64..9bab4842cd4411f8e282c083f526937b2979f6a0 100644 (file)
@@ -1618,7 +1618,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = {
        .set_wptr = uvd_v6_0_enc_ring_set_wptr,
        .emit_frame_size =
                4 + /* uvd_v6_0_enc_ring_emit_pipeline_sync */
-               6 + /* uvd_v6_0_enc_ring_emit_vm_flush */
+               5 + /* uvd_v6_0_enc_ring_emit_vm_flush */
                5 + 5 + /* uvd_v6_0_enc_ring_emit_fence x2 vm fence */
                1, /* uvd_v6_0_enc_ring_insert_end */
        .emit_ib_size = 5, /* uvd_v6_0_enc_ring_emit_ib */
index 1ce4c98385e3a17385a00b076a699cd64462d4dd..63c67346d316ac26a53a6f52e34feb8857dc9550 100644 (file)
@@ -629,11 +629,13 @@ static int dm_resume(void *handle)
 {
        struct amdgpu_device *adev = handle;
        struct amdgpu_display_manager *dm = &adev->dm;
+       int ret = 0;
 
        /* power on hardware */
        dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
 
-       return 0;
+       ret = amdgpu_dm_display_resume(adev);
+       return ret;
 }
 
 int amdgpu_dm_display_resume(struct amdgpu_device *adev)
@@ -1035,6 +1037,10 @@ static void handle_hpd_rx_irq(void *param)
                        !is_mst_root_connector) {
                /* Downstream Port status changed. */
                if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
+
+                       if (aconnector->fake_enable)
+                               aconnector->fake_enable = false;
+
                        amdgpu_dm_update_connector_after_detect(aconnector);
 
 
@@ -2010,30 +2016,32 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode,
        dst.width = stream->timing.h_addressable;
        dst.height = stream->timing.v_addressable;
 
-       rmx_type = dm_state->scaling;
-       if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) {
-               if (src.width * dst.height <
-                               src.height * dst.width) {
-                       /* height needs less upscaling/more downscaling */
-                       dst.width = src.width *
-                                       dst.height / src.height;
-               } else {
-                       /* width needs less upscaling/more downscaling */
-                       dst.height = src.height *
-                                       dst.width / src.width;
+       if (dm_state) {
+               rmx_type = dm_state->scaling;
+               if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) {
+                       if (src.width * dst.height <
+                                       src.height * dst.width) {
+                               /* height needs less upscaling/more downscaling */
+                               dst.width = src.width *
+                                               dst.height / src.height;
+                       } else {
+                               /* width needs less upscaling/more downscaling */
+                               dst.height = src.height *
+                                               dst.width / src.width;
+                       }
+               } else if (rmx_type == RMX_CENTER) {
+                       dst = src;
                }
-       } else if (rmx_type == RMX_CENTER) {
-               dst = src;
-       }
 
-       dst.x = (stream->timing.h_addressable - dst.width) / 2;
-       dst.y = (stream->timing.v_addressable - dst.height) / 2;
+               dst.x = (stream->timing.h_addressable - dst.width) / 2;
+               dst.y = (stream->timing.v_addressable - dst.height) / 2;
 
-       if (dm_state->underscan_enable) {
-               dst.x += dm_state->underscan_hborder / 2;
-               dst.y += dm_state->underscan_vborder / 2;
-               dst.width -= dm_state->underscan_hborder;
-               dst.height -= dm_state->underscan_vborder;
+               if (dm_state->underscan_enable) {
+                       dst.x += dm_state->underscan_hborder / 2;
+                       dst.y += dm_state->underscan_vborder / 2;
+                       dst.width -= dm_state->underscan_hborder;
+                       dst.height -= dm_state->underscan_vborder;
+               }
        }
 
        stream->src = src;
@@ -2358,12 +2366,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 
        if (aconnector == NULL) {
                DRM_ERROR("aconnector is NULL!\n");
-               goto drm_connector_null;
-       }
-
-       if (dm_state == NULL) {
-               DRM_ERROR("dm_state is NULL!\n");
-               goto dm_state_null;
+               return stream;
        }
 
        drm_connector = &aconnector->base;
@@ -2375,18 +2378,18 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
                 */
                if (aconnector->mst_port) {
                        dm_dp_mst_dc_sink_create(drm_connector);
-                       goto mst_dc_sink_create_done;
+                       return stream;
                }
 
                if (create_fake_sink(aconnector))
-                       goto stream_create_fail;
+                       return stream;
        }
 
        stream = dc_create_stream_for_sink(aconnector->dc_sink);
 
        if (stream == NULL) {
                DRM_ERROR("Failed to create stream for sink!\n");
-               goto stream_create_fail;
+               return stream;
        }
 
        list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
@@ -2412,9 +2415,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
        } else {
                decide_crtc_timing_for_drm_display_mode(
                                &mode, preferred_mode,
-                               dm_state->scaling != RMX_OFF);
+                               dm_state ? (dm_state->scaling != RMX_OFF) : false);
        }
 
+       if (!dm_state)
+               drm_mode_set_crtcinfo(&mode, 0);
+
        fill_stream_properties_from_drm_display_mode(stream,
                        &mode, &aconnector->base);
        update_stream_scaling_settings(&mode, dm_state, stream);
@@ -2424,10 +2430,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
                drm_connector,
                aconnector->dc_sink);
 
-stream_create_fail:
-dm_state_null:
-drm_connector_null:
-mst_dc_sink_create_done:
+       update_stream_signal(stream);
+
        return stream;
 }
 
@@ -2495,6 +2499,27 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
        return &state->base;
 }
 
+
+static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
+{
+       enum dc_irq_source irq_source;
+       struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+       struct amdgpu_device *adev = crtc->dev->dev_private;
+
+       irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
+       return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY;
+}
+
+static int dm_enable_vblank(struct drm_crtc *crtc)
+{
+       return dm_set_vblank(crtc, true);
+}
+
+static void dm_disable_vblank(struct drm_crtc *crtc)
+{
+       dm_set_vblank(crtc, false);
+}
+
 /* Implemented only the options currently availible for the driver */
 static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
        .reset = dm_crtc_reset_state,
@@ -2504,6 +2529,8 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
        .page_flip = drm_atomic_helper_page_flip,
        .atomic_duplicate_state = dm_crtc_duplicate_state,
        .atomic_destroy_state = dm_crtc_destroy_state,
+       .enable_vblank = dm_enable_vblank,
+       .disable_vblank = dm_disable_vblank,
 };
 
 static enum drm_connector_status
@@ -2798,7 +2825,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
                goto fail;
        }
 
-       stream = dc_create_stream_for_sink(dc_sink);
+       stream = create_stream_for_sink(aconnector, mode, NULL);
        if (stream == NULL) {
                DRM_ERROR("Failed to create stream for sink!\n");
                goto fail;
@@ -3058,6 +3085,9 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
        if (!dm_plane_state->dc_state)
                return 0;
 
+       if (!fill_rects_from_plane_state(state, dm_plane_state->dc_state))
+               return -EINVAL;
+
        if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
                return 0;
 
@@ -3104,8 +3134,6 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 
        switch (aplane->base.type) {
        case DRM_PLANE_TYPE_PRIMARY:
-               aplane->base.format_default = true;
-
                res = drm_universal_plane_init(
                                dm->adev->ddev,
                                &aplane->base,
@@ -4630,8 +4658,6 @@ static int dm_update_planes_state(struct dc *dc,
        bool pflip_needed  = !state->allow_modeset;
        int ret = 0;
 
-       if (pflip_needed)
-               return ret;
 
        /* Add new planes */
        for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
@@ -4646,6 +4672,8 @@ static int dm_update_planes_state(struct dc *dc,
 
                /* Remove any changed/removed planes */
                if (!enable) {
+                       if (pflip_needed)
+                               continue;
 
                        if (!old_plane_crtc)
                                continue;
@@ -4677,6 +4705,7 @@ static int dm_update_planes_state(struct dc *dc,
                        *lock_and_validation_needed = true;
 
                } else { /* Add new planes */
+                       struct dc_plane_state *dc_new_plane_state;
 
                        if (drm_atomic_plane_disabling(plane->state, new_plane_state))
                                continue;
@@ -4690,38 +4719,50 @@ static int dm_update_planes_state(struct dc *dc,
                        if (!dm_new_crtc_state->stream)
                                continue;
 
+                       if (pflip_needed)
+                               continue;
 
                        WARN_ON(dm_new_plane_state->dc_state);
 
-                       dm_new_plane_state->dc_state = dc_create_plane_state(dc);
-
-                       DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n",
-                                       plane->base.id, new_plane_crtc->base.id);
-
-                       if (!dm_new_plane_state->dc_state) {
+                       dc_new_plane_state = dc_create_plane_state(dc);
+                       if (!dc_new_plane_state) {
                                ret = -EINVAL;
                                return ret;
                        }
 
+                       DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n",
+                                       plane->base.id, new_plane_crtc->base.id);
+
                        ret = fill_plane_attributes(
                                new_plane_crtc->dev->dev_private,
-                               dm_new_plane_state->dc_state,
+                               dc_new_plane_state,
                                new_plane_state,
                                new_crtc_state);
-                       if (ret)
+                       if (ret) {
+                               dc_plane_state_release(dc_new_plane_state);
                                return ret;
+                       }
 
-
+                       /*
+                        * Any atomic check errors that occur after this will
+                        * not need a release. The plane state will be attached
+                        * to the stream, and therefore part of the atomic
+                        * state. It'll be released when the atomic state is
+                        * cleaned.
+                        */
                        if (!dc_add_plane_to_context(
                                        dc,
                                        dm_new_crtc_state->stream,
-                                       dm_new_plane_state->dc_state,
+                                       dc_new_plane_state,
                                        dm_state->context)) {
 
+                               dc_plane_state_release(dc_new_plane_state);
                                ret = -EINVAL;
                                return ret;
                        }
 
+                       dm_new_plane_state->dc_state = dc_new_plane_state;
+
                        /* Tell DC to do a full surface update every time there
                         * is a plane change. Inefficient, but works for now.
                         */
@@ -4735,6 +4776,33 @@ static int dm_update_planes_state(struct dc *dc,
        return ret;
 }
 
+static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state,
+                                         struct drm_crtc *crtc)
+{
+       struct drm_plane *plane;
+       struct drm_crtc_state *crtc_state;
+
+       WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
+
+       drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
+               struct drm_plane_state *plane_state =
+                       drm_atomic_get_plane_state(state, plane);
+
+               if (IS_ERR(plane_state))
+                       return -EDEADLK;
+
+               crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc);
+               if (IS_ERR(crtc_state))
+                       return PTR_ERR(crtc_state);
+
+               if (crtc->primary == plane && crtc_state->active) {
+                       if (!plane_state->fb)
+                               return -EINVAL;
+               }
+       }
+       return 0;
+}
+
 static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                  struct drm_atomic_state *state)
 {
@@ -4758,6 +4826,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                goto fail;
 
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+               ret = dm_atomic_check_plane_state_fb(state, crtc);
+               if (ret)
+                       goto fail;
+
                if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
                    !new_crtc_state->color_mgmt_changed)
                        continue;
index 9bd142f65f9baa9b9881dcde18c6ec9d8e527416..e1acc10e35a2fd6a4215c3d3179ac50b27bda6ce 100644 (file)
@@ -109,7 +109,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
                struct cea_sad *sad = &sads[i];
 
                edid_caps->audio_modes[i].format_code = sad->format;
-               edid_caps->audio_modes[i].channel_count = sad->channels;
+               edid_caps->audio_modes[i].channel_count = sad->channels + 1;
                edid_caps->audio_modes[i].sample_rate = sad->freq;
                edid_caps->audio_modes[i].sample_size = sad->byte2;
        }
index 1874b6cee6afa1dd81aeb0177c605c69c1b68e65..422055080df4a1b59b5fa4c66a12d6b5bd90f5ac 100644 (file)
@@ -683,10 +683,8 @@ static const struct amdgpu_irq_src_funcs dm_hpd_irq_funcs = {
 
 void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev)
 {
-       if (adev->mode_info.num_crtc > 0)
-               adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
-       else
-               adev->crtc_irq.num_types = 0;
+
+       adev->crtc_irq.num_types = adev->mode_info.num_crtc;
        adev->crtc_irq.funcs = &dm_crtc_irq_funcs;
 
        adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
index f3d87f418d2efffd349358fd08b3b52e2a3cca5d..93421dad21bd3fdeba7f7d19946bf4c0005a4921 100644 (file)
@@ -189,6 +189,12 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
                        .link = aconnector->dc_link,
                        .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
 
+       /*
+        * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
+        */
+       if (!aconnector->port || !aconnector->port->aux.ddc.algo)
+               return;
+
        edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
 
        if (!edid) {
index 35e84ed031de08f5edfadbfb71e550291ae8ebef..12868c769606b8de546b193412d5c28052353dd5 100644 (file)
@@ -1358,13 +1358,13 @@ enum dc_irq_source dc_interrupt_to_irq_source(
        return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
 }
 
-void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
+bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
 {
 
        if (dc == NULL)
-               return;
+               return false;
 
-       dal_irq_service_set(dc->res_pool->irqs, src, enable);
+       return dal_irq_service_set(dc->res_pool->irqs, src, enable);
 }
 
 void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
index a3742827157361ac0c3c57733eb845cd34ea4720..be5546181fa84d0dbbf91935878cae6e10129154 100644 (file)
@@ -1749,8 +1749,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
                        link->link_enc,
                        pipe_ctx->clock_source->id,
                        display_color_depth,
-                       pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A,
-                       pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK,
+                       pipe_ctx->stream->signal,
                        stream->phy_pix_clk);
 
        if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
index 61e8c3e02d1696bf08f53bb24cefdc074a74cf10..639421a00ab629eefce3b7333126632f4d2b0848 100644 (file)
@@ -718,7 +718,7 @@ static enum link_training_result perform_channel_equalization_sequence(
        uint32_t retries_ch_eq;
        enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
        union lane_align_status_updated dpcd_lane_status_updated = {{0}};
-       union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};;
+       union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};
 
        hw_tr_pattern = get_supported_tp(link);
 
@@ -1465,7 +1465,7 @@ void decide_link_settings(struct dc_stream_state *stream,
        /* MST doesn't perform link training for now
         * TODO: add MST specific link training routine
         */
-       if (is_mst_supported(link)) {
+       if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
                *link_setting = link->verified_link_cap;
                return;
        }
index 95b8dd0e53c6951a1e28e988fd4cb13dcaf04f0d..4d07ffebfd3112f937d0082b4482df4e4330451d 100644 (file)
@@ -1360,9 +1360,6 @@ bool dc_is_stream_scaling_unchanged(
        return true;
 }
 
-/* Maximum TMDS single link pixel clock 165MHz */
-#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
-
 static void update_stream_engine_usage(
                struct resource_context *res_ctx,
                const struct resource_pool *pool,
index 261811e0c094a81a0a1c0c1c6420f83d4db4a3bc..cd5819789d76aa7b1106dc8991685a17b1e4c6af 100644 (file)
@@ -33,8 +33,7 @@
 /*******************************************************************************
  * Private functions
  ******************************************************************************/
-#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000
-static void update_stream_signal(struct dc_stream_state *stream)
+void update_stream_signal(struct dc_stream_state *stream)
 {
 
        struct dc_sink *dc_sink = stream->sink;
@@ -45,8 +44,9 @@ static void update_stream_signal(struct dc_stream_state *stream)
                stream->signal = dc_sink->sink_signal;
 
        if (dc_is_dvi_signal(stream->signal)) {
-               if (stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST &&
-                       stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
+               if (stream->ctx->dc->caps.dual_link_dvi &&
+                   stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK &&
+                   stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
                        stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK;
                else
                        stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
@@ -193,44 +193,20 @@ bool dc_stream_set_cursor_attributes(
 
        core_dc = stream->ctx->dc;
        res_ctx = &core_dc->current_state->res_ctx;
+       stream->cursor_attributes = *attributes;
 
        for (i = 0; i < MAX_PIPES; i++) {
                struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 
-               if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
+               if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm &&
+                   !pipe_ctx->plane_res.dpp) || !pipe_ctx->plane_res.ipp)
                        continue;
                if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
                        continue;
 
 
-               if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
-                       pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
-                                               pipe_ctx->plane_res.ipp, attributes);
-
-               if (pipe_ctx->plane_res.hubp != NULL &&
-                               pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
-                       pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
-                                       pipe_ctx->plane_res.hubp, attributes);
-
-               if (pipe_ctx->plane_res.mi != NULL &&
-                               pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
-                       pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
-                                       pipe_ctx->plane_res.mi, attributes);
-
-
-               if (pipe_ctx->plane_res.xfm != NULL &&
-                               pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
-                       pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
-                               pipe_ctx->plane_res.xfm, attributes);
-
-               if (pipe_ctx->plane_res.dpp != NULL &&
-                               pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
-                       pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
-                               pipe_ctx->plane_res.dpp, attributes->color_format);
+               core_dc->hwss.set_cursor_attribute(pipe_ctx);
        }
-
-       stream->cursor_attributes = *attributes;
-
        return true;
 }
 
@@ -254,55 +230,21 @@ bool dc_stream_set_cursor_position(
 
        core_dc = stream->ctx->dc;
        res_ctx = &core_dc->current_state->res_ctx;
+       stream->cursor_position = *position;
 
        for (i = 0; i < MAX_PIPES; i++) {
                struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
-               struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
-               struct mem_input *mi = pipe_ctx->plane_res.mi;
-               struct hubp *hubp = pipe_ctx->plane_res.hubp;
-               struct dpp *dpp = pipe_ctx->plane_res.dpp;
-               struct dc_cursor_position pos_cpy = *position;
-               struct dc_cursor_mi_param param = {
-                       .pixel_clk_khz = stream->timing.pix_clk_khz,
-                       .ref_clk_khz = core_dc->res_pool->ref_clock_inKhz,
-                       .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
-                       .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
-                       .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
-               };
 
                if (pipe_ctx->stream != stream ||
                                (!pipe_ctx->plane_res.mi  && !pipe_ctx->plane_res.hubp) ||
                                !pipe_ctx->plane_state ||
-                               (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
-                       continue;
-
-               if (pipe_ctx->plane_state->address.type
-                               == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
-                       pos_cpy.enable = false;
-
-               if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
-                       pos_cpy.enable = false;
-
-
-               if (ipp != NULL && ipp->funcs->ipp_cursor_set_position != NULL)
-                       ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
-
-               if (mi != NULL && mi->funcs->set_cursor_position != NULL)
-                       mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
-
-               if (!hubp)
+                               (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp) ||
+                               !pipe_ctx->plane_res.ipp)
                        continue;
 
-               if (hubp->funcs->set_cursor_position != NULL)
-                       hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
-
-               if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
-                       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
-
+               core_dc->hwss.set_cursor_position(pipe_ctx);
        }
 
-       stream->cursor_position = *position;
-
        return true;
 }
 
index e2e3c9df79ea0f976dbbc6f6bf889169ccce0484..d6d56611604eb417e47d009e1f0119305cb2ab91 100644 (file)
@@ -62,6 +62,7 @@ struct dc_caps {
        bool dcc_const_color;
        bool dynamic_audio;
        bool is_apu;
+       bool dual_link_dvi;
 };
 
 struct dc_dcc_surface_param {
@@ -672,7 +673,7 @@ enum dc_irq_source dc_interrupt_to_irq_source(
                struct dc *dc,
                uint32_t src_id,
                uint32_t ext_id);
-void dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable);
+bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable);
 void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src);
 enum dc_irq_source dc_get_hpd_irq_source_at_index(
                struct dc *dc, uint32_t link_index);
index 01c60f11b2bdeec208f5df9e5cfd2092a614eac5..456e4d29eaddcc4b19f0b28290efdeefd8a2f3e8 100644 (file)
@@ -237,6 +237,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
  */
 struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink);
 
+void update_stream_signal(struct dc_stream_state *stream);
+
 void dc_stream_retain(struct dc_stream_state *dc_stream);
 void dc_stream_release(struct dc_stream_state *dc_stream);
 
index b73db9e784375618f87422f143cf36d00e1ce552..f11f17fe08f98196fe6f105f5bb86860810b1d0b 100644 (file)
        SR(D2VGA_CONTROL), \
        SR(D3VGA_CONTROL), \
        SR(D4VGA_CONTROL), \
+       SR(VGA_TEST_CONTROL), \
        SR(DC_IP_REQUEST_CNTL), \
        BL_REG_LIST()
 
@@ -337,6 +338,7 @@ struct dce_hwseq_registers {
        uint32_t D2VGA_CONTROL;
        uint32_t D3VGA_CONTROL;
        uint32_t D4VGA_CONTROL;
+       uint32_t VGA_TEST_CONTROL;
        /* MMHUB registers. read only. temporary hack */
        uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32;
        uint32_t VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
@@ -493,6 +495,12 @@ struct dce_hwseq_registers {
        HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
        HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
        HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+       HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\
+       HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\
+       HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\
        HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
        HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
 
@@ -583,7 +591,13 @@ struct dce_hwseq_registers {
        type DCFCLK_GATE_DIS; \
        type DCHUBBUB_GLOBAL_TIMER_REFDIV; \
        type DENTIST_DPPCLK_WDIVIDER; \
-       type DENTIST_DISPCLK_WDIVIDER;
+       type DENTIST_DISPCLK_WDIVIDER; \
+       type VGA_TEST_ENABLE; \
+       type VGA_TEST_RENDER_START; \
+       type D1VGA_MODE_ENABLE; \
+       type D2VGA_MODE_ENABLE; \
+       type D3VGA_MODE_ENABLE; \
+       type D4VGA_MODE_ENABLE;
 
 struct dce_hwseq_shift {
        HWSEQ_REG_FIELD_LIST(uint8_t)
index a266e3f5e75fd7ae82a46f7d3e09f900660c72cc..e4741f1a2b01b2f4d31ede97dcc8be7ad71e2b64 100644 (file)
 #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
 
-/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
-#define TMDS_MIN_PIXEL_CLOCK 25000
-/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
-#define TMDS_MAX_PIXEL_CLOCK 165000
-/* For current ASICs pixel clock - 600MHz */
-#define MAX_ENCODER_CLOCK 600000
-
 enum {
        DP_MST_UPDATE_MAX_RETRY = 50
 };
@@ -683,6 +676,7 @@ void dce110_link_encoder_construct(
 {
        struct bp_encoder_cap_info bp_cap_info = {0};
        const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
+       enum bp_result result = BP_RESULT_OK;
 
        enc110->base.funcs = &dce110_lnk_enc_funcs;
        enc110->base.ctx = init_data->ctx;
@@ -757,15 +751,24 @@ void dce110_link_encoder_construct(
                enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
        }
 
+       /* default to one to mirror Windows behavior */
+       enc110->base.features.flags.bits.HDMI_6GB_EN = 1;
+
+       result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios,
+                                               enc110->base.id, &bp_cap_info);
+
        /* Override features with DCE-specific values */
-       if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
-                       enc110->base.ctx->dc_bios, enc110->base.id,
-                       &bp_cap_info)) {
+       if (BP_RESULT_OK == result) {
                enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
                                bp_cap_info.DP_HBR2_EN;
                enc110->base.features.flags.bits.IS_HBR3_CAPABLE =
                                bp_cap_info.DP_HBR3_EN;
                enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
+       } else {
+               dm_logger_write(enc110->base.ctx->logger, LOG_WARNING,
+                               "%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
+                               __func__,
+                               result);
        }
 }
 
@@ -904,8 +907,7 @@ void dce110_link_encoder_enable_tmds_output(
        struct link_encoder *enc,
        enum clock_source_id clock_source,
        enum dc_color_depth color_depth,
-       bool hdmi,
-       bool dual_link,
+       enum signal_type signal,
        uint32_t pixel_clock)
 {
        struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
@@ -919,16 +921,12 @@ void dce110_link_encoder_enable_tmds_output(
        cntl.engine_id = enc->preferred_engine;
        cntl.transmitter = enc110->base.transmitter;
        cntl.pll_id = clock_source;
-       if (hdmi) {
-               cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
-               cntl.lanes_number = 4;
-       } else if (dual_link) {
-               cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
+       cntl.signal = signal;
+       if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
                cntl.lanes_number = 8;
-       } else {
-               cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
+       else
                cntl.lanes_number = 4;
-       }
+
        cntl.hpd_sel = enc110->base.hpd_source;
 
        cntl.pixel_clock = pixel_clock;
index 8ca9afe47a2b268af39b502cc8547f5a0ba7e3cc..0ec3433d34b622cdc9ebd6251cbf75a0c3261002 100644 (file)
@@ -210,8 +210,7 @@ void dce110_link_encoder_enable_tmds_output(
        struct link_encoder *enc,
        enum clock_source_id clock_source,
        enum dc_color_depth color_depth,
-       bool hdmi,
-       bool dual_link,
+       enum signal_type signal,
        uint32_t pixel_clock);
 
 /* enables DP PHY output */
index 3931412ab6d32e139a9653a12fe5c2d6de8c9337..87093894ea9e73f8e4a4b1f46787b6a30a2bcb5a 100644 (file)
@@ -128,23 +128,22 @@ static void set_truncation(
                return;
        }
        /* on other format-to do */
-       if (params->flags.TRUNCATE_ENABLED == 0 ||
-                       params->flags.TRUNCATE_DEPTH == 2)
+       if (params->flags.TRUNCATE_ENABLED == 0)
                return;
        /*Set truncation depth and Enable truncation*/
        REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
                                FMT_TRUNCATE_EN, 1,
                                FMT_TRUNCATE_DEPTH,
-                               params->flags.TRUNCATE_MODE,
+                               params->flags.TRUNCATE_DEPTH,
                                FMT_TRUNCATE_MODE,
-                               params->flags.TRUNCATE_DEPTH);
+                               params->flags.TRUNCATE_MODE);
 }
 
 
 /**
  *     set_spatial_dither
  *     1) set spatial dithering mode: pattern of seed
- *     2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
+ *     2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp
  *     3) set random seed
  *     4) set random mode
  *             lfsr is reset every frame or not reset
index 3ea43e2a9450ce562cd01b8a5c18a9ee060d2a62..442dd2d93618d57eeff5c21ae576750f86c50416 100644 (file)
@@ -852,6 +852,7 @@ static bool construct(
        dc->caps.max_downscale_ratio = 200;
        dc->caps.i2c_speed_in_khz = 40;
        dc->caps.max_cursor_size = 128;
+       dc->caps.dual_link_dvi = true;
 
        for (i = 0; i < pool->base.pipe_count; i++) {
                pool->base.timing_generators[i] =
index 86cdd7b4811fb7f1195ce7d8e73db9e8e42c6c3a..6f382a3ac90f19a3c210ef33c97dca43ac55df42 100644 (file)
@@ -688,15 +688,22 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
        struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
        struct dc_link *link = pipe_ctx->stream->sink->link;
 
-       /* 1. update AVI info frame (HDMI, DP)
-        * we always need to update info frame
-       */
+
        uint32_t active_total_with_borders;
        uint32_t early_control = 0;
        struct timing_generator *tg = pipe_ctx->stream_res.tg;
 
-       /* TODOFPGA may change to hwss.update_info_frame */
+       /* For MST, there are multiply stream go to only one link.
+        * connect DIG back_end to front_end while enable_stream and
+        * disconnect them during disable_stream
+        * BY this, it is logic clean to separate stream and link */
+       link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
+                                                   pipe_ctx->stream_res.stream_enc->id, true);
+
+       /* update AVI info frame (HDMI, DP)*/
+       /* TODO: FPGA may change to hwss.update_info_frame */
        dce110_update_info_frame(pipe_ctx);
+
        /* enable early control to avoid corruption on DP monitor*/
        active_total_with_borders =
                        timing->h_addressable
@@ -717,12 +724,8 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
                        pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
        }
 
-       /* For MST, there are multiply stream go to only one link.
-        * connect DIG back_end to front_end while enable_stream and
-        * disconnect them during disable_stream
-        * BY this, it is logic clean to separate stream and link */
-       link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
-                                                   pipe_ctx->stream_res.stream_enc->id, true);
+
+
 
 }
 
@@ -1690,9 +1693,13 @@ static void apply_min_clocks(
  *  Check if FBC can be enabled
  */
 static bool should_enable_fbc(struct dc *dc,
-                             struct dc_state *context)
+                             struct dc_state *context,
+                             uint32_t *pipe_idx)
 {
-       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
+       uint32_t i;
+       struct pipe_ctx *pipe_ctx = NULL;
+       struct resource_context *res_ctx = &context->res_ctx;
+
 
        ASSERT(dc->fbc_compressor);
 
@@ -1704,6 +1711,14 @@ static bool should_enable_fbc(struct dc *dc,
        if (context->stream_count != 1)
                return false;
 
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (res_ctx->pipe_ctx[i].stream) {
+                       pipe_ctx = &res_ctx->pipe_ctx[i];
+                       *pipe_idx = i;
+                       break;
+               }
+       }
+
        /* Only supports eDP */
        if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
                return false;
@@ -1729,11 +1744,14 @@ static bool should_enable_fbc(struct dc *dc,
 static void enable_fbc(struct dc *dc,
                       struct dc_state *context)
 {
-       if (should_enable_fbc(dc, context)) {
+       uint32_t pipe_idx = 0;
+
+       if (should_enable_fbc(dc, context, &pipe_idx)) {
                /* Program GRPH COMPRESSED ADDRESS and PITCH */
                struct compr_addr_and_pitch_params params = {0, 0, 0};
                struct compressor *compr = dc->fbc_compressor;
-               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
+
 
                params.source_view_width = pipe_ctx->stream->timing.h_addressable;
                params.source_view_height = pipe_ctx->stream->timing.v_addressable;
@@ -2915,6 +2933,49 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
        }
 }
 
+void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+       struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+       struct mem_input *mi = pipe_ctx->plane_res.mi;
+       struct dc_cursor_mi_param param = {
+               .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
+               .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
+               .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
+               .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
+               .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
+       };
+
+       if (pipe_ctx->plane_state->address.type
+                       == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+               pos_cpy.enable = false;
+
+       if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
+               pos_cpy.enable = false;
+
+       if (ipp->funcs->ipp_cursor_set_position)
+               ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+       if (mi->funcs->set_cursor_position)
+               mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+}
+
+void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+       if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
+               pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
+                               pipe_ctx->plane_res.ipp, attributes);
+
+       if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
+               pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
+                               pipe_ctx->plane_res.mi, attributes);
+
+       if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
+               pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
+                               pipe_ctx->plane_res.xfm, attributes);
+}
+
 static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
 
 static void optimize_shared_resources(struct dc *dc) {}
@@ -2957,6 +3018,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
        .edp_backlight_control = hwss_edp_backlight_control,
        .edp_power_control = hwss_edp_power_control,
        .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+       .set_cursor_position = dce110_set_cursor_position,
+       .set_cursor_attribute = dce110_set_cursor_attribute
 };
 
 void dce110_hw_sequencer_construct(struct dc *dc)
index 7c4779578fb76528caef31a1a531f73214c86059..00f18c485e1e7b5a7d38e7bfb50df0d92d207a71 100644 (file)
@@ -846,6 +846,16 @@ static bool dce110_validate_bandwidth(
        return result;
 }
 
+enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state,
+                                    struct dc_caps *caps)
+{
+       if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) ||
+           ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height))
+               return DC_FAIL_SURFACE_VALIDATE;
+
+       return DC_OK;
+}
+
 static bool dce110_validate_surface_sets(
                struct dc_state *context)
 {
@@ -869,6 +879,13 @@ static bool dce110_validate_surface_sets(
                                        plane->src_rect.height > 1080))
                                        return false;
 
+                               /* we don't have the logic to support underlay
+                                * only yet so block the use case where we get
+                                * NV12 plane as top layer
+                                */
+                               if (j == 0)
+                                       return false;
+
                                /* irrespective of plane format,
                                 * stream should be RGB encoded
                                 */
@@ -1021,6 +1038,7 @@ static const struct resource_funcs dce110_res_pool_funcs = {
        .link_enc_create = dce110_link_encoder_create,
        .validate_guaranteed = dce110_validate_guaranteed,
        .validate_bandwidth = dce110_validate_bandwidth,
+       .validate_plane = dce110_validate_plane,
        .acquire_idle_pipe_for_layer = dce110_acquire_underlay,
        .add_stream_to_ctx = dce110_add_stream_to_ctx,
        .validate_global = dce110_validate_global
index 663e0a047a4becc5bae59b672ad951df24cedcfc..98d9cd0109e1f3cf5dbfa7b9111353c163aa4ad4 100644 (file)
@@ -1103,6 +1103,8 @@ static bool construct(
        dc->caps.max_downscale_ratio = 200;
        dc->caps.i2c_speed_in_khz = 100;
        dc->caps.max_cursor_size = 128;
+       dc->caps.dual_link_dvi = true;
+
 
        /*************************************************
         *  Create resources                             *
index 57cd67359567b5bd80a61bf2df3697a765d92dd5..5aab01db28ee78e1cd1c83fef2b240a3911cca52 100644 (file)
@@ -835,6 +835,8 @@ static bool construct(
        dc->caps.max_downscale_ratio = 200;
        dc->caps.i2c_speed_in_khz = 100;
        dc->caps.max_cursor_size = 128;
+       dc->caps.dual_link_dvi = true;
+
        dc->debug = debug_defaults;
 
        /*************************************************
index 8f2bd56f3461d665e8dd7c15e6280b32b0f135c1..25d7eb1567aeb10bc61d23df101f6b3303fe107c 100644 (file)
@@ -793,6 +793,7 @@ static bool dce80_construct(
        dc->caps.max_downscale_ratio = 200;
        dc->caps.i2c_speed_in_khz = 40;
        dc->caps.max_cursor_size = 128;
+       dc->caps.dual_link_dvi = true;
 
        /*************************************************
         *  Create resources                             *
index 82572863acab747759e3d8c2787a1e2cffc1f8df..dc1e010725c13d7f56bde96c1047626ef25745c0 100644 (file)
@@ -238,10 +238,34 @@ static void enable_power_gating_plane(
 static void disable_vga(
        struct dce_hwseq *hws)
 {
+       unsigned int in_vga1_mode = 0;
+       unsigned int in_vga2_mode = 0;
+       unsigned int in_vga3_mode = 0;
+       unsigned int in_vga4_mode = 0;
+
+       REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode);
+       REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode);
+       REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode);
+       REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode);
+
+       if (in_vga1_mode == 0 && in_vga2_mode == 0 &&
+                       in_vga3_mode == 0 && in_vga4_mode == 0)
+               return;
+
        REG_WRITE(D1VGA_CONTROL, 0);
        REG_WRITE(D2VGA_CONTROL, 0);
        REG_WRITE(D3VGA_CONTROL, 0);
        REG_WRITE(D4VGA_CONTROL, 0);
+
+       /* HW Engineer's Notes:
+        *  During switch from vga->extended, if we set the VGA_TEST_ENABLE and
+        *  then hit the VGA_TEST_RENDER_START, then the DCHUBP timing gets updated correctly.
+        *
+        *  Then vBIOS will have it poll for the VGA_TEST_RENDER_DONE and unset
+        *  VGA_TEST_ENABLE, to leave it in the same state as before.
+        */
+       REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_ENABLE, 1);
+       REG_UPDATE(VGA_TEST_CONTROL, VGA_TEST_RENDER_START, 1);
 }
 
 static void dpp_pg_control(
@@ -1761,6 +1785,11 @@ static void update_dchubp_dpp(
                        &pipe_ctx->plane_res.scl_data.viewport_c);
        }
 
+       if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
+               dc->hwss.set_cursor_position(pipe_ctx);
+               dc->hwss.set_cursor_attribute(pipe_ctx);
+       }
+
        if (plane_state->update_flags.bits.full_update) {
                /*gamut remap*/
                program_gamut_remap(pipe_ctx);
@@ -2296,7 +2325,7 @@ static bool dcn10_dummy_display_power_gating(
        return true;
 }
 
-void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
+static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
 {
        struct dc_plane_state *plane_state = pipe_ctx->plane_state;
        struct timing_generator *tg = pipe_ctx->stream_res.tg;
@@ -2316,12 +2345,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
        }
 }
 
-void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
+static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
 {
        if (hws->ctx->dc->res_pool->hubbub != NULL)
                hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data);
 }
 
+static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+       struct hubp *hubp = pipe_ctx->plane_res.hubp;
+       struct dpp *dpp = pipe_ctx->plane_res.dpp;
+       struct dc_cursor_mi_param param = {
+               .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
+               .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
+               .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
+               .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
+               .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
+       };
+
+       if (pipe_ctx->plane_state->address.type
+                       == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+               pos_cpy.enable = false;
+
+       if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
+               pos_cpy.enable = false;
+
+       hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
+}
+
+static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+       struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+       pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+                       pipe_ctx->plane_res.hubp, attributes);
+       pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+               pipe_ctx->plane_res.dpp, attributes->color_format);
+}
+
 static const struct hw_sequencer_funcs dcn10_funcs = {
        .program_gamut_remap = program_gamut_remap,
        .program_csc_matrix = program_csc_matrix,
@@ -2362,6 +2425,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .edp_backlight_control = hwss_edp_backlight_control,
        .edp_power_control = hwss_edp_power_control,
        .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+       .set_cursor_position = dcn10_set_cursor_position,
+       .set_cursor_attribute = dcn10_set_cursor_attribute
 };
 
 
index 0fd329deacd8a047c6302e092075972698191fff..54d8a13861423483dfc01050a78edc1d190424da 100644 (file)
@@ -123,8 +123,7 @@ struct link_encoder_funcs {
        void (*enable_tmds_output)(struct link_encoder *enc,
                enum clock_source_id clock_source,
                enum dc_color_depth color_depth,
-               bool hdmi,
-               bool dual_link,
+               enum signal_type signal,
                uint32_t pixel_clock);
        void (*enable_dp_output)(struct link_encoder *enc,
                const struct dc_link_settings *link_settings,
index 4c0aa56f7bae255e42b18db495efba17b9868971..379c6ecd271a5919b87640dff21edb96caf36933 100644 (file)
@@ -198,6 +198,9 @@ struct hw_sequencer_funcs {
                        bool enable);
        void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
 
+       void (*set_cursor_position)(struct pipe_ctx *pipe);
+       void (*set_cursor_attribute)(struct pipe_ctx *pipe);
+
 };
 
 void color_space_to_black_color(
index f7e40b292dfbbbdc5b81dfd8a444a63f42542a5b..d3e1923b01a8d0eaa076b6617ba659c459c4810e 100644 (file)
@@ -217,7 +217,7 @@ bool dce110_vblank_set(
                        core_dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg;
 
        if (enable) {
-               if (!tg->funcs->arm_vert_intr(tg, 2)) {
+               if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) {
                        DC_ERROR("Failed to get VBLANK!\n");
                        return false;
                }
index 57a54a7b89e5f73d5f67dcb8177368ccc0f8acd0..1c079ba37c3006cd7f51c49ea74599575ed46e05 100644 (file)
@@ -42,8 +42,7 @@ static void virtual_link_encoder_enable_tmds_output(
        struct link_encoder *enc,
        enum clock_source_id clock_source,
        enum dc_color_depth color_depth,
-       bool hdmi,
-       bool dual_link,
+       enum signal_type signal,
        uint32_t pixel_clock) {}
 
 static void virtual_link_encoder_enable_dp_output(
index 7a9b43f84a31636bbb958597a3b66cbabf792810..36bbad5942674bcda382624f2d13b2fe3f6b304e 100644 (file)
@@ -419,11 +419,6 @@ struct bios_event_info {
        bool backlight_changed;
 };
 
-enum {
-       HDMI_PIXEL_CLOCK_IN_KHZ_297 = 297000,
-       TMDS_PIXEL_CLOCK_IN_KHZ_165 = 165000
-};
-
 /*
  * DFS-bypass flag
  */
index b5ebde642207431080f62db9adbbf18491f6a33b..199c5db67cbca1e0ed7aeba6a721c92d4ba25468 100644 (file)
 #ifndef __DC_SIGNAL_TYPES_H__
 #define __DC_SIGNAL_TYPES_H__
 
+/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
+#define TMDS_MIN_PIXEL_CLOCK 25000
+/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
+#define TMDS_MAX_PIXEL_CLOCK 165000
+
 enum signal_type {
        SIGNAL_TYPE_NONE                = 0L,           /* no signal */
        SIGNAL_TYPE_DVI_SINGLE_LINK     = (1 << 0),
index 4c3223a4d62b04d0264686e2eb6e493e6daf7c23..adb6e7b9280ce48650b4bb287a1b122e4c06002b 100644 (file)
@@ -162,7 +162,7 @@ static int pp_hw_init(void *handle)
                if(hwmgr->smumgr_funcs->start_smu(pp_handle->hwmgr)) {
                        pr_err("smc start failed\n");
                        hwmgr->smumgr_funcs->smu_fini(pp_handle->hwmgr);
-                       return -EINVAL;;
+                       return -EINVAL;
                }
                if (ret == PP_DPM_DISABLED)
                        goto exit;
index 41e42beff213905837c15db1841800b2021ec502..08e8a793714f26dc38e571a51b52f8421bb72444 100644 (file)
@@ -2756,10 +2756,13 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
                                    PHM_PlatformCaps_DisableMclkSwitchingForFrameLock);
 
 
-       disable_mclk_switching = ((1 < info.display_count) ||
-                                 disable_mclk_switching_for_frame_lock ||
-                                 smu7_vblank_too_short(hwmgr, mode_info.vblank_time_us) ||
-                                 (mode_info.refresh_rate > 120));
+       if (info.display_count == 0)
+               disable_mclk_switching = false;
+       else
+               disable_mclk_switching = ((1 < info.display_count) ||
+                                         disable_mclk_switching_for_frame_lock ||
+                                         smu7_vblank_too_short(hwmgr, mode_info.vblank_time_us) ||
+                                         (mode_info.refresh_rate > 120));
 
        sclk = smu7_ps->performance_levels[0].engine_clock;
        mclk = smu7_ps->performance_levels[0].memory_clock;
@@ -4534,13 +4537,6 @@ static int smu7_set_power_profile_state(struct pp_hwmgr *hwmgr,
        int tmp_result, result = 0;
        uint32_t sclk_mask = 0, mclk_mask = 0;
 
-       if (hwmgr->chip_id == CHIP_FIJI) {
-               if (request->type == AMD_PP_GFX_PROFILE)
-                       smu7_enable_power_containment(hwmgr);
-               else if (request->type == AMD_PP_COMPUTE_PROFILE)
-                       smu7_disable_power_containment(hwmgr);
-       }
-
        if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_AUTO)
                return -EINVAL;
 
index 2d55dabc77d4112d0b1c50bf1e1ae38ac0505dd0..5f9c3efb532f6c48471b75a0e5510369b98fffff 100644 (file)
@@ -3168,10 +3168,13 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
        disable_mclk_switching_for_vr = PP_CAP(PHM_PlatformCaps_DisableMclkSwitchForVR);
        force_mclk_high = PP_CAP(PHM_PlatformCaps_ForceMclkHigh);
 
-       disable_mclk_switching = (info.display_count > 1) ||
-                                   disable_mclk_switching_for_frame_lock ||
-                                   disable_mclk_switching_for_vr ||
-                                   force_mclk_high;
+       if (info.display_count == 0)
+               disable_mclk_switching = false;
+       else
+               disable_mclk_switching = (info.display_count > 1) ||
+                       disable_mclk_switching_for_frame_lock ||
+                       disable_mclk_switching_for_vr ||
+                       force_mclk_high;
 
        sclk = vega10_ps->performance_levels[0].gfx_clock;
        mclk = vega10_ps->performance_levels[0].mem_clock;
index 5f4c2e833a650dd6be2e6afb5e9835cf7e434e17..d665dd5af5dd80f2348dd1290c41ecb4756ab9d7 100644 (file)
@@ -97,7 +97,7 @@ static const struct ast_vbios_dclk_info dclk_table[] = {
        {0x67, 0x22, 0x00},                     /* 0E: VCLK157_5        */
        {0x6A, 0x22, 0x00},                     /* 0F: VCLK162          */
        {0x4d, 0x4c, 0x80},                     /* 10: VCLK154          */
-       {0xa7, 0x78, 0x80},                     /* 11: VCLK83.5         */
+       {0x68, 0x6f, 0x80},                     /* 11: VCLK83.5         */
        {0x28, 0x49, 0x80},                     /* 12: VCLK106.5        */
        {0x37, 0x49, 0x80},                     /* 13: VCLK146.25       */
        {0x1f, 0x45, 0x80},                     /* 14: VCLK148.5        */
@@ -127,7 +127,7 @@ static const struct ast_vbios_dclk_info dclk_table_ast2500[] = {
        {0x67, 0x22, 0x00},                     /* 0E: VCLK157_5        */
        {0x6A, 0x22, 0x00},                     /* 0F: VCLK162          */
        {0x4d, 0x4c, 0x80},                     /* 10: VCLK154          */
-       {0xa7, 0x78, 0x80},                     /* 11: VCLK83.5         */
+       {0x68, 0x6f, 0x80},                     /* 11: VCLK83.5         */
        {0x28, 0x49, 0x80},                     /* 12: VCLK106.5        */
        {0x37, 0x49, 0x80},                     /* 13: VCLK146.25       */
        {0x1f, 0x45, 0x80},                     /* 14: VCLK148.5        */
index cd23b1b28259435602efeaf99fcc885366291efe..c91b9b054e3f77805bd3ae00b0db3bf74144f6d1 100644 (file)
@@ -294,22 +294,7 @@ static void cirrus_crtc_prepare(struct drm_crtc *crtc)
 {
 }
 
-/*
- * This is called after a mode is programmed. It should reverse anything done
- * by the prepare function
- */
-static void cirrus_crtc_commit(struct drm_crtc *crtc)
-{
-}
-
-/*
- * The core can pass us a set of gamma values to program. We actually only
- * use this for 8-bit mode so can't perform smooth fades on deeper modes,
- * but it's a requirement that we provide the function
- */
-static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
-                                u16 *blue, uint32_t size,
-                                struct drm_modeset_acquire_ctx *ctx)
+static void cirrus_crtc_load_lut(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
        struct cirrus_device *cdev = dev->dev_private;
@@ -317,7 +302,7 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
        int i;
 
        if (!crtc->enabled)
-               return 0;
+               return;
 
        r = crtc->gamma_store;
        g = r + crtc->gamma_size;
@@ -330,6 +315,27 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                WREG8(PALETTE_DATA, *g++ >> 8);
                WREG8(PALETTE_DATA, *b++ >> 8);
        }
+}
+
+/*
+ * This is called after a mode is programmed. It should reverse anything done
+ * by the prepare function
+ */
+static void cirrus_crtc_commit(struct drm_crtc *crtc)
+{
+       cirrus_crtc_load_lut(crtc);
+}
+
+/*
+ * The core can pass us a set of gamma values to program. We actually only
+ * use this for 8-bit mode so can't perform smooth fades on deeper modes,
+ * but it's a requirement that we provide the function
+ */
+static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
+                                u16 *blue, uint32_t size,
+                                struct drm_modeset_acquire_ctx *ctx)
+{
+       cirrus_crtc_load_lut(crtc);
 
        return 0;
 }
index ab4032167094cca0ddeb3583915af6fe07ae5301..ae3cbfe9e01cd6a52cc7c6a15ec809e971139ee4 100644 (file)
@@ -1878,6 +1878,8 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
                new_crtc_state->event->base.completion = &commit->flip_done;
                new_crtc_state->event->base.completion_release = release_crtc_commit;
                drm_crtc_commit_get(commit);
+
+               commit->abort_completion = true;
        }
 
        for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
@@ -3421,8 +3423,21 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
 {
        if (state->commit) {
+               /*
+                * In the event that a non-blocking commit returns
+                * -ERESTARTSYS before the commit_tail work is queued, we will
+                * have an extra reference to the commit object. Release it, if
+                * the event has not been consumed by the worker.
+                *
+                * state->event may be freed, so we can't directly look at
+                * state->event->base.completion.
+                */
+               if (state->event && state->commit->abort_completion)
+                       drm_crtc_commit_put(state->commit);
+
                kfree(state->commit->event);
                state->commit->event = NULL;
+
                drm_crtc_commit_put(state->commit);
        }
 
index ddd5379145758014f1a5a9915abb1528edc1cf17..4f751a9d71a34b858950ddae058bb50eaa281afa 100644 (file)
@@ -113,6 +113,9 @@ static const struct edid_quirk {
        /* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
        { "AEO", 0, EDID_QUIRK_FORCE_6BPC },
 
+       /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
+       { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
+
        /* Belinea 10 15 55 */
        { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
        { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
@@ -162,6 +165,24 @@ static const struct edid_quirk {
 
        /* HTC Vive VR Headset */
        { "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP },
+
+       /* Oculus Rift DK1, DK2, and CV1 VR Headsets */
+       { "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP },
+       { "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP },
+       { "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP },
+
+       /* Windows Mixed Reality Headsets */
+       { "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP },
+       { "HPN", 0x3515, EDID_QUIRK_NON_DESKTOP },
+       { "LEN", 0x0408, EDID_QUIRK_NON_DESKTOP },
+       { "LEN", 0xb800, EDID_QUIRK_NON_DESKTOP },
+       { "FUJ", 0x1970, EDID_QUIRK_NON_DESKTOP },
+       { "DEL", 0x7fce, EDID_QUIRK_NON_DESKTOP },
+       { "SEC", 0x144a, EDID_QUIRK_NON_DESKTOP },
+       { "AUS", 0xc102, EDID_QUIRK_NON_DESKTOP },
+
+       /* Sony PlayStation VR Headset */
+       { "SNY", 0x0704, EDID_QUIRK_NON_DESKTOP },
 };
 
 /*
index 5a13ff29f4f04af99c61fa07261a35a44ac0dd8e..2dc5e8bed17214f187fdbe93e28b72cceeb6b376 100644 (file)
@@ -121,6 +121,10 @@ int drm_mode_addfb(struct drm_device *dev,
        r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
        r.handles[0] = or->handle;
 
+       if (r.pixel_format == DRM_FORMAT_XRGB2101010 &&
+           dev->driver->driver_features & DRIVER_PREFER_XBGR_30BPP)
+               r.pixel_format = DRM_FORMAT_XBGR2101010;
+
        ret = drm_mode_addfb2(dev, &r, file_priv);
        if (ret)
                return ret;
@@ -457,6 +461,12 @@ int drm_mode_getfb(struct drm_device *dev,
        if (!fb)
                return -ENOENT;
 
+       /* Multi-planar framebuffers need getfb2. */
+       if (fb->format->num_planes > 1) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        r->height = fb->height;
        r->width = fb->width;
        r->depth = fb->format->depth;
@@ -480,6 +490,7 @@ int drm_mode_getfb(struct drm_device *dev,
                ret = -ENODEV;
        }
 
+out:
        drm_framebuffer_put(fb);
 
        return ret;
index 186c4e90cc1cd25e06a19a89da1bf88a7d9e0cf7..89eef1bb4ddc3f606dea32ac24a3702c7293152c 100644 (file)
@@ -836,9 +836,24 @@ struct drm_mm_node *drm_mm_scan_color_evict(struct drm_mm_scan *scan)
        if (!mm->color_adjust)
                return NULL;
 
-       hole = list_first_entry(&mm->hole_stack, typeof(*hole), hole_stack);
-       hole_start = __drm_mm_hole_node_start(hole);
-       hole_end = hole_start + hole->hole_size;
+       /*
+        * The hole found during scanning should ideally be the first element
+        * in the hole_stack list, but due to side-effects in the driver it
+        * may not be.
+        */
+       list_for_each_entry(hole, &mm->hole_stack, hole_stack) {
+               hole_start = __drm_mm_hole_node_start(hole);
+               hole_end = hole_start + hole->hole_size;
+
+               if (hole_start <= scan->hit_start &&
+                   hole_end >= scan->hit_end)
+                       break;
+       }
+
+       /* We should only be called after we found the hole previously */
+       DRM_MM_BUG_ON(&hole->hole_stack == &mm->hole_stack);
+       if (unlikely(&hole->hole_stack == &mm->hole_stack))
+               return NULL;
 
        DRM_MM_BUG_ON(hole_start > scan->hit_start);
        DRM_MM_BUG_ON(hole_end < scan->hit_end);
index 555fbe54d6e224e2b58a7d263353efac2d7e0104..00b8445ba8192b63bf6015eb1442342c39b47378 100644 (file)
@@ -653,6 +653,26 @@ out:
                schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
 }
 
+/**
+ * drm_kms_helper_is_poll_worker - is %current task an output poll worker?
+ *
+ * Determine if %current task is an output poll worker.  This can be used
+ * to select distinct code paths for output polling versus other contexts.
+ *
+ * One use case is to avoid a deadlock between the output poll worker and
+ * the autosuspend worker wherein the latter waits for polling to finish
+ * upon calling drm_kms_helper_poll_disable(), while the former waits for
+ * runtime suspend to finish upon calling pm_runtime_get_sync() in a
+ * connector ->detect hook.
+ */
+bool drm_kms_helper_is_poll_worker(void)
+{
+       struct work_struct *work = current_work();
+
+       return work && work->func == output_poll_execute;
+}
+EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
+
 /**
  * drm_kms_helper_poll_disable - disable output polling
  * @dev: drm_device
index 2b8bf2dd63874e36e0d29c4c383a74c2d365489d..f68ef1b3a28c7fac6c427d975d8df015cd09b915 100644 (file)
@@ -286,7 +286,6 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
 
        node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL);
        if (!node) {
-               dev_err(dev, "failed to allocate memory\n");
                ret = -ENOMEM;
                goto err;
        }
@@ -926,7 +925,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
        struct drm_device *drm_dev = g2d->subdrv.drm_dev;
        struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
        struct drm_exynos_pending_g2d_event *e;
-       struct timeval now;
+       struct timespec64 now;
 
        if (list_empty(&runqueue_node->event_list))
                return;
@@ -934,9 +933,9 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
        e = list_first_entry(&runqueue_node->event_list,
                             struct drm_exynos_pending_g2d_event, base.link);
 
-       do_gettimeofday(&now);
+       ktime_get_ts64(&now);
        e->event.tv_sec = now.tv_sec;
-       e->event.tv_usec = now.tv_usec;
+       e->event.tv_usec = now.tv_nsec / NSEC_PER_USEC;
        e->event.cmdlist_no = cmdlist_no;
 
        drm_send_event(drm_dev, &e->base);
@@ -1358,10 +1357,9 @@ int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
                return -EFAULT;
 
        runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL);
-       if (!runqueue_node) {
-               dev_err(dev, "failed to allocate memory\n");
+       if (!runqueue_node)
                return -ENOMEM;
-       }
+
        run_cmdlist = &runqueue_node->run_cmdlist;
        event_list = &runqueue_node->event_list;
        INIT_LIST_HEAD(run_cmdlist);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.h b/drivers/gpu/drm/exynos/exynos_drm_rotator.h
deleted file mode 100644 (file)
index 71a0b4c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *
- * Authors:
- *     YoungJun Cho <yj44.cho@samsung.com>
- *     Eunchul Kim <chulspro.kim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef        _EXYNOS_DRM_ROTATOR_H_
-#define        _EXYNOS_DRM_ROTATOR_H_
-
-/* TODO */
-
-#endif
index a4b75a46f946306165e7140fa4b753fe116868ca..abd84cbcf1c2ca763e71d4e493661f8bef22170f 100644 (file)
@@ -1068,10 +1068,13 @@ static void hdmi_audio_config(struct hdmi_context *hdata)
        /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
                        | HDMI_I2S_SEL_LRCK(6));
-       hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
-                       | HDMI_I2S_SEL_SDATA2(4));
+
+       hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(3)
+                       | HDMI_I2S_SEL_SDATA0(4));
+
        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
                        | HDMI_I2S_SEL_SDATA2(2));
+
        hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
 
        /* I2S_CON_1 & 2 */
index 30496134a3d0720bcc649711bd8d2ef5d35cf47a..d7cbe53c4c01f440cf9c0aecec153dc3d4f3f912 100644 (file)
 #define EXYNOS_CIIMGEFF_FIN_EMBOSSING          (4 << 26)
 #define EXYNOS_CIIMGEFF_FIN_SILHOUETTE         (5 << 26)
 #define EXYNOS_CIIMGEFF_FIN_MASK                       (7 << 26)
-#define EXYNOS_CIIMGEFF_PAT_CBCR_MASK          ((0xff < 13) | (0xff < 0))
+#define EXYNOS_CIIMGEFF_PAT_CBCR_MASK          ((0xff << 13) | (0xff << 0))
 
 /* Real input DMA size register */
 #define EXYNOS_CIREAL_ISIZE_AUTOLOAD_ENABLE    (1 << 31)
index 04be0f7e81932682e7f5d9427580f46191061d9e..4420c203ac85e54e1afee35f0ef73c2aff550876 100644 (file)
 
 /* I2S_PIN_SEL_1 */
 #define HDMI_I2S_SEL_SDATA1(x)         (((x) & 0x7) << 4)
-#define HDMI_I2S_SEL_SDATA2(x)         ((x) & 0x7)
+#define HDMI_I2S_SEL_SDATA0(x)         ((x) & 0x7)
 
 /* I2S_PIN_SEL_2 */
 #define HDMI_I2S_SEL_SDATA3(x)         (((x) & 0x7) << 4)
index c8454ac43fae0fbdece898d38abc9c8e7059582b..db6b94dda5dfaede1ebb97cc21b17ea301fdd275 100644 (file)
@@ -471,6 +471,7 @@ struct parser_exec_state {
         * used when ret from 2nd level batch buffer
         */
        int saved_buf_addr_type;
+       bool is_ctx_wa;
 
        struct cmd_info *info;
 
@@ -1715,6 +1716,11 @@ static int perform_bb_shadow(struct parser_exec_state *s)
        bb->accessing = true;
        bb->bb_start_cmd_va = s->ip_va;
 
+       if ((s->buf_type == BATCH_BUFFER_INSTRUCTION) && (!s->is_ctx_wa))
+               bb->bb_offset = s->ip_va - s->rb_va;
+       else
+               bb->bb_offset = 0;
+
        /*
         * ip_va saves the virtual address of the shadow batch buffer, while
         * ip_gma saves the graphics address of the original batch buffer.
@@ -2571,6 +2577,7 @@ static int scan_workload(struct intel_vgpu_workload *workload)
        s.ring_tail = gma_tail;
        s.rb_va = workload->shadow_ring_buffer_va;
        s.workload = workload;
+       s.is_ctx_wa = false;
 
        if ((bypass_scan_mask & (1 << workload->ring_id)) ||
                gma_head == gma_tail)
@@ -2624,6 +2631,7 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
        s.ring_tail = gma_tail;
        s.rb_va = wa_ctx->indirect_ctx.shadow_va;
        s.workload = workload;
+       s.is_ctx_wa = true;
 
        if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
                ret = -EINVAL;
index 909499b73d03acba1a1af1f6f5b77c7ccdd07b5c..021f722e248165d461953999b02a7683d37dc7fa 100644 (file)
@@ -733,6 +733,25 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
        return ret == 0 ? count : ret;
 }
 
+static bool gtt_entry(struct mdev_device *mdev, loff_t *ppos)
+{
+       struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
+       unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
+       struct intel_gvt *gvt = vgpu->gvt;
+       int offset;
+
+       /* Only allow MMIO GGTT entry access */
+       if (index != PCI_BASE_ADDRESS_0)
+               return false;
+
+       offset = (u64)(*ppos & VFIO_PCI_OFFSET_MASK) -
+               intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_0);
+
+       return (offset >= gvt->device_info.gtt_start_offset &&
+               offset < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) ?
+                       true : false;
+}
+
 static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
                        size_t count, loff_t *ppos)
 {
@@ -742,7 +761,21 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
        while (count) {
                size_t filled;
 
-               if (count >= 4 && !(*ppos % 4)) {
+               /* Only support GGTT entry 8 bytes read */
+               if (count >= 8 && !(*ppos % 8) &&
+                       gtt_entry(mdev, ppos)) {
+                       u64 val;
+
+                       ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+                                       ppos, false);
+                       if (ret <= 0)
+                               goto read_err;
+
+                       if (copy_to_user(buf, &val, sizeof(val)))
+                               goto read_err;
+
+                       filled = 8;
+               } else if (count >= 4 && !(*ppos % 4)) {
                        u32 val;
 
                        ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
@@ -802,7 +835,21 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
        while (count) {
                size_t filled;
 
-               if (count >= 4 && !(*ppos % 4)) {
+               /* Only support GGTT entry 8 bytes write */
+               if (count >= 8 && !(*ppos % 8) &&
+                       gtt_entry(mdev, ppos)) {
+                       u64 val;
+
+                       if (copy_from_user(&val, buf, sizeof(val)))
+                               goto write_err;
+
+                       ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+                                       ppos, true);
+                       if (ret <= 0)
+                               goto write_err;
+
+                       filled = 8;
+               } else if (count >= 4 && !(*ppos % 4)) {
                        u32 val;
 
                        if (copy_from_user(&val, buf, sizeof(val)))
index 73ad6e90e49db17cc427c611f715f74ff1e710ec..152df3d0291e543fa9ae9eb923e773df62cb10ef 100644 (file)
@@ -118,6 +118,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = {
        {RCS, HALF_SLICE_CHICKEN3, 0xffff, true}, /* 0xe184 */
        {RCS, GEN9_HALF_SLICE_CHICKEN5, 0xffff, true}, /* 0xe188 */
        {RCS, GEN9_HALF_SLICE_CHICKEN7, 0xffff, true}, /* 0xe194 */
+       {RCS, GEN8_ROW_CHICKEN, 0xffff, true}, /* 0xe4f0 */
        {RCS, TRVATTL3PTRDW(0), 0, false}, /* 0x4de0 */
        {RCS, TRVATTL3PTRDW(1), 0, false}, /* 0x4de4 */
        {RCS, TRNULLDETCT, 0, false}, /* 0x4de8 */
@@ -393,9 +394,11 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
         * performace for batch mmio read/write, so we need
         * handle forcewake mannually.
         */
+       intel_runtime_pm_get(dev_priv);
        intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
        switch_mmio(pre, next, ring_id);
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+       intel_runtime_pm_put(dev_priv);
 }
 
 /**
index b55b3580ca1dd00402374354f3d12918817de378..d74d6f05c62c4e60d4b1604707cd79ffa992d041 100644 (file)
@@ -52,6 +52,54 @@ static void set_context_pdp_root_pointer(
                pdp_pair[i].val = pdp[7 - i];
 }
 
+/*
+ * when populating shadow ctx from guest, we should not overrride oa related
+ * registers, so that they will not be overlapped by guest oa configs. Thus
+ * made it possible to capture oa data from host for both host and guests.
+ */
+static void sr_oa_regs(struct intel_vgpu_workload *workload,
+               u32 *reg_state, bool save)
+{
+       struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
+       u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset;
+       u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset;
+       int i = 0;
+       u32 flex_mmio[] = {
+               i915_mmio_reg_offset(EU_PERF_CNTL0),
+               i915_mmio_reg_offset(EU_PERF_CNTL1),
+               i915_mmio_reg_offset(EU_PERF_CNTL2),
+               i915_mmio_reg_offset(EU_PERF_CNTL3),
+               i915_mmio_reg_offset(EU_PERF_CNTL4),
+               i915_mmio_reg_offset(EU_PERF_CNTL5),
+               i915_mmio_reg_offset(EU_PERF_CNTL6),
+       };
+
+       if (!workload || !reg_state || workload->ring_id != RCS)
+               return;
+
+       if (save) {
+               workload->oactxctrl = reg_state[ctx_oactxctrl + 1];
+
+               for (i = 0; i < ARRAY_SIZE(workload->flex_mmio); i++) {
+                       u32 state_offset = ctx_flexeu0 + i * 2;
+
+                       workload->flex_mmio[i] = reg_state[state_offset + 1];
+               }
+       } else {
+               reg_state[ctx_oactxctrl] =
+                       i915_mmio_reg_offset(GEN8_OACTXCONTROL);
+               reg_state[ctx_oactxctrl + 1] = workload->oactxctrl;
+
+               for (i = 0; i < ARRAY_SIZE(workload->flex_mmio); i++) {
+                       u32 state_offset = ctx_flexeu0 + i * 2;
+                       u32 mmio = flex_mmio[i];
+
+                       reg_state[state_offset] = mmio;
+                       reg_state[state_offset + 1] = workload->flex_mmio[i];
+               }
+       }
+}
+
 static int populate_shadow_context(struct intel_vgpu_workload *workload)
 {
        struct intel_vgpu *vgpu = workload->vgpu;
@@ -98,6 +146,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
        page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
        shadow_ring_context = kmap(page);
 
+       sr_oa_regs(workload, (u32 *)shadow_ring_context, true);
 #define COPY_REG(name) \
        intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \
                + RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4)
@@ -122,6 +171,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
                        sizeof(*shadow_ring_context),
                        I915_GTT_PAGE_SIZE - sizeof(*shadow_ring_context));
 
+       sr_oa_regs(workload, (u32 *)shadow_ring_context, false);
        kunmap(page);
        return 0;
 }
@@ -376,6 +426,17 @@ static int prepare_shadow_batch_buffer(struct intel_vgpu_workload *workload)
                        goto err;
                }
 
+               /* For privilge batch buffer and not wa_ctx, the bb_start_cmd_va
+                * is only updated into ring_scan_buffer, not real ring address
+                * allocated in later copy_workload_to_ring_buffer. pls be noted
+                * shadow_ring_buffer_va is now pointed to real ring buffer va
+                * in copy_workload_to_ring_buffer.
+                */
+
+               if (bb->bb_offset)
+                       bb->bb_start_cmd_va = workload->shadow_ring_buffer_va
+                               + bb->bb_offset;
+
                /* relocate shadow batch buffer */
                bb->bb_start_cmd_va[1] = i915_ggtt_offset(bb->vma);
                if (gmadr_bytes == 8)
@@ -1044,10 +1105,12 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
 
        bitmap_zero(s->shadow_ctx_desc_updated, I915_NUM_ENGINES);
 
-       s->workloads = kmem_cache_create("gvt-g_vgpu_workload",
-                       sizeof(struct intel_vgpu_workload), 0,
-                       SLAB_HWCACHE_ALIGN,
-                       NULL);
+       s->workloads = kmem_cache_create_usercopy("gvt-g_vgpu_workload",
+                                                 sizeof(struct intel_vgpu_workload), 0,
+                                                 SLAB_HWCACHE_ALIGN,
+                                                 offsetof(struct intel_vgpu_workload, rb_tail),
+                                                 sizeof_field(struct intel_vgpu_workload, rb_tail),
+                                                 NULL);
 
        if (!s->workloads) {
                ret = -ENOMEM;
index ff175a98b19ed41c6cdd8405a8872d4bdb6003dd..a79a4f60637ebbe451f7f2f0442ca663deba3bdf 100644 (file)
@@ -110,6 +110,10 @@ struct intel_vgpu_workload {
        /* shadow batch buffer */
        struct list_head shadow_bb;
        struct intel_shadow_wa_ctx wa_ctx;
+
+       /* oa registers */
+       u32 oactxctrl;
+       u32 flex_mmio[7];
 };
 
 struct intel_vgpu_shadow_bb {
@@ -120,6 +124,7 @@ struct intel_vgpu_shadow_bb {
        u32 *bb_start_cmd_va;
        unsigned int clflush;
        bool accessing;
+       unsigned long bb_offset;
 };
 
 #define workload_q_head(vgpu, ring_id) \
index 7a2511538f340f5d5f6f7a06519bbc844e6fc4b1..736bd2bc5127f059e7705639275be775e433594c 100644 (file)
@@ -333,7 +333,7 @@ TRACE_EVENT(render_mmio,
        TP_PROTO(int old_id, int new_id, char *action, unsigned int reg,
                 unsigned int old_val, unsigned int new_val),
 
-       TP_ARGS(old_id, new_id, action, reg, new_val, old_val),
+       TP_ARGS(old_id, new_id, action, reg, old_val, new_val),
 
        TP_STRUCT__entry(
                __field(int, old_id)
index 173d0095e3b2120e2bd2f4090cbe7da1e25c6619..2f5209de03915277879f9c5e01e597637b93836f 100644 (file)
@@ -1433,19 +1433,7 @@ void i915_driver_unload(struct drm_device *dev)
 
        intel_modeset_cleanup(dev);
 
-       /*
-        * free the memory space allocated for the child device
-        * config parsed from VBT
-        */
-       if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
-               kfree(dev_priv->vbt.child_dev);
-               dev_priv->vbt.child_dev = NULL;
-               dev_priv->vbt.child_dev_num = 0;
-       }
-       kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
-       dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
-       kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
-       dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
+       intel_bios_cleanup(dev_priv);
 
        vga_switcheroo_unregister_client(pdev);
        vga_client_register(pdev, NULL, NULL, NULL);
index a42deebedb0f12784155bb7499fef44a2c31cf28..d307429a5ae0a029e1f3b37c6ed76b39d9967b97 100644 (file)
@@ -1349,6 +1349,7 @@ struct intel_vbt_data {
                u32 size;
                u8 *data;
                const u8 *sequence[MIPI_SEQ_MAX];
+               u8 *deassert_seq; /* Used by fixup_mipi_sequences() */
        } dsi;
 
        int crt_ddc_pin;
@@ -3657,6 +3658,7 @@ extern void intel_i2c_reset(struct drm_i915_private *dev_priv);
 
 /* intel_bios.c */
 void intel_bios_init(struct drm_i915_private *dev_priv);
+void intel_bios_cleanup(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
 bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin);
index dd89abd2263d20334403ae4c4b1ef61af5482135..6ff5d655c20249b27926dea99b4243a8ed2f122a 100644 (file)
@@ -434,20 +434,28 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
                        dma_fence_put(shared[i]);
                kfree(shared);
 
+               /*
+                * If both shared fences and an exclusive fence exist,
+                * then by construction the shared fences must be later
+                * than the exclusive fence. If we successfully wait for
+                * all the shared fences, we know that the exclusive fence
+                * must all be signaled. If all the shared fences are
+                * signaled, we can prune the array and recover the
+                * floating references on the fences/requests.
+                */
                prune_fences = count && timeout >= 0;
        } else {
                excl = reservation_object_get_excl_rcu(resv);
        }
 
-       if (excl && timeout >= 0) {
+       if (excl && timeout >= 0)
                timeout = i915_gem_object_wait_fence(excl, flags, timeout,
                                                     rps_client);
-               prune_fences = timeout >= 0;
-       }
 
        dma_fence_put(excl);
 
-       /* Oportunistically prune the fences iff we know they have *all* been
+       /*
+        * Opportunistically prune the fences iff we know they have *all* been
         * signaled and that the reservation object has not been changed (i.e.
         * no new fences have been added).
         */
@@ -3205,8 +3213,10 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
         * rolling the global seqno forward (since this would complete requests
         * for which we haven't set the fence error to EIO yet).
         */
-       for_each_engine(engine, i915, id)
+       for_each_engine(engine, i915, id) {
+               i915_gem_reset_prepare_engine(engine);
                engine->submit_request = nop_submit_request;
+       }
 
        /*
         * Make sure no one is running the old callback before we proceed with
@@ -3244,6 +3254,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
                intel_engine_init_global_seqno(engine,
                                               intel_engine_last_submit(engine));
                spin_unlock_irqrestore(&engine->timeline->lock, flags);
+
+               i915_gem_reset_finish_engine(engine);
        }
 
        set_bit(I915_WEDGED, &i915->gpu_error.flags);
index 648e7536ff51e0eae1365971293ab150f72d9956..0c963fcf31ffd1d2527deaa8df796908a36ec027 100644 (file)
@@ -803,7 +803,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
 
        case I915_CONTEXT_PARAM_PRIORITY:
                {
-                       int priority = args->value;
+                       s64 priority = args->value;
 
                        if (args->size)
                                ret = -EINVAL;
index 4401068ff468ad36aef1d5df5277e2f008f01bb3..3ab1ace2a6bdd8a4be32828e58262d9ef9e20ae7 100644 (file)
@@ -505,6 +505,8 @@ eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma)
                list_add_tail(&vma->exec_link, &eb->unbound);
                if (drm_mm_node_allocated(&vma->node))
                        err = i915_vma_unbind(vma);
+               if (unlikely(err))
+                       vma->exec_flags = NULL;
        }
        return err;
 }
@@ -2410,7 +2412,7 @@ err_request:
        if (out_fence) {
                if (err == 0) {
                        fd_install(out_fence_fd, out_fence->file);
-                       args->rsvd2 &= GENMASK_ULL(0, 31); /* keep in-fence */
+                       args->rsvd2 &= GENMASK_ULL(31, 0); /* keep in-fence */
                        args->rsvd2 |= (u64)out_fence_fd << 32;
                        out_fence_fd = -1;
                } else {
index e09d18df8b7f18ca0b17f65797e5cbdc4baec072..a3e93d46316a267571f199cfcbd665434f41003f 100644 (file)
@@ -476,8 +476,6 @@ void __i915_gem_request_submit(struct drm_i915_gem_request *request)
        GEM_BUG_ON(!irqs_disabled());
        lockdep_assert_held(&engine->timeline->lock);
 
-       trace_i915_gem_request_execute(request);
-
        /* Transfer from per-context onto the global per-engine timeline */
        timeline = engine->timeline;
        GEM_BUG_ON(timeline == request->timeline);
@@ -501,6 +499,8 @@ void __i915_gem_request_submit(struct drm_i915_gem_request *request)
        list_move_tail(&request->link, &timeline->requests);
        spin_unlock(&request->timeline->lock);
 
+       trace_i915_gem_request_execute(request);
+
        wake_up_all(&request->execute);
 }
 
index 42ff06fe54a3a89b4e1d50e3ad2a033cc92a786a..792facdb6702bffdcb808f8bc748518c8299ac8e 100644 (file)
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv)
 {
-       strncpy(dev_priv->perf.oa.test_config.uuid,
+       strlcpy(dev_priv->perf.oa.test_config.uuid,
                "577e8e2c-3fa0-4875-8743-3538d585e3b0",
-               UUID_STRING_LEN);
+               sizeof(dev_priv->perf.oa.test_config.uuid));
        dev_priv->perf.oa.test_config.id = 1;
 
        dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
index ff0ac3627cc4bc73858d6c71df9b9571a27de4df..ba9140c87cc0ba7de03f0c36ef91ebcaf372b4c8 100644 (file)
@@ -96,9 +96,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv)
 {
-       strncpy(dev_priv->perf.oa.test_config.uuid,
+       strlcpy(dev_priv->perf.oa.test_config.uuid,
                "db41edd4-d8e7-4730-ad11-b9a2d6833503",
-               UUID_STRING_LEN);
+               sizeof(dev_priv->perf.oa.test_config.uuid));
        dev_priv->perf.oa.test_config.id = 1;
 
        dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
index 0be50e43507de0e15ef06245335940eed75d3f6b..f8fe5ffcdcfff8cb27667efdcec2914eb3b7b06b 100644 (file)
@@ -1303,9 +1303,8 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
         */
        mutex_lock(&dev_priv->drm.struct_mutex);
        dev_priv->perf.oa.exclusive_stream = NULL;
-       mutex_unlock(&dev_priv->drm.struct_mutex);
-
        dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
+       mutex_unlock(&dev_priv->drm.struct_mutex);
 
        free_oa_buffer(dev_priv);
 
@@ -1756,22 +1755,13 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
  * Note: it's only the RCS/Render context that has any OA state.
  */
 static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
-                                      const struct i915_oa_config *oa_config,
-                                      bool interruptible)
+                                      const struct i915_oa_config *oa_config)
 {
        struct i915_gem_context *ctx;
        int ret;
        unsigned int wait_flags = I915_WAIT_LOCKED;
 
-       if (interruptible) {
-               ret = i915_mutex_lock_interruptible(&dev_priv->drm);
-               if (ret)
-                       return ret;
-
-               wait_flags |= I915_WAIT_INTERRUPTIBLE;
-       } else {
-               mutex_lock(&dev_priv->drm.struct_mutex);
-       }
+       lockdep_assert_held(&dev_priv->drm.struct_mutex);
 
        /* Switch away from any user context. */
        ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config);
@@ -1819,8 +1809,6 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
        }
 
  out:
-       mutex_unlock(&dev_priv->drm.struct_mutex);
-
        return ret;
 }
 
@@ -1863,7 +1851,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
         * to make sure all slices/subslices are ON before writing to NOA
         * registers.
         */
-       ret = gen8_configure_all_contexts(dev_priv, oa_config, true);
+       ret = gen8_configure_all_contexts(dev_priv, oa_config);
        if (ret)
                return ret;
 
@@ -1878,7 +1866,7 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
 static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
 {
        /* Reset all contexts' slices/subslices configurations. */
-       gen8_configure_all_contexts(dev_priv, NULL, false);
+       gen8_configure_all_contexts(dev_priv, NULL);
 
        I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
                                      ~GT_NOA_ENABLE));
@@ -1888,7 +1876,7 @@ static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
 static void gen10_disable_metric_set(struct drm_i915_private *dev_priv)
 {
        /* Reset all contexts' slices/subslices configurations. */
-       gen8_configure_all_contexts(dev_priv, NULL, false);
+       gen8_configure_all_contexts(dev_priv, NULL);
 
        /* Make sure we disable noa to save power. */
        I915_WRITE(RPM_CONFIG1,
@@ -2138,6 +2126,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
        if (ret)
                goto err_oa_buf_alloc;
 
+       ret = i915_mutex_lock_interruptible(&dev_priv->drm);
+       if (ret)
+               goto err_lock;
+
        ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv,
                                                      stream->oa_config);
        if (ret)
@@ -2145,23 +2137,17 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
 
        stream->ops = &i915_oa_stream_ops;
 
-       /* Lock device for exclusive_stream access late because
-        * enable_metric_set() might lock as well on gen8+.
-        */
-       ret = i915_mutex_lock_interruptible(&dev_priv->drm);
-       if (ret)
-               goto err_lock;
-
        dev_priv->perf.oa.exclusive_stream = stream;
 
        mutex_unlock(&dev_priv->drm.struct_mutex);
 
        return 0;
 
-err_lock:
+err_enable:
        dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
+       mutex_unlock(&dev_priv->drm.struct_mutex);
 
-err_enable:
+err_lock:
        free_oa_buffer(dev_priv);
 
 err_oa_buf_alloc:
index 55a8a1e2942483cda1d631cc623d56f2a75b4683..0e9b98c32b62b0225633a24d3fa41396f9ab70d8 100644 (file)
@@ -285,26 +285,41 @@ static u64 count_interrupts(struct drm_i915_private *i915)
        return sum;
 }
 
-static void i915_pmu_event_destroy(struct perf_event *event)
+static void engine_event_destroy(struct perf_event *event)
 {
-       WARN_ON(event->parent);
+       struct drm_i915_private *i915 =
+               container_of(event->pmu, typeof(*i915), pmu.base);
+       struct intel_engine_cs *engine;
+
+       engine = intel_engine_lookup_user(i915,
+                                         engine_event_class(event),
+                                         engine_event_instance(event));
+       if (WARN_ON_ONCE(!engine))
+               return;
+
+       if (engine_event_sample(event) == I915_SAMPLE_BUSY &&
+           intel_engine_supports_stats(engine))
+               intel_disable_engine_stats(engine);
 }
 
-static int engine_event_init(struct perf_event *event)
+static void i915_pmu_event_destroy(struct perf_event *event)
 {
-       struct drm_i915_private *i915 =
-               container_of(event->pmu, typeof(*i915), pmu.base);
+       WARN_ON(event->parent);
 
-       if (!intel_engine_lookup_user(i915, engine_event_class(event),
-                                     engine_event_instance(event)))
-               return -ENODEV;
+       if (is_engine_event(event))
+               engine_event_destroy(event);
+}
 
-       switch (engine_event_sample(event)) {
+static int
+engine_event_status(struct intel_engine_cs *engine,
+                   enum drm_i915_pmu_engine_sample sample)
+{
+       switch (sample) {
        case I915_SAMPLE_BUSY:
        case I915_SAMPLE_WAIT:
                break;
        case I915_SAMPLE_SEMA:
-               if (INTEL_GEN(i915) < 6)
+               if (INTEL_GEN(engine->i915) < 6)
                        return -ENODEV;
                break;
        default:
@@ -314,6 +329,30 @@ static int engine_event_init(struct perf_event *event)
        return 0;
 }
 
+static int engine_event_init(struct perf_event *event)
+{
+       struct drm_i915_private *i915 =
+               container_of(event->pmu, typeof(*i915), pmu.base);
+       struct intel_engine_cs *engine;
+       u8 sample;
+       int ret;
+
+       engine = intel_engine_lookup_user(i915, engine_event_class(event),
+                                         engine_event_instance(event));
+       if (!engine)
+               return -ENODEV;
+
+       sample = engine_event_sample(event);
+       ret = engine_event_status(engine, sample);
+       if (ret)
+               return ret;
+
+       if (sample == I915_SAMPLE_BUSY && intel_engine_supports_stats(engine))
+               ret = intel_enable_engine_stats(engine);
+
+       return ret;
+}
+
 static int i915_pmu_event_init(struct perf_event *event)
 {
        struct drm_i915_private *i915 =
@@ -370,7 +409,94 @@ static int i915_pmu_event_init(struct perf_event *event)
        return 0;
 }
 
-static u64 __i915_pmu_event_read(struct perf_event *event)
+static u64 __get_rc6(struct drm_i915_private *i915)
+{
+       u64 val;
+
+       val = intel_rc6_residency_ns(i915,
+                                    IS_VALLEYVIEW(i915) ?
+                                    VLV_GT_RENDER_RC6 :
+                                    GEN6_GT_GFX_RC6);
+
+       if (HAS_RC6p(i915))
+               val += intel_rc6_residency_ns(i915, GEN6_GT_GFX_RC6p);
+
+       if (HAS_RC6pp(i915))
+               val += intel_rc6_residency_ns(i915, GEN6_GT_GFX_RC6pp);
+
+       return val;
+}
+
+static u64 get_rc6(struct drm_i915_private *i915, bool locked)
+{
+#if IS_ENABLED(CONFIG_PM)
+       unsigned long flags;
+       u64 val;
+
+       if (intel_runtime_pm_get_if_in_use(i915)) {
+               val = __get_rc6(i915);
+               intel_runtime_pm_put(i915);
+
+               /*
+                * If we are coming back from being runtime suspended we must
+                * be careful not to report a larger value than returned
+                * previously.
+                */
+
+               if (!locked)
+                       spin_lock_irqsave(&i915->pmu.lock, flags);
+
+               if (val >= i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
+                       i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0;
+                       i915->pmu.sample[__I915_SAMPLE_RC6].cur = val;
+               } else {
+                       val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
+               }
+
+               if (!locked)
+                       spin_unlock_irqrestore(&i915->pmu.lock, flags);
+       } else {
+               struct pci_dev *pdev = i915->drm.pdev;
+               struct device *kdev = &pdev->dev;
+               unsigned long flags2;
+
+               /*
+                * We are runtime suspended.
+                *
+                * Report the delta from when the device was suspended to now,
+                * on top of the last known real value, as the approximated RC6
+                * counter value.
+                */
+               if (!locked)
+                       spin_lock_irqsave(&i915->pmu.lock, flags);
+
+               spin_lock_irqsave(&kdev->power.lock, flags2);
+
+               if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
+                       i915->pmu.suspended_jiffies_last =
+                                               kdev->power.suspended_jiffies;
+
+               val = kdev->power.suspended_jiffies -
+                     i915->pmu.suspended_jiffies_last;
+               val += jiffies - kdev->power.accounting_timestamp;
+
+               spin_unlock_irqrestore(&kdev->power.lock, flags2);
+
+               val = jiffies_to_nsecs(val);
+               val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
+               i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
+
+               if (!locked)
+                       spin_unlock_irqrestore(&i915->pmu.lock, flags);
+       }
+
+       return val;
+#else
+       return __get_rc6(i915);
+#endif
+}
+
+static u64 __i915_pmu_event_read(struct perf_event *event, bool locked)
 {
        struct drm_i915_private *i915 =
                container_of(event->pmu, typeof(*i915), pmu.base);
@@ -387,7 +513,7 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
                if (WARN_ON_ONCE(!engine)) {
                        /* Do nothing */
                } else if (sample == I915_SAMPLE_BUSY &&
-                          engine->pmu.busy_stats) {
+                          intel_engine_supports_stats(engine)) {
                        val = ktime_to_ns(intel_engine_get_busy_time(engine));
                } else {
                        val = engine->pmu.sample[sample].cur;
@@ -408,18 +534,7 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
                        val = count_interrupts(i915);
                        break;
                case I915_PMU_RC6_RESIDENCY:
-                       intel_runtime_pm_get(i915);
-                       val = intel_rc6_residency_ns(i915,
-                                                    IS_VALLEYVIEW(i915) ?
-                                                    VLV_GT_RENDER_RC6 :
-                                                    GEN6_GT_GFX_RC6);
-                       if (HAS_RC6p(i915))
-                               val += intel_rc6_residency_ns(i915,
-                                                             GEN6_GT_GFX_RC6p);
-                       if (HAS_RC6pp(i915))
-                               val += intel_rc6_residency_ns(i915,
-                                                             GEN6_GT_GFX_RC6pp);
-                       intel_runtime_pm_put(i915);
+                       val = get_rc6(i915, locked);
                        break;
                }
        }
@@ -434,7 +549,7 @@ static void i915_pmu_event_read(struct perf_event *event)
 
 again:
        prev = local64_read(&hwc->prev_count);
-       new = __i915_pmu_event_read(event);
+       new = __i915_pmu_event_read(event, false);
 
        if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
                goto again;
@@ -442,12 +557,6 @@ again:
        local64_add(new - prev, &event->count);
 }
 
-static bool engine_needs_busy_stats(struct intel_engine_cs *engine)
-{
-       return intel_engine_supports_stats(engine) &&
-              (engine->pmu.enable & BIT(I915_SAMPLE_BUSY));
-}
-
 static void i915_pmu_enable(struct perf_event *event)
 {
        struct drm_i915_private *i915 =
@@ -487,21 +596,7 @@ static void i915_pmu_enable(struct perf_event *event)
 
                GEM_BUG_ON(sample >= I915_PMU_SAMPLE_BITS);
                GEM_BUG_ON(engine->pmu.enable_count[sample] == ~0);
-               if (engine->pmu.enable_count[sample]++ == 0) {
-                       /*
-                        * Enable engine busy stats tracking if needed or
-                        * alternatively cancel the scheduled disable.
-                        *
-                        * If the delayed disable was pending, cancel it and
-                        * in this case do not enable since it already is.
-                        */
-                       if (engine_needs_busy_stats(engine) &&
-                           !engine->pmu.busy_stats) {
-                               engine->pmu.busy_stats = true;
-                               if (!cancel_delayed_work(&engine->pmu.disable_busy_stats))
-                                       intel_enable_engine_stats(engine);
-                       }
-               }
+               engine->pmu.enable_count[sample]++;
        }
 
        /*
@@ -509,19 +604,11 @@ static void i915_pmu_enable(struct perf_event *event)
         * for all listeners. Even when the event was already enabled and has
         * an existing non-zero value.
         */
-       local64_set(&event->hw.prev_count, __i915_pmu_event_read(event));
+       local64_set(&event->hw.prev_count, __i915_pmu_event_read(event, true));
 
        spin_unlock_irqrestore(&i915->pmu.lock, flags);
 }
 
-static void __disable_busy_stats(struct work_struct *work)
-{
-       struct intel_engine_cs *engine =
-              container_of(work, typeof(*engine), pmu.disable_busy_stats.work);
-
-       intel_disable_engine_stats(engine);
-}
-
 static void i915_pmu_disable(struct perf_event *event)
 {
        struct drm_i915_private *i915 =
@@ -545,26 +632,8 @@ static void i915_pmu_disable(struct perf_event *event)
                 * Decrement the reference count and clear the enabled
                 * bitmask when the last listener on an event goes away.
                 */
-               if (--engine->pmu.enable_count[sample] == 0) {
+               if (--engine->pmu.enable_count[sample] == 0)
                        engine->pmu.enable &= ~BIT(sample);
-                       if (!engine_needs_busy_stats(engine) &&
-                           engine->pmu.busy_stats) {
-                               engine->pmu.busy_stats = false;
-                               /*
-                                * We request a delayed disable to handle the
-                                * rapid on/off cycles on events, which can
-                                * happen when tools like perf stat start, in a
-                                * nicer way.
-                                *
-                                * In addition, this also helps with busy stats
-                                * accuracy with background CPU offline/online
-                                * migration events.
-                                */
-                               queue_delayed_work(system_wq,
-                                                  &engine->pmu.disable_busy_stats,
-                                                  round_jiffies_up_relative(HZ));
-                       }
-               }
        }
 
        GEM_BUG_ON(bit >= I915_PMU_MASK_BITS);
@@ -797,8 +866,6 @@ static void i915_pmu_unregister_cpuhp_state(struct drm_i915_private *i915)
 
 void i915_pmu_register(struct drm_i915_private *i915)
 {
-       struct intel_engine_cs *engine;
-       enum intel_engine_id id;
        int ret;
 
        if (INTEL_GEN(i915) <= 2) {
@@ -820,10 +887,6 @@ void i915_pmu_register(struct drm_i915_private *i915)
        hrtimer_init(&i915->pmu.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        i915->pmu.timer.function = i915_sample;
 
-       for_each_engine(engine, i915, id)
-               INIT_DELAYED_WORK(&engine->pmu.disable_busy_stats,
-                                 __disable_busy_stats);
-
        ret = perf_pmu_register(&i915->pmu.base, "i915", -1);
        if (ret)
                goto err;
@@ -843,9 +906,6 @@ err:
 
 void i915_pmu_unregister(struct drm_i915_private *i915)
 {
-       struct intel_engine_cs *engine;
-       enum intel_engine_id id;
-
        if (!i915->pmu.base.event_init)
                return;
 
@@ -853,11 +913,6 @@ void i915_pmu_unregister(struct drm_i915_private *i915)
 
        hrtimer_cancel(&i915->pmu.timer);
 
-       for_each_engine(engine, i915, id) {
-               GEM_BUG_ON(engine->pmu.busy_stats);
-               flush_delayed_work(&engine->pmu.disable_busy_stats);
-       }
-
        i915_pmu_unregister_cpuhp_state(i915);
 
        perf_pmu_unregister(&i915->pmu.base);
index 40c154d13565a09b34399c462c18aa69cec24226..bb62df15afa4f4cf3f0b79cd3c1fa2b182a5bcca 100644 (file)
@@ -27,6 +27,8 @@
 enum {
        __I915_SAMPLE_FREQ_ACT = 0,
        __I915_SAMPLE_FREQ_REQ,
+       __I915_SAMPLE_RC6,
+       __I915_SAMPLE_RC6_ESTIMATED,
        __I915_NUM_PMU_SAMPLERS
 };
 
@@ -94,6 +96,10 @@ struct i915_pmu {
         * struct intel_engine_cs.
         */
        struct i915_pmu_sample sample[__I915_NUM_PMU_SAMPLERS];
+       /**
+        * @suspended_jiffies_last: Cached suspend time from PM core.
+        */
+       unsigned long suspended_jiffies_last;
 };
 
 #ifdef CONFIG_PERF_EVENTS
index a2108e35c599982831cab1eab39c6b6721af1d80..33eb0c5b1d3244d944a9e80fa883352952cb5ac0 100644 (file)
@@ -2027,7 +2027,7 @@ enum i915_power_well_id {
 #define _CNL_PORT_TX_DW5_LN0_AE                0x162454
 #define _CNL_PORT_TX_DW5_LN0_B         0x162654
 #define _CNL_PORT_TX_DW5_LN0_C         0x162C54
-#define _CNL_PORT_TX_DW5_LN0_D         0x162ED4
+#define _CNL_PORT_TX_DW5_LN0_D         0x162E54
 #define _CNL_PORT_TX_DW5_LN0_F         0x162854
 #define CNL_PORT_TX_DW5_GRP(port)      _MMIO_PORT6(port, \
                                                    _CNL_PORT_TX_DW5_GRP_AE, \
@@ -2058,7 +2058,7 @@ enum i915_power_well_id {
 #define _CNL_PORT_TX_DW7_LN0_AE                0x16245C
 #define _CNL_PORT_TX_DW7_LN0_B         0x16265C
 #define _CNL_PORT_TX_DW7_LN0_C         0x162C5C
-#define _CNL_PORT_TX_DW7_LN0_D         0x162EDC
+#define _CNL_PORT_TX_DW7_LN0_D         0x162E5C
 #define _CNL_PORT_TX_DW7_LN0_F         0x16285C
 #define CNL_PORT_TX_DW7_GRP(port)      _MMIO_PORT6(port, \
                                                    _CNL_PORT_TX_DW7_GRP_AE, \
index b33d2158c234df68fc0a983b58daa37d74a74575..e5e6f6bb2b05a62039652c260a2accd51e2b2c95 100644 (file)
@@ -304,8 +304,9 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
 {
        struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
        struct intel_rps *rps = &dev_priv->gt_pm.rps;
-       u32 val;
+       bool boost = false;
        ssize_t ret;
+       u32 val;
 
        ret = kstrtou32(buf, 0, &val);
        if (ret)
@@ -317,8 +318,13 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
                return -EINVAL;
 
        mutex_lock(&dev_priv->pcu_lock);
-       rps->boost_freq = val;
+       if (val != rps->boost_freq) {
+               rps->boost_freq = val;
+               boost = atomic_read(&rps->num_waiters);
+       }
        mutex_unlock(&dev_priv->pcu_lock);
+       if (boost)
+               schedule_work(&rps->work);
 
        return count;
 }
index 522d54fecb53489193eb2b72dbf9fdd41009ac67..4a01f62a392dd18569ca0f3503c87bd1bbbe59b9 100644 (file)
@@ -779,11 +779,11 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
 {
        struct intel_encoder *encoder;
 
-       if (WARN_ON(pipe >= ARRAY_SIZE(dev_priv->av_enc_map)))
-               return NULL;
-
        /* MST */
        if (pipe >= 0) {
+               if (WARN_ON(pipe >= ARRAY_SIZE(dev_priv->av_enc_map)))
+                       return NULL;
+
                encoder = dev_priv->av_enc_map[pipe];
                /*
                 * when bootup, audio driver may not know it is
index f7f771749e4809dcedbea023bea54e4be4ac1537..b49a2df444301c82ce4fcc2de6b7111fe8a26a01 100644 (file)
@@ -947,6 +947,86 @@ static int goto_next_sequence_v3(const u8 *data, int index, int total)
        return 0;
 }
 
+/*
+ * Get len of pre-fixed deassert fragment from a v1 init OTP sequence,
+ * skip all delay + gpio operands and stop at the first DSI packet op.
+ */
+static int get_init_otp_deassert_fragment_len(struct drm_i915_private *dev_priv)
+{
+       const u8 *data = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP];
+       int index, len;
+
+       if (WARN_ON(!data || dev_priv->vbt.dsi.seq_version != 1))
+               return 0;
+
+       /* index = 1 to skip sequence byte */
+       for (index = 1; data[index] != MIPI_SEQ_ELEM_END; index += len) {
+               switch (data[index]) {
+               case MIPI_SEQ_ELEM_SEND_PKT:
+                       return index == 1 ? 0 : index;
+               case MIPI_SEQ_ELEM_DELAY:
+                       len = 5; /* 1 byte for operand + uint32 */
+                       break;
+               case MIPI_SEQ_ELEM_GPIO:
+                       len = 3; /* 1 byte for op, 1 for gpio_nr, 1 for value */
+                       break;
+               default:
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Some v1 VBT MIPI sequences do the deassert in the init OTP sequence.
+ * The deassert must be done before calling intel_dsi_device_ready, so for
+ * these devices we split the init OTP sequence into a deassert sequence and
+ * the actual init OTP part.
+ */
+static void fixup_mipi_sequences(struct drm_i915_private *dev_priv)
+{
+       u8 *init_otp;
+       int len;
+
+       /* Limit this to VLV for now. */
+       if (!IS_VALLEYVIEW(dev_priv))
+               return;
+
+       /* Limit this to v1 vid-mode sequences */
+       if (dev_priv->vbt.dsi.config->is_cmd_mode ||
+           dev_priv->vbt.dsi.seq_version != 1)
+               return;
+
+       /* Only do this if there are otp and assert seqs and no deassert seq */
+       if (!dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] ||
+           !dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET] ||
+           dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET])
+               return;
+
+       /* The deassert-sequence ends at the first DSI packet */
+       len = get_init_otp_deassert_fragment_len(dev_priv);
+       if (!len)
+               return;
+
+       DRM_DEBUG_KMS("Using init OTP fragment to deassert reset\n");
+
+       /* Copy the fragment, update seq byte and terminate it */
+       init_otp = (u8 *)dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP];
+       dev_priv->vbt.dsi.deassert_seq = kmemdup(init_otp, len + 1, GFP_KERNEL);
+       if (!dev_priv->vbt.dsi.deassert_seq)
+               return;
+       dev_priv->vbt.dsi.deassert_seq[0] = MIPI_SEQ_DEASSERT_RESET;
+       dev_priv->vbt.dsi.deassert_seq[len] = MIPI_SEQ_ELEM_END;
+       /* Use the copy for deassert */
+       dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET] =
+               dev_priv->vbt.dsi.deassert_seq;
+       /* Replace the last byte of the fragment with init OTP seq byte */
+       init_otp[len - 1] = MIPI_SEQ_INIT_OTP;
+       /* And make MIPI_MIPI_SEQ_INIT_OTP point to it */
+       dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1;
+}
+
 static void
 parse_mipi_sequence(struct drm_i915_private *dev_priv,
                    const struct bdb_header *bdb)
@@ -1016,6 +1096,8 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv,
        dev_priv->vbt.dsi.size = seq_size;
        dev_priv->vbt.dsi.seq_version = sequence->version;
 
+       fixup_mipi_sequences(dev_priv);
+
        DRM_DEBUG_DRIVER("MIPI related VBT parsing complete\n");
        return;
 
@@ -1588,6 +1670,29 @@ out:
                pci_unmap_rom(pdev, bios);
 }
 
+/**
+ * intel_bios_cleanup - Free any resources allocated by intel_bios_init()
+ * @dev_priv: i915 device instance
+ */
+void intel_bios_cleanup(struct drm_i915_private *dev_priv)
+{
+       kfree(dev_priv->vbt.child_dev);
+       dev_priv->vbt.child_dev = NULL;
+       dev_priv->vbt.child_dev_num = 0;
+       kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
+       dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
+       kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
+       dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
+       kfree(dev_priv->vbt.dsi.data);
+       dev_priv->vbt.dsi.data = NULL;
+       kfree(dev_priv->vbt.dsi.pps);
+       dev_priv->vbt.dsi.pps = NULL;
+       kfree(dev_priv->vbt.dsi.config);
+       dev_priv->vbt.dsi.config = NULL;
+       kfree(dev_priv->vbt.dsi.deassert_seq);
+       dev_priv->vbt.dsi.deassert_seq = NULL;
+}
+
 /**
  * intel_bios_is_tv_present - is integrated TV present in VBT
  * @dev_priv:  i915 device instance
index bd40fea16b4f1fc6d01bfdc6e80705d5234c9fce..f54ddda9fdadac01226cd65084674b91b807af76 100644 (file)
@@ -594,29 +594,16 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine,
        spin_unlock_irq(&b->rb_lock);
 }
 
-static bool signal_valid(const struct drm_i915_gem_request *request)
-{
-       return intel_wait_check_request(&request->signaling.wait, request);
-}
-
 static bool signal_complete(const struct drm_i915_gem_request *request)
 {
        if (!request)
                return false;
 
-       /* If another process served as the bottom-half it may have already
-        * signalled that this wait is already completed.
-        */
-       if (intel_wait_complete(&request->signaling.wait))
-               return signal_valid(request);
-
-       /* Carefully check if the request is complete, giving time for the
+       /*
+        * Carefully check if the request is complete, giving time for the
         * seqno to be visible or if the GPU hung.
         */
-       if (__i915_request_irq_complete(request))
-               return true;
-
-       return false;
+       return __i915_request_irq_complete(request);
 }
 
 static struct drm_i915_gem_request *to_signaler(struct rb_node *rb)
@@ -659,9 +646,13 @@ static int intel_breadcrumbs_signaler(void *arg)
                        request = i915_gem_request_get_rcu(request);
                rcu_read_unlock();
                if (signal_complete(request)) {
-                       local_bh_disable();
-                       dma_fence_signal(&request->fence);
-                       local_bh_enable(); /* kick start the tasklets */
+                       if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
+                                     &request->fence.flags)) {
+                               local_bh_disable();
+                               dma_fence_signal(&request->fence);
+                               GEM_BUG_ON(!i915_gem_request_completed(request));
+                               local_bh_enable(); /* kick start the tasklets */
+                       }
 
                        spin_lock_irq(&b->rb_lock);
 
index 5dc118f26b51b7b63c8849e53b6a295c11328c80..1704c8897afd0f91458d490ff9531a4f3ad2414f 100644 (file)
@@ -1952,6 +1952,14 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
        if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
                min_cdclk = max(2 * 96000, min_cdclk);
 
+       /*
+        * On Valleyview some DSI panels lose (v|h)sync when the clock is lower
+        * than 320000KHz.
+        */
+       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&
+           IS_VALLEYVIEW(dev_priv))
+               min_cdclk = max(320000, min_cdclk);
+
        if (min_cdclk > dev_priv->max_cdclk_freq) {
                DRM_DEBUG_KMS("required cdclk (%d kHz) exceeds max (%d kHz)\n",
                              min_cdclk, dev_priv->max_cdclk_freq);
index f51645a08dcaf489e0668af616fe39d421822a38..6aff9d096e13d08addb7b0bdf143aa9e73c2223b 100644 (file)
@@ -2175,8 +2175,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
                intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
        intel_ddi_init_dp_buf_reg(encoder);
-       if (!is_mst)
-               intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+       intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
        intel_dp_start_link_train(intel_dp);
        if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
                intel_dp_stop_link_train(intel_dp);
@@ -2274,14 +2273,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
        struct intel_dp *intel_dp = &dig_port->dp;
-       bool is_mst = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST);
 
        /*
         * Power down sink before disabling the port, otherwise we end
         * up getting interrupts from the sink on detecting link loss.
         */
-       if (!is_mst)
-               intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+       intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 
        intel_disable_ddi_buf(encoder);
 
index 35c5299feab6862659023ce54f3d99dd45aacbec..a29868cd30c740feec642e801838b5eb5e9a0e95 100644 (file)
@@ -620,19 +620,15 @@ static int
 bxt_power_sequencer_idx(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+       int backlight_controller = dev_priv->vbt.backlight.controller;
 
        lockdep_assert_held(&dev_priv->pps_mutex);
 
        /* We should never land here with regular DP ports */
        WARN_ON(!intel_dp_is_edp(intel_dp));
 
-       /*
-        * TODO: BXT has 2 PPS instances. The correct port->PPS instance
-        * mapping needs to be retrieved from VBT, for now just hard-code to
-        * use instance #0 always.
-        */
        if (!intel_dp->pps_reset)
-               return 0;
+               return backlight_controller;
 
        intel_dp->pps_reset = false;
 
@@ -642,7 +638,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp)
         */
        intel_dp_init_panel_power_sequencer_registers(intel_dp, false);
 
-       return 0;
+       return backlight_controller;
 }
 
 typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv,
index d790bdc227ffb562fa58f50023e264d2bd8b5c38..fa960cfd2764f8e44d3d48d0e810cb2cfe4b087a 100644 (file)
@@ -1458,7 +1458,9 @@ static bool ring_is_idle(struct intel_engine_cs *engine)
        struct drm_i915_private *dev_priv = engine->i915;
        bool idle = true;
 
-       intel_runtime_pm_get(dev_priv);
+       /* If the whole device is asleep, the engine must be idle */
+       if (!intel_runtime_pm_get_if_in_use(dev_priv))
+               return true;
 
        /* First check that no commands are left in the ring */
        if ((I915_READ_HEAD(engine) & HEAD_ADDR) !=
@@ -1943,16 +1945,22 @@ intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
  */
 int intel_enable_engine_stats(struct intel_engine_cs *engine)
 {
+       struct intel_engine_execlists *execlists = &engine->execlists;
        unsigned long flags;
+       int err = 0;
 
        if (!intel_engine_supports_stats(engine))
                return -ENODEV;
 
+       tasklet_disable(&execlists->tasklet);
        spin_lock_irqsave(&engine->stats.lock, flags);
-       if (engine->stats.enabled == ~0)
-               goto busy;
+
+       if (unlikely(engine->stats.enabled == ~0)) {
+               err = -EBUSY;
+               goto unlock;
+       }
+
        if (engine->stats.enabled++ == 0) {
-               struct intel_engine_execlists *execlists = &engine->execlists;
                const struct execlist_port *port = execlists->port;
                unsigned int num_ports = execlists_num_ports(execlists);
 
@@ -1967,14 +1975,12 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
                if (engine->stats.active)
                        engine->stats.start = engine->stats.enabled_at;
        }
-       spin_unlock_irqrestore(&engine->stats.lock, flags);
-
-       return 0;
 
-busy:
+unlock:
        spin_unlock_irqrestore(&engine->stats.lock, flags);
+       tasklet_enable(&execlists->tasklet);
 
-       return -EBUSY;
+       return err;
 }
 
 static ktime_t __intel_engine_get_busy_time(struct intel_engine_cs *engine)
index 348a4f7ffb674b435bdb77089f9c229abe171ab5..53747318f4a7162fe79f2217108ad889e138b3e7 100644 (file)
@@ -246,7 +246,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
         */
        tmp = I915_READ_CTL(engine);
        if (tmp & RING_WAIT) {
-               i915_handle_error(dev_priv, 0,
+               i915_handle_error(dev_priv, BIT(engine->id),
                                  "Kicking stuck wait on %s",
                                  engine->name);
                I915_WRITE_CTL(engine, tmp);
@@ -258,7 +258,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
                default:
                        return ENGINE_DEAD;
                case 1:
-                       i915_handle_error(dev_priv, 0,
+                       i915_handle_error(dev_priv, ALL_ENGINES,
                                          "Kicking stuck semaphore on %s",
                                          engine->name);
                        I915_WRITE_CTL(engine, tmp);
index 7ece2f061b9e8087ce7f5b22179377435d50af9b..e0fca035ff789be49a9811eade75cd92a67eea3a 100644 (file)
@@ -719,6 +719,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
        struct rb_node *rb;
        unsigned long flags;
 
+       GEM_TRACE("%s\n", engine->name);
+
        spin_lock_irqsave(&engine->timeline->lock, flags);
 
        /* Cancel the requests on the HW and clear the ELSP tracker. */
@@ -765,6 +767,9 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
         */
        clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
 
+       /* Mark all CS interrupts as complete */
+       execlists->active = 0;
+
        spin_unlock_irqrestore(&engine->timeline->lock, flags);
 }
 
index c5ff203e42d6a8627d3c6bb18c589a103311d0c3..a0e7a6c2a57cd8f0b66f27e7e5dcc874857fd649 100644 (file)
@@ -366,20 +366,6 @@ struct intel_engine_cs {
                 */
 #define I915_ENGINE_SAMPLE_MAX (I915_SAMPLE_SEMA + 1)
                struct i915_pmu_sample sample[I915_ENGINE_SAMPLE_MAX];
-               /**
-                * @busy_stats: Has enablement of engine stats tracking been
-                *              requested.
-                */
-               bool busy_stats;
-               /**
-                * @disable_busy_stats: Work item for busy stats disabling.
-                *
-                * Same as with @enable_busy_stats action, with the difference
-                * that we delay it in case there are rapid enable-disable
-                * actions, which can happen during tool startup (like perf
-                * stat).
-                */
-               struct delayed_work disable_busy_stats;
        } pmu;
 
        /*
index 9a9961802f5c39ce7270217903c550b2f01ed92d..e83af0f2be869a105036bf49c4f1b612acab83ee 100644 (file)
@@ -225,7 +225,11 @@ static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
                                  struct drm_crtc_state *old_crtc_state)
 {
        drm_crtc_vblank_on(crtc);
+}
 
+static void ipu_crtc_atomic_flush(struct drm_crtc *crtc,
+                                 struct drm_crtc_state *old_crtc_state)
+{
        spin_lock_irq(&crtc->dev->event_lock);
        if (crtc->state->event) {
                WARN_ON(drm_crtc_vblank_get(crtc));
@@ -293,6 +297,7 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
        .mode_set_nofb = ipu_crtc_mode_set_nofb,
        .atomic_check = ipu_crtc_atomic_check,
        .atomic_begin = ipu_crtc_atomic_begin,
+       .atomic_flush = ipu_crtc_atomic_flush,
        .atomic_disable = ipu_crtc_atomic_disable,
        .atomic_enable = ipu_crtc_atomic_enable,
 };
index 57ed56d8623fcb67133f1fe79f390ad45c38c257..d9113faaa62f56400e5e974a5005edc928d0fae3 100644 (file)
@@ -22,6 +22,7 @@
 #include <drm/drm_plane_helper.h>
 
 #include "video/imx-ipu-v3.h"
+#include "imx-drm.h"
 #include "ipuv3-plane.h"
 
 struct ipu_plane_state {
@@ -272,7 +273,7 @@ static void ipu_plane_destroy(struct drm_plane *plane)
        kfree(ipu_plane);
 }
 
-void ipu_plane_state_reset(struct drm_plane *plane)
+static void ipu_plane_state_reset(struct drm_plane *plane)
 {
        struct ipu_plane_state *ipu_state;
 
@@ -292,7 +293,8 @@ void ipu_plane_state_reset(struct drm_plane *plane)
        plane->state = &ipu_state->base;
 }
 
-struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
+static struct drm_plane_state *
+ipu_plane_duplicate_state(struct drm_plane *plane)
 {
        struct ipu_plane_state *state;
 
@@ -306,8 +308,8 @@ struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
        return &state->base;
 }
 
-void ipu_plane_destroy_state(struct drm_plane *plane,
-                            struct drm_plane_state *state)
+static void ipu_plane_destroy_state(struct drm_plane *plane,
+                                   struct drm_plane_state *state)
 {
        struct ipu_plane_state *ipu_state = to_ipu_plane_state(state);
 
index 5155f0179b61744f41f18922a9d0c1b39ec28b10..05520202c96778c1401dac07a9b9ff768ba97b91 100644 (file)
@@ -36,6 +36,7 @@
 #include "meson_venc.h"
 #include "meson_vpp.h"
 #include "meson_viu.h"
+#include "meson_canvas.h"
 #include "meson_registers.h"
 
 /* CRTC definition */
@@ -192,6 +193,11 @@ void meson_crtc_irq(struct meson_drm *priv)
                } else
                        meson_vpp_disable_interlace_vscaler_osd1(priv);
 
+               meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
+                          priv->viu.osd1_addr, priv->viu.osd1_stride,
+                          priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
+                          MESON_CANVAS_BLKMODE_LINEAR);
+
                /* Enable OSD1 */
                writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
                                    priv->io_base + _REG(VPP_MISC));
index 5e8b392b9d1ff0da66a429b386a308019467c62a..8450d6ac8c9bc1dcd049fd8c2205d1c5a8c7c924 100644 (file)
@@ -43,6 +43,9 @@ struct meson_drm {
                bool osd1_commit;
                uint32_t osd1_ctrl_stat;
                uint32_t osd1_blk0_cfg[5];
+               uint32_t osd1_addr;
+               uint32_t osd1_stride;
+               uint32_t osd1_height;
        } viu;
 
        struct {
index d0a6ac8390f39fd64dd194b76c3078e374ef51f2..27bd3503e1e49eb82b51a9b2cf11bfd7593da20a 100644 (file)
@@ -164,10 +164,9 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
        /* Update Canvas with buffer address */
        gem = drm_fb_cma_get_gem_obj(fb, 0);
 
-       meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
-                          gem->paddr, fb->pitches[0],
-                          fb->height, MESON_CANVAS_WRAP_NONE,
-                          MESON_CANVAS_BLKMODE_LINEAR);
+       priv->viu.osd1_addr = gem->paddr;
+       priv->viu.osd1_stride = fb->pitches[0];
+       priv->viu.osd1_height = fb->height;
 
        spin_unlock_irqrestore(&priv->drm->event_lock, flags);
 }
index 3e9bba4d66246b10a2f4a914fbddf97513681de0..6d8e3a9a6fc093164adc20e37e7b70db54cfe7bf 100644 (file)
@@ -680,7 +680,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
        } else {
                dev_info(&pdev->dev,
                         "no iommu, fallback to phys contig buffers for scanout\n");
-               aspace = NULL;;
+               aspace = NULL;
        }
 
        pm_runtime_put_sync(&pdev->dev);
index 380f340204e8a844be6541adc8b7c506844c9ba0..debbbf0fd4bdda619732c67952c772f9957c4166 100644 (file)
@@ -134,7 +134,7 @@ nv50_get_intensity(struct backlight_device *bd)
        struct nouveau_encoder *nv_encoder = bl_get_data(bd);
        struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
        struct nvif_object *device = &drm->client.device.object;
-       int or = nv_encoder->or;
+       int or = ffs(nv_encoder->dcb->or) - 1;
        u32 div = 1025;
        u32 val;
 
@@ -149,7 +149,7 @@ nv50_set_intensity(struct backlight_device *bd)
        struct nouveau_encoder *nv_encoder = bl_get_data(bd);
        struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
        struct nvif_object *device = &drm->client.device.object;
-       int or = nv_encoder->or;
+       int or = ffs(nv_encoder->dcb->or) - 1;
        u32 div = 1025;
        u32 val = (bd->props.brightness * div) / 100;
 
@@ -170,7 +170,7 @@ nva3_get_intensity(struct backlight_device *bd)
        struct nouveau_encoder *nv_encoder = bl_get_data(bd);
        struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
        struct nvif_object *device = &drm->client.device.object;
-       int or = nv_encoder->or;
+       int or = ffs(nv_encoder->dcb->or) - 1;
        u32 div, val;
 
        div  = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
@@ -188,7 +188,7 @@ nva3_set_intensity(struct backlight_device *bd)
        struct nouveau_encoder *nv_encoder = bl_get_data(bd);
        struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
        struct nvif_object *device = &drm->client.device.object;
-       int or = nv_encoder->or;
+       int or = ffs(nv_encoder->dcb->or) - 1;
        u32 div, val;
 
        div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
@@ -228,7 +228,7 @@ nv50_backlight_init(struct drm_connector *connector)
                        return -ENODEV;
        }
 
-       if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or)))
+       if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1)))
                return 0;
 
        if (drm->client.device.info.chipset <= 0xa0 ||
@@ -268,13 +268,13 @@ nouveau_backlight_init(struct drm_device *dev)
        struct nvif_device *device = &drm->client.device;
        struct drm_connector *connector;
 
+       INIT_LIST_HEAD(&drm->bl_connectors);
+
        if (apple_gmux_present()) {
                NV_INFO(drm, "Apple GMUX detected: not registering Nouveau backlight interface\n");
                return 0;
        }
 
-       INIT_LIST_HEAD(&drm->bl_connectors);
-
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
                    connector->connector_type != DRM_MODE_CONNECTOR_eDP)
index 69d6e61a01ecfb3e48d6ecaa7749b532227ec0bf..6ed9cb053dfa5fd3bff312b155541ef17a4aadad 100644 (file)
@@ -570,9 +570,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
                nv_connector->edid = NULL;
        }
 
-       ret = pm_runtime_get_sync(connector->dev->dev);
-       if (ret < 0 && ret != -EACCES)
-               return conn_status;
+       /* Outputs are only polled while runtime active, so acquiring a
+        * runtime PM ref here is unnecessary (and would deadlock upon
+        * runtime suspend because it waits for polling to finish).
+        */
+       if (!drm_kms_helper_is_poll_worker()) {
+               ret = pm_runtime_get_sync(connector->dev->dev);
+               if (ret < 0 && ret != -EACCES)
+                       return conn_status;
+       }
 
        nv_encoder = nouveau_connector_ddc_detect(connector);
        if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
@@ -647,8 +653,10 @@ detect_analog:
 
  out:
 
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return conn_status;
 }
index dd8d4352ed998e7f09d36a981098edae84830808..caddce88d2d8b3e5eaf0528c609fc2a190c8294f 100644 (file)
@@ -4477,6 +4477,7 @@ nv50_display_create(struct drm_device *dev)
        nouveau_display(dev)->fini = nv50_display_fini;
        disp->disp = &nouveau_display(dev)->disp;
        dev->mode_config.funcs = &nv50_disp_func;
+       dev->driver->driver_features |= DRIVER_PREFER_XBGR_30BPP;
        if (nouveau_atomic)
                dev->driver->driver_features |= DRIVER_ATOMIC;
 
index 93946dcee3191be1418ecf332ef7135854849a09..1c12e58f44c2684b5ce0d84a18e286b55a01235f 100644 (file)
@@ -1354,7 +1354,7 @@ nvkm_vmm_get_locked(struct nvkm_vmm *vmm, bool getref, bool mapref, bool sparse,
 
                tail = this->addr + this->size;
                if (vmm->func->page_block && next && next->page != p)
-                       tail = ALIGN_DOWN(addr, vmm->func->page_block);
+                       tail = ALIGN_DOWN(tail, vmm->func->page_block);
 
                if (addr <= tail && tail - addr >= size) {
                        rb_erase(&this->tree, &vmm->free);
index bf62303571b39addb787e5237635f55edf9f42ba..3695cde669f881335445fb14db5e15f8c26f565a 100644 (file)
@@ -301,7 +301,7 @@ nvkm_therm_attr_set(struct nvkm_therm *therm,
 void
 nvkm_therm_clkgate_enable(struct nvkm_therm *therm)
 {
-       if (!therm->func->clkgate_enable || !therm->clkgating_enabled)
+       if (!therm || !therm->func->clkgate_enable || !therm->clkgating_enabled)
                return;
 
        nvkm_debug(&therm->subdev,
@@ -312,7 +312,7 @@ nvkm_therm_clkgate_enable(struct nvkm_therm *therm)
 void
 nvkm_therm_clkgate_fini(struct nvkm_therm *therm, bool suspend)
 {
-       if (!therm->func->clkgate_fini || !therm->clkgating_enabled)
+       if (!therm || !therm->func->clkgate_fini || !therm->clkgating_enabled)
                return;
 
        nvkm_debug(&therm->subdev,
@@ -395,7 +395,7 @@ void
 nvkm_therm_clkgate_init(struct nvkm_therm *therm,
                        const struct nvkm_therm_clkgate_pack *p)
 {
-       if (!therm->func->clkgate_init || !therm->clkgating_enabled)
+       if (!therm || !therm->func->clkgate_init || !therm->clkgating_enabled)
                return;
 
        therm->func->clkgate_init(therm, p);
index d3045a371a557261776ff32a88aca99b8836c538..7c73bc7e2f854e815aeb249bb4f80dbb932794f4 100644 (file)
@@ -3221,35 +3221,8 @@ static void cik_gpu_init(struct radeon_device *rdev)
        case CHIP_KAVERI:
                rdev->config.cik.max_shader_engines = 1;
                rdev->config.cik.max_tile_pipes = 4;
-               if ((rdev->pdev->device == 0x1304) ||
-                   (rdev->pdev->device == 0x1305) ||
-                   (rdev->pdev->device == 0x130C) ||
-                   (rdev->pdev->device == 0x130F) ||
-                   (rdev->pdev->device == 0x1310) ||
-                   (rdev->pdev->device == 0x1311) ||
-                   (rdev->pdev->device == 0x131C)) {
-                       rdev->config.cik.max_cu_per_sh = 8;
-                       rdev->config.cik.max_backends_per_se = 2;
-               } else if ((rdev->pdev->device == 0x1309) ||
-                          (rdev->pdev->device == 0x130A) ||
-                          (rdev->pdev->device == 0x130D) ||
-                          (rdev->pdev->device == 0x1313) ||
-                          (rdev->pdev->device == 0x131D)) {
-                       rdev->config.cik.max_cu_per_sh = 6;
-                       rdev->config.cik.max_backends_per_se = 2;
-               } else if ((rdev->pdev->device == 0x1306) ||
-                          (rdev->pdev->device == 0x1307) ||
-                          (rdev->pdev->device == 0x130B) ||
-                          (rdev->pdev->device == 0x130E) ||
-                          (rdev->pdev->device == 0x1315) ||
-                          (rdev->pdev->device == 0x1318) ||
-                          (rdev->pdev->device == 0x131B)) {
-                       rdev->config.cik.max_cu_per_sh = 4;
-                       rdev->config.cik.max_backends_per_se = 1;
-               } else {
-                       rdev->config.cik.max_cu_per_sh = 3;
-                       rdev->config.cik.max_backends_per_se = 1;
-               }
+               rdev->config.cik.max_cu_per_sh = 8;
+               rdev->config.cik.max_backends_per_se = 2;
                rdev->config.cik.max_sh_per_se = 1;
                rdev->config.cik.max_texture_channel_caches = 4;
                rdev->config.cik.max_gprs = 256;
index 5012f5e47a1e599d1758b91957d79925487de260..df9469a8fdb1689ec2a5f8b4c3e1a5995b4e4e82 100644 (file)
@@ -90,25 +90,18 @@ void radeon_connector_hotplug(struct drm_connector *connector)
                /* don't do anything if sink is not display port, i.e.,
                 * passive dp->(dvi|hdmi) adaptor
                 */
-               if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
-                       int saved_dpms = connector->dpms;
-                       /* Only turn off the display if it's physically disconnected */
-                       if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
-                               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
-                       } else if (radeon_dp_needs_link_train(radeon_connector)) {
-                               /* Don't try to start link training before we
-                                * have the dpcd */
-                               if (!radeon_dp_getdpcd(radeon_connector))
-                                       return;
-
-                               /* set it to OFF so that drm_helper_connector_dpms()
-                                * won't return immediately since the current state
-                                * is ON at this point.
-                                */
-                               connector->dpms = DRM_MODE_DPMS_OFF;
-                               drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
-                       }
-                       connector->dpms = saved_dpms;
+               if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
+                   radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
+                   radeon_dp_needs_link_train(radeon_connector)) {
+                       /* Don't start link training before we have the DPCD */
+                       if (!radeon_dp_getdpcd(radeon_connector))
+                               return;
+
+                       /* Turn the connector off and back on immediately, which
+                        * will trigger link training
+                        */
+                       drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+                       drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
                }
        }
 }
@@ -899,9 +892,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
        enum drm_connector_status ret = connector_status_disconnected;
        int r;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        if (encoder) {
                struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -924,8 +919,12 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
        /* check acpi lid status ??? */
 
        radeon_connector_update_scratch_regs(connector, ret);
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
+
        return ret;
 }
 
@@ -1039,9 +1038,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
        enum drm_connector_status ret = connector_status_disconnected;
        int r;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        encoder = radeon_best_single_encoder(connector);
        if (!encoder)
@@ -1108,8 +1109,10 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
        radeon_connector_update_scratch_regs(connector, ret);
 
 out:
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return ret;
 }
@@ -1173,9 +1176,11 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
        if (!radeon_connector->dac_load_detect)
                return ret;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        encoder = radeon_best_single_encoder(connector);
        if (!encoder)
@@ -1187,8 +1192,12 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
        if (ret == connector_status_connected)
                ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
        radeon_connector_update_scratch_regs(connector, ret);
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
+
        return ret;
 }
 
@@ -1251,9 +1260,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
        enum drm_connector_status ret = connector_status_disconnected;
        bool dret = false, broken_edid = false;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        if (radeon_connector->detected_hpd_without_ddc) {
                force = true;
@@ -1436,8 +1447,10 @@ out:
        }
 
 exit:
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return ret;
 }
@@ -1688,9 +1701,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
        if (radeon_dig_connector->is_mst)
                return connector_status_disconnected;
 
-       r = pm_runtime_get_sync(connector->dev->dev);
-       if (r < 0)
-               return connector_status_disconnected;
+       if (!drm_kms_helper_is_poll_worker()) {
+               r = pm_runtime_get_sync(connector->dev->dev);
+               if (r < 0)
+                       return connector_status_disconnected;
+       }
 
        if (!force && radeon_check_hpd_status_unchanged(connector)) {
                ret = connector->status;
@@ -1777,8 +1792,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
        }
 
 out:
-       pm_runtime_mark_last_busy(connector->dev->dev);
-       pm_runtime_put_autosuspend(connector->dev->dev);
+       if (!drm_kms_helper_is_poll_worker()) {
+               pm_runtime_mark_last_busy(connector->dev->dev);
+               pm_runtime_put_autosuspend(connector->dev->dev);
+       }
 
        return ret;
 }
index 8d3e3d2e0090938c2ec895d0836871622fad0bd7..7828a5e1062999b1bae507440b6dd8847095546b 100644 (file)
@@ -1365,6 +1365,10 @@ int radeon_device_init(struct radeon_device *rdev,
        if ((rdev->flags & RADEON_IS_PCI) &&
            (rdev->family <= CHIP_RS740))
                rdev->need_dma32 = true;
+#ifdef CONFIG_PPC64
+       if (rdev->family == CHIP_CEDAR)
+               rdev->need_dma32 = true;
+#endif
 
        dma_bits = rdev->need_dma32 ? 32 : 40;
        r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
index a9962ffba720b784b24de5f5f117f330b19e5710..27d8e7dd2d0676c4f369041be3bcb5b95774a1b3 100644 (file)
@@ -34,8 +34,6 @@ void radeon_gem_object_free(struct drm_gem_object *gobj)
        struct radeon_bo *robj = gem_to_radeon_bo(gobj);
 
        if (robj) {
-               if (robj->gem_base.import_attach)
-                       drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
                radeon_mn_unregister(robj);
                radeon_bo_unref(&robj);
        }
index 15404af9d740612d6882f832c7373eea04ec9f71..31f5ad605e59f694bad78c5f18ffa211c422dfef 100644 (file)
@@ -82,6 +82,8 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
        mutex_unlock(&bo->rdev->gem.mutex);
        radeon_bo_clear_surface_reg(bo);
        WARN_ON_ONCE(!list_empty(&bo->va));
+       if (bo->gem_base.import_attach)
+               drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg);
        drm_gem_object_release(&bo->gem_base);
        kfree(bo);
 }
index 326ad068c15aa63ef38a6c85fbcc368ad52bd801..4b6542538ff91581272deadb6e971c50f2429033 100644 (file)
@@ -47,7 +47,6 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev);
 static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);
 static void radeon_pm_update_profile(struct radeon_device *rdev);
 static void radeon_pm_set_clocks(struct radeon_device *rdev);
-static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev);
 
 int radeon_pm_get_type_index(struct radeon_device *rdev,
                             enum radeon_pm_state_type ps_type,
@@ -80,8 +79,6 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev)
                                radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power);
                }
                mutex_unlock(&rdev->pm.mutex);
-               /* allow new DPM state to be picked */
-               radeon_pm_compute_clocks_dpm(rdev);
        } else if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
                if (rdev->pm.profile == PM_PROFILE_AUTO) {
                        mutex_lock(&rdev->pm.mutex);
@@ -885,8 +882,7 @@ static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
                dpm_state = POWER_STATE_TYPE_INTERNAL_3DPERF;
        /* balanced states don't exist at the moment */
        if (dpm_state == POWER_STATE_TYPE_BALANCED)
-               dpm_state = rdev->pm.dpm.ac_power ?
-                       POWER_STATE_TYPE_PERFORMANCE : POWER_STATE_TYPE_BATTERY;
+               dpm_state = POWER_STATE_TYPE_PERFORMANCE;
 
 restart_search:
        /* Pick the best power state based on current conditions */
index 2c18996d59c58e6247a24936da9dc155f76d78cf..0d95888ccc3e778bb9752376682c5cccba525e7b 100644 (file)
@@ -461,7 +461,7 @@ void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched, struct drm_sched_jo
 {
        struct drm_sched_job *s_job;
        struct drm_sched_entity *entity, *tmp;
-       int i;;
+       int i;
 
        spin_lock(&sched->job_list_lock);
        list_for_each_entry_reverse(s_job, &sched->ring_mirror_list, node) {
index 5decae0069d0bfda0f45a0c78ea033f1186282c6..78cbc3145e44063426ed40c09b5fadbb35bbdd75 100644 (file)
@@ -93,6 +93,8 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
 
        DRM_DEBUG_DRIVER("Disabling the CRTC\n");
 
+       drm_crtc_vblank_off(crtc);
+
        sun4i_tcon_set_status(scrtc->tcon, encoder, false);
 
        if (crtc->state->event && !crtc->state->active) {
@@ -113,6 +115,8 @@ static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
        DRM_DEBUG_DRIVER("Enabling the CRTC\n");
 
        sun4i_tcon_set_status(scrtc->tcon, encoder, true);
+
+       drm_crtc_vblank_on(crtc);
 }
 
 static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
index 023f39bda633de70825243b3a28335e2686091ed..e36004fbe45360deb9487fa80cdd564c33fa030e 100644 (file)
@@ -132,10 +132,13 @@ static int sun4i_dclk_get_phase(struct clk_hw *hw)
 static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees)
 {
        struct sun4i_dclk *dclk = hw_to_dclk(hw);
+       u32 val = degrees / 120;
+
+       val <<= 28;
 
        regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
                           GENMASK(29, 28),
-                          degrees / 120);
+                          val);
 
        return 0;
 }
index 4570da0227b4e49523b7f9c697fce54777dacd7e..d9a71f361b1440fd6a84c4dcbd9f295c7e873a39 100644 (file)
@@ -111,7 +111,7 @@ static int sun4i_drv_bind(struct device *dev)
        /* drm_vblank_init calls kcalloc, which can fail */
        ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
        if (ret)
-               goto free_mem_region;
+               goto cleanup_mode_config;
 
        drm->irq_enabled = true;
 
@@ -139,7 +139,6 @@ finish_poll:
        sun4i_framebuffer_free(drm);
 cleanup_mode_config:
        drm_mode_config_cleanup(drm);
-free_mem_region:
        of_reserved_mem_device_release(dev);
 free_drm:
        drm_dev_unref(drm);
index 500b6fb3e0284d2fdfc71265a64f0d5b51fe4f99..fa4bcd092eaf20f9f04faaaf49ca9339f134f385 100644 (file)
@@ -538,7 +538,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
                                             &sun4i_hdmi_regmap_config);
        if (IS_ERR(hdmi->regmap)) {
                dev_err(dev, "Couldn't create HDMI encoder regmap\n");
-               return PTR_ERR(hdmi->regmap);
+               ret = PTR_ERR(hdmi->regmap);
+               goto err_disable_mod_clk;
        }
 
        ret = sun4i_tmds_create(hdmi);
@@ -551,7 +552,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
                hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc");
                if (IS_ERR(hdmi->ddc_parent_clk)) {
                        dev_err(dev, "Couldn't get the HDMI DDC clock\n");
-                       return PTR_ERR(hdmi->ddc_parent_clk);
+                       ret = PTR_ERR(hdmi->ddc_parent_clk);
+                       goto err_disable_mod_clk;
                }
        } else {
                hdmi->ddc_parent_clk = hdmi->tmds_clk;
index 832f8f9bc47fd046baebde3af7c4d406b301a40c..b8da5a50a61d3b820d8ee5c8badc26132efe0b2b 100644 (file)
@@ -92,6 +92,8 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
 
        DRM_DEBUG_DRIVER("Vertical parameters OK\n");
 
+       tcon->dclk_min_div = 6;
+       tcon->dclk_max_div = 127;
        rounded_rate = clk_round_rate(tcon->dclk, rate);
        if (rounded_rate < rate)
                return MODE_CLOCK_LOW;
index 3c15cf24b50360918253ed5bcff4d4a73a1e6cd0..a818ca4916051ade239efa0f4789d5c3cab36165 100644 (file)
@@ -101,10 +101,13 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
                return;
        }
 
-       if (enabled)
+       if (enabled) {
                clk_prepare_enable(clk);
-       else
+               clk_rate_exclusive_get(clk);
+       } else {
+               clk_rate_exclusive_put(clk);
                clk_disable_unprepare(clk);
+       }
 }
 
 static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
@@ -335,6 +338,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
        regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
                           SUN4I_TCON_GCTL_IOMAP_MASK,
                           SUN4I_TCON_GCTL_IOMAP_TCON0);
+
+       /* Enable the output on the pins */
+       regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
 }
 
 static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
@@ -870,52 +876,56 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
                return ret;
        }
 
-       /*
-        * This can only be made optional since we've had DT nodes
-        * without the LVDS reset properties.
-        *
-        * If the property is missing, just disable LVDS, and print a
-        * warning.
-        */
-       tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
-       if (IS_ERR(tcon->lvds_rst)) {
-               dev_err(dev, "Couldn't get our reset line\n");
-               return PTR_ERR(tcon->lvds_rst);
-       } else if (tcon->lvds_rst) {
-               has_lvds_rst = true;
-               reset_control_reset(tcon->lvds_rst);
-       } else {
-               has_lvds_rst = false;
-       }
+       if (tcon->quirks->supports_lvds) {
+               /*
+                * This can only be made optional since we've had DT
+                * nodes without the LVDS reset properties.
+                *
+                * If the property is missing, just disable LVDS, and
+                * print a warning.
+                */
+               tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
+               if (IS_ERR(tcon->lvds_rst)) {
+                       dev_err(dev, "Couldn't get our reset line\n");
+                       return PTR_ERR(tcon->lvds_rst);
+               } else if (tcon->lvds_rst) {
+                       has_lvds_rst = true;
+                       reset_control_reset(tcon->lvds_rst);
+               } else {
+                       has_lvds_rst = false;
+               }
 
-       /*
-        * This can only be made optional since we've had DT nodes
-        * without the LVDS reset properties.
-        *
-        * If the property is missing, just disable LVDS, and print a
-        * warning.
-        */
-       if (tcon->quirks->has_lvds_alt) {
-               tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
-               if (IS_ERR(tcon->lvds_pll)) {
-                       if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
-                               has_lvds_alt = false;
+               /*
+                * This can only be made optional since we've had DT
+                * nodes without the LVDS reset properties.
+                *
+                * If the property is missing, just disable LVDS, and
+                * print a warning.
+                */
+               if (tcon->quirks->has_lvds_alt) {
+                       tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
+                       if (IS_ERR(tcon->lvds_pll)) {
+                               if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
+                                       has_lvds_alt = false;
+                               } else {
+                                       dev_err(dev, "Couldn't get the LVDS PLL\n");
+                                       return PTR_ERR(tcon->lvds_pll);
+                               }
                        } else {
-                               dev_err(dev, "Couldn't get the LVDS PLL\n");
-                               return PTR_ERR(tcon->lvds_pll);
+                               has_lvds_alt = true;
                        }
-               } else {
-                       has_lvds_alt = true;
                }
-       }
 
-       if (!has_lvds_rst || (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
-               dev_warn(dev,
-                        "Missing LVDS properties, Please upgrade your DT\n");
-               dev_warn(dev, "LVDS output disabled\n");
-               can_lvds = false;
+               if (!has_lvds_rst ||
+                   (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
+                       dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
+                       dev_warn(dev, "LVDS output disabled\n");
+                       can_lvds = false;
+               } else {
+                       can_lvds = true;
+               }
        } else {
-               can_lvds = true;
+               can_lvds = false;
        }
 
        ret = sun4i_tcon_init_clocks(dev, tcon);
@@ -1134,7 +1144,7 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
 };
 
 static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
-       /* nothing is supported */
+       .supports_lvds          = true,
 };
 
 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
index b761c7b823c560536b0f44a3c6eab6337d3e32d7..278700c7bf9f6f71ec3c85686c81919362aa40fa 100644 (file)
@@ -175,6 +175,7 @@ struct sun4i_tcon_quirks {
        bool    has_channel_1;  /* a33 does not have channel 1 */
        bool    has_lvds_alt;   /* Does the LVDS clock have a parent other than the TCON clock? */
        bool    needs_de_be_mux; /* sun6i needs mux to select backend */
+       bool    supports_lvds;   /* Does the TCON support an LVDS output? */
 
        /* callback to handle tcon muxing options */
        int     (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
index b8403ed48285288c277d224e253285caebed3adb..fbffe1948b3bb2d5311ecbee000ee879fbd6ce28 100644 (file)
@@ -1903,8 +1903,12 @@ cleanup:
        if (!IS_ERR(primary))
                drm_plane_cleanup(primary);
 
-       if (group && tegra->domain) {
-               iommu_detach_group(tegra->domain, group);
+       if (group && dc->domain) {
+               if (group == tegra->group) {
+                       iommu_detach_group(dc->domain, group);
+                       tegra->group = NULL;
+               }
+
                dc->domain = NULL;
        }
 
@@ -1913,8 +1917,10 @@ cleanup:
 
 static int tegra_dc_exit(struct host1x_client *client)
 {
+       struct drm_device *drm = dev_get_drvdata(client->parent);
        struct iommu_group *group = iommu_group_get(client->dev);
        struct tegra_dc *dc = host1x_client_to_dc(client);
+       struct tegra_drm *tegra = drm->dev_private;
        int err;
 
        devm_free_irq(dc->dev, dc->irq, dc);
@@ -1926,7 +1932,11 @@ static int tegra_dc_exit(struct host1x_client *client)
        }
 
        if (group && dc->domain) {
-               iommu_detach_group(dc->domain, group);
+               if (group == tegra->group) {
+                       iommu_detach_group(dc->domain, group);
+                       tegra->group = NULL;
+               }
+
                dc->domain = NULL;
        }
 
index d50bddb2e4474e456b8105d6b90b47488ff21263..7fcf4a24284088ba798296016797032f70e5fa96 100644 (file)
@@ -250,6 +250,7 @@ static void tegra_drm_unload(struct drm_device *drm)
 
        drm_kms_helper_poll_fini(drm);
        tegra_drm_fb_exit(drm);
+       drm_atomic_helper_shutdown(drm);
        drm_mode_config_cleanup(drm);
 
        err = host1x_device_exit(device);
index 4d2ed966f9e3248a074ab25dcdfb6156e9c93200..87c5d89bc9baf3cd09012f5a2385510b645ebe1b 100644 (file)
@@ -1072,7 +1072,6 @@ static int tegra_dsi_exit(struct host1x_client *client)
        struct tegra_dsi *dsi = host1x_client_to_dsi(client);
 
        tegra_output_exit(&dsi->output);
-       regulator_disable(dsi->vdd);
 
        return 0;
 }
index 36a06a99369821aed88bbf9701550848b420493e..94dac79ac3c9641b84aa1af53093e104e0661ca4 100644 (file)
@@ -297,6 +297,10 @@ int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha)
        case WIN_COLOR_DEPTH_B8G8R8X8:
                *alpha = WIN_COLOR_DEPTH_B8G8R8A8;
                return 0;
+
+       case WIN_COLOR_DEPTH_B5G6R5:
+               *alpha = opaque;
+               return 0;
        }
 
        return -EINVAL;
@@ -330,9 +334,6 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra,
        unsigned int zpos[2];
        unsigned int i;
 
-       for (i = 0; i < 3; i++)
-               state->dependent[i] = false;
-
        for (i = 0; i < 2; i++)
                zpos[i] = 0;
 
@@ -346,6 +347,8 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra,
 
                index = tegra_plane_get_overlap_index(tegra, p);
 
+               state->dependent[index] = false;
+
                /*
                 * If any of the other planes is on top of this plane and uses
                 * a format with an alpha component, mark this plane as being
index b5b335c9b2bbe504fdddf47246820e1e64199d18..2ebdc6d5a76e60a33d6a271ff158258a61b7908c 100644 (file)
@@ -159,10 +159,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        unsigned long start = vma->vm_start;
        unsigned long size = vma->vm_end - vma->vm_start;
-       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long offset;
        unsigned long page, pos;
 
-       if (offset + size > info->fix.smem_len)
+       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+               return -EINVAL;
+
+       offset = vma->vm_pgoff << PAGE_SHIFT;
+
+       if (offset > info->fix.smem_len || size > info->fix.smem_len - offset)
                return -EINVAL;
 
        pos = (unsigned long)info->fix.smem_start + offset;
index 984501e3f0b0adc02ed12342eb8f1fbafd8e3dd4..b92c6603c7a2f3c976cd147d39b5174662cdfac9 100644 (file)
@@ -995,15 +995,17 @@ static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
        { "TX", NULL, "Playback" },
 };
 
-static const struct snd_soc_codec_driver vc4_hdmi_audio_codec_drv = {
-       .component_driver = {
-               .controls = vc4_hdmi_audio_controls,
-               .num_controls = ARRAY_SIZE(vc4_hdmi_audio_controls),
-               .dapm_widgets = vc4_hdmi_audio_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(vc4_hdmi_audio_widgets),
-               .dapm_routes = vc4_hdmi_audio_routes,
-               .num_dapm_routes = ARRAY_SIZE(vc4_hdmi_audio_routes),
-       },
+static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
+       .controls               = vc4_hdmi_audio_controls,
+       .num_controls           = ARRAY_SIZE(vc4_hdmi_audio_controls),
+       .dapm_widgets           = vc4_hdmi_audio_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(vc4_hdmi_audio_widgets),
+       .dapm_routes            = vc4_hdmi_audio_routes,
+       .num_dapm_routes        = ARRAY_SIZE(vc4_hdmi_audio_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct snd_soc_dai_ops vc4_hdmi_audio_dai_ops = {
@@ -1101,11 +1103,11 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
                return ret;
        }
 
-       /* register codec and codec dai */
-       ret = snd_soc_register_codec(dev, &vc4_hdmi_audio_codec_drv,
+       /* register component and codec dai */
+       ret = devm_snd_soc_register_component(dev, &vc4_hdmi_audio_component_drv,
                                     &vc4_hdmi_audio_codec_dai_drv, 1);
        if (ret) {
-               dev_err(dev, "Could not register codec: %d\n", ret);
+               dev_err(dev, "Could not register component: %d\n", ret);
                return ret;
        }
 
@@ -1130,29 +1132,11 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
         */
        snd_soc_card_set_drvdata(card, hdmi);
        ret = devm_snd_soc_register_card(dev, card);
-       if (ret) {
+       if (ret)
                dev_err(dev, "Could not register sound card: %d\n", ret);
-               goto unregister_codec;
-       }
-
-       return 0;
-
-unregister_codec:
-       snd_soc_unregister_codec(dev);
 
        return ret;
-}
-
-static void vc4_hdmi_audio_cleanup(struct vc4_hdmi *hdmi)
-{
-       struct device *dev = &hdmi->pdev->dev;
 
-       /*
-        * If drvdata is not set this means the audio card was not
-        * registered, just skip codec unregistration in this case.
-        */
-       if (dev_get_drvdata(dev))
-               snd_soc_unregister_codec(dev);
 }
 
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
@@ -1480,7 +1464,6 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
        struct vc4_dev *vc4 = drm->dev_private;
        struct vc4_hdmi *hdmi = vc4->hdmi;
 
-       vc4_hdmi_audio_cleanup(hdmi);
        cec_unregister_adapter(hdmi->cec_adap);
        vc4_hdmi_connector_destroy(hdmi->connector);
        vc4_hdmi_encoder_destroy(hdmi->encoder);
index 5720a0d4ac0a9ebf242755921bc1ac6fea8c2630..677ac16c8a6dea750e80ec914973344d972bb765 100644 (file)
@@ -197,6 +197,9 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data,
        case VIRTGPU_PARAM_3D_FEATURES:
                value = vgdev->has_virgl_3d == true ? 1 : 0;
                break;
+       case VIRTGPU_PARAM_CAPSET_QUERY_FIX:
+               value = 1;
+               break;
        default:
                return -EINVAL;
        }
@@ -472,7 +475,7 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
 {
        struct virtio_gpu_device *vgdev = dev->dev_private;
        struct drm_virtgpu_get_caps *args = data;
-       int size;
+       unsigned size, host_caps_size;
        int i;
        int found_valid = -1;
        int ret;
@@ -481,6 +484,10 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
        if (vgdev->num_capsets == 0)
                return -ENOSYS;
 
+       /* don't allow userspace to pass 0 */
+       if (args->size == 0)
+               return -EINVAL;
+
        spin_lock(&vgdev->display_info_lock);
        for (i = 0; i < vgdev->num_capsets; i++) {
                if (vgdev->capsets[i].id == args->cap_set_id) {
@@ -496,11 +503,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
                return -EINVAL;
        }
 
-       size = vgdev->capsets[found_valid].max_size;
-       if (args->size > size) {
-               spin_unlock(&vgdev->display_info_lock);
-               return -EINVAL;
-       }
+       host_caps_size = vgdev->capsets[found_valid].max_size;
+       /* only copy to user the minimum of the host caps size or the guest caps size */
+       size = min(args->size, host_caps_size);
 
        list_for_each_entry(cache_ent, &vgdev->cap_cache, head) {
                if (cache_ent->id == args->cap_set_id &&
index 184340d486c377d38a2f21bb66cc56385a52d37b..86d25f18aa992745e9c4ebb3c89e2bd3199212b9 100644 (file)
@@ -1337,6 +1337,19 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv)
  */
 void vmw_svga_disable(struct vmw_private *dev_priv)
 {
+       /*
+        * Disabling SVGA will turn off device modesetting capabilities, so
+        * notify KMS about that so that it doesn't cache atomic state that
+        * isn't valid anymore, for example crtcs turned on.
+        * Strictly we'd want to do this under the SVGA lock (or an SVGA mutex),
+        * but vmw_kms_lost_device() takes the reservation sem and thus we'll
+        * end up with lock order reversal. Thus, a master may actually perform
+        * a new modeset just after we call vmw_kms_lost_device() and race with
+        * vmw_svga_disable(), but that should at worst cause atomic KMS state
+        * to be inconsistent with the device, causing modesetting problems.
+        *
+        */
+       vmw_kms_lost_device(dev_priv->dev);
        ttm_write_lock(&dev_priv->reservation_sem, false);
        spin_lock(&dev_priv->svga_lock);
        if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) {
index d08753e8fd94f077b3815f2d64f5ac63d0cdd7f2..9116fe8baebcab24575a0b6dc329578ac4db0b40 100644 (file)
@@ -938,6 +938,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
+void vmw_kms_lost_device(struct drm_device *dev);
 
 int vmw_dumb_create(struct drm_file *file_priv,
                    struct drm_device *dev,
index ead61015cd79ceb0a2602615c72cddf7020da85d..3c824fd7cbf36d64e72e758bdb7c5b5e3b270dd6 100644 (file)
@@ -31,7 +31,6 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_rect.h>
 
-
 /* Might need a hrtimer here? */
 #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
 
@@ -2517,9 +2516,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
  * Helper to be used if an error forces the caller to undo the actions of
  * vmw_kms_helper_resource_prepare.
  */
-void vmw_kms_helper_resource_revert(struct vmw_resource *res)
+void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx)
 {
-       vmw_kms_helper_buffer_revert(res->backup);
+       struct vmw_resource *res = ctx->res;
+
+       vmw_kms_helper_buffer_revert(ctx->buf);
+       vmw_dmabuf_unreference(&ctx->buf);
        vmw_resource_unreserve(res, false, NULL, 0);
        mutex_unlock(&res->dev_priv->cmdbuf_mutex);
 }
@@ -2536,10 +2538,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res)
  * interrupted by a signal.
  */
 int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
-                                   bool interruptible)
+                                   bool interruptible,
+                                   struct vmw_validation_ctx *ctx)
 {
        int ret = 0;
 
+       ctx->buf = NULL;
+       ctx->res = res;
+
        if (interruptible)
                ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
        else
@@ -2558,6 +2564,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
                                                    res->dev_priv->has_mob);
                if (ret)
                        goto out_unreserve;
+
+               ctx->buf = vmw_dmabuf_reference(res->backup);
        }
        ret = vmw_resource_validate(res);
        if (ret)
@@ -2565,7 +2573,7 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
        return 0;
 
 out_revert:
-       vmw_kms_helper_buffer_revert(res->backup);
+       vmw_kms_helper_buffer_revert(ctx->buf);
 out_unreserve:
        vmw_resource_unreserve(res, false, NULL, 0);
 out_unlock:
@@ -2581,11 +2589,13 @@ out_unlock:
  * @out_fence: Optional pointer to a fence pointer. If non-NULL, a
  * ref-counted fence pointer is returned here.
  */
-void vmw_kms_helper_resource_finish(struct vmw_resource *res,
-                            struct vmw_fence_obj **out_fence)
+void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
+                                   struct vmw_fence_obj **out_fence)
 {
-       if (res->backup || out_fence)
-               vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup,
+       struct vmw_resource *res = ctx->res;
+
+       if (ctx->buf || out_fence)
+               vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
                                             out_fence, NULL);
 
        vmw_resource_unreserve(res, false, NULL, 0);
@@ -2851,3 +2861,14 @@ int vmw_kms_set_config(struct drm_mode_set *set,
 
        return drm_atomic_helper_set_config(set, ctx);
 }
+
+
+/**
+ * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
+ *
+ * @dev: Pointer to the drm device
+ */
+void vmw_kms_lost_device(struct drm_device *dev)
+{
+       drm_atomic_helper_shutdown(dev);
+}
index cd9da2dd79af1a062d4aaa3d6b6ded468bd4207e..3d2ca280eaa72ee1a5f8b216bfe7b54467e3d842 100644 (file)
@@ -240,6 +240,11 @@ struct vmw_display_unit {
        int set_gui_y;
 };
 
+struct vmw_validation_ctx {
+       struct vmw_resource *res;
+       struct vmw_dma_buffer *buf;
+};
+
 #define vmw_crtc_to_du(x) \
        container_of(x, struct vmw_display_unit, crtc)
 #define vmw_connector_to_du(x) \
@@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
                                  struct drm_vmw_fence_rep __user *
                                  user_fence_rep);
 int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
-                                   bool interruptible);
-void vmw_kms_helper_resource_revert(struct vmw_resource *res);
-void vmw_kms_helper_resource_finish(struct vmw_resource *res,
+                                   bool interruptible,
+                                   struct vmw_validation_ctx *ctx);
+void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx);
+void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
                                    struct vmw_fence_obj **out_fence);
 int vmw_kms_readback(struct vmw_private *dev_priv,
                     struct drm_file *file_priv,
@@ -439,5 +445,4 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
 
 int vmw_kms_set_config(struct drm_mode_set *set,
                       struct drm_modeset_acquire_ctx *ctx);
-
 #endif
index 63a4cd794b73a12821ea8adbfb72e997367c5193..3ec9eae831b8f15295a6da11a9a267e3e2b4fcb8 100644 (file)
@@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
        struct vmw_framebuffer_surface *vfbs =
                container_of(framebuffer, typeof(*vfbs), base);
        struct vmw_kms_sou_surface_dirty sdirty;
+       struct vmw_validation_ctx ctx;
        int ret;
 
        if (!srf)
                srf = &vfbs->surface->res;
 
-       ret = vmw_kms_helper_resource_prepare(srf, true);
+       ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
        if (ret)
                return ret;
 
@@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
        ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
                                   dest_x, dest_y, num_clips, inc,
                                   &sdirty.base);
-       vmw_kms_helper_resource_finish(srf, out_fence);
+       vmw_kms_helper_resource_finish(&ctx, out_fence);
 
        return ret;
 }
index b68d74888ab1100be82f8a2a9fdc3234a4e04293..6b969e5dea2a862b392153822649217783ac661b 100644 (file)
@@ -980,12 +980,13 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
        struct vmw_framebuffer_surface *vfbs =
                container_of(framebuffer, typeof(*vfbs), base);
        struct vmw_stdu_dirty sdirty;
+       struct vmw_validation_ctx ctx;
        int ret;
 
        if (!srf)
                srf = &vfbs->surface->res;
 
-       ret = vmw_kms_helper_resource_prepare(srf, true);
+       ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
        if (ret)
                return ret;
 
@@ -1008,7 +1009,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
                                   dest_x, dest_y, num_clips, inc,
                                   &sdirty.base);
 out_finish:
-       vmw_kms_helper_resource_finish(srf, out_fence);
+       vmw_kms_helper_resource_finish(&ctx, out_fence);
 
        return ret;
 }
index 658fa2d3e40c260d051d4299bda4eddb0af5abeb..48685cddbad1b7218519841c58478e12333bb90e 100644 (file)
@@ -1089,7 +1089,7 @@ static void ipu_irq_handler(struct irq_desc *desc)
 {
        struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
        struct irq_chip *chip = irq_desc_get_chip(desc);
-       const int int_reg[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
+       static const int int_reg[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
 
        chained_irq_enter(chip, desc);
 
@@ -1102,7 +1102,7 @@ static void ipu_err_irq_handler(struct irq_desc *desc)
 {
        struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
        struct irq_chip *chip = irq_desc_get_chip(desc);
-       const int int_reg[] = { 4, 5, 8, 9};
+       static const int int_reg[] = { 4, 5, 8, 9};
 
        chained_irq_enter(chip, desc);
 
index bb9c087e6c0d2e81dddabc47f4174a91af67220c..9f2d9ec42add6731069cad774762efc06eab0139 100644 (file)
@@ -788,12 +788,14 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
        case V4L2_PIX_FMT_SGBRG8:
        case V4L2_PIX_FMT_SGRBG8:
        case V4L2_PIX_FMT_SRGGB8:
+       case V4L2_PIX_FMT_GREY:
                offset = image->rect.left + image->rect.top * pix->bytesperline;
                break;
        case V4L2_PIX_FMT_SBGGR16:
        case V4L2_PIX_FMT_SGBRG16:
        case V4L2_PIX_FMT_SGRBG16:
        case V4L2_PIX_FMT_SRGGB16:
+       case V4L2_PIX_FMT_Y16:
                offset = image->rect.left * 2 +
                         image->rect.top * pix->bytesperline;
                break;
index 24e12b87a0cbe387b24557a230a1ed1d05e150ca..caa05b0702e1671c39c15edff2e3801a37e83074 100644 (file)
@@ -288,6 +288,7 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code)
        case MEDIA_BUS_FMT_SGBRG10_1X10:
        case MEDIA_BUS_FMT_SGRBG10_1X10:
        case MEDIA_BUS_FMT_SRGGB10_1X10:
+       case MEDIA_BUS_FMT_Y10_1X10:
                cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
                cfg->mipi_dt = MIPI_DT_RAW10;
                cfg->data_width = IPU_CSI_DATA_WIDTH_10;
@@ -296,6 +297,7 @@ static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code)
        case MEDIA_BUS_FMT_SGBRG12_1X12:
        case MEDIA_BUS_FMT_SGRBG12_1X12:
        case MEDIA_BUS_FMT_SRGGB12_1X12:
+       case MEDIA_BUS_FMT_Y12_1X12:
                cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
                cfg->mipi_dt = MIPI_DT_RAW12;
                cfg->data_width = IPU_CSI_DATA_WIDTH_12;
index f1cec3d70498ab526f9765f66422e0835f338dc0..0f70e88475409f8795dfdb6f36e5a1a452badc7d 100644 (file)
@@ -129,11 +129,14 @@ ipu_pre_lookup_by_phandle(struct device *dev, const char *name, int index)
                if (pre_node == pre->dev->of_node) {
                        mutex_unlock(&ipu_pre_list_mutex);
                        device_link_add(dev, pre->dev, DL_FLAG_AUTOREMOVE);
+                       of_node_put(pre_node);
                        return pre;
                }
        }
        mutex_unlock(&ipu_pre_list_mutex);
 
+       of_node_put(pre_node);
+
        return NULL;
 }
 
index 067365c733c63b257f3be41102d7f54354d52f18..83f9dd934a5dc37ecb95f57b91d19af0c08f9e51 100644 (file)
@@ -102,11 +102,14 @@ ipu_prg_lookup_by_phandle(struct device *dev, const char *name, int ipu_id)
                        mutex_unlock(&ipu_prg_list_mutex);
                        device_link_add(dev, prg->dev, DL_FLAG_AUTOREMOVE);
                        prg->id = ipu_id;
+                       of_node_put(prg_node);
                        return prg;
                }
        }
        mutex_unlock(&ipu_prg_list_mutex);
 
+       of_node_put(prg_node);
+
        return NULL;
 }
 
@@ -247,10 +250,14 @@ void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan)
 {
        int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
        struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
-       struct ipu_prg_channel *chan = &prg->chan[prg_chan];
+       struct ipu_prg_channel *chan;
        u32 val;
 
-       if (!chan->enabled || prg_chan < 0)
+       if (prg_chan < 0)
+               return;
+
+       chan = &prg->chan[prg_chan];
+       if (!chan->enabled)
                return;
 
        pm_runtime_get_sync(prg->dev);
@@ -277,13 +284,15 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan,
 {
        int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
        struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
-       struct ipu_prg_channel *chan = &prg->chan[prg_chan];
+       struct ipu_prg_channel *chan;
        u32 val;
        int ret;
 
        if (prg_chan < 0)
                return prg_chan;
 
+       chan = &prg->chan[prg_chan];
+
        if (chan->enabled) {
                ipu_pre_update(prg->pres[chan->used_pre], *eba);
                return 0;
index 43ddcdfbd0da415b4fc397a89582290f3f37c786..9454ac134ce22fee3658d210c4046dbe2d0c5626 100644 (file)
 #define USB_DEVICE_ID_LD_MICROCASSYTIME                0x1033
 #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035
 #define USB_DEVICE_ID_LD_MICROCASSYPH          0x1038
+#define USB_DEVICE_ID_LD_POWERANALYSERCASSY    0x1040
+#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY      0x1042
+#define USB_DEVICE_ID_LD_MACHINETESTCASSY      0x1043
 #define USB_DEVICE_ID_LD_JWM           0x1080
 #define USB_DEVICE_ID_LD_DMMP          0x1081
 #define USB_DEVICE_ID_LD_UMIP          0x1090
index 5f6035a5ce367a947aa8fb773de8b39c5bd22bd7..e92b77fa574a940439ec8059265ba440dc91b993 100644 (file)
@@ -809,6 +809,9 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
index 50e071444a5c5c319b8c253d4e8ee8cb87e1145f..8699bb969e7e31dd42a249018f1bb4db78b520c8 100644 (file)
@@ -417,13 +417,24 @@ __hv_pkt_iter_next(struct vmbus_channel *channel,
 }
 EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
 
+/* How many bytes were read in this iterator cycle */
+static u32 hv_pkt_iter_bytes_read(const struct hv_ring_buffer_info *rbi,
+                                       u32 start_read_index)
+{
+       if (rbi->priv_read_index >= start_read_index)
+               return rbi->priv_read_index - start_read_index;
+       else
+               return rbi->ring_datasize - start_read_index +
+                       rbi->priv_read_index;
+}
+
 /*
  * Update host ring buffer after iterating over packets.
  */
 void hv_pkt_iter_close(struct vmbus_channel *channel)
 {
        struct hv_ring_buffer_info *rbi = &channel->inbound;
-       u32 orig_write_sz = hv_get_bytes_to_write(rbi);
+       u32 curr_write_sz, pending_sz, bytes_read, start_read_index;
 
        /*
         * Make sure all reads are done before we update the read index since
@@ -431,8 +442,12 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
         * is updated.
         */
        virt_rmb();
+       start_read_index = rbi->ring_buffer->read_index;
        rbi->ring_buffer->read_index = rbi->priv_read_index;
 
+       if (!rbi->ring_buffer->feature_bits.feat_pending_send_sz)
+               return;
+
        /*
         * Issue a full memory barrier before making the signaling decision.
         * Here is the reason for having this barrier:
@@ -446,26 +461,29 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
         */
        virt_mb();
 
-       /* If host has disabled notifications then skip */
-       if (rbi->ring_buffer->interrupt_mask)
+       pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+       if (!pending_sz)
                return;
 
-       if (rbi->ring_buffer->feature_bits.feat_pending_send_sz) {
-               u32 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+       /*
+        * Ensure the read of write_index in hv_get_bytes_to_write()
+        * happens after the read of pending_send_sz.
+        */
+       virt_rmb();
+       curr_write_sz = hv_get_bytes_to_write(rbi);
+       bytes_read = hv_pkt_iter_bytes_read(rbi, start_read_index);
 
-               /*
-                * If there was space before we began iteration,
-                * then host was not blocked. Also handles case where
-                * pending_sz is zero then host has nothing pending
-                * and does not need to be signaled.
-                */
-               if (orig_write_sz > pending_sz)
-                       return;
+       /*
+        * If there was space before we began iteration,
+        * then host was not blocked.
+        */
 
-               /* If pending write will not fit, don't give false hope. */
-               if (hv_get_bytes_to_write(rbi) < pending_sz)
-                       return;
-       }
+       if (curr_write_sz - bytes_read > pending_sz)
+               return;
+
+       /* If pending write will not fit, don't give false hope. */
+       if (curr_write_sz <= pending_sz)
+               return;
 
        vmbus_setevent(channel);
 }
index 4bdbf77f7197fc039e240021f9e15d5f4eae76e8..72c338eb5fae5a94c5558ebe5aae4530bb649763 100644 (file)
@@ -269,13 +269,13 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
        for (i = 0; i < ARRAY_SIZE(tjmax_model_table); i++) {
                const struct tjmax_model *tm = &tjmax_model_table[i];
                if (c->x86_model == tm->model &&
-                   (tm->mask == ANY || c->x86_mask == tm->mask))
+                   (tm->mask == ANY || c->x86_stepping == tm->mask))
                        return tm->tjmax;
        }
 
        /* Early chips have no MSR for TjMax */
 
-       if (c->x86_model == 0xf && c->x86_mask < 4)
+       if (c->x86_model == 0xf && c->x86_stepping < 4)
                usemsr_ee = 0;
 
        if (c->x86_model > 0xe && usemsr_ee) {
@@ -426,7 +426,7 @@ static int chk_ucode_version(unsigned int cpu)
         * Readings might stop update when processor visited too deep sleep,
         * fixed for stepping D0 (6EC).
         */
-       if (c->x86_model == 0xe && c->x86_mask < 0xc && c->microcode < 0x39) {
+       if (c->x86_model == 0xe && c->x86_stepping < 0xc && c->microcode < 0x39) {
                pr_err("Errata AE18 not fixed, update BIOS or microcode of the CPU!\n");
                return -ENODEV;
        }
index ef91b8a6754924319c781b89eb83b2ec393fb3a9..84e91286fc4fde72e30502516b0205213efa9c45 100644 (file)
@@ -293,7 +293,7 @@ u8 vid_which_vrm(void)
        if (c->x86 < 6)         /* Any CPU with family lower than 6 */
                return 0;       /* doesn't have VID */
 
-       vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_mask, c->x86_vendor);
+       vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_stepping, c->x86_vendor);
        if (vrm_ret == 134)
                vrm_ret = get_via_model_d_vrm();
        if (vrm_ret == 0)
index 06b4e1c78bd8f175e258041584d546ed8cf5538f..051a72eecb2455794d51becf66ea66348e6f17c9 100644 (file)
@@ -129,7 +129,10 @@ static ssize_t temp1_input_show(struct device *dev,
 
        data->read_tempreg(data->pdev, &regval);
        temp = (regval >> 21) * 125;
-       temp -= data->temp_offset;
+       if (temp > data->temp_offset)
+               temp -= data->temp_offset;
+       else
+               temp = 0;
 
        return sprintf(buf, "%u\n", temp);
 }
@@ -227,7 +230,7 @@ static bool has_erratum_319(struct pci_dev *pdev)
         * and AM3 formats, but that's the best we can do.
         */
        return boot_cpu_data.x86_model < 4 ||
-              (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask <= 2);
+              (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
 }
 
 static int k10temp_probe(struct pci_dev *pdev,
index 5a632bcf869bbf78d3835474a066eaa76b84688d..e59f9113fb93b0834209dfd1d0abe4e03f64327d 100644 (file)
@@ -187,7 +187,7 @@ static int k8temp_probe(struct pci_dev *pdev,
                return -ENOMEM;
 
        model = boot_cpu_data.x86_model;
-       stepping = boot_cpu_data.x86_mask;
+       stepping = boot_cpu_data.x86_stepping;
 
        /* feature available since SH-C0, exclude older revisions */
        if ((model == 4 && stepping == 0) ||
index a9805c7cb305ac56162519a65b4398cb2f39fd73..e2954fb86d659f366a250ab65640ed2e0ad002ec 100644 (file)
@@ -123,8 +123,10 @@ config I2C_I801
            Wildcat Point (PCH)
            Wildcat Point-LP (PCH)
            BayTrail (SOC)
+           Braswell (SOC)
            Sunrise Point-H (PCH)
            Sunrise Point-LP (PCH)
+           Kaby Lake-H (PCH)
            DNV (SOC)
            Broxton (SOC)
            Lewisburg (PCH)
index cd07a69e2e9355540442785f95e90823b05c9d10..44deae78913e5fa259927d1b5e8b6bf9aee60138 100644 (file)
@@ -50,6 +50,9 @@
 #define BCM2835_I2C_S_CLKT     BIT(9)
 #define BCM2835_I2C_S_LEN      BIT(10) /* Fake bit for SW error reporting */
 
+#define BCM2835_I2C_FEDL_SHIFT 16
+#define BCM2835_I2C_REDL_SHIFT 0
+
 #define BCM2835_I2C_CDIV_MIN   0x0002
 #define BCM2835_I2C_CDIV_MAX   0xFFFE
 
@@ -81,7 +84,7 @@ static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg)
 
 static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
 {
-       u32 divider;
+       u32 divider, redl, fedl;
 
        divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk),
                               i2c_dev->bus_clk_rate);
@@ -100,6 +103,22 @@ static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
 
        bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
 
+       /*
+        * Number of core clocks to wait after falling edge before
+        * outputting the next data bit.  Note that both FEDL and REDL
+        * can't be greater than CDIV/2.
+        */
+       fedl = max(divider / 16, 1u);
+
+       /*
+        * Number of core clocks to wait after rising edge before
+        * sampling the next incoming data bit.
+        */
+       redl = max(divider / 4, 1u);
+
+       bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DEL,
+                          (fedl << BCM2835_I2C_FEDL_SHIFT) |
+                          (redl << BCM2835_I2C_REDL_SHIFT));
        return 0;
 }
 
index ae691884d07161c9940aad5162d8b6dda6eadd9c..05732531829fe090185d5f133ea2d7958a94e87a 100644 (file)
@@ -209,7 +209,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
        i2c_dw_disable_int(dev);
 
        /* Enable the adapter */
-       __i2c_dw_enable(dev, true);
+       __i2c_dw_enable_and_wait(dev, true);
 
        /* Clear and enable interrupts */
        dw_readl(dev, DW_IC_CLR_INTR);
@@ -644,7 +644,7 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev)
        gpio = devm_gpiod_get(dev->dev, "scl", GPIOD_OUT_HIGH);
        if (IS_ERR(gpio)) {
                r = PTR_ERR(gpio);
-               if (r == -ENOENT)
+               if (r == -ENOENT || r == -ENOSYS)
                        return 0;
                return r;
        }
index 8eac00efadc1ad8f8e477094e26790a1ec317117..692b341258667493a4eb0ae1996528d5fee52c3b 100644 (file)
@@ -58,6 +58,7 @@
  * Wildcat Point (PCH)         0x8ca2  32      hard    yes     yes     yes
  * Wildcat Point-LP (PCH)      0x9ca2  32      hard    yes     yes     yes
  * BayTrail (SOC)              0x0f12  32      hard    yes     yes     yes
+ * Braswell (SOC)              0x2292  32      hard    yes     yes     yes
  * Sunrise Point-H (PCH)       0xa123  32      hard    yes     yes     yes
  * Sunrise Point-LP (PCH)      0x9d23  32      hard    yes     yes     yes
  * DNV (SOC)                   0x19df  32      hard    yes     yes     yes
index 1d87757990568c40b9cebe4df7dda54fe21918f7..d9607905dc2f1dd0db15c6ca457ebc445921d829 100644 (file)
@@ -233,6 +233,7 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
                return -EOPNOTSUPP;
 
        case STAT_TXDATA_NAK:
+       case STAT_BUS_ERROR:
                return -EIO;
        case STAT_TXADDR_NAK:
        case STAT_RXADDR_NAK:
index a7ef19855bb8fa9b0670d7406652e1aa214e76c6..9bb9f64fdda0392364638ecbaafe3fab5612baf6 100644 (file)
@@ -43,7 +43,7 @@
 #define TWSI_CTL_AAK           0x04    /* Assert ACK */
 
 /* Status values */
-#define STAT_ERROR             0x00
+#define STAT_BUS_ERROR         0x00
 #define STAT_START             0x08
 #define STAT_REP_START         0x10
 #define STAT_TXADDR_ACK                0x18
index 2fd8b6d0039106976ced7443b184b5dcacd81576..87197ece0f9034192aaf36e4baa3520d8eeb772f 100644 (file)
@@ -341,7 +341,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, adap);
        init_completion(&siic->done);
 
-       /* Controller Initalisation */
+       /* Controller initialisation */
 
        writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
        while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
@@ -369,7 +369,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
         * but they start to affect the speed when clock is set to faster
         * frequencies.
         * Through the actual tests, use the different user_div value(which
-        * in the divider formular 'Fio / (Fi2c * user_div)') to adapt
+        * in the divider formula 'Fio / (Fi2c * user_div)') to adapt
         * the different ranges of i2c bus clock frequency, to make the SCL
         * more accurate.
         */
index 17fd55af4d9247ee89c0b581c5de3ab3437860a2..caa20eb5f26b03c7e02569e54dbb599fd2e73ec1 100644 (file)
@@ -928,7 +928,7 @@ static int exact_lock(dev_t dev, void *data)
 {
        struct gendisk *p = data;
 
-       if (!get_disk(p))
+       if (!get_disk_and_module(p))
                return -1;
        return 0;
 }
index 6fe995cf16a6a7eb49403784dcaf0ffe25f65a64..3e6fd5a8ac5be13fba3a8bf1d14f75481eafd2a9 100644 (file)
@@ -920,6 +920,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
 int st_accel_common_probe(struct iio_dev *indio_dev)
 {
        struct st_sensor_data *adata = iio_priv(indio_dev);
+       struct st_sensors_platform_data *pdata =
+               (struct st_sensors_platform_data *)adata->dev->platform_data;
        int irq = adata->get_irq_data_ready(indio_dev);
        int err;
 
@@ -946,7 +948,10 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
                                        &adata->sensor_settings->fs.fs_avl[0];
        adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
 
-       err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
+       if (!pdata)
+               pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
+
+       err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
                goto st_accel_power_off;
 
index 327a49ba19916e1405c41980ef7677f5bf7a8bdb..9515ca165dfdbc17258be4b0c578efb851a883a5 100644 (file)
@@ -243,7 +243,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
                                         ASPEED_ADC_INIT_POLLING_TIME,
                                         ASPEED_ADC_INIT_TIMEOUT);
                if (ret)
-                       goto scaler_error;
+                       goto poll_timeout_error;
        }
 
        /* Start all channels in normal mode. */
@@ -274,9 +274,10 @@ iio_register_error:
        writel(ASPEED_OPERATION_MODE_POWER_DOWN,
                data->base + ASPEED_REG_ENGINE_CONTROL);
        clk_disable_unprepare(data->clk_scaler->clk);
-reset_error:
-       reset_control_assert(data->rst);
 clk_enable_error:
+poll_timeout_error:
+       reset_control_assert(data->rst);
+reset_error:
        clk_hw_unregister_divider(data->clk_scaler);
 scaler_error:
        clk_hw_unregister_divider(data->clk_prescaler);
index 29fa7736d80caae392095123d207695cc87f53df..ede955d9b2a4d67582ab596fc48cc032dae3158b 100644 (file)
@@ -462,8 +462,10 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
                        regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
                } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
 
-               if (timeout < 0)
+               if (timeout < 0) {
+                       mutex_unlock(&indio_dev->mlock);
                        return -ETIMEDOUT;
+               }
        }
 
        return 0;
index 7f5def465340e6444e8023a2e11d8b0b877d89b0..9a2583caedaaefd8c028081ff947c04a5f612496 100644 (file)
@@ -722,8 +722,6 @@ static int stm32h7_adc_enable(struct stm32_adc *adc)
        int ret;
        u32 val;
 
-       /* Clear ADRDY by writing one, then enable ADC */
-       stm32_adc_set_bits(adc, STM32H7_ADC_ISR, STM32H7_ADRDY);
        stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADEN);
 
        /* Poll for ADRDY to be set (after adc startup time) */
@@ -731,8 +729,11 @@ static int stm32h7_adc_enable(struct stm32_adc *adc)
                                           val & STM32H7_ADRDY,
                                           100, STM32_ADC_TIMEOUT_US);
        if (ret) {
-               stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADEN);
+               stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADDIS);
                dev_err(&indio_dev->dev, "Failed to enable ADC\n");
+       } else {
+               /* Clear ADRDY by writing one */
+               stm32_adc_set_bits(adc, STM32H7_ADC_ISR, STM32H7_ADRDY);
        }
 
        return ret;
index daa026d6a94f90304d16cfc4348a963833c973e7..01422d11753cf39be105b9352e06746927d75731 100644 (file)
@@ -54,7 +54,6 @@ struct stm32_dfsdm_adc {
        struct stm32_dfsdm *dfsdm;
        const struct stm32_dfsdm_dev_data *dev_data;
        unsigned int fl_id;
-       unsigned int ch_id;
 
        /* ADC specific */
        unsigned int oversamp;
@@ -384,7 +383,7 @@ static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev,
 {
        struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
        struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
-       struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id];
+       struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel];
        unsigned int sample_freq = adc->sample_freq;
        unsigned int spi_freq;
        int ret;
@@ -419,18 +418,20 @@ static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev,
        return len;
 }
 
-static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma)
+static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc,
+                                 const struct iio_chan_spec *chan,
+                                 bool dma)
 {
        struct regmap *regmap = adc->dfsdm->regmap;
        int ret;
        unsigned int dma_en = 0, cont_en = 0;
 
-       ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id);
+       ret = stm32_dfsdm_start_channel(adc->dfsdm, chan->channel);
        if (ret < 0)
                return ret;
 
        ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id,
-                                          adc->ch_id);
+                                          chan->channel);
        if (ret < 0)
                goto stop_channels;
 
@@ -464,12 +465,13 @@ stop_channels:
 
        regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
                           DFSDM_CR1_RCONT_MASK, 0);
-       stm32_dfsdm_stop_channel(adc->dfsdm, adc->fl_id);
+       stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel);
 
        return ret;
 }
 
-static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc)
+static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc,
+                                 const struct iio_chan_spec *chan)
 {
        struct regmap *regmap = adc->dfsdm->regmap;
 
@@ -482,7 +484,7 @@ static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc)
        regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
                           DFSDM_CR1_RCONT_MASK, 0);
 
-       stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id);
+       stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel);
 }
 
 static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev,
@@ -609,6 +611,7 @@ static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
 static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
 {
        struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
+       const struct iio_chan_spec *chan = &indio_dev->channels[0];
        int ret;
 
        /* Reset adc buffer index */
@@ -618,7 +621,7 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
        if (ret < 0)
                return ret;
 
-       ret = stm32_dfsdm_start_conv(adc, true);
+       ret = stm32_dfsdm_start_conv(adc, chan, true);
        if (ret) {
                dev_err(&indio_dev->dev, "Can't start conversion\n");
                goto stop_dfsdm;
@@ -635,7 +638,7 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
        return 0;
 
 err_stop_conv:
-       stm32_dfsdm_stop_conv(adc);
+       stm32_dfsdm_stop_conv(adc, chan);
 stop_dfsdm:
        stm32_dfsdm_stop_dfsdm(adc->dfsdm);
 
@@ -645,11 +648,12 @@ stop_dfsdm:
 static int stm32_dfsdm_predisable(struct iio_dev *indio_dev)
 {
        struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
+       const struct iio_chan_spec *chan = &indio_dev->channels[0];
 
        if (adc->dma_chan)
                dmaengine_terminate_all(adc->dma_chan);
 
-       stm32_dfsdm_stop_conv(adc);
+       stm32_dfsdm_stop_conv(adc, chan);
 
        stm32_dfsdm_stop_dfsdm(adc->dfsdm);
 
@@ -730,7 +734,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
        if (ret < 0)
                goto stop_dfsdm;
 
-       ret = stm32_dfsdm_start_conv(adc, false);
+       ret = stm32_dfsdm_start_conv(adc, chan, false);
        if (ret < 0) {
                regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
                                   DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));
@@ -751,7 +755,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
        else
                ret = IIO_VAL_INT;
 
-       stm32_dfsdm_stop_conv(adc);
+       stm32_dfsdm_stop_conv(adc, chan);
 
 stop_dfsdm:
        stm32_dfsdm_stop_dfsdm(adc->dfsdm);
@@ -765,7 +769,7 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
 {
        struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
        struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
-       struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id];
+       struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel];
        unsigned int spi_freq = adc->spi_freq;
        int ret = -EINVAL;
 
@@ -972,7 +976,6 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
        }
        ch->scan_type.realbits = 24;
        ch->scan_type.storagebits = 32;
-       adc->ch_id = ch->channel;
 
        return stm32_dfsdm_chan_configure(adc->dfsdm,
                                          &adc->dfsdm->ch_list[ch->channel]);
@@ -1001,7 +1004,7 @@ static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev)
        }
        ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ);
 
-       d_ch = &adc->dfsdm->ch_list[adc->ch_id];
+       d_ch = &adc->dfsdm->ch_list[ch->channel];
        if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
                adc->spi_freq = adc->dfsdm->spi_master_freq;
 
@@ -1042,8 +1045,8 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
                return -ENOMEM;
 
        for (chan_idx = 0; chan_idx < num_ch; chan_idx++) {
-               ch->scan_index = chan_idx;
-               ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
+               ch[chan_idx].scan_index = chan_idx;
+               ret = stm32_dfsdm_adc_chan_init_one(indio_dev, &ch[chan_idx]);
                if (ret < 0) {
                        dev_err(&indio_dev->dev, "Channels init failed\n");
                        return ret;
index 6290332cfd3f8a7654d6f68cc13024540031a5c7..e50efdcc41ff38c04b87c31c20d4e5c8f542deac 100644 (file)
@@ -83,7 +83,7 @@ int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm)
 {
        struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm);
        struct device *dev = &priv->pdev->dev;
-       unsigned int clk_div = priv->spi_clk_out_div;
+       unsigned int clk_div = priv->spi_clk_out_div, clk_src;
        int ret;
 
        if (atomic_inc_return(&priv->n_active_ch) == 1) {
@@ -100,6 +100,14 @@ int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm)
                        }
                }
 
+               /* select clock source, e.g. 0 for "dfsdm" or 1 for "audio" */
+               clk_src = priv->aclk ? 1 : 0;
+               ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
+                                        DFSDM_CHCFGR1_CKOUTSRC_MASK,
+                                        DFSDM_CHCFGR1_CKOUTSRC(clk_src));
+               if (ret < 0)
+                       goto disable_aclk;
+
                /* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */
                ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
                                         DFSDM_CHCFGR1_CKOUTDIV_MASK,
@@ -274,7 +282,7 @@ static int stm32_dfsdm_probe(struct platform_device *pdev)
 
        dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm",
                                                  dfsdm->base,
-                                                 &stm32h7_dfsdm_regmap_cfg);
+                                                 dev_data->regmap_cfg);
        if (IS_ERR(dfsdm->regmap)) {
                ret = PTR_ERR(dfsdm->regmap);
                dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n",
index fbe2431f5b81b25dcd14647ca656ae70c4925e7e..1ea9f5513b0249019d91b9028c9aca2ba3e92342 100644 (file)
@@ -133,6 +133,9 @@ static int ccs811_start_sensor_application(struct i2c_client *client)
        if (ret < 0)
                return ret;
 
+       if ((ret & CCS811_STATUS_FW_MODE_APPLICATION))
+               return 0;
+
        if ((ret & CCS811_STATUS_APP_VALID_MASK) !=
            CCS811_STATUS_APP_VALID_LOADED)
                return -EIO;
index 0dd5a381be64f6db3e538553cc030a664b8d3ccd..457372f36791b9efa6787a53f823fda62d4ca5d1 100644 (file)
@@ -46,6 +46,10 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
        if (adis->trig == NULL)
                return -ENOMEM;
 
+       adis->trig->dev.parent = &adis->spi->dev;
+       adis->trig->ops = &adis_trigger_ops;
+       iio_trigger_set_drvdata(adis->trig, adis);
+
        ret = request_irq(adis->spi->irq,
                          &iio_trigger_generic_data_rdy_poll,
                          IRQF_TRIGGER_RISING,
@@ -54,9 +58,6 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
        if (ret)
                goto error_free_trig;
 
-       adis->trig->dev.parent = &adis->spi->dev;
-       adis->trig->ops = &adis_trigger_ops;
-       iio_trigger_set_drvdata(adis->trig, adis);
        ret = iio_trigger_register(adis->trig);
 
        indio_dev->trig = iio_trigger_get(adis->trig);
index 79abf70a126ddde78e0a60fe5adecb829f0423ce..cd5bfe39591bb2b2d44b3848cc2d84ef2d4a38f2 100644 (file)
@@ -175,7 +175,7 @@ __poll_t iio_buffer_poll(struct file *filp,
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
 
-       if (!indio_dev->info)
+       if (!indio_dev->info || rb == NULL)
                return 0;
 
        poll_wait(filp, &rb->pollq, wait);
index 349e5c713c03b882f91b33a22e8007f6b53c8667..4ddb6cf7d401e9088cd6d8f59db61b739831b30d 100644 (file)
@@ -640,7 +640,7 @@ int st_press_common_probe(struct iio_dev *indio_dev)
                       press_data->sensor_settings->drdy_irq.int2.addr))
                pdata = (struct st_sensors_platform_data *)&default_press_pdata;
 
-       err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
+       err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
                goto st_press_power_off;
 
index fcb1c4ba5e4143d2c8457b5a436355ca2158899a..f726f9427602f9ddff3820797ac40111702c937c 100644 (file)
@@ -68,6 +68,8 @@ config SX9500
 
 config SRF08
        tristate "Devantech SRF02/SRF08/SRF10 ultrasonic ranger sensor"
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
        depends on I2C
        help
          Say Y here to build a driver for Devantech SRF02/SRF08/SRF10
index a5b4cf030c11b74291baa6859ee370295fd0c42f..9183d148d644484c11f4e26fc87ff332c4fbb4eb 100644 (file)
@@ -550,18 +550,13 @@ static int addr_resolve(struct sockaddr *src_in,
                dst_release(dst);
        }
 
-       if (ndev->flags & IFF_LOOPBACK) {
-               ret = rdma_translate_ip(dst_in, addr);
-               /*
-                * Put the loopback device and get the translated
-                * device instead.
-                */
+       if (ndev) {
+               if (ndev->flags & IFF_LOOPBACK)
+                       ret = rdma_translate_ip(dst_in, addr);
+               else
+                       addr->bound_dev_if = ndev->ifindex;
                dev_put(ndev);
-               ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
-       } else {
-               addr->bound_dev_if = ndev->ifindex;
        }
-       dev_put(ndev);
 
        return ret;
 }
index e66963ca58bddaf02813c4e080f48ad4cf18be00..a5367c5efbe713401ee482b3ac0e58efcd45906b 100644 (file)
@@ -3069,7 +3069,8 @@ static int cma_port_is_unique(struct rdma_bind_list *bind_list,
                        continue;
 
                /* different dest port -> unique */
-               if (!cma_any_port(cur_daddr) &&
+               if (!cma_any_port(daddr) &&
+                   !cma_any_port(cur_daddr) &&
                    (dport != cur_dport))
                        continue;
 
@@ -3080,7 +3081,8 @@ static int cma_port_is_unique(struct rdma_bind_list *bind_list,
                        continue;
 
                /* different dst address -> unique */
-               if (!cma_any_addr(cur_daddr) &&
+               if (!cma_any_addr(daddr) &&
+                   !cma_any_addr(cur_daddr) &&
                    cma_addr_cmp(daddr, cur_daddr))
                        continue;
 
@@ -3378,13 +3380,13 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
                }
 #endif
        }
+       daddr = cma_dst_addr(id_priv);
+       daddr->sa_family = addr->sa_family;
+
        ret = cma_get_port(id_priv);
        if (ret)
                goto err2;
 
-       daddr = cma_dst_addr(id_priv);
-       daddr->sa_family = addr->sa_family;
-
        return 0;
 err2:
        if (id_priv->cma_dev)
@@ -4173,6 +4175,9 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
        struct cma_multicast *mc;
        int ret;
 
+       if (!id->device)
+               return -EINVAL;
+
        id_priv = container_of(id, struct rdma_id_private, id);
        if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) &&
            !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED))
index c4560d84dfaebd550f504f2ed6b5f30bfb7ad520..25bb178f60742233c018dc7edb51c0e6520689af 100644 (file)
@@ -305,16 +305,21 @@ void nldev_exit(void);
 static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
                                          struct ib_pd *pd,
                                          struct ib_qp_init_attr *attr,
-                                         struct ib_udata *udata)
+                                         struct ib_udata *udata,
+                                         struct ib_uobject *uobj)
 {
        struct ib_qp *qp;
 
+       if (!dev->create_qp)
+               return ERR_PTR(-EOPNOTSUPP);
+
        qp = dev->create_qp(pd, attr, udata);
        if (IS_ERR(qp))
                return qp;
 
        qp->device = dev;
        qp->pd = pd;
+       qp->uobject = uobj;
        /*
         * We don't track XRC QPs for now, because they don't have PD
         * and more importantly they are created internaly by driver,
index bc79ca8215d7c25ff22c2a901db04b209b49052a..af5ad6a56ae404d1cd2aae64f95e59d7ccded0ac 100644 (file)
@@ -17,6 +17,7 @@
 
 /* # of WCs to poll for with a single call to ib_poll_cq */
 #define IB_POLL_BATCH                  16
+#define IB_POLL_BATCH_DIRECT           8
 
 /* # of WCs to iterate over before yielding */
 #define IB_POLL_BUDGET_IRQ             256
 #define IB_POLL_FLAGS \
        (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS)
 
-static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
+static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *wcs,
+                          int batch)
 {
        int i, n, completed = 0;
-       struct ib_wc *wcs = poll_wc ? : cq->wc;
 
        /*
         * budget might be (-1) if the caller does not
         * want to bound this call, thus we need unsigned
         * minimum here.
         */
-       while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH,
-                       budget - completed), wcs)) > 0) {
+       while ((n = ib_poll_cq(cq, min_t(u32, batch,
+                                        budget - completed), wcs)) > 0) {
                for (i = 0; i < n; i++) {
                        struct ib_wc *wc = &wcs[i];
 
@@ -48,8 +49,7 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
 
                completed += n;
 
-               if (n != IB_POLL_BATCH ||
-                   (budget != -1 && completed >= budget))
+               if (n != batch || (budget != -1 && completed >= budget))
                        break;
        }
 
@@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
  */
 int ib_process_cq_direct(struct ib_cq *cq, int budget)
 {
-       struct ib_wc wcs[IB_POLL_BATCH];
+       struct ib_wc wcs[IB_POLL_BATCH_DIRECT];
 
-       return __ib_process_cq(cq, budget, wcs);
+       return __ib_process_cq(cq, budget, wcs, IB_POLL_BATCH_DIRECT);
 }
 EXPORT_SYMBOL(ib_process_cq_direct);
 
@@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget)
        struct ib_cq *cq = container_of(iop, struct ib_cq, iop);
        int completed;
 
-       completed = __ib_process_cq(cq, budget, NULL);
+       completed = __ib_process_cq(cq, budget, cq->wc, IB_POLL_BATCH);
        if (completed < budget) {
                irq_poll_complete(&cq->iop);
                if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
@@ -108,7 +108,8 @@ static void ib_cq_poll_work(struct work_struct *work)
        struct ib_cq *cq = container_of(work, struct ib_cq, work);
        int completed;
 
-       completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL);
+       completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, cq->wc,
+                                   IB_POLL_BATCH);
        if (completed >= IB_POLL_BUDGET_WORKQUEUE ||
            ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
                queue_work(ib_comp_wq, &cq->work);
index e8010e73a1cf4fe27ec9e5d3c25190003d55107a..bb065c9449be46617bd82e2b26d7648aa00212a3 100644 (file)
@@ -536,14 +536,14 @@ int ib_register_device(struct ib_device *device,
        ret = device->query_device(device, &device->attrs, &uhw);
        if (ret) {
                pr_warn("Couldn't query the device attributes\n");
-               goto cache_cleanup;
+               goto cg_cleanup;
        }
 
        ret = ib_device_register_sysfs(device, port_callback);
        if (ret) {
                pr_warn("Couldn't register device %s with driver model\n",
                        device->name);
-               goto cache_cleanup;
+               goto cg_cleanup;
        }
 
        device->reg_state = IB_DEV_REGISTERED;
@@ -559,6 +559,8 @@ int ib_register_device(struct ib_device *device,
        mutex_unlock(&device_mutex);
        return 0;
 
+cg_cleanup:
+       ib_device_unregister_rdmacg(device);
 cache_cleanup:
        ib_cache_cleanup_one(device);
        ib_cache_release_one(device);
index 85b5ee4defa4bed1cabaeaa1fe0f1121bc91c242..d8eead5d106df4326c476699cb44ee8756ddeec1 100644 (file)
@@ -141,7 +141,12 @@ static struct ib_uobject *alloc_uobj(struct ib_ucontext *context,
         */
        uobj->context = context;
        uobj->type = type;
-       atomic_set(&uobj->usecnt, 0);
+       /*
+        * Allocated objects start out as write locked to deny any other
+        * syscalls from accessing them until they are committed. See
+        * rdma_alloc_commit_uobject
+        */
+       atomic_set(&uobj->usecnt, -1);
        kref_init(&uobj->ref);
 
        return uobj;
@@ -196,7 +201,15 @@ static struct ib_uobject *lookup_get_idr_uobject(const struct uverbs_obj_type *t
                goto free;
        }
 
-       uverbs_uobject_get(uobj);
+       /*
+        * The idr_find is guaranteed to return a pointer to something that
+        * isn't freed yet, or NULL, as the free after idr_remove goes through
+        * kfree_rcu(). However the object may still have been released and
+        * kfree() could be called at any time.
+        */
+       if (!kref_get_unless_zero(&uobj->ref))
+               uobj = ERR_PTR(-ENOENT);
+
 free:
        rcu_read_unlock();
        return uobj;
@@ -399,13 +412,13 @@ static int __must_check remove_commit_fd_uobject(struct ib_uobject *uobj,
        return ret;
 }
 
-static void lockdep_check(struct ib_uobject *uobj, bool exclusive)
+static void assert_uverbs_usecnt(struct ib_uobject *uobj, bool exclusive)
 {
 #ifdef CONFIG_LOCKDEP
        if (exclusive)
-               WARN_ON(atomic_read(&uobj->usecnt) > 0);
+               WARN_ON(atomic_read(&uobj->usecnt) != -1);
        else
-               WARN_ON(atomic_read(&uobj->usecnt) == -1);
+               WARN_ON(atomic_read(&uobj->usecnt) <= 0);
 #endif
 }
 
@@ -444,7 +457,7 @@ int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj)
                WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n");
                return 0;
        }
-       lockdep_check(uobj, true);
+       assert_uverbs_usecnt(uobj, true);
        ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_DESTROY);
 
        up_read(&ucontext->cleanup_rwsem);
@@ -474,16 +487,17 @@ int rdma_explicit_destroy(struct ib_uobject *uobject)
                WARN(true, "ib_uverbs: Cleanup is running while removing an uobject\n");
                return 0;
        }
-       lockdep_check(uobject, true);
+       assert_uverbs_usecnt(uobject, true);
        ret = uobject->type->type_class->remove_commit(uobject,
                                                       RDMA_REMOVE_DESTROY);
        if (ret)
-               return ret;
+               goto out;
 
        uobject->type = &null_obj_type;
 
+out:
        up_read(&ucontext->cleanup_rwsem);
-       return 0;
+       return ret;
 }
 
 static void alloc_commit_idr_uobject(struct ib_uobject *uobj)
@@ -527,6 +541,10 @@ int rdma_alloc_commit_uobject(struct ib_uobject *uobj)
                return ret;
        }
 
+       /* matches atomic_set(-1) in alloc_uobj */
+       assert_uverbs_usecnt(uobj, true);
+       atomic_set(&uobj->usecnt, 0);
+
        uobj->type->type_class->alloc_commit(uobj);
        up_read(&uobj->context->cleanup_rwsem);
 
@@ -561,7 +579,7 @@ static void lookup_put_fd_uobject(struct ib_uobject *uobj, bool exclusive)
 
 void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive)
 {
-       lockdep_check(uobj, exclusive);
+       assert_uverbs_usecnt(uobj, exclusive);
        uobj->type->type_class->lookup_put(uobj, exclusive);
        /*
         * In order to unlock an object, either decrease its usecnt for
index 857637bf46da275262f3d4c023b27411f86e9e40..3dbc4e4cca415fd94a24443e44d1430a5cbe63d7 100644 (file)
@@ -7,7 +7,6 @@
 #include <rdma/restrack.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
-#include <linux/uaccess.h>
 #include <linux/pid_namespace.h>
 
 void rdma_restrack_init(struct rdma_restrack_root *res)
@@ -63,7 +62,6 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
 {
        enum rdma_restrack_type type = res->type;
        struct ib_device *dev;
-       struct ib_xrcd *xrcd;
        struct ib_pd *pd;
        struct ib_cq *cq;
        struct ib_qp *qp;
@@ -81,10 +79,6 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
                qp = container_of(res, struct ib_qp, res);
                dev = qp->device;
                break;
-       case RDMA_RESTRACK_XRCD:
-               xrcd = container_of(res, struct ib_xrcd, res);
-               dev = xrcd->device;
-               break;
        default:
                WARN_ONCE(true, "Wrong resource tracking type %u\n", type);
                return NULL;
@@ -93,6 +87,21 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
        return dev;
 }
 
+static bool res_is_user(struct rdma_restrack_entry *res)
+{
+       switch (res->type) {
+       case RDMA_RESTRACK_PD:
+               return container_of(res, struct ib_pd, res)->uobject;
+       case RDMA_RESTRACK_CQ:
+               return container_of(res, struct ib_cq, res)->uobject;
+       case RDMA_RESTRACK_QP:
+               return container_of(res, struct ib_qp, res)->uobject;
+       default:
+               WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type);
+               return false;
+       }
+}
+
 void rdma_restrack_add(struct rdma_restrack_entry *res)
 {
        struct ib_device *dev = res_to_dev(res);
@@ -100,7 +109,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res)
        if (!dev)
                return;
 
-       if (!uaccess_kernel()) {
+       if (res_is_user(res)) {
                get_task_struct(current);
                res->task = current;
                res->kern_name = NULL;
index 8cf15d4a8ac438db82971ad3d3bc16649a5ed6da..9f029a1ca5ea9555b2ab366012d5eabd04168e3c 100644 (file)
@@ -1291,10 +1291,9 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,
 
                resolved_dev = dev_get_by_index(dev_addr.net,
                                                dev_addr.bound_dev_if);
-               if (resolved_dev->flags & IFF_LOOPBACK) {
-                       dev_put(resolved_dev);
-                       resolved_dev = idev;
-                       dev_hold(resolved_dev);
+               if (!resolved_dev) {
+                       dev_put(idev);
+                       return -ENODEV;
                }
                ndev = ib_get_ndev_from_path(rec);
                rcu_read_lock();
index f015f1bf88c9c8c52c2a739bb130c2949348f0e4..e5a1e7d813265fc3f0947d3a6aa643367745d9cc 100644 (file)
@@ -132,7 +132,7 @@ static inline struct ucma_context *_ucma_find_context(int id,
        ctx = idr_find(&ctx_idr, id);
        if (!ctx)
                ctx = ERR_PTR(-ENOENT);
-       else if (ctx->file != file)
+       else if (ctx->file != file || !ctx->cm_id)
                ctx = ERR_PTR(-EINVAL);
        return ctx;
 }
@@ -456,6 +456,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
        struct rdma_ucm_create_id cmd;
        struct rdma_ucm_create_id_resp resp;
        struct ucma_context *ctx;
+       struct rdma_cm_id *cm_id;
        enum ib_qp_type qp_type;
        int ret;
 
@@ -476,10 +477,10 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
                return -ENOMEM;
 
        ctx->uid = cmd.uid;
-       ctx->cm_id = rdma_create_id(current->nsproxy->net_ns,
-                                   ucma_event_handler, ctx, cmd.ps, qp_type);
-       if (IS_ERR(ctx->cm_id)) {
-               ret = PTR_ERR(ctx->cm_id);
+       cm_id = rdma_create_id(current->nsproxy->net_ns,
+                              ucma_event_handler, ctx, cmd.ps, qp_type);
+       if (IS_ERR(cm_id)) {
+               ret = PTR_ERR(cm_id);
                goto err1;
        }
 
@@ -489,14 +490,19 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
                ret = -EFAULT;
                goto err2;
        }
+
+       ctx->cm_id = cm_id;
        return 0;
 
 err2:
-       rdma_destroy_id(ctx->cm_id);
+       rdma_destroy_id(cm_id);
 err1:
        mutex_lock(&mut);
        idr_remove(&ctx_idr, ctx->id);
        mutex_unlock(&mut);
+       mutex_lock(&file->mut);
+       list_del(&ctx->list);
+       mutex_unlock(&file->mut);
        kfree(ctx);
        return ret;
 }
@@ -664,19 +670,23 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,
                               int in_len, int out_len)
 {
        struct rdma_ucm_resolve_ip cmd;
+       struct sockaddr *src, *dst;
        struct ucma_context *ctx;
        int ret;
 
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
+       src = (struct sockaddr *) &cmd.src_addr;
+       dst = (struct sockaddr *) &cmd.dst_addr;
+       if (!rdma_addr_size(src) || !rdma_addr_size(dst))
+               return -EINVAL;
+
        ctx = ucma_get_ctx(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
-                               (struct sockaddr *) &cmd.dst_addr,
-                               cmd.timeout_ms);
+       ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
        ucma_put_ctx(ctx);
        return ret;
 }
@@ -1149,6 +1159,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
+       if (cmd.qp_state > IB_QPS_ERR)
+               return -EINVAL;
+
        ctx = ucma_get_ctx(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
@@ -1294,6 +1307,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
+       if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
+               return -EINVAL;
+
        optval = memdup_user((void __user *) (unsigned long) cmd.optval,
                             cmd.optlen);
        if (IS_ERR(optval)) {
@@ -1343,7 +1359,7 @@ static ssize_t ucma_process_join(struct ucma_file *file,
                return -ENOSPC;
 
        addr = (struct sockaddr *) &cmd->addr;
-       if (!cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
+       if (cmd->addr_size != rdma_addr_size(addr))
                return -EINVAL;
 
        if (cmd->join_flags == RDMA_MC_JOIN_FLAG_FULLMEMBER)
@@ -1411,6 +1427,9 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
        join_cmd.uid = cmd.uid;
        join_cmd.id = cmd.id;
        join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+       if (!join_cmd.addr_size)
+               return -EINVAL;
+
        join_cmd.join_flags = RDMA_MC_JOIN_FLAG_FULLMEMBER;
        memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
 
@@ -1426,6 +1445,9 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
+       if (!rdma_addr_size((struct sockaddr *)&cmd.addr))
+               return -EINVAL;
+
        return ucma_process_join(file, &cmd, out_len);
 }
 
index 256934d1f64fba0e6461f857d372e31f82049b4c..a148de35df8d4008bf2534c4920f6ff075c0e698 100644 (file)
@@ -562,9 +562,10 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
        if (f.file)
                fdput(f);
 
+       mutex_unlock(&file->device->xrcd_tree_mutex);
+
        uobj_alloc_commit(&obj->uobject);
 
-       mutex_unlock(&file->device->xrcd_tree_mutex);
        return in_len;
 
 err_copy:
@@ -603,10 +604,8 @@ ssize_t ib_uverbs_close_xrcd(struct ib_uverbs_file *file,
 
        uobj  = uobj_get_write(uobj_get_type(xrcd), cmd.xrcd_handle,
                               file->ucontext);
-       if (IS_ERR(uobj)) {
-               mutex_unlock(&file->device->xrcd_tree_mutex);
+       if (IS_ERR(uobj))
                return PTR_ERR(uobj);
-       }
 
        ret = uobj_remove_commit(uobj);
        return ret ?: in_len;
@@ -979,6 +978,9 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
        struct ib_uverbs_ex_create_cq_resp resp;
        struct ib_cq_init_attr attr = {};
 
+       if (!ib_dev->create_cq)
+               return ERR_PTR(-EOPNOTSUPP);
+
        if (cmd->comp_vector >= file->device->num_comp_vectors)
                return ERR_PTR(-EINVAL);
 
@@ -1030,14 +1032,14 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
        resp.response_length = offsetof(typeof(resp), response_length) +
                sizeof(resp.response_length);
 
+       cq->res.type = RDMA_RESTRACK_CQ;
+       rdma_restrack_add(&cq->res);
+
        ret = cb(file, obj, &resp, ucore, context);
        if (ret)
                goto err_cb;
 
        uobj_alloc_commit(&obj->uobject);
-       cq->res.type = RDMA_RESTRACK_CQ;
-       rdma_restrack_add(&cq->res);
-
        return obj;
 
 err_cb:
@@ -1518,7 +1520,8 @@ static int create_qp(struct ib_uverbs_file *file,
        if (cmd->qp_type == IB_QPT_XRC_TGT)
                qp = ib_create_qp(pd, &attr);
        else
-               qp = _ib_create_qp(device, pd, &attr, uhw);
+               qp = _ib_create_qp(device, pd, &attr, uhw,
+                                  &obj->uevent.uobject);
 
        if (IS_ERR(qp)) {
                ret = PTR_ERR(qp);
@@ -1550,8 +1553,10 @@ static int create_qp(struct ib_uverbs_file *file,
                        atomic_inc(&attr.srq->usecnt);
                if (ind_tbl)
                        atomic_inc(&ind_tbl->usecnt);
+       } else {
+               /* It is done in _ib_create_qp for other QP types */
+               qp->uobject = &obj->uevent.uobject;
        }
-       qp->uobject = &obj->uevent.uobject;
 
        obj->uevent.uobject.object = qp;
 
@@ -1971,8 +1976,15 @@ static int modify_qp(struct ib_uverbs_file *file,
                goto release_qp;
        }
 
+       if ((cmd->base.attr_mask & IB_QP_AV) &&
+           !rdma_is_port_valid(qp->device, cmd->base.dest.port_num)) {
+               ret = -EINVAL;
+               goto release_qp;
+       }
+
        if ((cmd->base.attr_mask & IB_QP_ALT_PATH) &&
-           !rdma_is_port_valid(qp->device, cmd->base.alt_port_num)) {
+           (!rdma_is_port_valid(qp->device, cmd->base.alt_port_num) ||
+           !rdma_is_port_valid(qp->device, cmd->base.alt_dest.port_num))) {
                ret = -EINVAL;
                goto release_qp;
        }
@@ -2941,6 +2953,11 @@ int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file,
                wq_init_attr.create_flags = cmd.create_flags;
        obj->uevent.events_reported = 0;
        INIT_LIST_HEAD(&obj->uevent.event_list);
+
+       if (!pd->device->create_wq) {
+               err = -EOPNOTSUPP;
+               goto err_put_cq;
+       }
        wq = pd->device->create_wq(pd, &wq_init_attr, uhw);
        if (IS_ERR(wq)) {
                err = PTR_ERR(wq);
@@ -3084,7 +3101,12 @@ int ib_uverbs_ex_modify_wq(struct ib_uverbs_file *file,
                wq_attr.flags = cmd.flags;
                wq_attr.flags_mask = cmd.flags_mask;
        }
+       if (!wq->device->modify_wq) {
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
        ret = wq->device->modify_wq(wq, &wq_attr, cmd.attr_mask, uhw);
+out:
        uobj_put_obj_read(wq);
        return ret;
 }
@@ -3181,6 +3203,11 @@ int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file,
 
        init_attr.log_ind_tbl_size = cmd.log_ind_tbl_size;
        init_attr.ind_tbl = wqs;
+
+       if (!ib_dev->create_rwq_ind_table) {
+               err = -EOPNOTSUPP;
+               goto err_uobj;
+       }
        rwq_ind_tbl = ib_dev->create_rwq_ind_table(ib_dev, &init_attr, uhw);
 
        if (IS_ERR(rwq_ind_tbl)) {
@@ -3770,6 +3797,9 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
        struct ib_device_attr attr = {0};
        int err;
 
+       if (!ib_dev->query_device)
+               return -EOPNOTSUPP;
+
        if (ucore->inlen < sizeof(cmd))
                return -EINVAL;
 
index d96dc1d17be189a287475a076929af9b9cedd7f1..339b851450446567d34780aec5779d0aa76fedeb 100644 (file)
@@ -59,6 +59,9 @@ static int uverbs_process_attr(struct ib_device *ibdev,
                        return 0;
        }
 
+       if (test_bit(attr_id, attr_bundle_h->valid_bitmap))
+               return -EINVAL;
+
        spec = &attr_spec_bucket->attrs[attr_id];
        e = &elements[attr_id];
        e->uattr = uattr_ptr;
index 062485f9300dc05fdd581fcf487032bafe9317d7..62e1eb1d2a28ad1bd854699c62a1da6149443286 100644 (file)
@@ -114,6 +114,7 @@ static size_t get_elements_above_id(const void **iters,
        short min = SHRT_MAX;
        const void *elem;
        int i, j, last_stored = -1;
+       unsigned int equal_min = 0;
 
        for_each_element(elem, i, j, elements, num_elements, num_offset,
                         data_offset) {
@@ -136,6 +137,10 @@ static size_t get_elements_above_id(const void **iters,
                 */
                iters[last_stored == i ? num_iters - 1 : num_iters++] = elem;
                last_stored = i;
+               if (min == GET_ID(id))
+                       equal_min++;
+               else
+                       equal_min = 1;
                min = GET_ID(id);
        }
 
@@ -146,15 +151,10 @@ static size_t get_elements_above_id(const void **iters,
         * Therefore, we need to clean the beginning of the array to make sure
         * all ids of final elements are equal to min.
         */
-       for (i = num_iters - 1; i >= 0 &&
-            GET_ID(*(u16 *)(iters[i] + id_offset)) == min; i--)
-               ;
-
-       num_iters -= i + 1;
-       memmove(iters, iters + i + 1, sizeof(*iters) * num_iters);
+       memmove(iters, iters + num_iters - equal_min, sizeof(*iters) * equal_min);
 
        *min_id = min;
-       return num_iters;
+       return equal_min;
 }
 
 #define find_max_element_entry_id(num_elements, elements, num_objects_fld, \
@@ -322,7 +322,7 @@ static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_me
                hash = kzalloc(sizeof(*hash) +
                               ALIGN(sizeof(*hash->attrs) * (attr_max_bucket + 1),
                                     sizeof(long)) +
-                              BITS_TO_LONGS(attr_max_bucket) * sizeof(long),
+                              BITS_TO_LONGS(attr_max_bucket + 1) * sizeof(long),
                               GFP_KERNEL);
                if (!hash) {
                        res = -ENOMEM;
@@ -509,7 +509,7 @@ static struct uverbs_object_spec *build_object_with_methods(const struct uverbs_
                         * first handler which != NULL. This also defines the
                         * set of flags used for this handler.
                         */
-                       for (i = num_object_defs - 1;
+                       for (i = num_method_defs - 1;
                             i >= 0 && !method_defs[i]->handler; i--)
                                ;
                        hash->methods[min_id++] = method;
index 395a3b091229fbec064e17698e8dcc5967b9f9e5..b1ca223aa3808425cb0b435c65478b7fce85371f 100644 (file)
@@ -650,12 +650,21 @@ static int verify_command_mask(struct ib_device *ib_dev, __u32 command)
        return -1;
 }
 
+static bool verify_command_idx(u32 command, bool extended)
+{
+       if (extended)
+               return command < ARRAY_SIZE(uverbs_ex_cmd_table);
+
+       return command < ARRAY_SIZE(uverbs_cmd_table);
+}
+
 static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                             size_t count, loff_t *pos)
 {
        struct ib_uverbs_file *file = filp->private_data;
        struct ib_device *ib_dev;
        struct ib_uverbs_cmd_hdr hdr;
+       bool extended_command;
        __u32 command;
        __u32 flags;
        int srcu_key;
@@ -688,6 +697,15 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
        }
 
        command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK;
+       flags = (hdr.command &
+                IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT;
+
+       extended_command = flags & IB_USER_VERBS_CMD_FLAG_EXTENDED;
+       if (!verify_command_idx(command, extended_command)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        if (verify_command_mask(ib_dev, command)) {
                ret = -EOPNOTSUPP;
                goto out;
@@ -699,12 +717,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                goto out;
        }
 
-       flags = (hdr.command &
-                IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT;
-
        if (!flags) {
-               if (command >= ARRAY_SIZE(uverbs_cmd_table) ||
-                   !uverbs_cmd_table[command]) {
+               if (!uverbs_cmd_table[command]) {
                        ret = -EINVAL;
                        goto out;
                }
@@ -725,8 +739,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                struct ib_udata uhw;
                size_t written_count = count;
 
-               if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) ||
-                   !uverbs_ex_cmd_table[command]) {
+               if (!uverbs_ex_cmd_table[command]) {
                        ret = -ENOSYS;
                        goto out;
                }
@@ -942,6 +955,7 @@ static const struct file_operations uverbs_fops = {
        .llseek  = no_llseek,
 #if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS)
        .unlocked_ioctl = ib_uverbs_ioctl,
+       .compat_ioctl = ib_uverbs_ioctl,
 #endif
 };
 
@@ -954,6 +968,7 @@ static const struct file_operations uverbs_mmap_fops = {
        .llseek  = no_llseek,
 #if IS_ENABLED(CONFIG_INFINIBAND_EXP_USER_ACCESS)
        .unlocked_ioctl = ib_uverbs_ioctl,
+       .compat_ioctl = ib_uverbs_ioctl,
 #endif
 };
 
index cab0ac3556eb0392b77ef7309b2da732ee06cfc4..df1360e6774f4e3d05631b353cf0f4352037832f 100644 (file)
@@ -234,15 +234,18 @@ static void create_udata(struct uverbs_attr_bundle *ctx,
                uverbs_attr_get(ctx, UVERBS_UHW_OUT);
 
        if (!IS_ERR(uhw_in)) {
-               udata->inbuf = uhw_in->ptr_attr.ptr;
                udata->inlen = uhw_in->ptr_attr.len;
+               if (uverbs_attr_ptr_is_inline(uhw_in))
+                       udata->inbuf = &uhw_in->uattr->data;
+               else
+                       udata->inbuf = u64_to_user_ptr(uhw_in->ptr_attr.data);
        } else {
                udata->inbuf = NULL;
                udata->inlen = 0;
        }
 
        if (!IS_ERR(uhw_out)) {
-               udata->outbuf = uhw_out->ptr_attr.ptr;
+               udata->outbuf = u64_to_user_ptr(uhw_out->ptr_attr.data);
                udata->outlen = uhw_out->ptr_attr.len;
        } else {
                udata->outbuf = NULL;
@@ -323,7 +326,8 @@ static int uverbs_create_cq_handler(struct ib_device *ib_dev,
        cq->res.type = RDMA_RESTRACK_CQ;
        rdma_restrack_add(&cq->res);
 
-       ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe);
+       ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe,
+                            sizeof(cq->cqe));
        if (ret)
                goto err_cq;
 
@@ -375,7 +379,7 @@ static int uverbs_destroy_cq_handler(struct ib_device *ib_dev,
        resp.comp_events_reported  = obj->comp_events_reported;
        resp.async_events_reported = obj->async_events_reported;
 
-       return uverbs_copy_to(attrs, DESTROY_CQ_RESP, &resp);
+       return uverbs_copy_to(attrs, DESTROY_CQ_RESP, &resp, sizeof(resp));
 }
 
 static DECLARE_UVERBS_METHOD(
index 16ebc6372c31abe449f4e892d26e2d384cec56fc..93025d2009b89f8679a19001357b53bdc4733184 100644 (file)
@@ -887,7 +887,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
        if (qp_init_attr->cap.max_rdma_ctxs)
                rdma_rw_init_qp(device, qp_init_attr);
 
-       qp = _ib_create_qp(device, pd, qp_init_attr, NULL);
+       qp = _ib_create_qp(device, pd, qp_init_attr, NULL, NULL);
        if (IS_ERR(qp))
                return qp;
 
@@ -898,7 +898,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
        }
 
        qp->real_qp    = qp;
-       qp->uobject    = NULL;
        qp->qp_type    = qp_init_attr->qp_type;
        qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
 
index ca32057e886f00af4287cbe586c81866a3367ae4..96f76896488da6c0414411fea440520e75bf2843 100644 (file)
@@ -57,8 +57,8 @@
 #define BNXT_RE_PAGE_SIZE_8M           BIT(BNXT_RE_PAGE_SHIFT_8M)
 #define BNXT_RE_PAGE_SIZE_1G           BIT(BNXT_RE_PAGE_SHIFT_1G)
 
-#define BNXT_RE_MAX_MR_SIZE_LOW                BIT(BNXT_RE_PAGE_SHIFT_1G)
-#define BNXT_RE_MAX_MR_SIZE_HIGH       BIT(39)
+#define BNXT_RE_MAX_MR_SIZE_LOW                BIT_ULL(BNXT_RE_PAGE_SHIFT_1G)
+#define BNXT_RE_MAX_MR_SIZE_HIGH       BIT_ULL(39)
 #define BNXT_RE_MAX_MR_SIZE            BNXT_RE_MAX_MR_SIZE_HIGH
 
 #define BNXT_RE_MAX_QPC_COUNT          (64 * 1024)
@@ -120,7 +120,6 @@ struct bnxt_re_dev {
 #define BNXT_RE_FLAG_HAVE_L2_REF               3
 #define BNXT_RE_FLAG_RCFW_CHANNEL_EN           4
 #define BNXT_RE_FLAG_QOS_WORK_REG              5
-#define BNXT_RE_FLAG_TASK_IN_PROG              6
 #define BNXT_RE_FLAG_ISSUE_ROCE_STATS          29
        struct net_device               *netdev;
        unsigned int                    version, major, minor;
@@ -158,6 +157,7 @@ struct bnxt_re_dev {
        atomic_t                        srq_count;
        atomic_t                        mr_count;
        atomic_t                        mw_count;
+       atomic_t                        sched_count;
        /* Max of 2 lossless traffic class supported per port */
        u16                             cosq[2];
 
index ae9e9ff54826b322c97c061d1d6cc51c240f570e..8301d7e5fa8c4c97364ee9fb834beca84319027b 100644 (file)
@@ -174,10 +174,8 @@ int bnxt_re_query_device(struct ib_device *ibdev,
        ib_attr->max_pd = dev_attr->max_pd;
        ib_attr->max_qp_rd_atom = dev_attr->max_qp_rd_atom;
        ib_attr->max_qp_init_rd_atom = dev_attr->max_qp_init_rd_atom;
-       if (dev_attr->is_atomic) {
-               ib_attr->atomic_cap = IB_ATOMIC_HCA;
-               ib_attr->masked_atomic_cap = IB_ATOMIC_HCA;
-       }
+       ib_attr->atomic_cap = IB_ATOMIC_NONE;
+       ib_attr->masked_atomic_cap = IB_ATOMIC_NONE;
 
        ib_attr->max_ee_rd_atom = 0;
        ib_attr->max_res_rd_atom = 0;
@@ -787,20 +785,51 @@ int bnxt_re_query_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
        return 0;
 }
 
+unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp)
+       __acquires(&qp->scq->cq_lock) __acquires(&qp->rcq->cq_lock)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&qp->scq->cq_lock, flags);
+       if (qp->rcq != qp->scq)
+               spin_lock(&qp->rcq->cq_lock);
+       else
+               __acquire(&qp->rcq->cq_lock);
+
+       return flags;
+}
+
+void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,
+                       unsigned long flags)
+       __releases(&qp->scq->cq_lock) __releases(&qp->rcq->cq_lock)
+{
+       if (qp->rcq != qp->scq)
+               spin_unlock(&qp->rcq->cq_lock);
+       else
+               __release(&qp->rcq->cq_lock);
+       spin_unlock_irqrestore(&qp->scq->cq_lock, flags);
+}
+
 /* Queue Pairs */
 int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
 {
        struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
        struct bnxt_re_dev *rdev = qp->rdev;
        int rc;
+       unsigned int flags;
 
        bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);
-       bnxt_qplib_del_flush_qp(&qp->qplib_qp);
        rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
        if (rc) {
                dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP");
                return rc;
        }
+
+       flags = bnxt_re_lock_cqs(qp);
+       bnxt_qplib_clean_qp(&qp->qplib_qp);
+       bnxt_re_unlock_cqs(qp, flags);
+       bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp);
+
        if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) {
                rc = bnxt_qplib_destroy_ah(&rdev->qplib_res,
                                           &rdev->sqp_ah->qplib_ah);
@@ -810,7 +839,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
                        return rc;
                }
 
-               bnxt_qplib_del_flush_qp(&qp->qplib_qp);
+               bnxt_qplib_clean_qp(&qp->qplib_qp);
                rc = bnxt_qplib_destroy_qp(&rdev->qplib_res,
                                           &rdev->qp1_sqp->qplib_qp);
                if (rc) {
@@ -1069,6 +1098,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
                        goto fail;
                }
                qp->qplib_qp.scq = &cq->qplib_cq;
+               qp->scq = cq;
        }
 
        if (qp_init_attr->recv_cq) {
@@ -1080,6 +1110,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
                        goto fail;
                }
                qp->qplib_qp.rcq = &cq->qplib_cq;
+               qp->rcq = cq;
        }
 
        if (qp_init_attr->srq) {
@@ -1185,7 +1216,7 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
                rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp);
                if (rc) {
                        dev_err(rdev_to_dev(rdev), "Failed to create HW QP");
-                       goto fail;
+                       goto free_umem;
                }
        }
 
@@ -1213,6 +1244,13 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd,
        return &qp->ib_qp;
 qp_destroy:
        bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
+free_umem:
+       if (udata) {
+               if (qp->rumem)
+                       ib_umem_release(qp->rumem);
+               if (qp->sumem)
+                       ib_umem_release(qp->sumem);
+       }
 fail:
        kfree(qp);
        return ERR_PTR(rc);
@@ -1568,6 +1606,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
        int status;
        union ib_gid sgid;
        struct ib_gid_attr sgid_attr;
+       unsigned int flags;
        u8 nw_type;
 
        qp->qplib_qp.modify_flags = 0;
@@ -1596,14 +1635,18 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
                        dev_dbg(rdev_to_dev(rdev),
                                "Move QP = %p to flush list\n",
                                qp);
+                       flags = bnxt_re_lock_cqs(qp);
                        bnxt_qplib_add_flush_qp(&qp->qplib_qp);
+                       bnxt_re_unlock_cqs(qp, flags);
                }
                if (!qp->sumem &&
                    qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_RESET) {
                        dev_dbg(rdev_to_dev(rdev),
                                "Move QP = %p out of flush list\n",
                                qp);
-                       bnxt_qplib_del_flush_qp(&qp->qplib_qp);
+                       flags = bnxt_re_lock_cqs(qp);
+                       bnxt_qplib_clean_qp(&qp->qplib_qp);
+                       bnxt_re_unlock_cqs(qp, flags);
                }
        }
        if (qp_attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) {
@@ -2189,10 +2232,13 @@ static int bnxt_re_build_inv_wqe(struct ib_send_wr *wr,
        wqe->type = BNXT_QPLIB_SWQE_TYPE_LOCAL_INV;
        wqe->local_inv.inv_l_key = wr->ex.invalidate_rkey;
 
+       /* Need unconditional fence for local invalidate
+        * opcode to work as expected.
+        */
+       wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
+
        if (wr->send_flags & IB_SEND_SIGNALED)
                wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
-       if (wr->send_flags & IB_SEND_FENCE)
-               wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
        if (wr->send_flags & IB_SEND_SOLICITED)
                wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT;
 
@@ -2213,8 +2259,12 @@ static int bnxt_re_build_reg_wqe(struct ib_reg_wr *wr,
        wqe->frmr.levels = qplib_frpl->hwq.level + 1;
        wqe->type = BNXT_QPLIB_SWQE_TYPE_REG_MR;
 
-       if (wr->wr.send_flags & IB_SEND_FENCE)
-               wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
+       /* Need unconditional fence for reg_mr
+        * opcode to function as expected.
+        */
+
+       wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_UC_FENCE;
+
        if (wr->wr.send_flags & IB_SEND_SIGNALED)
                wqe->flags |= BNXT_QPLIB_SWQE_FLAGS_SIGNAL_COMP;
 
@@ -3548,7 +3598,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
        int umem_pgs, page_shift, rc;
 
        if (length > BNXT_RE_MAX_MR_SIZE) {
-               dev_err(rdev_to_dev(rdev), "MR Size: %lld > Max supported:%ld\n",
+               dev_err(rdev_to_dev(rdev), "MR Size: %lld > Max supported:%lld\n",
                        length, BNXT_RE_MAX_MR_SIZE);
                return ERR_PTR(-ENOMEM);
        }
index 423ebe012f957fa5f1007e204f5831725ec885aa..e62b7c2c7da6a1953605fbe7d089a3d9b6f9a50a 100644 (file)
@@ -89,6 +89,8 @@ struct bnxt_re_qp {
        /* QP1 */
        u32                     send_psn;
        struct ib_ud_header     qp1_hdr;
+       struct bnxt_re_cq       *scq;
+       struct bnxt_re_cq       *rcq;
 };
 
 struct bnxt_re_cq {
@@ -220,4 +222,7 @@ struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev,
                                           struct ib_udata *udata);
 int bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
 int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
+
+unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
+void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
 #endif /* __BNXT_RE_IB_VERBS_H__ */
index 508d00a5a1066cabd3e6ac7fc4855abbf19235e8..f6e361750466f50acab01a4f1a397260e3a84472 100644 (file)
@@ -656,7 +656,6 @@ static void bnxt_re_dev_remove(struct bnxt_re_dev *rdev)
        mutex_unlock(&bnxt_re_dev_lock);
 
        synchronize_rcu();
-       flush_workqueue(bnxt_re_wq);
 
        ib_dealloc_device(&rdev->ibdev);
        /* rdev is gone */
@@ -731,6 +730,13 @@ static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event,
                                         struct bnxt_re_qp *qp)
 {
        struct ib_event event;
+       unsigned int flags;
+
+       if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
+               flags = bnxt_re_lock_cqs(qp);
+               bnxt_qplib_add_flush_qp(&qp->qplib_qp);
+               bnxt_re_unlock_cqs(qp, flags);
+       }
 
        memset(&event, 0, sizeof(event));
        if (qp->qplib_qp.srq) {
@@ -1417,9 +1423,12 @@ static void bnxt_re_task(struct work_struct *work)
        switch (re_work->event) {
        case NETDEV_REGISTER:
                rc = bnxt_re_ib_reg(rdev);
-               if (rc)
+               if (rc) {
                        dev_err(rdev_to_dev(rdev),
                                "Failed to register with IB: %#x", rc);
+                       bnxt_re_remove_one(rdev);
+                       bnxt_re_dev_unreg(rdev);
+               }
                break;
        case NETDEV_UP:
                bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1,
@@ -1441,7 +1450,7 @@ static void bnxt_re_task(struct work_struct *work)
                break;
        }
        smp_mb__before_atomic();
-       clear_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags);
+       atomic_dec(&rdev->sched_count);
        kfree(re_work);
 }
 
@@ -1503,7 +1512,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier,
                /* netdev notifier will call NETDEV_UNREGISTER again later since
                 * we are still holding the reference to the netdev
                 */
-               if (test_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags))
+               if (atomic_read(&rdev->sched_count) > 0)
                        goto exit;
                bnxt_re_ib_unreg(rdev, false);
                bnxt_re_remove_one(rdev);
@@ -1523,7 +1532,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier,
                        re_work->vlan_dev = (real_dev == netdev ?
                                             NULL : netdev);
                        INIT_WORK(&re_work->work, bnxt_re_task);
-                       set_bit(BNXT_RE_FLAG_TASK_IN_PROG, &rdev->flags);
+                       atomic_inc(&rdev->sched_count);
                        queue_work(bnxt_re_wq, &re_work->work);
                }
        }
@@ -1578,6 +1587,11 @@ static void __exit bnxt_re_mod_exit(void)
        */
        list_for_each_entry_safe_reverse(rdev, next, &to_be_deleted, list) {
                dev_info(rdev_to_dev(rdev), "Unregistering Device");
+               /*
+                * Flush out any scheduled tasks before destroying the
+                * resources
+                */
+               flush_workqueue(bnxt_re_wq);
                bnxt_re_dev_stop(rdev);
                bnxt_re_ib_unreg(rdev, true);
                bnxt_re_remove_one(rdev);
index 1b0e94697fe34ceea2f7218deb394944458fcc78..3a78faba8d91b255bd6526f47ed9c5c3fbd8026b 100644 (file)
@@ -88,75 +88,35 @@ static void __bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp)
        }
 }
 
-void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,
-                                unsigned long *flags)
-       __acquires(&qp->scq->hwq.lock) __acquires(&qp->rcq->hwq.lock)
+static void bnxt_qplib_acquire_cq_flush_locks(struct bnxt_qplib_qp *qp,
+                                      unsigned long *flags)
+       __acquires(&qp->scq->flush_lock) __acquires(&qp->rcq->flush_lock)
 {
-       spin_lock_irqsave(&qp->scq->hwq.lock, *flags);
+       spin_lock_irqsave(&qp->scq->flush_lock, *flags);
        if (qp->scq == qp->rcq)
-               __acquire(&qp->rcq->hwq.lock);
+               __acquire(&qp->rcq->flush_lock);
        else
-               spin_lock(&qp->rcq->hwq.lock);
+               spin_lock(&qp->rcq->flush_lock);
 }
 
-void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp,
-                                unsigned long *flags)
-       __releases(&qp->scq->hwq.lock) __releases(&qp->rcq->hwq.lock)
+static void bnxt_qplib_release_cq_flush_locks(struct bnxt_qplib_qp *qp,
+                                      unsigned long *flags)
+       __releases(&qp->scq->flush_lock) __releases(&qp->rcq->flush_lock)
 {
        if (qp->scq == qp->rcq)
-               __release(&qp->rcq->hwq.lock);
+               __release(&qp->rcq->flush_lock);
        else
-               spin_unlock(&qp->rcq->hwq.lock);
-       spin_unlock_irqrestore(&qp->scq->hwq.lock, *flags);
-}
-
-static struct bnxt_qplib_cq *bnxt_qplib_find_buddy_cq(struct bnxt_qplib_qp *qp,
-                                                     struct bnxt_qplib_cq *cq)
-{
-       struct bnxt_qplib_cq *buddy_cq = NULL;
-
-       if (qp->scq == qp->rcq)
-               buddy_cq = NULL;
-       else if (qp->scq == cq)
-               buddy_cq = qp->rcq;
-       else
-               buddy_cq = qp->scq;
-       return buddy_cq;
-}
-
-static void bnxt_qplib_lock_buddy_cq(struct bnxt_qplib_qp *qp,
-                                    struct bnxt_qplib_cq *cq)
-       __acquires(&buddy_cq->hwq.lock)
-{
-       struct bnxt_qplib_cq *buddy_cq = NULL;
-
-       buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq);
-       if (!buddy_cq)
-               __acquire(&cq->hwq.lock);
-       else
-               spin_lock(&buddy_cq->hwq.lock);
-}
-
-static void bnxt_qplib_unlock_buddy_cq(struct bnxt_qplib_qp *qp,
-                                      struct bnxt_qplib_cq *cq)
-       __releases(&buddy_cq->hwq.lock)
-{
-       struct bnxt_qplib_cq *buddy_cq = NULL;
-
-       buddy_cq = bnxt_qplib_find_buddy_cq(qp, cq);
-       if (!buddy_cq)
-               __release(&cq->hwq.lock);
-       else
-               spin_unlock(&buddy_cq->hwq.lock);
+               spin_unlock(&qp->rcq->flush_lock);
+       spin_unlock_irqrestore(&qp->scq->flush_lock, *flags);
 }
 
 void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp)
 {
        unsigned long flags;
 
-       bnxt_qplib_acquire_cq_locks(qp, &flags);
+       bnxt_qplib_acquire_cq_flush_locks(qp, &flags);
        __bnxt_qplib_add_flush_qp(qp);
-       bnxt_qplib_release_cq_locks(qp, &flags);
+       bnxt_qplib_release_cq_flush_locks(qp, &flags);
 }
 
 static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
@@ -173,11 +133,11 @@ static void __bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
        }
 }
 
-void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
+void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp)
 {
        unsigned long flags;
 
-       bnxt_qplib_acquire_cq_locks(qp, &flags);
+       bnxt_qplib_acquire_cq_flush_locks(qp, &flags);
        __clean_cq(qp->scq, (u64)(unsigned long)qp);
        qp->sq.hwq.prod = 0;
        qp->sq.hwq.cons = 0;
@@ -186,7 +146,7 @@ void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp)
        qp->rq.hwq.cons = 0;
 
        __bnxt_qplib_del_flush_qp(qp);
-       bnxt_qplib_release_cq_locks(qp, &flags);
+       bnxt_qplib_release_cq_flush_locks(qp, &flags);
 }
 
 static void bnxt_qpn_cqn_sched_task(struct work_struct *work)
@@ -283,7 +243,7 @@ static void bnxt_qplib_service_nq(unsigned long data)
        u32 sw_cons, raw_cons;
        u16 type;
        int budget = nq->budget;
-       u64 q_handle;
+       uintptr_t q_handle;
 
        /* Service the NQ until empty */
        raw_cons = hwq->cons;
@@ -566,7 +526,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
 
        /* Configure the request */
        req.dpi = cpu_to_le32(srq->dpi->dpi);
-       req.srq_handle = cpu_to_le64(srq);
+       req.srq_handle = cpu_to_le64((uintptr_t)srq);
 
        req.srq_size = cpu_to_le16((u16)srq->hwq.max_elements);
        pbl = &srq->hwq.pbl[PBL_LVL_0];
@@ -1419,7 +1379,6 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
        struct bnxt_qplib_rcfw *rcfw = res->rcfw;
        struct cmdq_destroy_qp req;
        struct creq_destroy_qp_resp resp;
-       unsigned long flags;
        u16 cmd_flags = 0;
        int rc;
 
@@ -1437,19 +1396,12 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
                return rc;
        }
 
-       /* Must walk the associated CQs to nullified the QP ptr */
-       spin_lock_irqsave(&qp->scq->hwq.lock, flags);
-
-       __clean_cq(qp->scq, (u64)(unsigned long)qp);
-
-       if (qp->rcq && qp->rcq != qp->scq) {
-               spin_lock(&qp->rcq->hwq.lock);
-               __clean_cq(qp->rcq, (u64)(unsigned long)qp);
-               spin_unlock(&qp->rcq->hwq.lock);
-       }
-
-       spin_unlock_irqrestore(&qp->scq->hwq.lock, flags);
+       return 0;
+}
 
+void bnxt_qplib_free_qp_res(struct bnxt_qplib_res *res,
+                           struct bnxt_qplib_qp *qp)
+{
        bnxt_qplib_free_qp_hdr_buf(res, qp);
        bnxt_qplib_free_hwq(res->pdev, &qp->sq.hwq);
        kfree(qp->sq.swq);
@@ -1462,7 +1414,6 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
        if (qp->orrq.max_elements)
                bnxt_qplib_free_hwq(res->pdev, &qp->orrq);
 
-       return 0;
 }
 
 void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp,
@@ -2116,9 +2067,6 @@ void bnxt_qplib_mark_qp_error(void *qp_handle)
        /* Must block new posting of SQ and RQ */
        qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
        bnxt_qplib_cancel_phantom_processing(qp);
-
-       /* Add qp to flush list of the CQ */
-       __bnxt_qplib_add_flush_qp(qp);
 }
 
 /* Note: SQE is valid from sw_sq_cons up to cqe_sq_cons (exclusive)
@@ -2294,9 +2242,9 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
                                sw_sq_cons, cqe->wr_id, cqe->status);
                        cqe++;
                        (*budget)--;
-                       bnxt_qplib_lock_buddy_cq(qp, cq);
                        bnxt_qplib_mark_qp_error(qp);
-                       bnxt_qplib_unlock_buddy_cq(qp, cq);
+                       /* Add qp to flush list of the CQ */
+                       bnxt_qplib_add_flush_qp(qp);
                } else {
                        if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
                                /* Before we complete, do WA 9060 */
@@ -2412,9 +2360,7 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq,
                if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
                        qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
                        /* Add qp to flush list of the CQ */
-                       bnxt_qplib_lock_buddy_cq(qp, cq);
-                       __bnxt_qplib_add_flush_qp(qp);
-                       bnxt_qplib_unlock_buddy_cq(qp, cq);
+                       bnxt_qplib_add_flush_qp(qp);
                }
        }
 
@@ -2498,9 +2444,7 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq,
                if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
                        qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
                        /* Add qp to flush list of the CQ */
-                       bnxt_qplib_lock_buddy_cq(qp, cq);
-                       __bnxt_qplib_add_flush_qp(qp);
-                       bnxt_qplib_unlock_buddy_cq(qp, cq);
+                       bnxt_qplib_add_flush_qp(qp);
                }
        }
 done:
@@ -2510,11 +2454,9 @@ done:
 bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq)
 {
        struct cq_base *hw_cqe, **hw_cqe_ptr;
-       unsigned long flags;
        u32 sw_cons, raw_cons;
        bool rc = true;
 
-       spin_lock_irqsave(&cq->hwq.lock, flags);
        raw_cons = cq->hwq.cons;
        sw_cons = HWQ_CMP(raw_cons, &cq->hwq);
        hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
@@ -2522,7 +2464,6 @@ bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq)
 
         /* Check for Valid bit. If the CQE is valid, return false */
        rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements);
-       spin_unlock_irqrestore(&cq->hwq.lock, flags);
        return rc;
 }
 
@@ -2611,9 +2552,7 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
                if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
                        qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR;
                        /* Add qp to flush list of the CQ */
-                       bnxt_qplib_lock_buddy_cq(qp, cq);
-                       __bnxt_qplib_add_flush_qp(qp);
-                       bnxt_qplib_unlock_buddy_cq(qp, cq);
+                       bnxt_qplib_add_flush_qp(qp);
                }
        }
 
@@ -2728,9 +2667,7 @@ do_rq:
         */
 
        /* Add qp to flush list of the CQ */
-       bnxt_qplib_lock_buddy_cq(qp, cq);
-       __bnxt_qplib_add_flush_qp(qp);
-       bnxt_qplib_unlock_buddy_cq(qp, cq);
+       bnxt_qplib_add_flush_qp(qp);
 done:
        return rc;
 }
@@ -2759,7 +2696,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,
        u32 budget = num_cqes;
        unsigned long flags;
 
-       spin_lock_irqsave(&cq->hwq.lock, flags);
+       spin_lock_irqsave(&cq->flush_lock, flags);
        list_for_each_entry(qp, &cq->sqf_head, sq_flush) {
                dev_dbg(&cq->hwq.pdev->dev,
                        "QPLIB: FP: Flushing SQ QP= %p",
@@ -2773,7 +2710,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,
                        qp);
                __flush_rq(&qp->rq, qp, &cqe, &budget);
        }
-       spin_unlock_irqrestore(&cq->hwq.lock, flags);
+       spin_unlock_irqrestore(&cq->flush_lock, flags);
 
        return num_cqes - budget;
 }
@@ -2782,11 +2719,9 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
                       int num_cqes, struct bnxt_qplib_qp **lib_qp)
 {
        struct cq_base *hw_cqe, **hw_cqe_ptr;
-       unsigned long flags;
        u32 sw_cons, raw_cons;
        int budget, rc = 0;
 
-       spin_lock_irqsave(&cq->hwq.lock, flags);
        raw_cons = cq->hwq.cons;
        budget = num_cqes;
 
@@ -2862,20 +2797,15 @@ int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
                bnxt_qplib_arm_cq(cq, DBR_DBR_TYPE_CQ);
        }
 exit:
-       spin_unlock_irqrestore(&cq->hwq.lock, flags);
        return num_cqes - budget;
 }
 
 void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&cq->hwq.lock, flags);
        if (arm_type)
                bnxt_qplib_arm_cq(cq, arm_type);
        /* Using cq->arm_state variable to track whether to issue cq handler */
        atomic_set(&cq->arm_state, 1);
-       spin_unlock_irqrestore(&cq->hwq.lock, flags);
 }
 
 void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp)
index 211b27a8f9e275a88464f4de3d14292764038739..ade9f13c0fd1bb2e8cc04a8a1a85c9da1221db41 100644 (file)
@@ -389,6 +389,18 @@ struct bnxt_qplib_cq {
        struct list_head                sqf_head, rqf_head;
        atomic_t                        arm_state;
        spinlock_t                      compl_lock; /* synch CQ handlers */
+/* Locking Notes:
+ * QP can move to error state from modify_qp, async error event or error
+ * CQE as part of poll_cq. When QP is moved to error state, it gets added
+ * to two flush lists, one each for SQ and RQ.
+ * Each flush list is protected by qplib_cq->flush_lock. Both scq and rcq
+ * flush_locks should be acquired when QP is moved to error. The control path
+ * operations(modify_qp and async error events) are synchronized with poll_cq
+ * using upper level CQ locks (bnxt_re_cq->cq_lock) of both SCQ and RCQ.
+ * The qplib_cq->flush_lock is required to synchronize two instances of poll_cq
+ * of the same QP while manipulating the flush list.
+ */
+       spinlock_t                      flush_lock; /* QP flush management */
 };
 
 #define BNXT_QPLIB_MAX_IRRQE_ENTRY_SIZE        sizeof(struct xrrq_irrq)
@@ -478,6 +490,9 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp);
 int bnxt_qplib_modify_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp);
 int bnxt_qplib_query_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp);
 int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp);
+void bnxt_qplib_clean_qp(struct bnxt_qplib_qp *qp);
+void bnxt_qplib_free_qp_res(struct bnxt_qplib_res *res,
+                           struct bnxt_qplib_qp *qp);
 void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp,
                                struct bnxt_qplib_sge *sge);
 void *bnxt_qplib_get_qp1_rq_buf(struct bnxt_qplib_qp *qp,
@@ -500,7 +515,6 @@ void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type);
 void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq);
 int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq);
 void bnxt_qplib_add_flush_qp(struct bnxt_qplib_qp *qp);
-void bnxt_qplib_del_flush_qp(struct bnxt_qplib_qp *qp);
 void bnxt_qplib_acquire_cq_locks(struct bnxt_qplib_qp *qp,
                                 unsigned long *flags);
 void bnxt_qplib_release_cq_locks(struct bnxt_qplib_qp *qp,
index 8329ec6a794696ddbc4892bf255ea22150cd18e7..80027a494730df22944bfbdc678ca36deadcec51 100644 (file)
@@ -305,9 +305,8 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw,
                        err_event->res_err_state_reason);
                if (!qp)
                        break;
-               bnxt_qplib_acquire_cq_locks(qp, &flags);
                bnxt_qplib_mark_qp_error(qp);
-               bnxt_qplib_release_cq_locks(qp, &flags);
+               rcfw->aeq_handler(rcfw, qp_event, qp);
                break;
        default:
                /* Command Response */
@@ -460,7 +459,11 @@ int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
        int rc;
 
        RCFW_CMD_PREP(req, INITIALIZE_FW, cmd_flags);
-
+       /* Supply (log-base-2-of-host-page-size - base-page-shift)
+        * to bono to adjust the doorbell page sizes.
+        */
+       req.log2_dbr_pg_size = cpu_to_le16(PAGE_SHIFT -
+                                          RCFW_DBR_BASE_PAGE_SHIFT);
        /*
         * VFs need not setup the HW context area, PF
         * shall setup this area for VF. Skipping the
index 6bee6e3636ea400d5bb1be21a1b064af77475f37..c7cce2e4185e687d2572f3cedc875566a5b3e4ff 100644 (file)
@@ -49,6 +49,7 @@
 #define RCFW_COMM_SIZE                 0x104
 
 #define RCFW_DBR_PCI_BAR_REGION                2
+#define RCFW_DBR_BASE_PAGE_SHIFT       12
 
 #define RCFW_CMD_PREP(req, CMD, cmd_flags)                             \
        do {                                                            \
index c015c1861351ae91d1455b97ee493a97e5ee5645..ee98e5efef84652f4accdc05231dccbf935f029d 100644 (file)
@@ -52,18 +52,6 @@ const struct bnxt_qplib_gid bnxt_qplib_gid_zero = {{ 0, 0, 0, 0, 0, 0, 0, 0,
 
 /* Device */
 
-static bool bnxt_qplib_is_atomic_cap(struct bnxt_qplib_rcfw *rcfw)
-{
-       int rc;
-       u16 pcie_ctl2;
-
-       rc = pcie_capability_read_word(rcfw->pdev, PCI_EXP_DEVCTL2,
-                                      &pcie_ctl2);
-       if (rc)
-               return false;
-       return !!(pcie_ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ);
-}
-
 static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw *rcfw,
                                     char *fw_ver)
 {
@@ -151,7 +139,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
        attr->max_pkey = le32_to_cpu(sb->max_pkeys);
 
        attr->max_inline_data = le32_to_cpu(sb->max_inline_data);
-       attr->l2_db_size = (sb->l2_db_space_size + 1) * PAGE_SIZE;
+       attr->l2_db_size = (sb->l2_db_space_size + 1) *
+                           (0x01 << RCFW_DBR_BASE_PAGE_SHIFT);
        attr->max_sgid = le32_to_cpu(sb->max_gid);
 
        bnxt_qplib_query_version(rcfw, attr->fw_ver);
@@ -165,7 +154,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
                attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc);
        }
 
-       attr->is_atomic = bnxt_qplib_is_atomic_cap(rcfw);
+       attr->is_atomic = 0;
 bail:
        bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
        return rc;
index 2d7ea096a247478392acf58b4a234112ea35f54a..3e5a4f760d0eb6332032f824bf3a9367d1bbd07a 100644 (file)
@@ -1761,7 +1761,30 @@ struct cmdq_initialize_fw {
        #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_2M               (0x3UL << 4)
        #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_8M               (0x4UL << 4)
        #define CMDQ_INITIALIZE_FW_TIM_PG_SIZE_PG_1G               (0x5UL << 4)
-       __le16 reserved16;
+       /* This value is (log-base-2-of-DBR-page-size - 12).
+        * 0 for 4KB. HW supported values are enumerated below.
+        */
+       __le16  log2_dbr_pg_size;
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_MASK        0xfUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_SFT         0
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_4K       0x0UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_8K       0x1UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_16K      0x2UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_32K      0x3UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_64K      0x4UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128K     0x5UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_256K     0x6UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_512K     0x7UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_1M       0x8UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_2M       0x9UL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_4M       0xaUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_8M       0xbUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_16M      0xcUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_32M      0xdUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_64M      0xeUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128M     0xfUL
+       #define CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_LAST                \
+                       CMDQ_INITIALIZE_FW_LOG2_DBR_PG_SIZE_PG_128M
        __le64 qpc_page_dir;
        __le64 mrw_page_dir;
        __le64 srq_page_dir;
index 9a566ee3ceffeff4b76b90800f732727c1902ebd..82adc0d1d30ef39dfb716758164269a4a0702d52 100644 (file)
@@ -601,6 +601,7 @@ static void use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct
        wc->dlid_path_bits = 0;
 
        if (is_eth) {
+               wc->slid = 0;
                wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid);
                memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4);
                memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2);
@@ -851,7 +852,6 @@ repoll:
                        }
                }
 
-               wc->slid           = be16_to_cpu(cqe->rlid);
                g_mlpath_rqpn      = be32_to_cpu(cqe->g_mlpath_rqpn);
                wc->src_qp         = g_mlpath_rqpn & 0xffffff;
                wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;
@@ -860,6 +860,7 @@ repoll:
                wc->wc_flags      |= mlx4_ib_ipoib_csum_ok(cqe->status,
                                        cqe->checksum) ? IB_WC_IP_CSUM_OK : 0;
                if (is_eth) {
+                       wc->slid = 0;
                        wc->sl  = be16_to_cpu(cqe->sl_vid) >> 13;
                        if (be32_to_cpu(cqe->vlan_my_qpn) &
                                        MLX4_CQE_CVLAN_PRESENT_MASK) {
@@ -871,6 +872,7 @@ repoll:
                        memcpy(wc->smac, cqe->smac, ETH_ALEN);
                        wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC);
                } else {
+                       wc->slid = be16_to_cpu(cqe->rlid);
                        wc->sl  = be16_to_cpu(cqe->sl_vid) >> 12;
                        wc->vlan_id = 0xffff;
                }
index 8d2ee9322f2e04448cfbdbf72112432f8554c963..5a0e4fc4785aa0164fa9d25c7a11a8bbda8f1da5 100644 (file)
@@ -219,8 +219,6 @@ static int mlx4_ib_update_gids_v1_v2(struct gid_entry *gids,
                        gid_tbl[i].version = 2;
                        if (!ipv6_addr_v4mapped((struct in6_addr *)&gids[i].gid))
                                gid_tbl[i].type = 1;
-                       else
-                               memset(&gid_tbl[i].gid, 0, 12);
                }
        }
 
@@ -366,8 +364,13 @@ static int mlx4_ib_del_gid(struct ib_device *device,
                if (!gids) {
                        ret = -ENOMEM;
                } else {
-                       for (i = 0; i < MLX4_MAX_PORT_GIDS; i++)
-                               memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid));
+                       for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) {
+                               memcpy(&gids[i].gid,
+                                      &port_gid_table->gids[i].gid,
+                                      sizeof(union ib_gid));
+                               gids[i].gid_type =
+                                   port_gid_table->gids[i].gid_type;
+                       }
                }
        }
        spin_unlock_bh(&iboe->lock);
index 5b974fb97611bc57b6dd2110e1df487e9a001d42..15457c9569a778aae2a6d057f52e0672b651a115 100644 (file)
@@ -226,7 +226,6 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
                wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey);
                break;
        }
-       wc->slid           = be16_to_cpu(cqe->slid);
        wc->src_qp         = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;
        wc->dlid_path_bits = cqe->ml_path;
        g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;
@@ -241,10 +240,12 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
        }
 
        if (ll != IB_LINK_LAYER_ETHERNET) {
+               wc->slid = be16_to_cpu(cqe->slid);
                wc->sl = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
                return;
        }
 
+       wc->slid = 0;
        vlan_present = cqe->l4_l3_hdr_type & 0x1;
        roce_packet_type   = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0x3;
        if (vlan_present) {
@@ -1177,7 +1178,12 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
        if (ucmd.reserved0 || ucmd.reserved1)
                return -EINVAL;
 
-       umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size,
+       /* check multiplication overflow */
+       if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1)
+               return -EINVAL;
+
+       umem = ib_umem_get(context, ucmd.buf_addr,
+                          (size_t)ucmd.cqe_size * entries,
                           IB_ACCESS_LOCAL_WRITE, 1);
        if (IS_ERR(umem)) {
                err = PTR_ERR(umem);
index 4236c80868200822d30cfc3d8adea4c97ce9afc2..da091de4e69d81eda73de4e3ce758830aaa1413c 100644 (file)
@@ -245,12 +245,16 @@ struct mlx5_core_dev *mlx5_ib_get_native_port_mdev(struct mlx5_ib_dev *ibdev,
        struct mlx5_ib_multiport_info *mpi;
        struct mlx5_ib_port *port;
 
+       if (!mlx5_core_mp_enabled(ibdev->mdev) ||
+           ll != IB_LINK_LAYER_ETHERNET) {
+               if (native_port_num)
+                       *native_port_num = ib_port_num;
+               return ibdev->mdev;
+       }
+
        if (native_port_num)
                *native_port_num = 1;
 
-       if (!mlx5_core_mp_enabled(ibdev->mdev) || ll != IB_LINK_LAYER_ETHERNET)
-               return ibdev->mdev;
-
        port = &ibdev->port[ib_port_num - 1];
        if (!port)
                return NULL;
@@ -3263,7 +3267,7 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
        struct mlx5_ib_dev *ibdev;
        struct ib_event ibev;
        bool fatal = false;
-       u8 port = 0;
+       u8 port = (u8)work->param;
 
        if (mlx5_core_is_mp_slave(work->dev)) {
                ibdev = mlx5_ib_get_ibdev_from_mpi(work->context);
@@ -3283,8 +3287,6 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
        case MLX5_DEV_EVENT_PORT_UP:
        case MLX5_DEV_EVENT_PORT_DOWN:
        case MLX5_DEV_EVENT_PORT_INITIALIZED:
-               port = (u8)work->param;
-
                /* In RoCE, port up/down events are handled in
                 * mlx5_netdev_event().
                 */
@@ -3298,24 +3300,19 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
 
        case MLX5_DEV_EVENT_LID_CHANGE:
                ibev.event = IB_EVENT_LID_CHANGE;
-               port = (u8)work->param;
                break;
 
        case MLX5_DEV_EVENT_PKEY_CHANGE:
                ibev.event = IB_EVENT_PKEY_CHANGE;
-               port = (u8)work->param;
-
                schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);
                break;
 
        case MLX5_DEV_EVENT_GUID_CHANGE:
                ibev.event = IB_EVENT_GID_CHANGE;
-               port = (u8)work->param;
                break;
 
        case MLX5_DEV_EVENT_CLIENT_REREG:
                ibev.event = IB_EVENT_CLIENT_REREGISTER;
-               port = (u8)work->param;
                break;
        case MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT:
                schedule_work(&ibdev->delay_drop.delay_drop_work);
@@ -3327,7 +3324,7 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
        ibev.device           = &ibdev->ib_dev;
        ibev.element.port_num = port;
 
-       if (port < 1 || port > ibdev->num_ports) {
+       if (!rdma_is_port_valid(&ibdev->ib_dev, port)) {
                mlx5_ib_warn(ibdev, "warning: event on port %d\n", port);
                goto out;
        }
@@ -4863,19 +4860,19 @@ static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)
        return ib_register_device(&dev->ib_dev, NULL);
 }
 
-static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
+static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
 {
-       ib_unregister_device(&dev->ib_dev);
+       destroy_umrc_res(dev);
 }
 
-static int mlx5_ib_stage_umr_res_init(struct mlx5_ib_dev *dev)
+static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
 {
-       return create_umr_res(dev);
+       ib_unregister_device(&dev->ib_dev);
 }
 
-static void mlx5_ib_stage_umr_res_cleanup(struct mlx5_ib_dev *dev)
+static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)
 {
-       destroy_umrc_res(dev);
+       return create_umr_res(dev);
 }
 
 static int mlx5_ib_stage_delay_drop_init(struct mlx5_ib_dev *dev)
@@ -4985,12 +4982,15 @@ static const struct mlx5_ib_profile pf_profile = {
        STAGE_CREATE(MLX5_IB_STAGE_BFREG,
                     mlx5_ib_stage_bfrag_init,
                     mlx5_ib_stage_bfrag_cleanup),
+       STAGE_CREATE(MLX5_IB_STAGE_PRE_IB_REG_UMR,
+                    NULL,
+                    mlx5_ib_stage_pre_ib_reg_umr_cleanup),
        STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
                     mlx5_ib_stage_ib_reg_init,
                     mlx5_ib_stage_ib_reg_cleanup),
-       STAGE_CREATE(MLX5_IB_STAGE_UMR_RESOURCES,
-                    mlx5_ib_stage_umr_res_init,
-                    mlx5_ib_stage_umr_res_cleanup),
+       STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
+                    mlx5_ib_stage_post_ib_reg_umr_init,
+                    NULL),
        STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
                     mlx5_ib_stage_delay_drop_init,
                     mlx5_ib_stage_delay_drop_cleanup),
index 1393851299738d6173daff863e444e9fc5346af0..a5272499b60054d3a37a84cf277a0c067ca1c6e4 100644 (file)
@@ -739,8 +739,9 @@ enum mlx5_ib_stages {
        MLX5_IB_STAGE_CONG_DEBUGFS,
        MLX5_IB_STAGE_UAR,
        MLX5_IB_STAGE_BFREG,
+       MLX5_IB_STAGE_PRE_IB_REG_UMR,
        MLX5_IB_STAGE_IB_REG,
-       MLX5_IB_STAGE_UMR_RESOURCES,
+       MLX5_IB_STAGE_POST_IB_REG_UMR,
        MLX5_IB_STAGE_DELAY_DROP,
        MLX5_IB_STAGE_CLASS_ATTR,
        MLX5_IB_STAGE_MAX,
index 556e015678de26809f45d74ac6357ecf9dcbf501..c51c602f06d6ea6d9c4737abbf4a6ab6f09fa6eb 100644 (file)
@@ -838,7 +838,8 @@ static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
        *umem = ib_umem_get(pd->uobject->context, start, length,
                            access_flags, 0);
        err = PTR_ERR_OR_ZERO(*umem);
-       if (err < 0) {
+       if (err) {
+               *umem = NULL;
                mlx5_ib_err(dev, "umem get failed (%d)\n", err);
                return err;
        }
@@ -1415,6 +1416,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
                if (err) {
                        mlx5_ib_warn(dev, "Failed to rereg UMR\n");
                        ib_umem_release(mr->umem);
+                       mr->umem = NULL;
                        clean_mr(dev, mr);
                        return err;
                }
@@ -1498,14 +1500,11 @@ static int clean_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
                u32 key = mr->mmkey.key;
 
                err = destroy_mkey(dev, mr);
-               kfree(mr);
                if (err) {
                        mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
                                     key, err);
                        return err;
                }
-       } else {
-               mlx5_mr_cache_free(dev, mr);
        }
 
        return 0;
@@ -1548,6 +1547,11 @@ static int dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
                atomic_sub(npages, &dev->mdev->priv.reg_pages);
        }
 
+       if (!mr->allocated_from_cache)
+               kfree(mr);
+       else
+               mlx5_mr_cache_free(dev, mr);
+
        return 0;
 }
 
@@ -1816,7 +1820,6 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr,
 
        mr->ibmr.iova = sg_dma_address(sg) + sg_offset;
        mr->ibmr.length = 0;
-       mr->ndescs = sg_nents;
 
        for_each_sg(sgl, sg, sg_nents, i) {
                if (unlikely(i >= mr->max_descs))
@@ -1828,6 +1831,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr,
 
                sg_offset = 0;
        }
+       mr->ndescs = i;
 
        if (sg_offset_p)
                *sg_offset_p = sg_offset;
index 39d24bf694a864788f2d3dc806c3019bb4b12b8b..a2e1aa86e133b46d2e43868ba5abe419594472f9 100644 (file)
@@ -1161,7 +1161,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
        ib_umem_release(sq->ubuffer.umem);
 }
 
-static int get_rq_pas_size(void *qpc)
+static size_t get_rq_pas_size(void *qpc)
 {
        u32 log_page_size = MLX5_GET(qpc, qpc, log_page_size) + 12;
        u32 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride);
@@ -1177,7 +1177,8 @@ static int get_rq_pas_size(void *qpc)
 }
 
 static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
-                                  struct mlx5_ib_rq *rq, void *qpin)
+                                  struct mlx5_ib_rq *rq, void *qpin,
+                                  size_t qpinlen)
 {
        struct mlx5_ib_qp *mqp = rq->base.container_mibqp;
        __be64 *pas;
@@ -1186,9 +1187,12 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
        void *rqc;
        void *wq;
        void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);
-       int inlen;
+       size_t rq_pas_size = get_rq_pas_size(qpc);
+       size_t inlen;
        int err;
-       u32 rq_pas_size = get_rq_pas_size(qpc);
+
+       if (qpinlen < rq_pas_size + MLX5_BYTE_OFF(create_qp_in, pas))
+               return -EINVAL;
 
        inlen = MLX5_ST_SZ_BYTES(create_rq_in) + rq_pas_size;
        in = kvzalloc(inlen, GFP_KERNEL);
@@ -1277,7 +1281,7 @@ static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
 }
 
 static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
-                               u32 *in,
+                               u32 *in, size_t inlen,
                                struct ib_pd *pd)
 {
        struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
@@ -1309,7 +1313,7 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
                        rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING;
                if (qp->flags & MLX5_IB_QP_PCI_WRITE_END_PADDING)
                        rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING;
-               err = create_raw_packet_qp_rq(dev, rq, in);
+               err = create_raw_packet_qp_rq(dev, rq, in, inlen);
                if (err)
                        goto err_destroy_sq;
 
@@ -1584,6 +1588,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        u32 uidx = MLX5_IB_DEFAULT_UIDX;
        struct mlx5_ib_create_qp ucmd;
        struct mlx5_ib_qp_base *base;
+       int mlx5_st;
        void *qpc;
        u32 *in;
        int err;
@@ -1592,6 +1597,10 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        spin_lock_init(&qp->sq.lock);
        spin_lock_init(&qp->rq.lock);
 
+       mlx5_st = to_mlx5_st(init_attr->qp_type);
+       if (mlx5_st < 0)
+               return -EINVAL;
+
        if (init_attr->rwq_ind_tbl) {
                if (!udata)
                        return -ENOSYS;
@@ -1753,7 +1762,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
 
        qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
 
-       MLX5_SET(qpc, qpc, st, to_mlx5_st(init_attr->qp_type));
+       MLX5_SET(qpc, qpc, st, mlx5_st);
        MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
 
        if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR)
@@ -1867,11 +1876,16 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                }
        }
 
+       if (inlen < 0) {
+               err = -EINVAL;
+               goto err;
+       }
+
        if (init_attr->qp_type == IB_QPT_RAW_PACKET ||
            qp->flags & MLX5_IB_QP_UNDERLAY) {
                qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd.sq_buf_addr;
                raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
-               err = create_raw_packet_qp(dev, qp, in, pd);
+               err = create_raw_packet_qp(dev, qp, in, inlen, pd);
        } else {
                err = mlx5_core_create_qp(dev->mdev, &base->mqp, in, inlen);
        }
@@ -3095,8 +3109,10 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
                goto out;
 
        if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||
-           !optab[mlx5_cur][mlx5_new])
+           !optab[mlx5_cur][mlx5_new]) {
+               err = -EINVAL;
                goto out;
+       }
 
        op = optab[mlx5_cur][mlx5_new];
        optpar = ib_mask_to_mlx5_opt(attr_mask);
index 6d5fadad909081d17b80c967cbe69b8c381e6bd8..3c7522d025f2b559f638fd2bde05200702488dde 100644 (file)
@@ -241,8 +241,8 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
 {
        struct mlx5_ib_dev *dev = to_mdev(pd->device);
        struct mlx5_ib_srq *srq;
-       int desc_size;
-       int buf_size;
+       size_t desc_size;
+       size_t buf_size;
        int err;
        struct mlx5_srq_attr in = {0};
        __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
@@ -266,15 +266,18 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
 
        desc_size = sizeof(struct mlx5_wqe_srq_next_seg) +
                    srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg);
+       if (desc_size == 0 || srq->msrq.max_gs > desc_size)
+               return ERR_PTR(-EINVAL);
        desc_size = roundup_pow_of_two(desc_size);
-       desc_size = max_t(int, 32, desc_size);
+       desc_size = max_t(size_t, 32, desc_size);
+       if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg))
+               return ERR_PTR(-EINVAL);
        srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) /
                sizeof(struct mlx5_wqe_data_seg);
        srq->msrq.wqe_shift = ilog2(desc_size);
        buf_size = srq->msrq.max * desc_size;
-       mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n",
-                   desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs,
-                   srq->msrq.max_avail_gather);
+       if (buf_size < desc_size)
+               return ERR_PTR(-EINVAL);
        in.type = init_attr->srq_type;
 
        if (pd->uobject)
index 478b7317b80ab49fa281cb80621efb29ccde5e9a..26dc374787f74843fd0326ca87b37a312e422c3d 100644 (file)
@@ -458,8 +458,7 @@ qedr_addr6_resolve(struct qedr_dev *dev,
                }
                return -EINVAL;
        }
-       neigh = dst_neigh_lookup(dst, &dst_in);
-
+       neigh = dst_neigh_lookup(dst, &fl6.daddr);
        if (neigh) {
                rcu_read_lock();
                if (neigh->nud_state & NUD_VALID) {
@@ -494,10 +493,14 @@ int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 
        qp = idr_find(&dev->qpidr, conn_param->qpn);
 
-       laddr = (struct sockaddr_in *)&cm_id->local_addr;
-       raddr = (struct sockaddr_in *)&cm_id->remote_addr;
-       laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr;
-       raddr6 = (struct sockaddr_in6 *)&cm_id->remote_addr;
+       laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
+       raddr = (struct sockaddr_in *)&cm_id->m_remote_addr;
+       laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
+       raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr;
+
+       DP_DEBUG(dev, QEDR_MSG_IWARP, "MAPPED %d %d\n",
+                ntohs(((struct sockaddr_in *)&cm_id->remote_addr)->sin_port),
+                ntohs(raddr->sin_port));
 
        DP_DEBUG(dev, QEDR_MSG_IWARP,
                 "Connect source address: %pISpc, remote address: %pISpc\n",
@@ -599,8 +602,8 @@ int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog)
        int rc;
        int i;
 
-       laddr = (struct sockaddr_in *)&cm_id->local_addr;
-       laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr;
+       laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
+       laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
 
        DP_DEBUG(dev, QEDR_MSG_IWARP,
                 "Create Listener address: %pISpc\n", &cm_id->local_addr);
index 53f00dbf313f757941d32451ae23e62305f9cf53..875b17272d65289d2cfa826f3635683831e19886 100644 (file)
@@ -3034,6 +3034,11 @@ static int __qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
        switch (wr->opcode) {
        case IB_WR_SEND_WITH_IMM:
+               if (unlikely(rdma_protocol_iwarp(&dev->ibdev, 1))) {
+                       rc = -EINVAL;
+                       *bad_wr = wr;
+                       break;
+               }
                wqe->req_type = RDMA_SQ_REQ_TYPE_SEND_WITH_IMM;
                swqe = (struct rdma_sq_send_wqe_1st *)wqe;
                swqe->wqe_size = 2;
@@ -3075,6 +3080,11 @@ static int __qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                break;
 
        case IB_WR_RDMA_WRITE_WITH_IMM:
+               if (unlikely(rdma_protocol_iwarp(&dev->ibdev, 1))) {
+                       rc = -EINVAL;
+                       *bad_wr = wr;
+                       break;
+               }
                wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR_WITH_IMM;
                rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe;
 
@@ -3724,7 +3734,7 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
 {
        struct qedr_dev *dev = get_qedr_dev(ibcq->device);
        struct qedr_cq *cq = get_qedr_cq(ibcq);
-       union rdma_cqe *cqe = cq->latest_cqe;
+       union rdma_cqe *cqe;
        u32 old_cons, new_cons;
        unsigned long flags;
        int update = 0;
@@ -3741,6 +3751,7 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
                return qedr_gsi_poll_cq(ibcq, num_entries, wc);
 
        spin_lock_irqsave(&cq->cq_lock, flags);
+       cqe = cq->latest_cqe;
        old_cons = qed_chain_get_cons_idx_u32(&cq->pbl);
        while (num_entries && is_valid_cqe(cq, cqe)) {
                struct qedr_qp *qp;
index faa9478c14a6bda55d0fb518f03598d86454a259..f95b97646c25268c38f93807b37e4af18cee218b 100644 (file)
@@ -114,6 +114,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev,
        union pvrdma_cmd_resp rsp;
        struct pvrdma_cmd_create_cq *cmd = &req.create_cq;
        struct pvrdma_cmd_create_cq_resp *resp = &rsp.create_cq_resp;
+       struct pvrdma_create_cq_resp cq_resp = {0};
        struct pvrdma_create_cq ucmd;
 
        BUILD_BUG_ON(sizeof(struct pvrdma_cqe) != 64);
@@ -197,6 +198,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev,
 
        cq->ibcq.cqe = resp->cqe;
        cq->cq_handle = resp->cq_handle;
+       cq_resp.cqn = resp->cq_handle;
        spin_lock_irqsave(&dev->cq_tbl_lock, flags);
        dev->cq_tbl[cq->cq_handle % dev->dsr->caps.max_cq] = cq;
        spin_unlock_irqrestore(&dev->cq_tbl_lock, flags);
@@ -205,7 +207,7 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev,
                cq->uar = &(to_vucontext(context)->uar);
 
                /* Copy udata back. */
-               if (ib_copy_to_udata(udata, &cq->cq_handle, sizeof(__u32))) {
+               if (ib_copy_to_udata(udata, &cq_resp, sizeof(cq_resp))) {
                        dev_warn(&dev->pdev->dev,
                                 "failed to copy back udata\n");
                        pvrdma_destroy_cq(&cq->ibcq);
index 5acebb1ef631ae0070d28917530345689a2654de..af235967a9c2e9ac366c943c10f11b8c2003e7c5 100644 (file)
@@ -113,6 +113,7 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
        union pvrdma_cmd_resp rsp;
        struct pvrdma_cmd_create_srq *cmd = &req.create_srq;
        struct pvrdma_cmd_create_srq_resp *resp = &rsp.create_srq_resp;
+       struct pvrdma_create_srq_resp srq_resp = {0};
        struct pvrdma_create_srq ucmd;
        unsigned long flags;
        int ret;
@@ -204,12 +205,13 @@ struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
        }
 
        srq->srq_handle = resp->srqn;
+       srq_resp.srqn = resp->srqn;
        spin_lock_irqsave(&dev->srq_tbl_lock, flags);
        dev->srq_tbl[srq->srq_handle % dev->dsr->caps.max_srq] = srq;
        spin_unlock_irqrestore(&dev->srq_tbl_lock, flags);
 
        /* Copy udata back. */
-       if (ib_copy_to_udata(udata, &srq->srq_handle, sizeof(__u32))) {
+       if (ib_copy_to_udata(udata, &srq_resp, sizeof(srq_resp))) {
                dev_warn(&dev->pdev->dev, "failed to copy back udata\n");
                pvrdma_destroy_srq(&srq->ibsrq);
                return ERR_PTR(-EINVAL);
index 16b96616ef7e61b074d339e6ec8dd5fbab4f2c5e..a51463cd2f374729cf57a448a26d4be06fc0c342 100644 (file)
@@ -447,6 +447,7 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
        union pvrdma_cmd_resp rsp;
        struct pvrdma_cmd_create_pd *cmd = &req.create_pd;
        struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp;
+       struct pvrdma_alloc_pd_resp pd_resp = {0};
        int ret;
        void *ptr;
 
@@ -475,9 +476,10 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
        pd->privileged = !context;
        pd->pd_handle = resp->pd_handle;
        pd->pdn = resp->pd_handle;
+       pd_resp.pdn = resp->pd_handle;
 
        if (context) {
-               if (ib_copy_to_udata(udata, &pd->pdn, sizeof(__u32))) {
+               if (ib_copy_to_udata(udata, &pd_resp, sizeof(pd_resp))) {
                        dev_warn(&dev->pdev->dev,
                                 "failed to copy back protection domain\n");
                        pvrdma_dealloc_pd(&pd->ibpd);
index 1b2e5362a3ffeaeb3813707ed37d2ddb386c2f0d..cc429b567d0a4d1a10ee97a61f71b9f59c0d4561 100644 (file)
@@ -489,11 +489,13 @@ static int rvt_check_refs(struct rvt_mregion *mr, const char *t)
        unsigned long timeout;
        struct rvt_dev_info *rdi = ib_to_rvt(mr->pd->device);
 
-       if (percpu_ref_is_zero(&mr->refcount))
-               return 0;
-       /* avoid dma mr */
-       if (mr->lkey)
+       if (mr->lkey) {
+               /* avoid dma mr */
                rvt_dereg_clean_qps(mr);
+               /* @mr was indexed on rcu protected @lkey_table */
+               synchronize_rcu();
+       }
+
        timeout = wait_for_completion_timeout(&mr->comp, 5 * HZ);
        if (!timeout) {
                rvt_pr_err(rdi,
index 11f74cbe6660bbe0aa33fc7db2bac09bb2f7ad9e..ea302b0546016886e691fdaa38d85051ba36f23f 100644 (file)
@@ -281,8 +281,6 @@ void ipoib_delete_debug_files(struct net_device *dev)
 {
        struct ipoib_dev_priv *priv = ipoib_priv(dev);
 
-       WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n");
-       WARN_ONCE(!priv->path_dentry, "null path debug file\n");
        debugfs_remove(priv->mcg_dentry);
        debugfs_remove(priv->path_dentry);
        priv->mcg_dentry = priv->path_dentry = NULL;
index 1f316d66e6f71eaa232b295c9ba161be4c6a5a9d..41614c185918259d54546a50125601270f3852d7 100644 (file)
@@ -218,8 +218,10 @@ static void matrix_keypad_stop(struct input_dev *dev)
 {
        struct matrix_keypad *keypad = input_get_drvdata(dev);
 
+       spin_lock_irq(&keypad->lock);
        keypad->stopped = true;
-       mb();
+       spin_unlock_irq(&keypad->lock);
+
        flush_work(&keypad->work.work);
        /*
         * matrix_keypad_scan() will leave IRQs enabled;
index 3d2e23a0ae39dd6b9475db31ce2b30cc930ddc93..a246fc686bb728dbe48b2fc84b90a1734af60c66 100644 (file)
@@ -173,7 +173,6 @@ static const char * const smbus_pnp_ids[] = {
        "LEN0046", /* X250 */
        "LEN004a", /* W541 */
        "LEN200f", /* T450s */
-       "LEN2018", /* T460p */
        NULL
 };
 
index db4f6bb502e3fecd59607795e98ec68498641359..a5ab774da4cccceb584f94f41c50a68d990b72c7 100644 (file)
@@ -1,11 +1,8 @@
-/*
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+// Melfas MMS114/MMS152 touchscreen device driver
+//
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+// Author: Joonyoung Shim <jy0922.shim@samsung.com>
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -624,4 +621,4 @@ module_i2c_driver(mms114_driver);
 /* Module information */
 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
 MODULE_DESCRIPTION("MELFAS mms114 Touchscreen driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
index 35a408d0ae4fae9e4ea33e184dfc60a6d0ddc0b4..99bc9bd64b9ecc1de640cba1432a750db6e9491f 100644 (file)
@@ -205,7 +205,7 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d
                         * for example, an "address" value of 0x12345f000 will
                         * flush from 0x123440000 to 0x12347ffff (256KiB). */
                        unsigned long last = address + ((unsigned long)(pages - 1) << VTD_PAGE_SHIFT);
-                       unsigned long mask = __rounddown_pow_of_two(address ^ last);;
+                       unsigned long mask = __rounddown_pow_of_two(address ^ last);
 
                        desc.high = QI_DEV_EIOTLB_ADDR((address & ~mask) | (mask - 1)) | QI_DEV_EIOTLB_SIZE;
                } else {
index 55cfb986225be79386b3d6487b953ff63ca4ab59..faf734ff4cf3bc69c2a27d8b0ef1555530584fd1 100644 (file)
@@ -339,9 +339,6 @@ int __init bcm7038_l1_of_init(struct device_node *dn,
                goto out_unmap;
        }
 
-       pr_info("registered BCM7038 L1 intc (mem: 0x%p, IRQs: %d)\n",
-               intc->cpus[0]->map_base, IRQS_PER_WORD * intc->n_words);
-
        return 0;
 
 out_unmap:
index 983640eba418ec4e2658e10ddc93bf1f1815fc07..8968e5e93fcb8e3bf478329b765c149a47153cd0 100644 (file)
@@ -318,9 +318,6 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
                }
        }
 
-       pr_info("registered %s intc (mem: 0x%p, parent IRQ(s): %d)\n",
-                       intc_name, data->map_base[0], data->num_parent_irqs);
-
        return 0;
 
 out_free_domain:
index 691d20eb0bec1137c403c6d91097c67a1d906fac..0e65f609352ecee0519e2b207391b8ccace57869 100644 (file)
@@ -262,9 +262,6 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
                ct->chip.irq_set_wake = irq_gc_set_wake;
        }
 
-       pr_info("registered L2 intc (mem: 0x%p, parent irq: %d)\n",
-                       base, parent_irq);
-
        return 0;
 
 out_free_domain:
index 993a8426a45384a650ac1b68b19760d1a47ee684..1ff38aff9f29f32f895bc9a1975404a0f0e2ce3f 100644 (file)
@@ -94,7 +94,7 @@ static struct irq_chip gicv2m_msi_irq_chip = {
 
 static struct msi_domain_info gicv2m_msi_domain_info = {
        .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-                  MSI_FLAG_PCI_MSIX),
+                  MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI),
        .chip   = &gicv2m_msi_irq_chip,
 };
 
@@ -155,18 +155,12 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
        return 0;
 }
 
-static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq)
+static void gicv2m_unalloc_msi(struct v2m_data *v2m, unsigned int hwirq,
+                              int nr_irqs)
 {
-       int pos;
-
-       pos = hwirq - v2m->spi_start;
-       if (pos < 0 || pos >= v2m->nr_spis) {
-               pr_err("Failed to teardown msi. Invalid hwirq %d\n", hwirq);
-               return;
-       }
-
        spin_lock(&v2m_lock);
-       __clear_bit(pos, v2m->bm);
+       bitmap_release_region(v2m->bm, hwirq - v2m->spi_start,
+                             get_count_order(nr_irqs));
        spin_unlock(&v2m_lock);
 }
 
@@ -174,13 +168,13 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
                                   unsigned int nr_irqs, void *args)
 {
        struct v2m_data *v2m = NULL, *tmp;
-       int hwirq, offset, err = 0;
+       int hwirq, offset, i, err = 0;
 
        spin_lock(&v2m_lock);
        list_for_each_entry(tmp, &v2m_nodes, entry) {
-               offset = find_first_zero_bit(tmp->bm, tmp->nr_spis);
-               if (offset < tmp->nr_spis) {
-                       __set_bit(offset, tmp->bm);
+               offset = bitmap_find_free_region(tmp->bm, tmp->nr_spis,
+                                                get_count_order(nr_irqs));
+               if (offset >= 0) {
                        v2m = tmp;
                        break;
                }
@@ -192,16 +186,21 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 
        hwirq = v2m->spi_start + offset;
 
-       err = gicv2m_irq_gic_domain_alloc(domain, virq, hwirq);
-       if (err) {
-               gicv2m_unalloc_msi(v2m, hwirq);
-               return err;
-       }
+       for (i = 0; i < nr_irqs; i++) {
+               err = gicv2m_irq_gic_domain_alloc(domain, virq + i, hwirq + i);
+               if (err)
+                       goto fail;
 
-       irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
-                                     &gicv2m_irq_chip, v2m);
+               irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
+                                             &gicv2m_irq_chip, v2m);
+       }
 
        return 0;
+
+fail:
+       irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+       gicv2m_unalloc_msi(v2m, hwirq, get_count_order(nr_irqs));
+       return err;
 }
 
 static void gicv2m_irq_domain_free(struct irq_domain *domain,
@@ -210,8 +209,7 @@ static void gicv2m_irq_domain_free(struct irq_domain *domain,
        struct irq_data *d = irq_domain_get_irq_data(domain, virq);
        struct v2m_data *v2m = irq_data_get_irq_chip_data(d);
 
-       BUG_ON(nr_irqs != 1);
-       gicv2m_unalloc_msi(v2m, d->hwirq);
+       gicv2m_unalloc_msi(v2m, d->hwirq, nr_irqs);
        irq_domain_free_irqs_parent(domain, virq, nr_irqs);
 }
 
index 14a8c0a7e095eb32c383bccbb163174ce1ccec28..25a98de5cfb2831fa61d33fd3be3ef30d3f4e534 100644 (file)
@@ -132,6 +132,8 @@ static int __init its_pci_of_msi_init(void)
 
        for (np = of_find_matching_node(NULL, its_device_id); np;
             np = of_find_matching_node(np, its_device_id)) {
+               if (!of_device_is_available(np))
+                       continue;
                if (!of_property_read_bool(np, "msi-controller"))
                        continue;
 
index 833a90fe33aed839a81b781831027e677eef5581..8881a053c173edfdb11ad322b9b60f9b61ef57aa 100644 (file)
@@ -154,6 +154,8 @@ static void __init its_pmsi_of_init(void)
 
        for (np = of_find_matching_node(NULL, its_device_id); np;
             np = of_find_matching_node(np, its_device_id)) {
+               if (!of_device_is_available(np))
+                       continue;
                if (!of_property_read_bool(np, "msi-controller"))
                        continue;
 
index 06f025fd5726f6b230d51c880e7b8accf9e8c738..2cbb19cddbf8e06c1d08aef5fb1926131238fe31 100644 (file)
@@ -1412,7 +1412,7 @@ static struct irq_chip its_irq_chip = {
  * This gives us (((1UL << id_bits) - 8192) >> 5) possible allocations.
  */
 #define IRQS_PER_CHUNK_SHIFT   5
-#define IRQS_PER_CHUNK         (1 << IRQS_PER_CHUNK_SHIFT)
+#define IRQS_PER_CHUNK         (1UL << IRQS_PER_CHUNK_SHIFT)
 #define ITS_MAX_LPI_NRBITS     16 /* 64K LPIs */
 
 static unsigned long *lpi_bitmap;
@@ -2119,11 +2119,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        /*
-        * At least one bit of EventID is being used, hence a minimum
-        * of two entries. No, the architecture doesn't let you
-        * express an ITT with a single entry.
+        * We allocate at least one chunk worth of LPIs bet device,
+        * and thus that many ITEs. The device may require less though.
         */
-       nr_ites = max(2UL, roundup_pow_of_two(nvecs));
+       nr_ites = max(IRQS_PER_CHUNK, roundup_pow_of_two(nvecs));
        sz = nr_ites * its->ite_size;
        sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
        itt = kzalloc(sz, GFP_KERNEL);
@@ -2495,7 +2494,7 @@ static int its_vpe_set_affinity(struct irq_data *d,
 
 static void its_vpe_schedule(struct its_vpe *vpe)
 {
-       void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
+       void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
        u64 val;
 
        /* Schedule the VPE */
@@ -2527,7 +2526,7 @@ static void its_vpe_schedule(struct its_vpe *vpe)
 
 static void its_vpe_deschedule(struct its_vpe *vpe)
 {
-       void * __iomem vlpi_base = gic_data_rdist_vlpi_base();
+       void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
        u32 count = 1000000;    /* 1s! */
        bool clean;
        u64 val;
@@ -3314,6 +3313,8 @@ static int __init its_of_probe(struct device_node *node)
 
        for (np = of_find_matching_node(node, its_device_id); np;
             np = of_find_matching_node(np, its_device_id)) {
+               if (!of_device_is_available(np))
+                       continue;
                if (!of_property_read_bool(np, "msi-controller")) {
                        pr_warn("%pOF: no msi-controller property, ITS ignored\n",
                                np);
index a57c0fbbd34a4af5651284666402be9fe5fea033..d99cc07903ec497279e3baf563743d9146e77f09 100644 (file)
@@ -673,7 +673,7 @@ static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq)
               MPIDR_TO_SGI_RS(cluster_id)              |
               tlist << ICC_SGI1R_TARGET_LIST_SHIFT);
 
-       pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val);
+       pr_devel("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val);
        gic_write_sgi1r(val);
 }
 
@@ -688,7 +688,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
         * Ensure that stores to Normal memory are visible to the
         * other CPUs before issuing the IPI.
         */
-       smp_wmb();
+       wmb();
 
        for_each_cpu(cpu, mask) {
                u64 cluster_id = MPIDR_TO_SGI_CLUSTER_ID(cpu_logical_map(cpu));
index 675eda5ff2b85f6037eaea58d49a3d48a9e2c33d..4760307ab43fc33404b6b2ec07b2c3b49a6f6405 100644 (file)
@@ -28,20 +28,6 @@ struct gpcv2_irqchip_data {
 
 static struct gpcv2_irqchip_data *imx_gpcv2_instance;
 
-/*
- * Interface for the low level wakeup code.
- */
-u32 imx_gpcv2_get_wakeup_source(u32 **sources)
-{
-       if (!imx_gpcv2_instance)
-               return 0;
-
-       if (sources)
-               *sources = imx_gpcv2_instance->wakeup_sources;
-
-       return IMR_NUM;
-}
-
 static int gpcv2_wakeup_source_save(void)
 {
        struct gpcv2_irqchip_data *cd;
index ef92a4d2038eef7f2c09ad9eaabf91adc3957435..d32268cc1174c75b8cc0942c15637916a5a333ff 100644 (file)
@@ -424,8 +424,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
        spin_lock_irqsave(&gic_lock, flags);
        write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
        write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
-       gic_clear_pcpu_masks(intr);
-       set_bit(intr, per_cpu_ptr(pcpu_masks, cpu));
        irq_data_update_effective_affinity(data, cpumask_of(cpu));
        spin_unlock_irqrestore(&gic_lock, flags);
 
index 62f541f968f6f8e1161967b82aa1979d471fba90..07074820a16746ec74351ea2273cfecee27e6353 100644 (file)
@@ -375,6 +375,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
        dev->ofdev.dev.of_node = np;
        dev->ofdev.archdata.dma_mask = 0xffffffffUL;
        dev->ofdev.dev.dma_mask = &dev->ofdev.archdata.dma_mask;
+       dev->ofdev.dev.coherent_dma_mask = dev->ofdev.archdata.dma_mask;
        dev->ofdev.dev.parent = parent;
        dev->ofdev.dev.bus = &macio_bus_type;
        dev->ofdev.dev.release = macio_release_dev;
index 1a46b41dac7018bbf43e1dc610abeacab21cb7a1..6422846b546ed27122dc277bd65568421e6986fc 100644 (file)
@@ -659,11 +659,11 @@ static void do_bio_hook(struct search *s, struct bio *orig_bio)
 static void search_free(struct closure *cl)
 {
        struct search *s = container_of(cl, struct search, cl);
-       bio_complete(s);
 
        if (s->iop.bio)
                bio_put(s->iop.bio);
 
+       bio_complete(s);
        closure_debug_destroy(cl);
        mempool_free(s, s->d->c->search);
 }
index 312895788036705cb0426d1af5b5662a4797faf3..f2273143b3cb2384109ba47bf3518adf31337ad8 100644 (file)
@@ -963,6 +963,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
        uint32_t rtime = cpu_to_le32(get_seconds());
        struct uuid_entry *u;
        char buf[BDEVNAME_SIZE];
+       struct cached_dev *exist_dc, *t;
 
        bdevname(dc->bdev, buf);
 
@@ -987,6 +988,16 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
                return -EINVAL;
        }
 
+       /* Check whether already attached */
+       list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) {
+               if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) {
+                       pr_err("Tried to attach %s but duplicate UUID already attached",
+                               buf);
+
+                       return -EINVAL;
+               }
+       }
+
        u = uuid_find(c, dc->sb.uuid);
 
        if (u &&
@@ -1204,7 +1215,7 @@ static void register_bdev(struct cache_sb *sb, struct page *sb_page,
 
        return;
 err:
-       pr_notice("error opening %s: %s", bdevname(bdev, name), err);
+       pr_notice("error %s: %s", bdevname(bdev, name), err);
        bcache_device_stop(&dc->disk);
 }
 
@@ -1274,7 +1285,7 @@ static int flash_devs_run(struct cache_set *c)
        struct uuid_entry *u;
 
        for (u = c->uuids;
-            u < c->uuids + c->devices_max_used && !ret;
+            u < c->uuids + c->nr_uuids && !ret;
             u++)
                if (UUID_FLASH_ONLY(u))
                        ret = flash_dev_run(c, u);
@@ -1883,6 +1894,8 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page,
        const char *err = NULL; /* must be set for any error case */
        int ret = 0;
 
+       bdevname(bdev, name);
+
        memcpy(&ca->sb, sb, sizeof(struct cache_sb));
        ca->bdev = bdev;
        ca->bdev->bd_holder = ca;
@@ -1891,11 +1904,12 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page,
        bio_first_bvec_all(&ca->sb_bio)->bv_page = sb_page;
        get_page(sb_page);
 
-       if (blk_queue_discard(bdev_get_queue(ca->bdev)))
+       if (blk_queue_discard(bdev_get_queue(bdev)))
                ca->discard = CACHE_DISCARD(&ca->sb);
 
        ret = cache_alloc(ca);
        if (ret != 0) {
+               blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
                if (ret == -ENOMEM)
                        err = "cache_alloc(): -ENOMEM";
                else
@@ -1918,14 +1932,14 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page,
                goto out;
        }
 
-       pr_info("registered cache device %s", bdevname(bdev, name));
+       pr_info("registered cache device %s", name);
 
 out:
        kobject_put(&ca->kobj);
 
 err:
        if (err)
-               pr_notice("error opening %s: %s", bdevname(bdev, name), err);
+               pr_notice("error %s: %s", name, err);
 
        return ret;
 }
@@ -2014,6 +2028,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
        if (err)
                goto err_close;
 
+       err = "failed to register device";
        if (SB_IS_BDEV(sb)) {
                struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
                if (!dc)
@@ -2028,7 +2043,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
                        goto err_close;
 
                if (register_cache(sb, sb_page, bdev, ca) != 0)
-                       goto err_close;
+                       goto err;
        }
 out:
        if (sb_page)
@@ -2041,7 +2056,7 @@ out:
 err_close:
        blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
 err:
-       pr_info("error opening %s: %s", path, err);
+       pr_info("error %s: %s", path, err);
        ret = -EINVAL;
        goto out;
 }
index 414c9af54ded2fde89531cedf3da430c53fcac9d..aa2032fa80d49eebaccf937a4a9a5182d91dadc9 100644 (file)
@@ -386,9 +386,6 @@ static void __cache_size_refresh(void)
 static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
                               enum data_mode *data_mode)
 {
-       unsigned noio_flag;
-       void *ptr;
-
        if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) {
                *data_mode = DATA_MODE_SLAB;
                return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask);
@@ -412,16 +409,15 @@ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
         * all allocations done by this process (including pagetables) are done
         * as if GFP_NOIO was specified.
         */
+       if (gfp_mask & __GFP_NORETRY) {
+               unsigned noio_flag = memalloc_noio_save();
+               void *ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);
 
-       if (gfp_mask & __GFP_NORETRY)
-               noio_flag = memalloc_noio_save();
-
-       ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);
-
-       if (gfp_mask & __GFP_NORETRY)
                memalloc_noio_restore(noio_flag);
+               return ptr;
+       }
 
-       return ptr;
+       return __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);
 }
 
 /*
index 7d3e572072f51f865d07a79ae5a0ac974bd98e4a..a05a560d3cba628eb8a5ed23e07a753c1efb0acd 100644 (file)
@@ -211,29 +211,27 @@ static int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m)
                else
                        m->queue_mode = DM_TYPE_REQUEST_BASED;
 
-       } else if (m->queue_mode == DM_TYPE_BIO_BASED ||
-                  m->queue_mode == DM_TYPE_NVME_BIO_BASED) {
+       } else if (m->queue_mode == DM_TYPE_BIO_BASED) {
                INIT_WORK(&m->process_queued_bios, process_queued_bios);
-
-               if (m->queue_mode == DM_TYPE_BIO_BASED) {
-                       /*
-                        * bio-based doesn't support any direct scsi_dh management;
-                        * it just discovers if a scsi_dh is attached.
-                        */
-                       set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags);
-               }
-       }
-
-       if (m->queue_mode != DM_TYPE_NVME_BIO_BASED) {
-               set_bit(MPATHF_QUEUE_IO, &m->flags);
-               atomic_set(&m->pg_init_in_progress, 0);
-               atomic_set(&m->pg_init_count, 0);
-               m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT;
-               init_waitqueue_head(&m->pg_init_wait);
+               /*
+                * bio-based doesn't support any direct scsi_dh management;
+                * it just discovers if a scsi_dh is attached.
+                */
+               set_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags);
        }
 
        dm_table_set_type(ti->table, m->queue_mode);
 
+       /*
+        * Init fields that are only used when a scsi_dh is attached
+        * - must do this unconditionally (really doesn't hurt non-SCSI uses)
+        */
+       set_bit(MPATHF_QUEUE_IO, &m->flags);
+       atomic_set(&m->pg_init_in_progress, 0);
+       atomic_set(&m->pg_init_count, 0);
+       m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT;
+       init_waitqueue_head(&m->pg_init_wait);
+
        return 0;
 }
 
@@ -337,9 +335,6 @@ static void __switch_pg(struct multipath *m, struct priority_group *pg)
 {
        m->current_pg = pg;
 
-       if (m->queue_mode == DM_TYPE_NVME_BIO_BASED)
-               return;
-
        /* Must we initialise the PG first, and queue I/O till it's ready? */
        if (m->hw_handler_name) {
                set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags);
@@ -385,8 +380,7 @@ static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes)
        unsigned bypassed = 1;
 
        if (!atomic_read(&m->nr_valid_paths)) {
-               if (m->queue_mode != DM_TYPE_NVME_BIO_BASED)
-                       clear_bit(MPATHF_QUEUE_IO, &m->flags);
+               clear_bit(MPATHF_QUEUE_IO, &m->flags);
                goto failed;
        }
 
@@ -599,7 +593,7 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio)
        return pgpath;
 }
 
-static struct pgpath *__map_bio_nvme(struct multipath *m, struct bio *bio)
+static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio)
 {
        struct pgpath *pgpath;
        unsigned long flags;
@@ -634,8 +628,8 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio,
 {
        struct pgpath *pgpath;
 
-       if (m->queue_mode == DM_TYPE_NVME_BIO_BASED)
-               pgpath = __map_bio_nvme(m, bio);
+       if (!m->hw_handler_name)
+               pgpath = __map_bio_fast(m, bio);
        else
                pgpath = __map_bio(m, bio);
 
@@ -675,8 +669,7 @@ static void process_queued_io_list(struct multipath *m)
 {
        if (m->queue_mode == DM_TYPE_MQ_REQUEST_BASED)
                dm_mq_kick_requeue_list(dm_table_get_md(m->ti->table));
-       else if (m->queue_mode == DM_TYPE_BIO_BASED ||
-                m->queue_mode == DM_TYPE_NVME_BIO_BASED)
+       else if (m->queue_mode == DM_TYPE_BIO_BASED)
                queue_work(kmultipathd, &m->process_queued_bios);
 }
 
@@ -811,15 +804,14 @@ static int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg,
        return 0;
 }
 
-static int setup_scsi_dh(struct block_device *bdev, struct multipath *m, char **error)
+static int setup_scsi_dh(struct block_device *bdev, struct multipath *m,
+                        const char *attached_handler_name, char **error)
 {
        struct request_queue *q = bdev_get_queue(bdev);
-       const char *attached_handler_name;
        int r;
 
        if (test_bit(MPATHF_RETAIN_ATTACHED_HW_HANDLER, &m->flags)) {
 retain:
-               attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
                if (attached_handler_name) {
                        /*
                         * Clear any hw_handler_params associated with a
@@ -873,6 +865,8 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
        int r;
        struct pgpath *p;
        struct multipath *m = ti->private;
+       struct request_queue *q;
+       const char *attached_handler_name;
 
        /* we need at least a path arg */
        if (as->argc < 1) {
@@ -891,9 +885,11 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
                goto bad;
        }
 
-       if (m->queue_mode != DM_TYPE_NVME_BIO_BASED) {
+       q = bdev_get_queue(p->path.dev->bdev);
+       attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
+       if (attached_handler_name) {
                INIT_DELAYED_WORK(&p->activate_path, activate_path_work);
-               r = setup_scsi_dh(p->path.dev->bdev, m, &ti->error);
+               r = setup_scsi_dh(p->path.dev->bdev, m, attached_handler_name, &ti->error);
                if (r) {
                        dm_put_device(ti, p->path.dev);
                        goto bad;
@@ -1001,8 +997,7 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
        if (!hw_argc)
                return 0;
 
-       if (m->queue_mode == DM_TYPE_BIO_BASED ||
-           m->queue_mode == DM_TYPE_NVME_BIO_BASED) {
+       if (m->queue_mode == DM_TYPE_BIO_BASED) {
                dm_consume_args(as, hw_argc);
                DMERR("bio-based multipath doesn't allow hardware handler args");
                return 0;
@@ -1091,8 +1086,6 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m)
 
                        if (!strcasecmp(queue_mode_name, "bio"))
                                m->queue_mode = DM_TYPE_BIO_BASED;
-                       else if (!strcasecmp(queue_mode_name, "nvme"))
-                               m->queue_mode = DM_TYPE_NVME_BIO_BASED;
                        else if (!strcasecmp(queue_mode_name, "rq"))
                                m->queue_mode = DM_TYPE_REQUEST_BASED;
                        else if (!strcasecmp(queue_mode_name, "mq"))
@@ -1193,7 +1186,7 @@ static int multipath_ctr(struct dm_target *ti, unsigned argc, char **argv)
        ti->num_discard_bios = 1;
        ti->num_write_same_bios = 1;
        ti->num_write_zeroes_bios = 1;
-       if (m->queue_mode == DM_TYPE_BIO_BASED || m->queue_mode == DM_TYPE_NVME_BIO_BASED)
+       if (m->queue_mode == DM_TYPE_BIO_BASED)
                ti->per_io_data_size = multipath_per_bio_data_size();
        else
                ti->per_io_data_size = sizeof(struct dm_mpath_io);
@@ -1730,9 +1723,6 @@ static void multipath_status(struct dm_target *ti, status_type_t type,
                        case DM_TYPE_BIO_BASED:
                                DMEMIT("queue_mode bio ");
                                break;
-                       case DM_TYPE_NVME_BIO_BASED:
-                               DMEMIT("queue_mode nvme ");
-                               break;
                        case DM_TYPE_MQ_REQUEST_BASED:
                                DMEMIT("queue_mode mq ");
                                break;
@@ -2030,8 +2020,9 @@ static int multipath_busy(struct dm_target *ti)
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
        .name = "multipath",
-       .version = {1, 12, 0},
-       .features = DM_TARGET_SINGLETON | DM_TARGET_IMMUTABLE,
+       .version = {1, 13, 0},
+       .features = DM_TARGET_SINGLETON | DM_TARGET_IMMUTABLE |
+                   DM_TARGET_PASSES_INTEGRITY,
        .module = THIS_MODULE,
        .ctr = multipath_ctr,
        .dtr = multipath_dtr,
index 7ef469e902c620126b95f69d899e528ae114b3bc..c1d1034ff7b75eb740d40920615c0ae10a308c43 100644 (file)
@@ -3408,9 +3408,10 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery,
                set_bit(RT_FLAG_RS_IN_SYNC, &rs->runtime_flags);
 
        } else {
-               if (test_bit(MD_RECOVERY_NEEDED, &recovery) ||
-                   test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
-                   test_bit(MD_RECOVERY_RUNNING, &recovery))
+               if (!test_bit(MD_RECOVERY_INTR, &recovery) &&
+                   (test_bit(MD_RECOVERY_NEEDED, &recovery) ||
+                    test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
+                    test_bit(MD_RECOVERY_RUNNING, &recovery)))
                        r = mddev->curr_resync_completed;
                else
                        r = mddev->recovery_cp;
index 5fe7ec356c333c940edb41e61f0e5844de0aea72..7eb3e2a3c07d5a607669d36aa0a462bfd175d9b3 100644 (file)
@@ -942,17 +942,12 @@ static int dm_table_determine_type(struct dm_table *t)
 
        if (t->type != DM_TYPE_NONE) {
                /* target already set the table's type */
-               if (t->type == DM_TYPE_BIO_BASED)
-                       return 0;
-               else if (t->type == DM_TYPE_NVME_BIO_BASED) {
-                       if (!dm_table_does_not_support_partial_completion(t)) {
-                               DMERR("nvme bio-based is only possible with devices"
-                                     " that don't support partial completion");
-                               return -EINVAL;
-                       }
-                       /* Fallthru, also verify all devices are blk-mq */
+               if (t->type == DM_TYPE_BIO_BASED) {
+                       /* possibly upgrade to a variant of bio-based */
+                       goto verify_bio_based;
                }
                BUG_ON(t->type == DM_TYPE_DAX_BIO_BASED);
+               BUG_ON(t->type == DM_TYPE_NVME_BIO_BASED);
                goto verify_rq_based;
        }
 
@@ -985,6 +980,7 @@ static int dm_table_determine_type(struct dm_table *t)
        }
 
        if (bio_based) {
+verify_bio_based:
                /* We must use this table as bio-based */
                t->type = DM_TYPE_BIO_BASED;
                if (dm_table_supports_dax(t) ||
@@ -1755,7 +1751,7 @@ static int device_no_partial_completion(struct dm_target *ti, struct dm_dev *dev
        char b[BDEVNAME_SIZE];
 
        /* For now, NVMe devices are the only devices of this class */
-       return (strncmp(bdevname(dev->bdev, b), "nvme", 3) == 0);
+       return (strncmp(bdevname(dev->bdev, b), "nvme", 4) == 0);
 }
 
 static bool dm_table_does_not_support_partial_completion(struct dm_table *t)
index d6de00f367efdde4137055dfa4c82fefcbcd1f9a..45328d8b2859640d04a01b6b7b14cd9990fa2b7e 100644 (file)
@@ -458,9 +458,11 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return dm_get_geometry(md, geo);
 }
 
-static int dm_grab_bdev_for_ioctl(struct mapped_device *md,
-                                 struct block_device **bdev,
-                                 fmode_t *mode)
+static char *_dm_claim_ptr = "I belong to device-mapper";
+
+static int dm_get_bdev_for_ioctl(struct mapped_device *md,
+                                struct block_device **bdev,
+                                fmode_t *mode)
 {
        struct dm_target *tgt;
        struct dm_table *map;
@@ -490,6 +492,10 @@ retry:
                goto out;
 
        bdgrab(*bdev);
+       r = blkdev_get(*bdev, *mode, _dm_claim_ptr);
+       if (r < 0)
+               goto out;
+
        dm_put_live_table(md, srcu_idx);
        return r;
 
@@ -508,7 +514,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
        struct mapped_device *md = bdev->bd_disk->private_data;
        int r;
 
-       r = dm_grab_bdev_for_ioctl(md, &bdev, &mode);
+       r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
        if (r < 0)
                return r;
 
@@ -528,7 +534,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
 
        r =  __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 out:
-       bdput(bdev);
+       blkdev_put(bdev, mode);
        return r;
 }
 
@@ -708,14 +714,13 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU)
 static int open_table_device(struct table_device *td, dev_t dev,
                             struct mapped_device *md)
 {
-       static char *_claim_ptr = "I belong to device-mapper";
        struct block_device *bdev;
 
        int r;
 
        BUG_ON(td->dm_dev.bdev);
 
-       bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _claim_ptr);
+       bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _dm_claim_ptr);
        if (IS_ERR(bdev))
                return PTR_ERR(bdev);
 
@@ -903,7 +908,8 @@ static void dec_pending(struct dm_io *io, blk_status_t error)
                        queue_io(md, bio);
                } else {
                        /* done with normal IO or empty flush */
-                       bio->bi_status = io_error;
+                       if (io_error)
+                               bio->bi_status = io_error;
                        bio_endio(bio);
                }
        }
@@ -3010,7 +3016,7 @@ static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,
        fmode_t mode;
        int r;
 
-       r = dm_grab_bdev_for_ioctl(md, &bdev, &mode);
+       r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
        if (r < 0)
                return r;
 
@@ -3020,7 +3026,7 @@ static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,
        else
                r = -EOPNOTSUPP;
 
-       bdput(bdev);
+       blkdev_put(bdev, mode);
        return r;
 }
 
@@ -3031,7 +3037,7 @@ static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
        fmode_t mode;
        int r;
 
-       r = dm_grab_bdev_for_ioctl(md, &bdev, &mode);
+       r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
        if (r < 0)
                return r;
 
@@ -3041,7 +3047,7 @@ static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
        else
                r = -EOPNOTSUPP;
 
-       bdput(bdev);
+       blkdev_put(bdev, mode);
        return r;
 }
 
@@ -3053,7 +3059,7 @@ static int dm_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key,
        fmode_t mode;
        int r;
 
-       r = dm_grab_bdev_for_ioctl(md, &bdev, &mode);
+       r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
        if (r < 0)
                return r;
 
@@ -3063,7 +3069,7 @@ static int dm_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key,
        else
                r = -EOPNOTSUPP;
 
-       bdput(bdev);
+       blkdev_put(bdev, mode);
        return r;
 }
 
@@ -3074,7 +3080,7 @@ static int dm_pr_clear(struct block_device *bdev, u64 key)
        fmode_t mode;
        int r;
 
-       r = dm_grab_bdev_for_ioctl(md, &bdev, &mode);
+       r = dm_get_bdev_for_ioctl(md, &bdev, &mode);
        if (r < 0)
                return r;
 
@@ -3084,7 +3090,7 @@ static int dm_pr_clear(struct block_device *bdev, u64 key)
        else
                r = -EOPNOTSUPP;
 
-       bdput(bdev);
+       blkdev_put(bdev, mode);
        return r;
 }
 
index e40065bdbfc84ef8455dbcc88d6a3208a6780571..0a7e99d62c69048d7000d3dc6bbcaa3320c742b5 100644 (file)
@@ -157,7 +157,7 @@ static void multipath_status(struct seq_file *seq, struct mddev *mddev)
                seq_printf (seq, "%s", rdev && test_bit(In_sync, &rdev->flags) ? "U" : "_");
        }
        rcu_read_unlock();
-       seq_printf (seq, "]");
+       seq_putc(seq, ']');
 }
 
 static int multipath_congested(struct mddev *mddev, int bits)
index bc67ab6844f02d540cf4ae3725ebdad13ee568b8..254e44e44668f5fff8cc2d95bdb3b682450a204f 100644 (file)
@@ -801,6 +801,9 @@ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
        struct bio *bio;
        int ff = 0;
 
+       if (!page)
+               return;
+
        if (test_bit(Faulty, &rdev->flags))
                return;
 
@@ -5452,6 +5455,7 @@ int md_run(struct mddev *mddev)
         * the only valid external interface is through the md
         * device.
         */
+       mddev->has_superblocks = false;
        rdev_for_each(rdev, mddev) {
                if (test_bit(Faulty, &rdev->flags))
                        continue;
@@ -5465,6 +5469,9 @@ int md_run(struct mddev *mddev)
                                set_disk_ro(mddev->gendisk, 1);
                }
 
+               if (rdev->sb_page)
+                       mddev->has_superblocks = true;
+
                /* perform some consistency tests on the device.
                 * We don't want the data to overlap the metadata,
                 * Internal Bitmap issues have been handled elsewhere.
@@ -5497,8 +5504,10 @@ int md_run(struct mddev *mddev)
        }
        if (mddev->sync_set == NULL) {
                mddev->sync_set = bioset_create(BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
-               if (!mddev->sync_set)
-                       return -ENOMEM;
+               if (!mddev->sync_set) {
+                       err = -ENOMEM;
+                       goto abort;
+               }
        }
 
        spin_lock(&pers_lock);
@@ -5511,7 +5520,8 @@ int md_run(struct mddev *mddev)
                else
                        pr_warn("md: personality for level %s is not loaded!\n",
                                mddev->clevel);
-               return -EINVAL;
+               err = -EINVAL;
+               goto abort;
        }
        spin_unlock(&pers_lock);
        if (mddev->level != pers->level) {
@@ -5524,7 +5534,8 @@ int md_run(struct mddev *mddev)
            pers->start_reshape == NULL) {
                /* This personality cannot handle reshaping... */
                module_put(pers->owner);
-               return -EINVAL;
+               err = -EINVAL;
+               goto abort;
        }
 
        if (pers->sync_request) {
@@ -5593,7 +5604,7 @@ int md_run(struct mddev *mddev)
                mddev->private = NULL;
                module_put(pers->owner);
                bitmap_destroy(mddev);
-               return err;
+               goto abort;
        }
        if (mddev->queue) {
                bool nonrot = true;
@@ -5655,6 +5666,18 @@ int md_run(struct mddev *mddev)
        sysfs_notify_dirent_safe(mddev->sysfs_action);
        sysfs_notify(&mddev->kobj, NULL, "degraded");
        return 0;
+
+abort:
+       if (mddev->bio_set) {
+               bioset_free(mddev->bio_set);
+               mddev->bio_set = NULL;
+       }
+       if (mddev->sync_set) {
+               bioset_free(mddev->sync_set);
+               mddev->sync_set = NULL;
+       }
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(md_run);
 
@@ -8049,6 +8072,7 @@ EXPORT_SYMBOL(md_done_sync);
 bool md_write_start(struct mddev *mddev, struct bio *bi)
 {
        int did_change = 0;
+
        if (bio_data_dir(bi) != WRITE)
                return true;
 
@@ -8081,6 +8105,8 @@ bool md_write_start(struct mddev *mddev, struct bio *bi)
        rcu_read_unlock();
        if (did_change)
                sysfs_notify_dirent_safe(mddev->sysfs_state);
+       if (!mddev->has_superblocks)
+               return true;
        wait_event(mddev->sb_wait,
                   !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) ||
                   mddev->suspended);
@@ -8543,6 +8569,19 @@ void md_do_sync(struct md_thread *thread)
        set_mask_bits(&mddev->sb_flags, 0,
                      BIT(MD_SB_CHANGE_PENDING) | BIT(MD_SB_CHANGE_DEVS));
 
+       if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+                       !test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
+                       mddev->delta_disks > 0 &&
+                       mddev->pers->finish_reshape &&
+                       mddev->pers->size &&
+                       mddev->queue) {
+               mddev_lock_nointr(mddev);
+               md_set_array_sectors(mddev, mddev->pers->size(mddev, 0, 0));
+               mddev_unlock(mddev);
+               set_capacity(mddev->gendisk, mddev->array_sectors);
+               revalidate_disk(mddev->gendisk);
+       }
+
        spin_lock(&mddev->lock);
        if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
                /* We completed so min/max setting can be forgotten if used. */
@@ -8569,6 +8608,10 @@ static int remove_and_add_spares(struct mddev *mddev,
        int removed = 0;
        bool remove_some = false;
 
+       if (this && test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+               /* Mustn't remove devices when resync thread is running */
+               return 0;
+
        rdev_for_each(rdev, mddev) {
                if ((this == NULL || rdev == this) &&
                    rdev->raid_disk >= 0 &&
index 58cd20a5e85edb1db853661dcd749d99682a796c..fbc925cce8107019dcc4b2aa5310c7d100431a46 100644 (file)
@@ -468,6 +468,8 @@ struct mddev {
        void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev);
        struct md_cluster_info          *cluster_info;
        unsigned int                    good_device_nr; /* good device num within cluster raid */
+
+       bool    has_superblocks:1;
 };
 
 enum recovery_flags {
index b2eae332e1a29ee585c04ba6d22c2a23b8b99ed3..fe872dc6712ed0c5c00caa60e5f152876f0b1025 100644 (file)
@@ -1108,7 +1108,7 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio,
 
        bio_copy_data(behind_bio, bio);
 skip_copy:
-       r1_bio->behind_master_bio = behind_bio;;
+       r1_bio->behind_master_bio = behind_bio;
        set_bit(R1BIO_BehindIO, &r1_bio->state);
 
        return;
@@ -1809,6 +1809,17 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
                        struct md_rdev *repl =
                                conf->mirrors[conf->raid_disks + number].rdev;
                        freeze_array(conf, 0);
+                       if (atomic_read(&repl->nr_pending)) {
+                               /* It means that some queued IO of retry_list
+                                * hold repl. Thus, we cannot set replacement
+                                * as NULL, avoiding rdev NULL pointer
+                                * dereference in sync_request_write and
+                                * handle_write_finished.
+                                */
+                               err = -EBUSY;
+                               unfreeze_array(conf);
+                               goto abort;
+                       }
                        clear_bit(Replacement, &repl->flags);
                        p->rdev = repl;
                        conf->mirrors[conf->raid_disks + number].rdev = NULL;
index c7294e7557e038bf5248e8c8bf9ce84cb6afad58..eb84bc68e2fd4c31cc996bc4d399183cd852b8f2 100644 (file)
 #define BARRIER_BUCKETS_NR_BITS                (PAGE_SHIFT - ilog2(sizeof(atomic_t)))
 #define BARRIER_BUCKETS_NR             (1<<BARRIER_BUCKETS_NR_BITS)
 
+/* Note: raid1_info.rdev can be set to NULL asynchronously by raid1_remove_disk.
+ * There are three safe ways to access raid1_info.rdev.
+ * 1/ when holding mddev->reconfig_mutex
+ * 2/ when resync/recovery is known to be happening - i.e. in code that is
+ *    called as part of performing resync/recovery.
+ * 3/ while holding rcu_read_lock(), use rcu_dereference to get the pointer
+ *    and if it is non-NULL, increment rdev->nr_pending before dropping the
+ *    RCU lock.
+ * When .rdev is set to NULL, the nr_pending count checked again and if it has
+ * been incremented, the pointer is put back in .rdev.
+ */
+
 struct raid1_info {
        struct md_rdev  *rdev;
        sector_t        head_position;
index 99c9207899a777c615880f286a6f617ffc4a70bf..c5e6c60fc0d41b53a578874087ae87259e3ebcce 100644 (file)
@@ -141,7 +141,7 @@ static void r10bio_pool_free(void *r10_bio, void *data)
 #define RESYNC_WINDOW (1024*1024)
 /* maximum number of concurrent requests, memory permitting */
 #define RESYNC_DEPTH (32*1024*1024/RESYNC_BLOCK_SIZE)
-#define CLUSTER_RESYNC_WINDOW (16 * RESYNC_WINDOW)
+#define CLUSTER_RESYNC_WINDOW (32 * RESYNC_WINDOW)
 #define CLUSTER_RESYNC_WINDOW_SECTORS (CLUSTER_RESYNC_WINDOW >> 9)
 
 /*
@@ -2655,7 +2655,8 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
                for (m = 0; m < conf->copies; m++) {
                        int dev = r10_bio->devs[m].devnum;
                        rdev = conf->mirrors[dev].rdev;
-                       if (r10_bio->devs[m].bio == NULL)
+                       if (r10_bio->devs[m].bio == NULL ||
+                               r10_bio->devs[m].bio->bi_end_io == NULL)
                                continue;
                        if (!r10_bio->devs[m].bio->bi_status) {
                                rdev_clear_badblocks(
@@ -2670,7 +2671,8 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
                                        md_error(conf->mddev, rdev);
                        }
                        rdev = conf->mirrors[dev].replacement;
-                       if (r10_bio->devs[m].repl_bio == NULL)
+                       if (r10_bio->devs[m].repl_bio == NULL ||
+                               r10_bio->devs[m].repl_bio->bi_end_io == NULL)
                                continue;
 
                        if (!r10_bio->devs[m].repl_bio->bi_status) {
@@ -3782,7 +3784,7 @@ static int raid10_run(struct mddev *mddev)
                if (fc > 1 || fo > 0) {
                        pr_err("only near layout is supported by clustered"
                                " raid10\n");
-                       goto out;
+                       goto out_free_conf;
                }
        }
 
@@ -4830,17 +4832,11 @@ static void raid10_finish_reshape(struct mddev *mddev)
                return;
 
        if (mddev->delta_disks > 0) {
-               sector_t size = raid10_size(mddev, 0, 0);
-               md_set_array_sectors(mddev, size);
                if (mddev->recovery_cp > mddev->resync_max_sectors) {
                        mddev->recovery_cp = mddev->resync_max_sectors;
                        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                }
-               mddev->resync_max_sectors = size;
-               if (mddev->queue) {
-                       set_capacity(mddev->gendisk, mddev->array_sectors);
-                       revalidate_disk(mddev->gendisk);
-               }
+               mddev->resync_max_sectors = mddev->array_sectors;
        } else {
                int d;
                rcu_read_lock();
index db2ac22ac1b42801a14e5eab8641109a3aa61505..e2e8840de9bfab734e9238bc59ca8e9058c7de0b 100644 (file)
@@ -2,6 +2,19 @@
 #ifndef _RAID10_H
 #define _RAID10_H
 
+/* Note: raid10_info.rdev can be set to NULL asynchronously by
+ * raid10_remove_disk.
+ * There are three safe ways to access raid10_info.rdev.
+ * 1/ when holding mddev->reconfig_mutex
+ * 2/ when resync/recovery/reshape is known to be happening - i.e. in code
+ *    that is called as part of performing resync/recovery/reshape.
+ * 3/ while holding rcu_read_lock(), use rcu_dereference to get the pointer
+ *    and if it is non-NULL, increment rdev->nr_pending before dropping the
+ *    RCU lock.
+ * When .rdev is set to NULL, the nr_pending count checked again and if it has
+ * been incremented, the pointer is put back in .rdev.
+ */
+
 struct raid10_info {
        struct md_rdev  *rdev, *replacement;
        sector_t        head_position;
index 0c76bcedfc1cbd8b0af33008652095e3862f22c9..a001808a2b77da16bc2ae3c1d4aa32b5f944a939 100644 (file)
@@ -44,6 +44,7 @@ extern void ppl_write_stripe_run(struct r5conf *conf);
 extern void ppl_stripe_write_finished(struct stripe_head *sh);
 extern int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add);
 extern void ppl_quiesce(struct r5conf *conf, int quiesce);
+extern int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio);
 
 static inline bool raid5_has_ppl(struct r5conf *conf)
 {
@@ -104,7 +105,7 @@ static inline int log_handle_flush_request(struct r5conf *conf, struct bio *bio)
        if (conf->log)
                ret = r5l_handle_flush_request(conf->log, bio);
        else if (raid5_has_ppl(conf))
-               ret = 0;
+               ret = ppl_handle_flush_request(conf->log, bio);
 
        return ret;
 }
index 2764c2290062862a607dca9145ef8f0e24cb5d89..42890a08375bc73b6bcdba7961e9c88062dded5d 100644 (file)
@@ -693,6 +693,16 @@ void ppl_quiesce(struct r5conf *conf, int quiesce)
        }
 }
 
+int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio)
+{
+       if (bio->bi_iter.bi_size == 0) {
+               bio_endio(bio);
+               return 0;
+       }
+       bio->bi_opf &= ~REQ_PREFLUSH;
+       return -EAGAIN;
+}
+
 void ppl_stripe_write_finished(struct stripe_head *sh)
 {
        struct ppl_io_unit *io;
index 50d01144b80535e2e937c16021cdeeba632b201e..b5d2601483e34fa97fc8cfb7faeff6f014c0e035 100644 (file)
@@ -2196,15 +2196,16 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t gfp)
 static int grow_stripes(struct r5conf *conf, int num)
 {
        struct kmem_cache *sc;
+       size_t namelen = sizeof(conf->cache_name[0]);
        int devs = max(conf->raid_disks, conf->previous_raid_disks);
 
        if (conf->mddev->gendisk)
-               sprintf(conf->cache_name[0],
+               snprintf(conf->cache_name[0], namelen,
                        "raid%d-%s", conf->level, mdname(conf->mddev));
        else
-               sprintf(conf->cache_name[0],
+               snprintf(conf->cache_name[0], namelen,
                        "raid%d-%p", conf->level, conf->mddev);
-       sprintf(conf->cache_name[1], "%s-alt", conf->cache_name[0]);
+       snprintf(conf->cache_name[1], namelen, "%.27s-alt", conf->cache_name[0]);
 
        conf->active_name = 0;
        sc = kmem_cache_create(conf->cache_name[conf->active_name],
@@ -6764,9 +6765,7 @@ static void free_conf(struct r5conf *conf)
 
        log_exit(conf);
 
-       if (conf->shrinker.nr_deferred)
-               unregister_shrinker(&conf->shrinker);
-
+       unregister_shrinker(&conf->shrinker);
        free_thread_groups(conf);
        shrink_stripes(conf);
        raid5_free_percpu(conf);
@@ -8001,13 +8000,7 @@ static void raid5_finish_reshape(struct mddev *mddev)
 
        if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
 
-               if (mddev->delta_disks > 0) {
-                       md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
-                       if (mddev->queue) {
-                               set_capacity(mddev->gendisk, mddev->array_sectors);
-                               revalidate_disk(mddev->gendisk);
-                       }
-               } else {
+               if (mddev->delta_disks <= 0) {
                        int d;
                        spin_lock_irq(&conf->device_lock);
                        mddev->degraded = raid5_calc_degraded(conf);
index 2e6123825095296555e8a73a52d63872f2fa2bff..3f8da26032accce9fdf492b58fc120a94ac31582 100644 (file)
@@ -450,6 +450,18 @@ enum {
  * HANDLE gets cleared if stripe_handle leaves nothing locked.
  */
 
+/* Note: disk_info.rdev can be set to NULL asynchronously by raid5_remove_disk.
+ * There are three safe ways to access disk_info.rdev.
+ * 1/ when holding mddev->reconfig_mutex
+ * 2/ when resync/recovery/reshape is known to be happening - i.e. in code that
+ *    is called as part of performing resync/recovery/reshape.
+ * 3/ while holding rcu_read_lock(), use rcu_dereference to get the pointer
+ *    and if it is non-NULL, increment rdev->nr_pending before dropping the RCU
+ *    lock.
+ * When .rdev is set to NULL, the nr_pending count checked again and if
+ * it has been incremented, the pointer is put back in .rdev.
+ */
+
 struct disk_info {
        struct md_rdev  *rdev, *replacement;
        struct page     *extra_page; /* extra page to use in prexor */
index 145e12bfb8190ab8274645c43493b9978fff6e1a..86c1a190d94684d1fef022227a138b557655bb55 100644 (file)
@@ -147,9 +147,11 @@ config DVB_CORE
 config DVB_MMAP
        bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
        depends on DVB_CORE
+       depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
+       select VIDEOBUF2_VMALLOC
        default n
        help
-         This option enables DVB experimental memory-mapped API, with
+         This option enables DVB experimental memory-mapped API, which
          reduces the number of context switches to read DVB buffers, as
          the buffers can use mmap() syscalls.
 
index 5df05250de947d7cf2bc396dc5104851f52fcb36..17c32ea58395d78f9fafe5525bbfbf1bdfe4b690 100644 (file)
@@ -3,6 +3,9 @@ config VIDEOBUF2_CORE
        select DMA_SHARED_BUFFER
        tristate
 
+config VIDEOBUF2_V4L2
+       tristate
+
 config VIDEOBUF2_MEMOPS
        tristate
        select FRAME_VECTOR
index 19de5ccda20b3c9de62a616077cfd11c6d743c58..77bebe8b202f46695ef239caaec98a567e088a03 100644 (file)
@@ -1,5 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+videobuf2-common-objs := videobuf2-core.o
 
-obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
+ifeq ($(CONFIG_TRACEPOINTS),y)
+  videobuf2-common-objs += vb2-trace.o
+endif
+
+obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-common.o
+obj-$(CONFIG_VIDEOBUF2_V4L2) += 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
diff --git a/drivers/media/common/videobuf2/vb2-trace.c b/drivers/media/common/videobuf2/vb2-trace.c
new file mode 100644 (file)
index 0000000..4c0f39d
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <media/videobuf2-core.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/vb2.h>
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf);
+EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf);
index 3a105d82019a0288b37f7a7143b1e8c79adffb42..62b028ded9f784438175969610608e60f35a9353 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
-dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o
+dvb-vb2-$(CONFIG_DVB_MMAP) := dvb_vb2.o
 
 dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o                 \
                 dvb_ca_en50221.o dvb_frontend.o                \
index 6d53af00190e396fda03bab661b56d4e4a1fc4a2..61a750fae4653be8da2ee47e60ae94e36e2143e6 100644 (file)
@@ -128,11 +128,7 @@ 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__);
 
@@ -144,17 +140,31 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
                return -ENODEV;
        }
 
-#ifndef DVB_MMAP
+       dmxdev->may_do_mmap = 0;
+
+       /*
+        * The logic here is a little tricky due to the ifdef.
+        *
+        * The ringbuffer is used for both read and mmap.
+        *
+        * It is not needed, however, on two situations:
+        *      - Write devices (access with O_WRONLY);
+        *      - For duplex device nodes, opened with O_RDWR.
+        */
+
        if ((file->f_flags & O_ACCMODE) == O_RDONLY)
                need_ringbuffer = true;
-#else
-       if ((file->f_flags & O_ACCMODE) == O_RDWR) {
+       else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
                if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
+#ifdef CONFIG_DVB_MMAP
+                       dmxdev->may_do_mmap = 1;
+                       need_ringbuffer = true;
+#else
                        mutex_unlock(&dmxdev->mutex);
                        return -EOPNOTSUPP;
+#endif
                }
        }
-#endif
 
        if (need_ringbuffer) {
                void *mem;
@@ -169,8 +179,9 @@ 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);
+               if (dmxdev->may_do_mmap)
+                       dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
+                                    file->f_flags & O_NONBLOCK);
                dvbdev->readers--;
        }
 
@@ -200,11 +211,6 @@ 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);
 
@@ -213,15 +219,14 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
                dmxdev->demux->connect_frontend(dmxdev->demux,
                                                dmxdev->dvr_orig_fe);
        }
-#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);
+       if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
+           dmxdev->may_do_mmap) {
+               if (dmxdev->may_do_mmap) {
+                       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;
@@ -380,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
 
 static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
                                       const u8 *buffer2, size_t buffer2_len,
-                                      struct dmx_section_filter *filter)
+                                      struct dmx_section_filter *filter,
+                                      u32 *buffer_flags)
 {
        struct dmxdev_filter *dmxdevfilter = filter->priv;
        int ret;
@@ -399,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
        dprintk("section callback %*ph\n", 6, buffer1);
        if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
                ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
-                                         buffer1, buffer1_len);
+                                         buffer1, buffer1_len,
+                                         buffer_flags);
                if (ret == buffer1_len)
                        ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
-                                                 buffer2, buffer2_len);
+                                                 buffer2, buffer2_len,
+                                                 buffer_flags);
        } else {
                ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
                                              buffer1, buffer1_len);
@@ -422,11 +430,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
 
 static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
                                  const u8 *buffer2, size_t buffer2_len,
-                                 struct dmx_ts_feed *feed)
+                                 struct dmx_ts_feed *feed,
+                                 u32 *buffer_flags)
 {
        struct dmxdev_filter *dmxdevfilter = feed->priv;
        struct dvb_ringbuffer *buffer;
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
        struct dvb_vb2_ctx *ctx;
 #endif
        int ret;
@@ -440,20 +449,22 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
        if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
            dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
                buffer = &dmxdevfilter->buffer;
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
                ctx = &dmxdevfilter->vb2_ctx;
 #endif
        } else {
                buffer = &dmxdevfilter->dev->dvr_buffer;
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
                ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
 #endif
        }
 
        if (dvb_vb2_is_streaming(ctx)) {
-               ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len);
+               ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,
+                                         buffer_flags);
                if (ret == buffer1_len)
-                       ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len);
+                       ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,
+                                                 buffer_flags);
        } else {
                if (buffer->error) {
                        spin_unlock(&dmxdevfilter->dev->lock);
@@ -802,6 +813,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
        mutex_init(&dmxdevfilter->mutex);
        file->private_data = dmxdevfilter;
 
+#ifdef CONFIG_DVB_MMAP
+       dmxdev->may_do_mmap = 1;
+#else
+       dmxdev->may_do_mmap = 0;
+#endif
+
        dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
        dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
                     file->f_flags & O_NONBLOCK);
@@ -1111,7 +1128,7 @@ static int dvb_demux_do_ioctl(struct file *file,
                mutex_unlock(&dmxdevfilter->mutex);
                break;
 
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
        case DMX_REQBUFS:
                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
                        mutex_unlock(&dmxdev->mutex);
@@ -1160,7 +1177,7 @@ static int dvb_demux_do_ioctl(struct file *file,
                break;
 #endif
        default:
-               ret = -EINVAL;
+               ret = -ENOTTY;
                break;
        }
        mutex_unlock(&dmxdev->mutex);
@@ -1199,13 +1216,16 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
        return mask;
 }
 
-#ifdef DVB_MMAP
+#ifdef CONFIG_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 (!dmxdev->may_do_mmap)
+               return -ENOTTY;
+
        if (mutex_lock_interruptible(&dmxdev->mutex))
                return -ERESTARTSYS;
 
@@ -1249,7 +1269,7 @@ static const struct file_operations dvb_demux_fops = {
        .release = dvb_demux_release,
        .poll = dvb_demux_poll,
        .llseek = default_llseek,
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
        .mmap = dvb_demux_mmap,
 #endif
 };
@@ -1280,7 +1300,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
                ret = dvb_dvr_set_buffer_size(dmxdev, arg);
                break;
 
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
        case DMX_REQBUFS:
                ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
                break;
@@ -1304,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
                break;
 #endif
        default:
-               ret = -EINVAL;
+               ret = -ENOTTY;
                break;
        }
        mutex_unlock(&dmxdev->mutex);
@@ -1322,11 +1342,6 @@ 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__);
 
@@ -1337,11 +1352,8 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
 
        poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
 
-#ifndef DVB_MMAP
-       if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-               need_ringbuffer = true;
-#endif
-       if (need_ringbuffer) {
+       if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
+           dmxdev->may_do_mmap) {
                if (dmxdev->dvr_buffer.error)
                        mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);
 
@@ -1353,13 +1365,16 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
        return mask;
 }
 
-#ifdef DVB_MMAP
+#ifdef CONFIG_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->may_do_mmap)
+               return -ENOTTY;
+
        if (dmxdev->exit)
                return -ENODEV;
 
@@ -1381,7 +1396,7 @@ static const struct file_operations dvb_dvr_fops = {
        .release = dvb_dvr_release,
        .poll = dvb_dvr_poll,
        .llseek = default_llseek,
-#ifdef DVB_MMAP
+#ifdef CONFIG_DVB_MMAP
        .mmap = dvb_dvr_mmap,
 #endif
 };
index 210eed0269b085d5b8c99d5f8941928cf0613a30..f45091246bdca90d870dc0a10bd35e8fd4d73eea 100644 (file)
@@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
                dprintk(x);                             \
 } while (0)
 
+#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
+#  define dprintk_sect_loss(x...) dprintk(x)
+#else
+#  define dprintk_sect_loss(x...)
+#endif
+
+#define set_buf_flags(__feed, __flag)                  \
+       do {                                            \
+               (__feed)->buffer_flags |= (__flag);     \
+       } while (0)
+
 /******************************************************************************
  * static inlined helper functions
  ******************************************************************************/
@@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
 {
        int count = payload(buf);
        int p;
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
        int ccok;
        u8 cc;
-#endif
 
        if (count == 0)
                return -1;
 
        p = 188 - count;
 
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
        cc = buf[3] & 0x0f;
        ccok = ((feed->cc + 1) & 0x0f) == cc;
        feed->cc = cc;
-       if (!ccok)
-               dprintk("missed packet: %d instead of %d!\n",
-                       cc, (feed->cc + 1) & 0x0f);
-#endif
+       if (!ccok) {
+               set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
+               dprintk_sect_loss("missed packet: %d instead of %d!\n",
+                                 cc, (feed->cc + 1) & 0x0f);
+       }
 
        if (buf[1] & 0x40)      // PUSI ?
                feed->peslen = 0xfffa;
 
        feed->peslen += count;
 
-       return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts);
+       return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts,
+                          &feed->buffer_flags);
 }
 
 static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
@@ -150,7 +160,7 @@ static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
                return 0;
 
        return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen,
-                           NULL, 0, &f->filter);
+                           NULL, 0, &f->filter, &feed->buffer_flags);
 }
 
 static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
@@ -169,8 +179,10 @@ static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed)
        if (sec->check_crc) {
                section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
                if (section_syntax_indicator &&
-                   demux->check_crc32(feed, sec->secbuf, sec->seclen))
+                   demux->check_crc32(feed, sec->secbuf, sec->seclen)) {
+                       set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD);
                        return -1;
+               }
        }
 
        do {
@@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
 {
        struct dmx_section_feed *sec = &feed->feed.sec;
 
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
        if (sec->secbufp < sec->tsfeedp) {
                int n = sec->tsfeedp - sec->secbufp;
 
@@ -197,12 +208,13 @@ 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("section ts padding loss: %d/%d\n",
-                              n, sec->tsfeedp);
-                       dprintk("pad data: %*ph\n", n, sec->secbuf);
+                       set_buf_flags(feed,
+                                     DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
+                       dprintk_sect_loss("section ts padding loss: %d/%d\n",
+                                         n, sec->tsfeedp);
+                       dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf);
                }
        }
-#endif
 
        sec->tsfeedp = sec->secbufp = sec->seclen = 0;
        sec->secbuf = sec->secbuf_base;
@@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
                return 0;
 
        if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
-               dprintk("section buffer full loss: %d/%d\n",
-                       sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
-                       DMX_MAX_SECFEED_SIZE);
-#endif
+               set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
+               dprintk_sect_loss("section buffer full loss: %d/%d\n",
+                                 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
+                                 DMX_MAX_SECFEED_SIZE);
                len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
        }
 
@@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
                sec->seclen = seclen;
                sec->crc_val = ~0;
                /* dump [secbuf .. secbuf+seclen) */
-               if (feed->pusi_seen)
+               if (feed->pusi_seen) {
                        dvb_dmx_swfilter_section_feed(feed);
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
-               else
-                       dprintk("pusi not seen, discarding section data\n");
-#endif
+               } else {
+                       set_buf_flags(feed,
+                                     DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
+                       dprintk_sect_loss("pusi not seen, discarding section data\n");
+               }
                sec->secbufp += seclen; /* secbufp and secbuf moving together is */
                sec->secbuf += seclen;  /* redundant but saves pointer arithmetic */
        }
@@ -307,18 +319,22 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
        }
 
        if (!ccok || dc_i) {
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
-               if (dc_i)
-                       dprintk("%d frame with disconnect indicator\n",
+               if (dc_i) {
+                       set_buf_flags(feed,
+                                     DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR);
+                       dprintk_sect_loss("%d frame with disconnect indicator\n",
                                cc);
-               else
-                       dprintk("discontinuity: %d instead of %d. %d bytes lost\n",
+               } else {
+                       set_buf_flags(feed,
+                                     DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
+                       dprintk_sect_loss("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
+                * those bytes under some circumstances will again be reported
                 * in the following dvb_dmx_swfilter_section_new
                 */
-#endif
+
                /*
                 * Discontinuity detected. Reset pusi_seen to
                 * stop feeding of suspicious data until next PUSI=1 arrives
@@ -326,6 +342,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
                 * FIXME: does it make sense if the MPEG-TS is the one
                 *      reporting discontinuity?
                 */
+
                feed->pusi_seen = false;
                dvb_dmx_swfilter_section_new(feed);
        }
@@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
                        dvb_dmx_swfilter_section_new(feed);
                        dvb_dmx_swfilter_section_copy_dump(feed, after,
                                                           after_len);
+               } else if (count > 0) {
+                       set_buf_flags(feed,
+                                     DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
+                       dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count);
                }
-#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
-               else if (count > 0)
-                       dprintk("PUSI=1 but %d bytes lost\n", count);
-#endif
        } else {
                /* PUSI=0 (is not set), no section boundary */
                dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count);
@@ -369,7 +386,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
                        if (feed->ts_type & TS_PAYLOAD_ONLY)
                                dvb_dmx_swfilter_payload(feed, buf);
                        else
-                               feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
+                               feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
+                                           &feed->buffer_flags);
                }
                /* Used only on full-featured devices */
                if (feed->ts_type & TS_DECODER)
@@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
        }
 
        if (buf[1] & 0x80) {
+               list_for_each_entry(feed, &demux->feed_list, list_head) {
+                       if ((feed->pid != pid) && (feed->pid != 0x2000))
+                               continue;
+                       set_buf_flags(feed, DMX_BUFFER_FLAG_TEI);
+               }
                dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n",
                                pid, buf[1]);
                /* data in this packet can't be trusted - drop it unless
@@ -445,6 +468,13 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
                                                (demux->cnt_storage[pid] + 1) & 0xf;
 
                                if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
+                                       list_for_each_entry(feed, &demux->feed_list, list_head) {
+                                               if ((feed->pid != pid) && (feed->pid != 0x2000))
+                                                       continue;
+                                               set_buf_flags(feed,
+                                                             DMX_BUFFER_PKT_COUNTER_MISMATCH);
+                                       }
+
                                        dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
                                                        pid, demux->cnt_storage[pid],
                                                        buf[3] & 0xf);
@@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
                if (feed->pid == pid)
                        dvb_dmx_swfilter_packet_type(feed, buf);
                else if (feed->pid == 0x2000)
-                       feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
+                       feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts,
+                                   &feed->buffer_flags);
        }
 }
 
@@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
 
        spin_lock_irqsave(&demux->lock, flags);
 
-       demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts);
+       demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts,
+                          &demux->feed->buffer_flags);
 
        spin_unlock_irqrestore(&demux->lock, flags);
 }
@@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
        feed->demux = demux;
        feed->pid = 0xffff;
        feed->peslen = 0xfffa;
+       feed->buffer_flags = 0;
 
        (*ts_feed) = &feed->feed.ts;
        (*ts_feed)->parent = dmx;
@@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
        dvbdmxfeed->cb.sec = callback;
        dvbdmxfeed->demux = dvbdmx;
        dvbdmxfeed->pid = 0xffff;
+       dvbdmxfeed->buffer_flags = 0;
        dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
        dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
        dvbdmxfeed->feed.sec.tsfeedp = 0;
index b6c7eec863b9232b5fb30d07b809a01298d85c22..ba39f9942e1db06f0eeadc6473287f641ff4af85 100644 (file)
@@ -883,7 +883,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
 
 static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
                               const u8 *buffer2, size_t buffer2_len,
-                              struct dmx_ts_feed *feed)
+                              struct dmx_ts_feed *feed,
+                              u32 *buffer_flags)
 {
        struct net_device *dev = feed->priv;
 
@@ -992,7 +993,7 @@ static void dvb_net_sec(struct net_device *dev,
 
 static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
                 const u8 *buffer2, size_t buffer2_len,
-                struct dmx_section_filter *filter)
+                struct dmx_section_filter *filter, u32 *buffer_flags)
 {
        struct net_device *dev = filter->priv;
 
index 763145d74e836aba5ae400e20522cce0c84a308d..b811adf88afa3424d14b6584969928d2b5cdae54 100644 (file)
@@ -256,7 +256,8 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx)
 }
 
 int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
-                       const unsigned char *src, int len)
+                       const unsigned char *src, int len,
+                       enum dmx_buffer_flags *buffer_flags)
 {
        unsigned long flags = 0;
        void *vbuf = NULL;
@@ -264,15 +265,17 @@ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
        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
-                */
+       /*
+        * normal case: This func is called twice from demux driver
+        * one with valid src pointer, second time with NULL pointer
+        */
+       if (!src || !len)
                return 0;
-       }
        spin_lock_irqsave(&ctx->slock, flags);
+       if (buffer_flags && *buffer_flags) {
+               ctx->flags |= *buffer_flags;
+               *buffer_flags = 0;
+       }
        while (todo) {
                if (!ctx->buf) {
                        if (list_empty(&ctx->dvb_q)) {
@@ -395,6 +398,7 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
 
 int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
 {
+       unsigned long flags;
        int ret;
 
        ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
@@ -402,7 +406,16 @@ int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
                dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
                return ret;
        }
-       dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
+
+       spin_lock_irqsave(&ctx->slock, flags);
+       b->count = ctx->count++;
+       b->flags = ctx->flags;
+       ctx->flags = 0;
+       spin_unlock_irqrestore(&ctx->slock, flags);
+
+       dprintk(5, "[%s] index=%d, count=%d, flags=%d\n",
+               ctx->name, b->index, ctx->count, b->flags);
+
 
        return 0;
 }
index 50bce68ffd6646526fa86e1eaa5c65692b02a7b6..65d157fe76d19dad45ac94fa9eb21cbdad5dd575 100644 (file)
@@ -1262,11 +1262,12 @@ static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan)
  * New users must use I2C client binding directly!
  */
 struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
-               struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter)
+                                     struct i2c_adapter *i2c,
+                                     struct i2c_adapter **tuner_i2c_adapter)
 {
        struct i2c_client *client;
        struct i2c_board_info board_info;
-       struct m88ds3103_platform_data pdata;
+       struct m88ds3103_platform_data pdata = {};
 
        pdata.clk = cfg->clock;
        pdata.i2c_wr_max = cfg->i2c_wr_max;
@@ -1409,6 +1410,8 @@ static int m88ds3103_probe(struct i2c_client *client,
        case M88DS3103_CHIP_ID:
                break;
        default:
+               ret = -ENODEV;
+               dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id);
                goto err_kfree;
        }
 
index 3c1851984b907a54b22920dec24e865731006f96..2476d812f669476a286672de807009df8f4980fb 100644 (file)
@@ -505,80 +505,77 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
        /* FIXME: Current api doesn't handle all VBI types, those not
           yet supported are placed under #if 0 */
 #if 0
-       {0x010, /* Teletext, SECAM, WST System A */
+       [0] = {0x010, /* Teletext, SECAM, WST System A */
                {V4L2_SLICED_TELETEXT_SECAM,6,23,1},
                { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26,
                  0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
 #endif
-       {0x030, /* Teletext, PAL, WST System B */
+       [1] = {0x030, /* Teletext, PAL, WST System B */
                {V4L2_SLICED_TELETEXT_B,6,22,1},
                { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b,
                  0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
 #if 0
-       {0x050, /* Teletext, PAL, WST System C */
+       [2] = {0x050, /* Teletext, PAL, WST System C */
                {V4L2_SLICED_TELETEXT_PAL_C,6,22,1},
                { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
                  0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x070, /* Teletext, NTSC, WST System B */
+       [3] = {0x070, /* Teletext, NTSC, WST System B */
                {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1},
                { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23,
                  0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x090, /* Tetetext, NTSC NABTS System C */
+       [4] = {0x090, /* Tetetext, NTSC NABTS System C */
                {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1},
                { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22,
                  0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 }
        },
-       {0x0b0, /* Teletext, NTSC-J, NABTS System D */
+       [5] = {0x0b0, /* Teletext, NTSC-J, NABTS System D */
                {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1},
                { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23,
                  0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 }
        },
-       {0x0d0, /* Closed Caption, PAL/SECAM */
+       [6] = {0x0d0, /* Closed Caption, PAL/SECAM */
                {V4L2_SLICED_CAPTION_625,22,22,1},
                { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
                  0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
        },
 #endif
-       {0x0f0, /* Closed Caption, NTSC */
+       [7] = {0x0f0, /* Closed Caption, NTSC */
                {V4L2_SLICED_CAPTION_525,21,21,1},
                { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02,
                  0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 }
        },
-       {0x110, /* Wide Screen Signal, PAL/SECAM */
+       [8] = {0x110, /* Wide Screen Signal, PAL/SECAM */
                {V4L2_SLICED_WSS_625,23,23,1},
                { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42,
                  0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 }
        },
 #if 0
-       {0x130, /* Wide Screen Signal, NTSC C */
+       [9] = {0x130, /* Wide Screen Signal, NTSC C */
                {V4L2_SLICED_WSS_525,20,20,1},
                { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43,
                  0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 }
        },
-       {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
+       [10] = {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */
                {V4l2_SLICED_VITC_625,6,22,0},
                { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
                  0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
        },
-       {0x170, /* Vertical Interval Timecode (VITC), NTSC */
+       [11] = {0x170, /* Vertical Interval Timecode (VITC), NTSC */
                {V4l2_SLICED_VITC_525,10,20,0},
                { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49,
                  0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 }
        },
 #endif
-       {0x190, /* Video Program System (VPS), PAL */
+       [12] = {0x190, /* Video Program System (VPS), PAL */
                {V4L2_SLICED_VPS,16,16,0},
                { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d,
                  0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 }
        },
        /* 0x1d0 User programmable */
-
-       /* End of struct */
-       { (u16)-1 }
 };
 
 static int tvp5150_write_inittab(struct v4l2_subdev *sd,
@@ -591,10 +588,10 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd,
        return 0;
 }
 
-static int tvp5150_vdp_init(struct v4l2_subdev *sd,
-                               const struct i2c_vbi_ram_value *regs)
+static int tvp5150_vdp_init(struct v4l2_subdev *sd)
 {
        unsigned int i;
+       int j;
 
        /* Disable Full Field */
        tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
@@ -604,14 +601,17 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd,
                tvp5150_write(sd, i, 0xff);
 
        /* Load Ram Table */
-       while (regs->reg != (u16)-1) {
+       for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) {
+               const struct i2c_vbi_ram_value *regs = &vbi_ram_default[j];
+
+               if (!regs->type.vbi_type)
+                       continue;
+
                tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
                tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
 
                for (i = 0; i < 16; i++)
                        tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
-
-               regs++;
        }
        return 0;
 }
@@ -620,19 +620,23 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd,
 static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
                                struct v4l2_sliced_vbi_cap *cap)
 {
-       const struct i2c_vbi_ram_value *regs = vbi_ram_default;
-       int line;
+       int line, i;
 
        dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n");
        memset(cap, 0, sizeof *cap);
 
-       while (regs->reg != (u16)-1 ) {
-               for (line=regs->type.ini_line;line<=regs->type.end_line;line++) {
+       for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) {
+               const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i];
+
+               if (!regs->type.vbi_type)
+                       continue;
+
+               for (line = regs->type.ini_line;
+                    line <= regs->type.end_line;
+                    line++) {
                        cap->service_lines[0][line] |= regs->type.vbi_type;
                }
                cap->service_set |= regs->type.vbi_type;
-
-               regs++;
        }
        return 0;
 }
@@ -651,14 +655,13 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
  *     MSB = field2
  */
 static int tvp5150_set_vbi(struct v4l2_subdev *sd,
-                       const struct i2c_vbi_ram_value *regs,
                        unsigned int type,u8 flags, int line,
                        const int fields)
 {
        struct tvp5150 *decoder = to_tvp5150(sd);
        v4l2_std_id std = decoder->norm;
        u8 reg;
-       int pos = 0;
+       int i, pos = 0;
 
        if (std == V4L2_STD_ALL) {
                dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n");
@@ -671,19 +674,19 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
        if (line < 6 || line > 27)
                return 0;
 
-       while (regs->reg != (u16)-1) {
+       for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) {
+               const struct i2c_vbi_ram_value *regs =  &vbi_ram_default[i];
+
+               if (!regs->type.vbi_type)
+                       continue;
+
                if ((type & regs->type.vbi_type) &&
                    (line >= regs->type.ini_line) &&
                    (line <= regs->type.end_line))
                        break;
-
-               regs++;
                pos++;
        }
 
-       if (regs->reg == (u16)-1)
-               return 0;
-
        type = pos | (flags & 0xf0);
        reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
 
@@ -696,8 +699,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
        return type;
 }
 
-static int tvp5150_get_vbi(struct v4l2_subdev *sd,
-                       const struct i2c_vbi_ram_value *regs, int line)
+static int tvp5150_get_vbi(struct v4l2_subdev *sd, int line)
 {
        struct tvp5150 *decoder = to_tvp5150(sd);
        v4l2_std_id std = decoder->norm;
@@ -726,8 +728,8 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd,
                        return 0;
                }
                pos = ret & 0x0f;
-               if (pos < 0x0f)
-                       type |= regs[pos].type.vbi_type;
+               if (pos < ARRAY_SIZE(vbi_ram_default))
+                       type |= vbi_ram_default[pos].type.vbi_type;
        }
 
        return type;
@@ -788,7 +790,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
        tvp5150_write_inittab(sd, tvp5150_init_default);
 
        /* Initializes VDP registers */
-       tvp5150_vdp_init(sd, vbi_ram_default);
+       tvp5150_vdp_init(sd);
 
        /* Selects decoder input */
        tvp5150_selmux(sd);
@@ -1121,8 +1123,8 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
                for (i = 0; i <= 23; i++) {
                        svbi->service_lines[1][i] = 0;
                        svbi->service_lines[0][i] =
-                               tvp5150_set_vbi(sd, vbi_ram_default,
-                                      svbi->service_lines[0][i], 0xf0, i, 3);
+                               tvp5150_set_vbi(sd, svbi->service_lines[0][i],
+                                               0xf0, i, 3);
                }
                /* Enables FIFO */
                tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
@@ -1148,7 +1150,7 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
 
        for (i = 0; i <= 23; i++) {
                svbi->service_lines[0][i] =
-                       tvp5150_get_vbi(sd, vbi_ram_default, i);
+                       tvp5150_get_vbi(sd, i);
                mask |= svbi->service_lines[0][i];
        }
        svbi->service_set = mask;
index dc8e577b2f748a4d287dacaf817beed1096e903e..d6816effb87866b80eae57d7c45004524d8cc031 100644 (file)
@@ -324,14 +324,15 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
                }
                return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
                                                  buffer2, buffer2_len,
-                                                 &dvbdmxfilter->filter);
+                                                 &dvbdmxfilter->filter, NULL);
        case DMX_TYPE_TS:
                if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
                        return 0;
                if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
                        return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
                                                         buffer2, buffer2_len,
-                                                        &dvbdmxfilter->feed->feed.ts);
+                                                        &dvbdmxfilter->feed->feed.ts,
+                                                        NULL);
                else
                        av7110_p2t_write(buffer1, buffer1_len,
                                         dvbdmxfilter->feed->pid,
index 4daba76ec240bc382e3b48e17f3d1cbafaaa6858..ef1bc17cdc4d37a8549b86d7085a8fdfd76abca3 100644 (file)
@@ -99,7 +99,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
                buf[4] = buf[5] = 0;
        if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
                return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
-                                        &dvbdmxfeed->feed.ts);
+                                        &dvbdmxfeed->feed.ts, NULL);
        else
                return dvb_filter_pes2ts(p2t, buf, len, 1);
 }
@@ -109,7 +109,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
        struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
 
        dvbdmxfeed->cb.ts(data, 188, NULL, 0,
-                         &dvbdmxfeed->feed.ts);
+                         &dvbdmxfeed->feed.ts, NULL);
        return 0;
 }
 
@@ -814,7 +814,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
                        memcpy(obuf + l, buf + c, TS_SIZE - l);
                        c = length;
                }
-               feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts);
+               feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, NULL);
                pes_start = 0;
        }
 }
index 92f93a88001588146206603adee10d8cd1ca58cd..aba488cd0e645721b381f9b3a8b3e7f9ab57b429 100644 (file)
@@ -172,16 +172,13 @@ static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
                }
        }
 
-       if (status & (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
-                     TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
-                     TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
-                     TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)) {
+       if (status & TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED) {
                cec_write(cec, TEGRA_CEC_INT_STAT,
-                         (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
-                          TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
-                          TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
-                          TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED));
-       } else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
+                         TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED);
+               cec->rx_done = false;
+               cec->rx_buf_cnt = 0;
+       }
+       if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
                u32 v;
 
                cec_write(cec, TEGRA_CEC_INT_STAT,
@@ -255,7 +252,7 @@ static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable)
                  TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
                  TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
                  TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
-                 TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN);
+                 TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED);
 
        cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE);
        return 0;
index 70521e0b4c5348b6a1ab563e122b557fb58c111b..bfaa806633df740ee72047d5ea81158eedfcb4b0 100644 (file)
@@ -1,7 +1,7 @@
 
 config VIDEO_AU0828
        tristate "Auvitek AU0828 support"
-       depends on I2C && INPUT && DVB_CORE && USB
+       depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
        select I2C_ALGOBIT
        select VIDEO_TVEEPROM
        select VIDEOBUF2_VMALLOC
index a8900f5571f784014d273eb29058fa04ca08a55c..44ca66cb9b8f141e15d7ca0ccc0b7ae5c2abee60 100644 (file)
@@ -428,7 +428,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
        struct ttusb_dec *dec = priv;
 
        dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
-                                      &dec->audio_filter->feed->feed.ts);
+                                      &dec->audio_filter->feed->feed.ts, NULL);
 
        return 0;
 }
@@ -438,7 +438,7 @@ static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
        struct ttusb_dec *dec = priv;
 
        dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
-                                      &dec->video_filter->feed->feed.ts);
+                                      &dec->video_filter->feed->feed.ts, NULL);
 
        return 0;
 }
@@ -490,7 +490,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
 
                if (output_pva) {
                        dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
-                               &dec->video_filter->feed->feed.ts);
+                               &dec->video_filter->feed->feed.ts, NULL);
                        return;
                }
 
@@ -551,7 +551,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
        case 0x02:              /* MainAudioStream */
                if (output_pva) {
                        dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
-                               &dec->audio_filter->feed->feed.ts);
+                               &dec->audio_filter->feed->feed.ts, NULL);
                        return;
                }
 
@@ -589,7 +589,7 @@ static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
 
        if (filter)
                filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
-                                    &filter->filter);
+                                    &filter->filter, NULL);
 }
 
 static void ttusb_dec_process_packet(struct ttusb_dec *dec)
index bf52fbd07aeddc3f228cef870d05e9622699bd03..8e37e7c5e0f7e25aca250b8b052f274f2b8f3c09 100644 (file)
@@ -7,6 +7,7 @@ config VIDEO_V4L2
        tristate
        depends on (I2C || I2C=n) && VIDEO_DEV
        select RATIONAL
+       select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
        default (I2C || I2C=n) && VIDEO_DEV
 
 config VIDEO_ADV_DEBUG
index 80de2cb9c476a256634815155a4d033a428228af..7df54582e95689ef2c189652dd5c33ea735a8023 100644 (file)
@@ -13,7 +13,7 @@ ifeq ($(CONFIG_COMPAT),y)
 endif
 obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
 ifeq ($(CONFIG_TRACEPOINTS),y)
-  videodev-objs += vb2-trace.o v4l2-trace.o
+  videodev-objs += v4l2-trace.o
 endif
 videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o
 
@@ -35,4 +35,3 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/tuners
-
diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/v4l2-core/vb2-trace.c
deleted file mode 100644 (file)
index 4c0f39d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <media/videobuf2-core.h>
-
-#define CREATE_TRACE_POINTS
-#include <trace/events/vb2.h>
-
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_done);
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_buf_queue);
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_dqbuf);
-EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_qbuf);
index 0a7bdbed3a6f0185ce35ec49d2e6ccce80592a9c..e9c1485c32b95c66c670e698557632964a946072 100644 (file)
 #define REG_TO_DCPU_MBOX       0x10
 #define REG_TO_HOST_MBOX       0x14
 
+/* Macros to process offsets returned by the DCPU */
+#define DRAM_MSG_ADDR_OFFSET   0x0
+#define DRAM_MSG_TYPE_OFFSET   0x1c
+#define DRAM_MSG_ADDR_MASK     ((1UL << DRAM_MSG_TYPE_OFFSET) - 1)
+#define DRAM_MSG_TYPE_MASK     ((1UL << \
+                                (BITS_PER_LONG - DRAM_MSG_TYPE_OFFSET)) - 1)
+
 /* Message RAM */
-#define DCPU_MSG_RAM(x)                (0x100 + (x) * sizeof(u32))
+#define DCPU_MSG_RAM_START     0x100
+#define DCPU_MSG_RAM(x)                (DCPU_MSG_RAM_START + (x) * sizeof(u32))
 
 /* DRAM Info Offsets & Masks */
 #define DRAM_INFO_INTERVAL     0x0
@@ -255,6 +263,40 @@ static unsigned int get_msg_chksum(const u32 msg[])
        return sum;
 }
 
+static void __iomem *get_msg_ptr(struct private_data *priv, u32 response,
+                                char *buf, ssize_t *size)
+{
+       unsigned int msg_type;
+       unsigned int offset;
+       void __iomem *ptr = NULL;
+
+       msg_type = (response >> DRAM_MSG_TYPE_OFFSET) & DRAM_MSG_TYPE_MASK;
+       offset = (response >> DRAM_MSG_ADDR_OFFSET) & DRAM_MSG_ADDR_MASK;
+
+       /*
+        * msg_type == 1: the offset is relative to the message RAM
+        * msg_type == 0: the offset is relative to the data RAM (this is the
+        *                previous way of passing data)
+        * msg_type is anything else: there's critical hardware problem
+        */
+       switch (msg_type) {
+       case 1:
+               ptr = priv->regs + DCPU_MSG_RAM_START + offset;
+               break;
+       case 0:
+               ptr = priv->dmem + offset;
+               break;
+       default:
+               dev_emerg(priv->dev, "invalid message reply from DCPU: %#x\n",
+                       response);
+               if (buf && size)
+                       *size = sprintf(buf,
+                               "FATAL: communication error with DCPU\n");
+       }
+
+       return ptr;
+}
+
 static int __send_command(struct private_data *priv, unsigned int cmd,
                          u32 result[])
 {
@@ -507,7 +549,7 @@ static ssize_t show_info(struct device *dev, struct device_attribute *devattr,
 {
        u32 response[MSG_FIELD_MAX];
        unsigned int info;
-       int ret;
+       ssize_t ret;
 
        ret = generic_show(DPFE_CMD_GET_INFO, response, dev, buf);
        if (ret)
@@ -528,18 +570,19 @@ static ssize_t show_refresh(struct device *dev,
        u32 response[MSG_FIELD_MAX];
        void __iomem *info;
        struct private_data *priv;
-       unsigned int offset;
        u8 refresh, sr_abort, ppre, thermal_offs, tuf;
        u32 mr4;
-       int ret;
+       ssize_t ret;
 
        ret = generic_show(DPFE_CMD_GET_REFRESH, response, dev, buf);
        if (ret)
                return ret;
 
        priv = dev_get_drvdata(dev);
-       offset = response[MSG_ARG0];
-       info = priv->dmem + offset;
+
+       info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret);
+       if (!info)
+               return ret;
 
        mr4 = readl_relaxed(info + DRAM_INFO_MR4) & DRAM_INFO_MR4_MASK;
 
@@ -561,7 +604,6 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
        u32 response[MSG_FIELD_MAX];
        struct private_data *priv;
        void __iomem *info;
-       unsigned int offset;
        unsigned long val;
        int ret;
 
@@ -574,8 +616,10 @@ static ssize_t store_refresh(struct device *dev, struct device_attribute *attr,
        if (ret)
                return ret;
 
-       offset = response[MSG_ARG0];
-       info = priv->dmem + offset;
+       info = get_msg_ptr(priv, response[MSG_ARG0], NULL, NULL);
+       if (!info)
+               return -EIO;
+
        writel_relaxed(val, info + DRAM_INFO_INTERVAL);
 
        return count;
@@ -587,23 +631,25 @@ static ssize_t show_vendor(struct device *dev, struct device_attribute *devattr,
        u32 response[MSG_FIELD_MAX];
        struct private_data *priv;
        void __iomem *info;
-       unsigned int offset;
-       int ret;
+       ssize_t ret;
 
        ret = generic_show(DPFE_CMD_GET_VENDOR, response, dev, buf);
        if (ret)
                return ret;
 
-       offset = response[MSG_ARG0];
        priv = dev_get_drvdata(dev);
-       info = priv->dmem + offset;
+
+       info = get_msg_ptr(priv, response[MSG_ARG0], buf, &ret);
+       if (!info)
+               return ret;
 
        return sprintf(buf, "%#x %#x %#x %#x %#x\n",
                       readl_relaxed(info + DRAM_VENDOR_MR5) & DRAM_VENDOR_MASK,
                       readl_relaxed(info + DRAM_VENDOR_MR6) & DRAM_VENDOR_MASK,
                       readl_relaxed(info + DRAM_VENDOR_MR7) & DRAM_VENDOR_MASK,
                       readl_relaxed(info + DRAM_VENDOR_MR8) & DRAM_VENDOR_MASK,
-                      readl_relaxed(info + DRAM_VENDOR_ERROR));
+                      readl_relaxed(info + DRAM_VENDOR_ERROR) &
+                                    DRAM_VENDOR_MASK);
 }
 
 static int brcmstb_dpfe_resume(struct platform_device *pdev)
index 8d12017b9893a2bf0a6f2aefd7d62acca22d939a..4470630dd54552032a3d92dc73c101289ab62d41 100644 (file)
@@ -2687,6 +2687,8 @@ mptctl_hp_targetinfo(unsigned long arg)
                                __FILE__, __LINE__, iocnum);
                return -ENODEV;
        }
+       if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
+               return -EINVAL;
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
            ioc->name));
 
index 3e5eabdae8d968d92ac9cedd5c83225267513126..772d02922529e2722184d23df7e65891f1b2b596 100644 (file)
@@ -548,12 +548,6 @@ int mei_cldev_disable(struct mei_cl_device *cldev)
                goto out;
        }
 
-       if (bus->dev_state == MEI_DEV_POWER_DOWN) {
-               dev_dbg(bus->dev, "Device is powering down, don't bother with disconnection\n");
-               err = 0;
-               goto out;
-       }
-
        err = mei_cl_disconnect(cl);
        if (err < 0)
                dev_err(bus->dev, "Could not disconnect from the ME client\n");
index be64969d986abcd6e6da6fcec6bb2f019b404a22..7e60c1817c311e0b54a0711c116adb8eea89cf00 100644 (file)
@@ -945,6 +945,12 @@ int mei_cl_disconnect(struct mei_cl *cl)
                return 0;
        }
 
+       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+               cl_dbg(dev, cl, "Device is powering down, don't bother with disconnection\n");
+               mei_cl_set_disconnected(cl);
+               return 0;
+       }
+
        rets = pm_runtime_get(dev->dev);
        if (rets < 0 && rets != -EINPROGRESS) {
                pm_runtime_put_noidle(dev->dev);
index 0ccccbaf530d258a08acf633d34d9861c630ba64..e4b10b2d1a0838af03f16f29922b86c653cf99ba 100644 (file)
 #define MEI_DEV_ID_KBP        0xA2BA  /* Kaby Point */
 #define MEI_DEV_ID_KBP_2      0xA2BB  /* Kaby Point 2 */
 
+#define MEI_DEV_ID_CNP_LP     0x9DE0  /* Cannon Point LP */
+#define MEI_DEV_ID_CNP_LP_4   0x9DE4  /* Cannon Point LP 4 (iTouch) */
+#define MEI_DEV_ID_CNP_H      0xA360  /* Cannon Point H */
+#define MEI_DEV_ID_CNP_H_4    0xA364  /* Cannon Point H 4 (iTouch) */
+
 /*
  * MEI HW Section
  */
index 4a0ccda4d04b9a898c4cd3163ada9d94f581242e..ea4e152270a3b0270b1dc23edd8c3620af0ffd26 100644 (file)
@@ -98,6 +98,11 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
        {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)},
        {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)},
 
+       {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH8_CFG)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_4, MEI_ME_PCH8_CFG)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH8_CFG)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)},
+
        /* required last entry */
        {0, }
 };
index d9aa407db06a11acd4c369b993c242c6a5bac3bd..038509e5d031f44e99fee275c59b7b08421c9f29 100644 (file)
@@ -102,10 +102,32 @@ static long afu_ioctl_attach(struct ocxl_context *ctx,
        return rc;
 }
 
+static long afu_ioctl_get_metadata(struct ocxl_context *ctx,
+               struct ocxl_ioctl_metadata __user *uarg)
+{
+       struct ocxl_ioctl_metadata arg;
+
+       memset(&arg, 0, sizeof(arg));
+
+       arg.version = 0;
+
+       arg.afu_version_major = ctx->afu->config.version_major;
+       arg.afu_version_minor = ctx->afu->config.version_minor;
+       arg.pasid = ctx->pasid;
+       arg.pp_mmio_size = ctx->afu->config.pp_mmio_stride;
+       arg.global_mmio_size = ctx->afu->config.global_mmio_size;
+
+       if (copy_to_user(uarg, &arg, sizeof(arg)))
+               return -EFAULT;
+
+       return 0;
+}
+
 #define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" :                        \
                        x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" :       \
                        x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" :         \
                        x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" :     \
+                       x == OCXL_IOCTL_GET_METADATA ? "GET_METADATA" : \
                        "UNKNOWN")
 
 static long afu_ioctl(struct file *file, unsigned int cmd,
@@ -133,8 +155,10 @@ static long afu_ioctl(struct file *file, unsigned int cmd,
                if (!rc) {
                        rc = copy_to_user((u64 __user *) args, &irq_offset,
                                        sizeof(irq_offset));
-                       if (rc)
+                       if (rc) {
                                ocxl_afu_irq_free(ctx, irq_offset);
+                               return -EFAULT;
+                       }
                }
                break;
 
@@ -157,6 +181,11 @@ static long afu_ioctl(struct file *file, unsigned int cmd,
                                        irq_fd.eventfd);
                break;
 
+       case OCXL_IOCTL_GET_METADATA:
+               rc = afu_ioctl_get_metadata(ctx,
+                               (struct ocxl_ioctl_metadata __user *) args);
+               break;
+
        default:
                rc = -EINVAL;
        }
@@ -277,7 +306,7 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
        struct ocxl_context *ctx = file->private_data;
        struct ocxl_kernel_event_header header;
        ssize_t rc;
-       size_t used = 0;
+       ssize_t used = 0;
        DEFINE_WAIT(event_wait);
 
        memset(&header, 0, sizeof(header));
@@ -329,7 +358,7 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
 
        used += sizeof(header);
 
-       rc = (ssize_t) used;
+       rc = used;
        return rc;
 }
 
index 20135a5de748846ec9101b5b88860d6da3c3850e..2cfb963d9f379ed5a29c6d357430f7dd3a1a4a79 100644 (file)
@@ -72,6 +72,7 @@ MODULE_ALIAS("mmc:block");
 #define MMC_BLK_TIMEOUT_MS  (10 * 1000)
 #define MMC_SANITIZE_REQ_TIMEOUT 240000
 #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
+#define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8)
 
 #define mmc_req_rel_wr(req)    ((req->cmd_flags & REQ_FUA) && \
                                  (rq_data_dir(req) == WRITE))
@@ -586,6 +587,24 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
                return data.error;
        }
 
+       /*
+        * Make sure the cache of the PARTITION_CONFIG register and
+        * PARTITION_ACCESS bits is updated in case the ioctl ext_csd write
+        * changed it successfully.
+        */
+       if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_PART_CONFIG) &&
+           (cmd.opcode == MMC_SWITCH)) {
+               struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev);
+               u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg);
+
+               /*
+                * Update cache so the next mmc_blk_part_switch call operates
+                * on up-to-date data.
+                */
+               card->ext_csd.part_config = value;
+               main_md->part_curr = value & EXT_CSD_PART_CONFIG_ACC_MASK;
+       }
+
        /*
         * According to the SD specs, some commands require a delay after
         * issuing the command.
index 79a5b985ccf5ee8fe5ba06b5aec717f36799794e..9c821eedd1566750ce044507bd986b5cad9a2ec0 100644 (file)
@@ -82,6 +82,7 @@ struct mmc_fixup {
 #define CID_MANFID_APACER       0x27
 #define CID_MANFID_KINGSTON     0x70
 #define CID_MANFID_HYNIX       0x90
+#define CID_MANFID_NUMONYX     0xFE
 
 #define END_FIXUP { NULL }
 
index 908e4db03535b038d548563188c0a11ac1ce4761..42d6aa89a48a95ad82bc60445f73971ac48730d2 100644 (file)
@@ -848,7 +848,6 @@ int mmc_interrupt_hpi(struct mmc_card *card)
                return 1;
        }
 
-       mmc_claim_host(card->host);
        err = mmc_send_status(card, &status);
        if (err) {
                pr_err("%s: Get card status fail\n", mmc_hostname(card->host));
@@ -890,7 +889,6 @@ int mmc_interrupt_hpi(struct mmc_card *card)
        } while (!err);
 
 out:
-       mmc_release_host(card->host);
        return err;
 }
 
@@ -932,9 +930,7 @@ static int mmc_read_bkops_status(struct mmc_card *card)
        int err;
        u8 *ext_csd;
 
-       mmc_claim_host(card->host);
        err = mmc_get_ext_csd(card, &ext_csd);
-       mmc_release_host(card->host);
        if (err)
                return err;
 
index 75d317623852dc9f55586e41a176311a48144e1d..5153577754f02861ceab4689813441f9ac4ea443 100644 (file)
@@ -109,6 +109,12 @@ static const struct mmc_fixup mmc_ext_csd_fixups[] = {
         */
        MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX,
                              0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5),
+       /*
+        * Certain Micron (Numonyx) eMMC 4.5 cards might get broken when HPI
+        * feature is used so disable the HPI feature for such buggy cards.
+        */
+       MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_NUMONYX,
+                             0x014e, add_quirk, MMC_QUIRK_BROKEN_HPI, 6),
 
        END_FIXUP
 };
index 229dc18f0581beb26733222be97f981b2038fb60..768972af8b853cf882b1b3311ed8fa1b0a64a49e 100644 (file)
@@ -1265,7 +1265,8 @@ static int bcm2835_add_host(struct bcm2835_host *host)
        char pio_limit_string[20];
        int ret;
 
-       mmc->f_max = host->max_clk;
+       if (!mmc->f_max || mmc->f_max > host->max_clk)
+               mmc->f_max = host->max_clk;
        mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV;
 
        mmc->max_busy_timeout = ~0 / (mmc->f_max / 1000);
index 35026795be2803c7387203c5719f4442c15b7c50..a84aa3f1ae8547c4cdbf24cb05ef7e32dca8d94a 100644 (file)
@@ -165,9 +165,15 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
 static int dw_mci_exynos_runtime_resume(struct device *dev)
 {
        struct dw_mci *host = dev_get_drvdata(dev);
+       int ret;
+
+       ret = dw_mci_runtime_resume(dev);
+       if (ret)
+               return ret;
 
        dw_mci_exynos_config_smu(host);
-       return dw_mci_runtime_resume(dev);
+
+       return ret;
 }
 
 /**
@@ -487,6 +493,7 @@ static unsigned long exynos_dwmmc_caps[4] = {
 
 static const struct dw_mci_drv_data exynos_drv_data = {
        .caps                   = exynos_dwmmc_caps,
+       .num_caps               = ARRAY_SIZE(exynos_dwmmc_caps),
        .init                   = dw_mci_exynos_priv_init,
        .set_ios                = dw_mci_exynos_set_ios,
        .parse_dt               = dw_mci_exynos_parse_dt,
index 73fd75c3c824904d7171a51f16943192f6c1bc03..89cdb3d533bb519f57e3a4c7d6a7570f54f3077c 100644 (file)
@@ -135,6 +135,9 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host)
        if (priv->ctrl_id < 0)
                priv->ctrl_id = 0;
 
+       if (priv->ctrl_id >= TIMING_MODE)
+               return -EINVAL;
+
        host->priv = priv;
        return 0;
 }
@@ -207,6 +210,7 @@ static int dw_mci_hi6220_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
 
 static const struct dw_mci_drv_data hi6220_data = {
        .caps                   = dw_mci_hi6220_caps,
+       .num_caps               = ARRAY_SIZE(dw_mci_hi6220_caps),
        .switch_voltage         = dw_mci_hi6220_switch_voltage,
        .set_ios                = dw_mci_hi6220_set_ios,
        .parse_dt               = dw_mci_hi6220_parse_dt,
index a3f1c2b3014534515db2246b0921b1be3a8b9c7d..3392952129355b2752f3131c0ff38a96b4e9d088 100644 (file)
@@ -319,6 +319,7 @@ static const struct dw_mci_drv_data rk2928_drv_data = {
 
 static const struct dw_mci_drv_data rk3288_drv_data = {
        .caps                   = dw_mci_rk3288_dwmmc_caps,
+       .num_caps               = ARRAY_SIZE(dw_mci_rk3288_dwmmc_caps),
        .set_ios                = dw_mci_rk3288_set_ios,
        .execute_tuning         = dw_mci_rk3288_execute_tuning,
        .parse_dt               = dw_mci_rk3288_parse_dt,
index d38e94ae2b855ccdbcd8c74db19950b9b9ea310e..c06b5393312ff185ffa9487931578665c74efd62 100644 (file)
@@ -195,6 +195,7 @@ static unsigned long zx_dwmmc_caps[3] = {
 
 static const struct dw_mci_drv_data zx_drv_data = {
        .caps                   = zx_dwmmc_caps,
+       .num_caps               = ARRAY_SIZE(zx_dwmmc_caps),
        .execute_tuning         = dw_mci_zx_execute_tuning,
        .prepare_hs400_tuning   = dw_mci_zx_prepare_hs400_tuning,
        .parse_dt               = dw_mci_zx_parse_dt,
index 0aa39975f33b8fbf36f0995cb56ffe283c7ca1b2..06d47414d0c19796beb70f130d192b3a4c3e592a 100644 (file)
@@ -165,6 +165,8 @@ static int dw_mci_regs_show(struct seq_file *s, void *v)
 {
        struct dw_mci *host = s->private;
 
+       pm_runtime_get_sync(host->dev);
+
        seq_printf(s, "STATUS:\t0x%08x\n", mci_readl(host, STATUS));
        seq_printf(s, "RINTSTS:\t0x%08x\n", mci_readl(host, RINTSTS));
        seq_printf(s, "CMD:\t0x%08x\n", mci_readl(host, CMD));
@@ -172,6 +174,8 @@ static int dw_mci_regs_show(struct seq_file *s, void *v)
        seq_printf(s, "INTMASK:\t0x%08x\n", mci_readl(host, INTMASK));
        seq_printf(s, "CLKENA:\t0x%08x\n", mci_readl(host, CLKENA));
 
+       pm_runtime_put_autosuspend(host->dev);
+
        return 0;
 }
 
@@ -409,7 +413,9 @@ static inline void dw_mci_set_cto(struct dw_mci *host)
        cto_div = (mci_readl(host, CLKDIV) & 0xff) * 2;
        if (cto_div == 0)
                cto_div = 1;
-       cto_ms = DIV_ROUND_UP(MSEC_PER_SEC * cto_clks * cto_div, host->bus_hz);
+
+       cto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * cto_clks * cto_div,
+                                 host->bus_hz);
 
        /* add a bit spare time */
        cto_ms += 10;
@@ -558,6 +564,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
                                        (sizeof(struct idmac_desc_64addr) *
                                                        (i + 1))) >> 32;
                        /* Initialize reserved and buffer size fields to "0" */
+                       p->des0 = 0;
                        p->des1 = 0;
                        p->des2 = 0;
                        p->des3 = 0;
@@ -580,6 +587,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
                     i++, p++) {
                        p->des3 = cpu_to_le32(host->sg_dma +
                                        (sizeof(struct idmac_desc) * (i + 1)));
+                       p->des0 = 0;
                        p->des1 = 0;
                }
 
@@ -1795,8 +1803,8 @@ static bool dw_mci_reset(struct dw_mci *host)
        }
 
        if (host->use_dma == TRANS_MODE_IDMAC)
-               /* It is also recommended that we reset and reprogram idmac */
-               dw_mci_idmac_reset(host);
+               /* It is also required that we reinit idmac */
+               dw_mci_idmac_init(host);
 
        ret = true;
 
@@ -1944,8 +1952,9 @@ static void dw_mci_set_drto(struct dw_mci *host)
        drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2;
        if (drto_div == 0)
                drto_div = 1;
-       drto_ms = DIV_ROUND_UP(MSEC_PER_SEC * drto_clks * drto_div,
-                              host->bus_hz);
+
+       drto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * drto_clks * drto_div,
+                                  host->bus_hz);
 
        /* add a bit spare time */
        drto_ms += 10;
@@ -2778,12 +2787,57 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
+{
+       struct dw_mci *host = slot->host;
+       const struct dw_mci_drv_data *drv_data = host->drv_data;
+       struct mmc_host *mmc = slot->mmc;
+       int ctrl_id;
+
+       if (host->pdata->caps)
+               mmc->caps = host->pdata->caps;
+
+       /*
+        * Support MMC_CAP_ERASE by default.
+        * It needs to use trim/discard/erase commands.
+        */
+       mmc->caps |= MMC_CAP_ERASE;
+
+       if (host->pdata->pm_caps)
+               mmc->pm_caps = host->pdata->pm_caps;
+
+       if (host->dev->of_node) {
+               ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
+               if (ctrl_id < 0)
+                       ctrl_id = 0;
+       } else {
+               ctrl_id = to_platform_device(host->dev)->id;
+       }
+
+       if (drv_data && drv_data->caps) {
+               if (ctrl_id >= drv_data->num_caps) {
+                       dev_err(host->dev, "invalid controller id %d\n",
+                               ctrl_id);
+                       return -EINVAL;
+               }
+               mmc->caps |= drv_data->caps[ctrl_id];
+       }
+
+       if (host->pdata->caps2)
+               mmc->caps2 = host->pdata->caps2;
+
+       /* Process SDIO IRQs through the sdio_irq_work. */
+       if (mmc->caps & MMC_CAP_SDIO_IRQ)
+               mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
+
+       return 0;
+}
+
 static int dw_mci_init_slot(struct dw_mci *host)
 {
        struct mmc_host *mmc;
        struct dw_mci_slot *slot;
-       const struct dw_mci_drv_data *drv_data = host->drv_data;
-       int ctrl_id, ret;
+       int ret;
        u32 freq[2];
 
        mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
@@ -2817,38 +2871,13 @@ static int dw_mci_init_slot(struct dw_mci *host)
        if (!mmc->ocr_avail)
                mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
-       if (host->pdata->caps)
-               mmc->caps = host->pdata->caps;
-
-       /*
-        * Support MMC_CAP_ERASE by default.
-        * It needs to use trim/discard/erase commands.
-        */
-       mmc->caps |= MMC_CAP_ERASE;
-
-       if (host->pdata->pm_caps)
-               mmc->pm_caps = host->pdata->pm_caps;
-
-       if (host->dev->of_node) {
-               ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
-               if (ctrl_id < 0)
-                       ctrl_id = 0;
-       } else {
-               ctrl_id = to_platform_device(host->dev)->id;
-       }
-       if (drv_data && drv_data->caps)
-               mmc->caps |= drv_data->caps[ctrl_id];
-
-       if (host->pdata->caps2)
-               mmc->caps2 = host->pdata->caps2;
-
        ret = mmc_of_parse(mmc);
        if (ret)
                goto err_host_allocated;
 
-       /* Process SDIO IRQs through the sdio_irq_work. */
-       if (mmc->caps & MMC_CAP_SDIO_IRQ)
-               mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
+       ret = dw_mci_init_slot_caps(slot);
+       if (ret)
+               goto err_host_allocated;
 
        /* Useful defaults if platform data is unset. */
        if (host->use_dma == TRANS_MODE_IDMAC) {
index e3124f06a47ef52840dc5abb77a7febd104b083d..1424bd490dd1bc1bcbd71dd4b2d803508db337b0 100644 (file)
@@ -543,6 +543,7 @@ struct dw_mci_slot {
 /**
  * dw_mci driver data - dw-mshc implementation specific driver data.
  * @caps: mmc subsystem specified capabilities of the controller(s).
+ * @num_caps: number of capabilities specified by @caps.
  * @init: early implementation specific initialization.
  * @set_ios: handle bus specific extensions.
  * @parse_dt: parse implementation specific device tree properties.
@@ -554,6 +555,7 @@ struct dw_mci_slot {
  */
 struct dw_mci_drv_data {
        unsigned long   *caps;
+       u32             num_caps;
        int             (*init)(struct dw_mci *host);
        void            (*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
        int             (*parse_dt)(struct dw_mci *host);
index 22438ebfe4e627a9edf789ba5b146158b3a6622e..4f972b879fe6f36ef0018d82a1b71f57c2de3cce 100644 (file)
@@ -717,22 +717,6 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode,
 static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
        struct meson_host *host = mmc_priv(mmc);
-       int ret;
-
-       /*
-        * If this is the initial tuning, try to get a sane Rx starting
-        * phase before doing the actual tuning.
-        */
-       if (!mmc->doing_retune) {
-               ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk);
-
-               if (ret)
-                       return ret;
-       }
-
-       ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk);
-       if (ret)
-               return ret;
 
        return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk);
 }
@@ -763,9 +747,8 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                if (!IS_ERR(mmc->supply.vmmc))
                        mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
 
-               /* Reset phases */
+               /* Reset rx phase */
                clk_set_phase(host->rx_clk, 0);
-               clk_set_phase(host->tx_clk, 270);
 
                break;
 
index 4065da58789d2d091cd918b8cd30c518aac331d7..32321bd596d880027358db10e9eb5f5b45957c1d 100644 (file)
@@ -680,7 +680,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
        host->hw_name   = "ACPI";
        host->ops       = &sdhci_acpi_ops_dflt;
        host->irq       = platform_get_irq(pdev, 0);
-       if (host->irq <= 0) {
+       if (host->irq < 0) {
                err = -EINVAL;
                goto err_free;
        }
index 6d1a983e622722b527d8a3c1b6cdea449c88d180..82c4f05f91d8781528a365d97b3033472df987f4 100644 (file)
@@ -654,9 +654,36 @@ static void byt_read_dsm(struct sdhci_pci_slot *slot)
        slot->chip->rpm_retune = intel_host->d3_retune;
 }
 
-static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+static int intel_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+       int err = sdhci_execute_tuning(mmc, opcode);
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       if (err)
+               return err;
+
+       /*
+        * Tuning can leave the IP in an active state (Buffer Read Enable bit
+        * set) which prevents the entry to low power states (i.e. S0i3). Data
+        * reset will clear it.
+        */
+       sdhci_reset(host, SDHCI_RESET_DATA);
+
+       return 0;
+}
+
+static void byt_probe_slot(struct sdhci_pci_slot *slot)
 {
+       struct mmc_host_ops *ops = &slot->host->mmc_host_ops;
+
        byt_read_dsm(slot);
+
+       ops->execute_tuning = intel_execute_tuning;
+}
+
+static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+{
+       byt_probe_slot(slot);
        slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
                                 MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
                                 MMC_CAP_CMD_DURING_TFR |
@@ -779,7 +806,7 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
        int err;
 
-       byt_read_dsm(slot);
+       byt_probe_slot(slot);
 
        err = ni_set_max_freq(slot);
        if (err)
@@ -792,7 +819,7 @@ static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 
 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 {
-       byt_read_dsm(slot);
+       byt_probe_slot(slot);
        slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
                                 MMC_CAP_WAIT_WHILE_BUSY;
        return 0;
@@ -800,7 +827,7 @@ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
 
 static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
 {
-       byt_read_dsm(slot);
+       byt_probe_slot(slot);
        slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY |
                                 MMC_CAP_AGGRESSIVE_PM | MMC_CAP_CD_WAKE;
        slot->cd_idx = 0;
index de8c902059b8b38db5a20705c3e2480af510a1d9..7d80a8bb96fe8b03b76f7b822f437a0e23eff119 100644 (file)
@@ -479,7 +479,7 @@ static int shrink_ecclayout(struct mtd_info *mtd,
        for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) {
                u32 eccpos;
 
-               ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
+               ret = mtd_ooblayout_ecc(mtd, section++, &oobregion);
                if (ret < 0) {
                        if (ret != -ERANGE)
                                return ret;
@@ -526,7 +526,7 @@ static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
        for (i = 0; i < ARRAY_SIZE(to->eccpos);) {
                u32 eccpos;
 
-               ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
+               ret = mtd_ooblayout_ecc(mtd, section++, &oobregion);
                if (ret < 0) {
                        if (ret != -ERANGE)
                                return ret;
index e6b8c59f2c0da7c0f5f8be9fc609e8f96b8b2140..736ac887303c88baa86ab4857653c322d1d2f60b 100644 (file)
@@ -328,7 +328,7 @@ config MTD_NAND_MARVELL
        tristate "NAND controller support on Marvell boards"
        depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \
                   COMPILE_TEST
-       depends on HAS_IOMEM
+       depends on HAS_IOMEM && HAS_DMA
        help
          This enables the NAND flash controller driver for Marvell boards,
          including:
index 4872a7ba6503278670f4963897b110c98554d708..5a9c2f0020c2d47677a960d73a4de3fe81de25b8 100644 (file)
@@ -173,14 +173,9 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
 
 /* returns nonzero if entire page is blank */
 static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
-                         u32 *eccstat, unsigned int bufnum)
+                         u32 eccstat, unsigned int bufnum)
 {
-       u32 reg = eccstat[bufnum / 4];
-       int errors;
-
-       errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
-
-       return errors;
+       return  (eccstat >> ((3 - bufnum % 4) * 8)) & 15;
 }
 
 /*
@@ -193,7 +188,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
        struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
        struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
-       u32 eccstat[4];
+       u32 eccstat;
        int i;
 
        /* set the chip select for NAND Transaction */
@@ -228,19 +223,17 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
        if (nctrl->eccread) {
                int errors;
                int bufnum = nctrl->page & priv->bufnum_mask;
-               int sector = bufnum * chip->ecc.steps;
-               int sector_end = sector + chip->ecc.steps - 1;
+               int sector_start = bufnum * chip->ecc.steps;
+               int sector_end = sector_start + chip->ecc.steps - 1;
                __be32 *eccstat_regs;
 
-               if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
-                       eccstat_regs = ifc->ifc_nand.v2_nand_eccstat;
-               else
-                       eccstat_regs = ifc->ifc_nand.v1_nand_eccstat;
+               eccstat_regs = ifc->ifc_nand.nand_eccstat;
+               eccstat = ifc_in32(&eccstat_regs[sector_start / 4]);
 
-               for (i = sector / 4; i <= sector_end / 4; i++)
-                       eccstat[i] = ifc_in32(&eccstat_regs[i]);
+               for (i = sector_start; i <= sector_end; i++) {
+                       if (i != sector_start && !(i % 4))
+                               eccstat = ifc_in32(&eccstat_regs[i / 4]);
 
-               for (i = sector; i <= sector_end; i++) {
                        errors = check_read_ecc(mtd, ctrl, eccstat, i);
 
                        if (errors == 15) {
@@ -626,6 +619,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
        struct fsl_ifc_ctrl *ctrl = priv->ctrl;
        struct fsl_ifc_runtime __iomem *ifc = ctrl->rregs;
        u32 nand_fsr;
+       int status;
 
        /* Use READ_STATUS command, but wait for the device to be ready */
        ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
@@ -640,12 +634,12 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
        fsl_ifc_run_command(mtd);
 
        nand_fsr = ifc_in32(&ifc->ifc_nand.nand_fsr);
-
+       status = nand_fsr >> 24;
        /*
         * The chip always seems to report that it is
         * write-protected, even when it is not.
         */
-       return nand_fsr | NAND_STATUS_WP;
+       return status | NAND_STATUS_WP;
 }
 
 /*
index 80d31a58e558cc14582c0b0c97ed77a4615cf454..f367144f3c6f39849dfcd35422a117dcedcb9b0e 100644 (file)
@@ -752,10 +752,8 @@ static int vf610_nfc_probe(struct platform_device *pdev)
                if (mtd->oobsize > 64)
                        mtd->oobsize = 64;
 
-               /*
-                * mtd->ecclayout is not specified here because we're using the
-                * default large page ECC layout defined in NAND core.
-                */
+               /* Use default large page ECC layout defined in NAND core */
+               mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
                if (chip->ecc.strength == 32) {
                        nfc->ecc_mode = ECC_60_BYTE;
                        chip->ecc.bytes = 60;
index 1e37313054f3950ee30e6c6fccad874d9262013a..6da69af103e60d9e26ed30815fc946be56aee224 100644 (file)
@@ -390,37 +390,23 @@ static int cc770_get_berr_counter(const struct net_device *dev,
        return 0;
 }
 
-static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static void cc770_tx(struct net_device *dev, int mo)
 {
        struct cc770_priv *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &dev->stats;
-       struct can_frame *cf = (struct can_frame *)skb->data;
-       unsigned int mo = obj2msgobj(CC770_OBJ_TX);
+       struct can_frame *cf = (struct can_frame *)priv->tx_skb->data;
        u8 dlc, rtr;
        u32 id;
        int i;
 
-       if (can_dropped_invalid_skb(dev, skb))
-               return NETDEV_TX_OK;
-
-       if ((cc770_read_reg(priv,
-                           msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
-               netdev_err(dev, "TX register is still occupied!\n");
-               return NETDEV_TX_BUSY;
-       }
-
-       netif_stop_queue(dev);
-
        dlc = cf->can_dlc;
        id = cf->can_id;
-       if (cf->can_id & CAN_RTR_FLAG)
-               rtr = 0;
-       else
-               rtr = MSGCFG_DIR;
+       rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR;
+
+       cc770_write_reg(priv, msgobj[mo].ctrl0,
+                       MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
        cc770_write_reg(priv, msgobj[mo].ctrl1,
                        RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
-       cc770_write_reg(priv, msgobj[mo].ctrl0,
-                       MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES);
+
        if (id & CAN_EFF_FLAG) {
                id &= CAN_EFF_MASK;
                cc770_write_reg(priv, msgobj[mo].config,
@@ -439,22 +425,30 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
        for (i = 0; i < dlc; i++)
                cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
 
-       /* Store echo skb before starting the transfer */
-       can_put_echo_skb(skb, dev, 0);
-
        cc770_write_reg(priv, msgobj[mo].ctrl1,
-                       RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
+                       RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
+       cc770_write_reg(priv, msgobj[mo].ctrl0,
+                       MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC);
+}
 
-       stats->tx_bytes += dlc;
+static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct cc770_priv *priv = netdev_priv(dev);
+       unsigned int mo = obj2msgobj(CC770_OBJ_TX);
 
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
 
-       /*
-        * HM: We had some cases of repeated IRQs so make sure the
-        * INT is acknowledged I know it's already further up, but
-        * doing again fixed the issue
-        */
-       cc770_write_reg(priv, msgobj[mo].ctrl0,
-                       MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+       netif_stop_queue(dev);
+
+       if ((cc770_read_reg(priv,
+                           msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
+               netdev_err(dev, "TX register is still occupied!\n");
+               return NETDEV_TX_BUSY;
+       }
+
+       priv->tx_skb = skb;
+       cc770_tx(dev, mo);
 
        return NETDEV_TX_OK;
 }
@@ -680,19 +674,46 @@ static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
        struct cc770_priv *priv = netdev_priv(dev);
        struct net_device_stats *stats = &dev->stats;
        unsigned int mo = obj2msgobj(o);
+       struct can_frame *cf;
+       u8 ctrl1;
+
+       ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
 
-       /* Nothing more to send, switch off interrupts */
        cc770_write_reg(priv, msgobj[mo].ctrl0,
                        MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
-       /*
-        * We had some cases of repeated IRQ so make sure the
-        * INT is acknowledged
+       cc770_write_reg(priv, msgobj[mo].ctrl1,
+                       RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES);
+
+       if (unlikely(!priv->tx_skb)) {
+               netdev_err(dev, "missing tx skb in tx interrupt\n");
+               return;
+       }
+
+       if (unlikely(ctrl1 & MSGLST_SET)) {
+               stats->rx_over_errors++;
+               stats->rx_errors++;
+       }
+
+       /* When the CC770 is sending an RTR message and it receives a regular
+        * message that matches the id of the RTR message, it will overwrite the
+        * outgoing message in the TX register. When this happens we must
+        * process the received message and try to transmit the outgoing skb
+        * again.
         */
-       cc770_write_reg(priv, msgobj[mo].ctrl0,
-                       MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+       if (unlikely(ctrl1 & NEWDAT_SET)) {
+               cc770_rx(dev, mo, ctrl1);
+               cc770_tx(dev, mo);
+               return;
+       }
 
+       cf = (struct can_frame *)priv->tx_skb->data;
+       stats->tx_bytes += cf->can_dlc;
        stats->tx_packets++;
+
+       can_put_echo_skb(priv->tx_skb, dev, 0);
        can_get_echo_skb(dev, 0);
+       priv->tx_skb = NULL;
+
        netif_wake_queue(dev);
 }
 
@@ -804,6 +825,7 @@ struct net_device *alloc_cc770dev(int sizeof_priv)
        priv->can.do_set_bittiming = cc770_set_bittiming;
        priv->can.do_set_mode = cc770_set_mode;
        priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+       priv->tx_skb = NULL;
 
        memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
 
index a1739db98d911f006f82a44682f0be1b8694a01c..95752e1d128397260968ee100b0b3035923547c9 100644 (file)
@@ -193,6 +193,8 @@ struct cc770_priv {
        u8 cpu_interface;       /* CPU interface register */
        u8 clkout;              /* Clock out register */
        u8 bus_config;          /* Bus conffiguration register */
+
+       struct sk_buff *tx_skb;
 };
 
 struct net_device *alloc_cc770dev(int sizeof_priv);
index 2772d05ff11caafbdf074aebccd32b415feae0c4..fedd927ba6ed998fe75260d5baa8c5e1bb274c4f 100644 (file)
@@ -30,6 +30,7 @@
 #define IFI_CANFD_STCMD_ERROR_ACTIVE           BIT(2)
 #define IFI_CANFD_STCMD_ERROR_PASSIVE          BIT(3)
 #define IFI_CANFD_STCMD_BUSOFF                 BIT(4)
+#define IFI_CANFD_STCMD_ERROR_WARNING          BIT(5)
 #define IFI_CANFD_STCMD_BUSMONITOR             BIT(16)
 #define IFI_CANFD_STCMD_LOOPBACK               BIT(18)
 #define IFI_CANFD_STCMD_DISABLE_CANFD          BIT(24)
 #define IFI_CANFD_TXSTCMD_OVERFLOW             BIT(13)
 
 #define IFI_CANFD_INTERRUPT                    0xc
+#define IFI_CANFD_INTERRUPT_ERROR_BUSOFF       BIT(0)
 #define IFI_CANFD_INTERRUPT_ERROR_WARNING      BIT(1)
+#define IFI_CANFD_INTERRUPT_ERROR_STATE_CHG    BIT(2)
+#define IFI_CANFD_INTERRUPT_ERROR_REC_TEC_INC  BIT(3)
 #define IFI_CANFD_INTERRUPT_ERROR_COUNTER      BIT(10)
 #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY       BIT(16)
 #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE      BIT(22)
 #define IFI_CANFD_INTERRUPT_SET_IRQ            ((u32)BIT(31))
 
 #define IFI_CANFD_IRQMASK                      0x10
+#define IFI_CANFD_IRQMASK_ERROR_BUSOFF         BIT(0)
+#define IFI_CANFD_IRQMASK_ERROR_WARNING                BIT(1)
+#define IFI_CANFD_IRQMASK_ERROR_STATE_CHG      BIT(2)
+#define IFI_CANFD_IRQMASK_ERROR_REC_TEC_INC    BIT(3)
 #define IFI_CANFD_IRQMASK_SET_ERR              BIT(7)
 #define IFI_CANFD_IRQMASK_SET_TS               BIT(15)
 #define IFI_CANFD_IRQMASK_TXFIFO_EMPTY         BIT(16)
 #define IFI_CANFD_SYSCLOCK                     0x50
 
 #define IFI_CANFD_VER                          0x54
+#define IFI_CANFD_VER_REV_MASK                 0xff
+#define IFI_CANFD_VER_REV_MIN_SUPPORTED                0x15
 
 #define IFI_CANFD_IP_ID                                0x58
 #define IFI_CANFD_IP_ID_VALUE                  0xD073CAFD
@@ -220,7 +230,10 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
 
        if (enable) {
                enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
-                       IFI_CANFD_IRQMASK_RXFIFO_NEMPTY;
+                       IFI_CANFD_IRQMASK_RXFIFO_NEMPTY |
+                       IFI_CANFD_IRQMASK_ERROR_STATE_CHG |
+                       IFI_CANFD_IRQMASK_ERROR_WARNING |
+                       IFI_CANFD_IRQMASK_ERROR_BUSOFF;
                if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
                        enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
        }
@@ -361,12 +374,13 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
        return 1;
 }
 
-static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr)
+static int ifi_canfd_handle_lec_err(struct net_device *ndev)
 {
        struct ifi_canfd_priv *priv = netdev_priv(ndev);
        struct net_device_stats *stats = &ndev->stats;
        struct can_frame *cf;
        struct sk_buff *skb;
+       u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
        const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
                            IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
                            IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
@@ -449,6 +463,11 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
 
        switch (new_state) {
        case CAN_STATE_ERROR_ACTIVE:
+               /* error active state */
+               priv->can.can_stats.error_warning++;
+               priv->can.state = CAN_STATE_ERROR_ACTIVE;
+               break;
+       case CAN_STATE_ERROR_WARNING:
                /* error warning state */
                priv->can.can_stats.error_warning++;
                priv->can.state = CAN_STATE_ERROR_WARNING;
@@ -477,7 +496,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
        ifi_canfd_get_berr_counter(ndev, &bec);
 
        switch (new_state) {
-       case CAN_STATE_ERROR_ACTIVE:
+       case CAN_STATE_ERROR_WARNING:
                /* error warning state */
                cf->can_id |= CAN_ERR_CRTL;
                cf->data[1] = (bec.txerr > bec.rxerr) ?
@@ -510,22 +529,21 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
        return 1;
 }
 
-static int ifi_canfd_handle_state_errors(struct net_device *ndev, u32 stcmd)
+static int ifi_canfd_handle_state_errors(struct net_device *ndev)
 {
        struct ifi_canfd_priv *priv = netdev_priv(ndev);
+       u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
        int work_done = 0;
-       u32 isr;
 
-       /*
-        * The ErrWarn condition is a little special, since the bit is
-        * located in the INTERRUPT register instead of STCMD register.
-        */
-       isr = readl(priv->base + IFI_CANFD_INTERRUPT);
-       if ((isr & IFI_CANFD_INTERRUPT_ERROR_WARNING) &&
+       if ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) &&
+           (priv->can.state != CAN_STATE_ERROR_ACTIVE)) {
+               netdev_dbg(ndev, "Error, entered active state\n");
+               work_done += ifi_canfd_handle_state_change(ndev,
+                                               CAN_STATE_ERROR_ACTIVE);
+       }
+
+       if ((stcmd & IFI_CANFD_STCMD_ERROR_WARNING) &&
            (priv->can.state != CAN_STATE_ERROR_WARNING)) {
-               /* Clear the interrupt */
-               writel(IFI_CANFD_INTERRUPT_ERROR_WARNING,
-                      priv->base + IFI_CANFD_INTERRUPT);
                netdev_dbg(ndev, "Error, entered warning state\n");
                work_done += ifi_canfd_handle_state_change(ndev,
                                                CAN_STATE_ERROR_WARNING);
@@ -552,18 +570,11 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
 {
        struct net_device *ndev = napi->dev;
        struct ifi_canfd_priv *priv = netdev_priv(ndev);
-       const u32 stcmd_state_mask = IFI_CANFD_STCMD_ERROR_PASSIVE |
-                                    IFI_CANFD_STCMD_BUSOFF;
-       int work_done = 0;
-
-       u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
        u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD);
-       u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
+       int work_done = 0;
 
        /* Handle bus state changes */
-       if ((stcmd & stcmd_state_mask) ||
-           ((stcmd & IFI_CANFD_STCMD_ERROR_ACTIVE) == 0))
-               work_done += ifi_canfd_handle_state_errors(ndev, stcmd);
+       work_done += ifi_canfd_handle_state_errors(ndev);
 
        /* Handle lost messages on RX */
        if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
@@ -571,7 +582,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
 
        /* Handle lec errors on the bus */
        if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
-               work_done += ifi_canfd_handle_lec_err(ndev, errctr);
+               work_done += ifi_canfd_handle_lec_err(ndev);
 
        /* Handle normal messages on RX */
        if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
@@ -592,12 +603,13 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
        struct net_device_stats *stats = &ndev->stats;
        const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
                                IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
+                               IFI_CANFD_INTERRUPT_ERROR_COUNTER |
+                               IFI_CANFD_INTERRUPT_ERROR_STATE_CHG |
                                IFI_CANFD_INTERRUPT_ERROR_WARNING |
-                               IFI_CANFD_INTERRUPT_ERROR_COUNTER;
+                               IFI_CANFD_INTERRUPT_ERROR_BUSOFF;
        const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
                                IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
-       const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ |
-                                        IFI_CANFD_INTERRUPT_ERROR_WARNING));
+       const u32 clr_irq_mask = ~((u32)IFI_CANFD_INTERRUPT_SET_IRQ);
        u32 isr;
 
        isr = readl(priv->base + IFI_CANFD_INTERRUPT);
@@ -933,7 +945,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
        struct resource *res;
        void __iomem *addr;
        int irq, ret;
-       u32 id;
+       u32 id, rev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        addr = devm_ioremap_resource(dev, res);
@@ -947,6 +959,13 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       rev = readl(addr + IFI_CANFD_VER) & IFI_CANFD_VER_REV_MASK;
+       if (rev < IFI_CANFD_VER_REV_MIN_SUPPORTED) {
+               dev_err(dev, "This block is too old (rev %i), minimum supported is rev %i\n",
+                       rev, IFI_CANFD_VER_REV_MIN_SUPPORTED);
+               return -EINVAL;
+       }
+
        ndev = alloc_candev(sizeof(*priv), 1);
        if (!ndev)
                return -ENOMEM;
index 2594f7779c6f147d71fdda29f2eab22b0c9e1955..b397a33f3d32b5e3c28398a660c736d45a74179d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/iopoll.h>
 #include <linux/can/dev.h>
+#include <linux/pinctrl/consumer.h>
 
 /* napi related */
 #define M_CAN_NAPI_WEIGHT      64
@@ -253,7 +254,7 @@ enum m_can_mram_cfg {
 
 /* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
 #define RXFC_FWM_SHIFT 24
-#define RXFC_FWM_MASK  (0x7f < RXFC_FWM_SHIFT)
+#define RXFC_FWM_MASK  (0x7f << RXFC_FWM_SHIFT)
 #define RXFC_FS_SHIFT  16
 #define RXFC_FS_MASK   (0x7f << RXFC_FS_SHIFT)
 
@@ -1700,6 +1701,8 @@ static __maybe_unused int m_can_suspend(struct device *dev)
                m_can_clk_stop(priv);
        }
 
+       pinctrl_pm_select_sleep_state(dev);
+
        priv->can.state = CAN_STATE_SLEEPING;
 
        return 0;
@@ -1710,6 +1713,8 @@ static __maybe_unused int m_can_resume(struct device *dev)
        struct net_device *ndev = dev_get_drvdata(dev);
        struct m_can_priv *priv = netdev_priv(ndev);
 
+       pinctrl_pm_select_default_state(dev);
+
        m_can_init_ram(priv);
 
        priv->can.state = CAN_STATE_ERROR_ACTIVE;
index 55513411a82e68e11d6b1ca30e90ea4337a0f2ee..ed8561d4a90f4b5e25683a5483f0d98248d7dca2 100644 (file)
@@ -262,7 +262,6 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
 
                spin_lock_irqsave(&priv->echo_lock, flags);
                can_get_echo_skb(priv->ndev, msg->client);
-               spin_unlock_irqrestore(&priv->echo_lock, flags);
 
                /* count bytes of the echo instead of skb */
                stats->tx_bytes += cf_len;
@@ -271,6 +270,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
                /* restart tx queue (a slot is free) */
                netif_wake_queue(priv->ndev);
 
+               spin_unlock_irqrestore(&priv->echo_lock, flags);
                return 0;
        }
 
@@ -333,7 +333,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
 
        /* this STATUS is the CNF of the RX_BARRIER: Tx path can be setup */
        if (pucan_status_is_rx_barrier(msg)) {
-               unsigned long flags;
 
                if (priv->enable_tx_path) {
                        int err = priv->enable_tx_path(priv);
@@ -342,16 +341,8 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
                                return err;
                }
 
-               /* restart network queue only if echo skb array is free */
-               spin_lock_irqsave(&priv->echo_lock, flags);
-
-               if (!priv->can.echo_skb[priv->echo_idx]) {
-                       spin_unlock_irqrestore(&priv->echo_lock, flags);
-
-                       netif_wake_queue(ndev);
-               } else {
-                       spin_unlock_irqrestore(&priv->echo_lock, flags);
-               }
+               /* start network queue (echo_skb array is empty) */
+               netif_start_queue(ndev);
 
                return 0;
        }
@@ -726,11 +717,6 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
         */
        should_stop_tx_queue = !!(priv->can.echo_skb[priv->echo_idx]);
 
-       spin_unlock_irqrestore(&priv->echo_lock, flags);
-
-       /* write the skb on the interface */
-       priv->write_tx_msg(priv, msg);
-
        /* stop network tx queue if not enough room to save one more msg too */
        if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
                should_stop_tx_queue |= (room_left <
@@ -742,6 +728,11 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
        if (should_stop_tx_queue)
                netif_stop_queue(ndev);
 
+       spin_unlock_irqrestore(&priv->echo_lock, flags);
+
+       /* write the skb on the interface */
+       priv->write_tx_msg(priv, msg);
+
        return NETDEV_TX_OK;
 }
 
index 788c3464a3b0e95aaa101591750b9de493a34a18..3c51a884db87bc90e71d5df8d5b0a91eadf69cdb 100644 (file)
@@ -349,8 +349,12 @@ static irqreturn_t pciefd_irq_handler(int irq, void *arg)
                priv->tx_pages_free++;
                spin_unlock_irqrestore(&priv->tx_lock, flags);
 
-               /* wake producer up */
-               netif_wake_queue(priv->ucan.ndev);
+               /* wake producer up (only if enough room in echo_skb array) */
+               spin_lock_irqsave(&priv->ucan.echo_lock, flags);
+               if (!priv->ucan.can.echo_skb[priv->ucan.echo_idx])
+                       netif_wake_queue(priv->ucan.ndev);
+
+               spin_unlock_irqrestore(&priv->ucan.echo_lock, flags);
        }
 
        /* re-enable Rx DMA transfer for this CAN */
index d040aeb45172662320bf63c75b094cde35b9b294..15c2a831edf192b2678901c9a4c6fce7e9df62cd 100644 (file)
@@ -1,7 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_NET_DSA_BCM_SF2)  += bcm-sf2.o
 bcm-sf2-objs                   := bcm_sf2.o bcm_sf2_cfp.o
-obj-$(CONFIG_NET_DSA_LOOP)     += dsa_loop.o dsa_loop_bdinfo.o
+obj-$(CONFIG_NET_DSA_LOOP)     += dsa_loop.o
+ifdef CONFIG_NET_DSA_LOOP
+obj-$(CONFIG_FIXED_PHY)                += dsa_loop_bdinfo.o
+endif
 obj-$(CONFIG_NET_DSA_MT7530)   += mt7530.o
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
 obj-$(CONFIG_NET_DSA_QCA8K)    += qca8k.o
index db830a1141d99774f6e21037a63840518dfdab25..63e02a54d5379202592a9dcdbbb3e0e095996173 100644 (file)
@@ -814,8 +814,8 @@ void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
        unsigned int i;
 
        for (i = 0; i < mib_size; i++)
-               memcpy(data + i * ETH_GSTRING_LEN,
-                      mibs[i].name, ETH_GSTRING_LEN);
+               strlcpy(data + i * ETH_GSTRING_LEN,
+                       mibs[i].name, ETH_GSTRING_LEN);
 }
 EXPORT_SYMBOL(b53_get_strings);
 
index 29c3075bfb052f1dbc7e788bf093bd0b8a94f152..fdc673484addcf09a8edd0f69f1c9d167816619f 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 config NET_VENDOR_8390
-       bool "National Semi-conductor 8390 devices"
+       bool "National Semiconductor 8390 devices"
        default y
        depends on NET_VENDOR_NATSEMI
        ---help---
index 3e5833cf1fabaa35f1fde959bcd4b7ed988ca44c..eb23f9ba1a9a10091f8d42bb71e35291e224c4f1 100644 (file)
@@ -426,6 +426,8 @@ static int xgbe_pci_resume(struct pci_dev *pdev)
        struct net_device *netdev = pdata->netdev;
        int ret = 0;
 
+       XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
+
        pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
        XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
 
index 0b49f1aeebd3dd98d6e0491aa1cc3e46a996a5a9..fc7383106946ca6461f62ea305be0f03bb59c227 100644 (file)
@@ -36,6 +36,8 @@
 #define AQ_CFG_TX_FRAME_MAX  (16U * 1024U)
 #define AQ_CFG_RX_FRAME_MAX  (4U * 1024U)
 
+#define AQ_CFG_TX_CLEAN_BUDGET 256U
+
 /* LRO */
 #define AQ_CFG_IS_LRO_DEF           1U
 
index ebbaf63eaf475123a0d67b7eef8cc1ed42e348e6..c96a92118b8b85272e7c3551dc5de31da3bf8852 100644 (file)
@@ -247,6 +247,8 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
        self->ndev->hw_features |= aq_hw_caps->hw_features;
        self->ndev->features = aq_hw_caps->hw_features;
        self->ndev->priv_flags = aq_hw_caps->hw_priv_flags;
+       self->ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+
        self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
        self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;
 
@@ -937,3 +939,23 @@ err_exit:
 out:
        return err;
 }
+
+void aq_nic_shutdown(struct aq_nic_s *self)
+{
+       int err = 0;
+
+       if (!self->ndev)
+               return;
+
+       rtnl_lock();
+
+       netif_device_detach(self->ndev);
+
+       err = aq_nic_stop(self);
+       if (err < 0)
+               goto err_exit;
+       aq_nic_deinit(self);
+
+err_exit:
+       rtnl_unlock();
+}
\ No newline at end of file
index d16b0f1a95aa485753f90afda57ad0edf86081c1..219b550d16650bd6b205fb6e10855627a0fd277b 100644 (file)
@@ -118,5 +118,6 @@ struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
 u32 aq_nic_get_fw_version(struct aq_nic_s *self);
 int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg);
 int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
+void aq_nic_shutdown(struct aq_nic_s *self);
 
 #endif /* AQ_NIC_H */
index 22889fc158f2779d57f990f1fb52641d55cfe550..ecc6306f940f5d9f975d9cd422114f0be05c3435 100644 (file)
@@ -226,6 +226,10 @@ static int aq_pci_probe(struct pci_dev *pdev,
                goto err_ioremap;
 
        self->aq_hw = kzalloc(sizeof(*self->aq_hw), GFP_KERNEL);
+       if (!self->aq_hw) {
+               err = -ENOMEM;
+               goto err_ioremap;
+       }
        self->aq_hw->aq_nic_cfg = aq_nic_get_cfg(self);
 
        for (bar = 0; bar < 4; ++bar) {
@@ -235,19 +239,19 @@ static int aq_pci_probe(struct pci_dev *pdev,
                        mmio_pa = pci_resource_start(pdev, bar);
                        if (mmio_pa == 0U) {
                                err = -EIO;
-                               goto err_ioremap;
+                               goto err_free_aq_hw;
                        }
 
                        reg_sz = pci_resource_len(pdev, bar);
                        if ((reg_sz <= 24 /*ATL_REGS_SIZE*/)) {
                                err = -EIO;
-                               goto err_ioremap;
+                               goto err_free_aq_hw;
                        }
 
                        self->aq_hw->mmio = ioremap_nocache(mmio_pa, reg_sz);
                        if (!self->aq_hw->mmio) {
                                err = -EIO;
-                               goto err_ioremap;
+                               goto err_free_aq_hw;
                        }
                        break;
                }
@@ -255,7 +259,7 @@ static int aq_pci_probe(struct pci_dev *pdev,
 
        if (bar == 4) {
                err = -EIO;
-               goto err_ioremap;
+               goto err_free_aq_hw;
        }
 
        numvecs = min((u8)AQ_CFG_VECS_DEF,
@@ -290,6 +294,8 @@ err_register:
        aq_pci_free_irq_vectors(self);
 err_hwinit:
        iounmap(self->aq_hw->mmio);
+err_free_aq_hw:
+       kfree(self->aq_hw);
 err_ioremap:
        free_netdev(ndev);
 err_pci_func:
@@ -317,6 +323,20 @@ static void aq_pci_remove(struct pci_dev *pdev)
        pci_disable_device(pdev);
 }
 
+static void aq_pci_shutdown(struct pci_dev *pdev)
+{
+       struct aq_nic_s *self = pci_get_drvdata(pdev);
+
+       aq_nic_shutdown(self);
+
+       pci_disable_device(pdev);
+
+       if (system_state == SYSTEM_POWER_OFF) {
+               pci_wake_from_d3(pdev, false);
+               pci_set_power_state(pdev, PCI_D3hot);
+       }
+}
+
 static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg)
 {
        struct aq_nic_s *self = pci_get_drvdata(pdev);
@@ -339,6 +359,7 @@ static struct pci_driver aq_pci_ops = {
        .remove = aq_pci_remove,
        .suspend = aq_pci_suspend,
        .resume = aq_pci_resume,
+       .shutdown = aq_pci_shutdown,
 };
 
 module_pci_driver(aq_pci_ops);
index 0be6a11370bb3e233370c0dd377c8558310ab0f5..b5f1f62e8e253785436fa7cd9119a8467edf4fd4 100644 (file)
@@ -136,11 +136,12 @@ void aq_ring_queue_stop(struct aq_ring_s *ring)
                netif_stop_subqueue(ndev, ring->idx);
 }
 
-void aq_ring_tx_clean(struct aq_ring_s *self)
+bool aq_ring_tx_clean(struct aq_ring_s *self)
 {
        struct device *dev = aq_nic_get_dev(self->aq_nic);
+       unsigned int budget = AQ_CFG_TX_CLEAN_BUDGET;
 
-       for (; self->sw_head != self->hw_head;
+       for (; self->sw_head != self->hw_head && budget--;
                self->sw_head = aq_ring_next_dx(self, self->sw_head)) {
                struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head];
 
@@ -167,6 +168,8 @@ void aq_ring_tx_clean(struct aq_ring_s *self)
                buff->pa = 0U;
                buff->eop_index = 0xffffU;
        }
+
+       return !!budget;
 }
 
 #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
index 965fae0fb6e0ddee8165a91097aeb148cb1308ab..ac1329f4051d7f3681e18f0e886fe9ec58accc88 100644 (file)
@@ -153,7 +153,7 @@ void aq_ring_free(struct aq_ring_s *self);
 void aq_ring_update_queue_state(struct aq_ring_s *ring);
 void aq_ring_queue_wake(struct aq_ring_s *ring);
 void aq_ring_queue_stop(struct aq_ring_s *ring);
-void aq_ring_tx_clean(struct aq_ring_s *self);
+bool aq_ring_tx_clean(struct aq_ring_s *self);
 int aq_ring_rx_clean(struct aq_ring_s *self,
                     struct napi_struct *napi,
                     int *work_done,
index f890b8a5a8623ef20a4c3ca016b4dbe2ad16f475..d335c334fa561ed2ae1a8dad45fcd9af822ee0a7 100644 (file)
@@ -35,12 +35,12 @@ struct aq_vec_s {
 static int aq_vec_poll(struct napi_struct *napi, int budget)
 {
        struct aq_vec_s *self = container_of(napi, struct aq_vec_s, napi);
+       unsigned int sw_tail_old = 0U;
        struct aq_ring_s *ring = NULL;
+       bool was_tx_cleaned = true;
+       unsigned int i = 0U;
        int work_done = 0;
        int err = 0;
-       unsigned int i = 0U;
-       unsigned int sw_tail_old = 0U;
-       bool was_tx_cleaned = false;
 
        if (!self) {
                err = -EINVAL;
@@ -57,9 +57,8 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
 
                        if (ring[AQ_VEC_TX_ID].sw_head !=
                            ring[AQ_VEC_TX_ID].hw_head) {
-                               aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]);
+                               was_tx_cleaned = aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]);
                                aq_ring_update_queue_state(&ring[AQ_VEC_TX_ID]);
-                               was_tx_cleaned = true;
                        }
 
                        err = self->aq_hw_ops->hw_ring_rx_receive(self->aq_hw,
@@ -90,7 +89,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
                        }
                }
 
-               if (was_tx_cleaned)
+               if (!was_tx_cleaned)
                        work_done = budget;
 
                if (work_done < budget) {
index 967f0fd07fcf2d5c377476b6feabba9e9b4f1eac..d3b847ec7465cc6a87f345d53b777662c969140b 100644 (file)
 
 #define HW_ATL_UCP_0X370_REG    0x0370U
 
+#define HW_ATL_MIF_CMD          0x0200U
+#define HW_ATL_MIF_ADDR         0x0208U
+#define HW_ATL_MIF_VAL          0x020CU
+
 #define HW_ATL_FW_SM_RAM        0x2U
 #define HW_ATL_MPI_FW_VERSION  0x18
 #define HW_ATL_MPI_CONTROL_ADR  0x0368U
@@ -79,16 +83,15 @@ int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
 
 static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
 {
+       u32 gsr, val;
        int k = 0;
-       u32 gsr;
 
        aq_hw_write_reg(self, 0x404, 0x40e1);
        AQ_HW_SLEEP(50);
 
        /* Cleanup SPI */
-       aq_hw_write_reg(self, 0x534, 0xA0);
-       aq_hw_write_reg(self, 0x100, 0x9F);
-       aq_hw_write_reg(self, 0x100, 0x809F);
+       val = aq_hw_read_reg(self, 0x53C);
+       aq_hw_write_reg(self, 0x53C, val | 0x10);
 
        gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
        aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
@@ -97,7 +100,14 @@ static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
        aq_hw_write_reg(self, 0x404, 0x80e0);
        aq_hw_write_reg(self, 0x32a8, 0x0);
        aq_hw_write_reg(self, 0x520, 0x1);
+
+       /* Reset SPI again because of possible interrupted SPI burst */
+       val = aq_hw_read_reg(self, 0x53C);
+       aq_hw_write_reg(self, 0x53C, val | 0x10);
        AQ_HW_SLEEP(10);
+       /* Clear SPI reset state */
+       aq_hw_write_reg(self, 0x53C, val & ~0x10);
+
        aq_hw_write_reg(self, 0x404, 0x180e0);
 
        for (k = 0; k < 1000; k++) {
@@ -141,13 +151,15 @@ static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
                aq_pr_err("FW kickstart failed\n");
                return -EIO;
        }
+       /* Old FW requires fixed delay after init */
+       AQ_HW_SLEEP(15);
 
        return 0;
 }
 
 static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
 {
-       u32 gsr, rbl_status;
+       u32 gsr, val, rbl_status;
        int k;
 
        aq_hw_write_reg(self, 0x404, 0x40e1);
@@ -157,6 +169,10 @@ static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
        /* Alter RBL status */
        aq_hw_write_reg(self, 0x388, 0xDEAD);
 
+       /* Cleanup SPI */
+       val = aq_hw_read_reg(self, 0x53C);
+       aq_hw_write_reg(self, 0x53C, val | 0x10);
+
        /* Global software reset*/
        hw_atl_rx_rx_reg_res_dis_set(self, 0U);
        hw_atl_tx_tx_reg_res_dis_set(self, 0U);
@@ -204,6 +220,8 @@ static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
                aq_pr_err("FW kickstart failed\n");
                return -EIO;
        }
+       /* Old FW requires fixed delay after init */
+       AQ_HW_SLEEP(15);
 
        return 0;
 }
@@ -255,18 +273,22 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
                }
        }
 
-       aq_hw_write_reg(self, 0x00000208U, a);
-
-       for (++cnt; --cnt;) {
-               u32 i = 0U;
+       aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
 
-               aq_hw_write_reg(self, 0x00000200U, 0x00008000U);
+       for (++cnt; --cnt && !err;) {
+               aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
 
-               for (i = 1024U;
-                       (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
-               }
+               if (IS_CHIP_FEATURE(REVISION_B1))
+                       AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
+                                                          HW_ATL_MIF_ADDR),
+                                      1, 1000U);
+               else
+                       AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
+                                                          HW_ATL_MIF_CMD)),
+                                      1, 1000U);
 
-               *(p++) = aq_hw_read_reg(self, 0x0000020CU);
+               *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
+               a += 4;
        }
 
        hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
@@ -662,14 +684,18 @@ void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
        u32 val = hw_atl_reg_glb_mif_id_get(self);
        u32 mif_rev = val & 0xFFU;
 
-       if ((3U & mif_rev) == 1U) {
-               chip_features |=
-                       HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
+       if ((0xFU & mif_rev) == 1U) {
+               chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
                        HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
                        HAL_ATLANTIC_UTILS_CHIP_MIPS;
-       } else if ((3U & mif_rev) == 2U) {
-               chip_features |=
-                       HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
+       } else if ((0xFU & mif_rev) == 2U) {
+               chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
+                       HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
+                       HAL_ATLANTIC_UTILS_CHIP_MIPS |
+                       HAL_ATLANTIC_UTILS_CHIP_TPO2 |
+                       HAL_ATLANTIC_UTILS_CHIP_RPF2;
+       } else if ((0xFU & mif_rev) == 0xAU) {
+               chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
                        HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
                        HAL_ATLANTIC_UTILS_CHIP_MIPS |
                        HAL_ATLANTIC_UTILS_CHIP_TPO2 |
index 2c690947910a3927f559efd63df20d99b0e8010b..cd8f18f39c611f8f709f71c7a1c23da8332a3fa4 100644 (file)
@@ -161,6 +161,7 @@ struct __packed hw_aq_atl_utils_mbox {
 #define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ       0x00000010U
 #define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0  0x01000000U
 #define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0  0x02000000U
+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B1  0x04000000U
 
 #define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \
        self->chip_features)
index 5265b937677bcada0c38e7b41ee3b744299cbece..a445de6837a6c8bff1c250d4702612f4795b2477 100644 (file)
@@ -13,7 +13,7 @@
 #define NIC_MAJOR_DRIVER_VERSION           2
 #define NIC_MINOR_DRIVER_VERSION           0
 #define NIC_BUILD_DRIVER_VERSION           2
-#define NIC_REVISION_DRIVER_VERSION        0
+#define NIC_REVISION_DRIVER_VERSION        1
 
 #define AQ_CFG_DRV_VERSION_SUFFIX "-kern"
 
index 16f9bee992fedfab2069a2324c38fd4a5f142c93..0f65768026072ae7ded390fef283269f180f6e24 100644 (file)
@@ -169,8 +169,10 @@ static int emac_rockchip_probe(struct platform_device *pdev)
        /* Optional regulator for PHY */
        priv->regulator = devm_regulator_get_optional(dev, "phy");
        if (IS_ERR(priv->regulator)) {
-               if (PTR_ERR(priv->regulator) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
+               if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) {
+                       err = -EPROBE_DEFER;
+                       goto out_clk_disable;
+               }
                dev_err(dev, "no regulator found\n");
                priv->regulator = NULL;
        }
index f15a8fc6dfc97419f8e1492dd1717b9d2e562b84..3fc549b88c43b082bd22023f99ec13fbf1d78525 100644 (file)
@@ -855,10 +855,12 @@ static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_tx_ring *ring,
 static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
                                             struct bcm_sysport_tx_ring *ring)
 {
-       unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
        unsigned int pkts_compl = 0, bytes_compl = 0;
        struct net_device *ndev = priv->netdev;
+       unsigned int txbds_processed = 0;
        struct bcm_sysport_cb *cb;
+       unsigned int txbds_ready;
+       unsigned int c_index;
        u32 hw_ind;
 
        /* Clear status before servicing to reduce spurious interrupts */
@@ -871,29 +873,23 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
        /* Compute how many descriptors have been processed since last call */
        hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
        c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
-       ring->p_index = (hw_ind & RING_PROD_INDEX_MASK);
-
-       last_c_index = ring->c_index;
-       num_tx_cbs = ring->size;
-
-       c_index &= (num_tx_cbs - 1);
-
-       if (c_index >= last_c_index)
-               last_tx_cn = c_index - last_c_index;
-       else
-               last_tx_cn = num_tx_cbs - last_c_index + c_index;
+       txbds_ready = (c_index - ring->c_index) & RING_CONS_INDEX_MASK;
 
        netif_dbg(priv, tx_done, ndev,
-                 "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
-                 ring->index, c_index, last_tx_cn, last_c_index);
+                 "ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n",
+                 ring->index, ring->c_index, c_index, txbds_ready);
 
-       while (last_tx_cn-- > 0) {
-               cb = ring->cbs + last_c_index;
+       while (txbds_processed < txbds_ready) {
+               cb = &ring->cbs[ring->clean_index];
                bcm_sysport_tx_reclaim_one(ring, cb, &bytes_compl, &pkts_compl);
 
                ring->desc_count++;
-               last_c_index++;
-               last_c_index &= (num_tx_cbs - 1);
+               txbds_processed++;
+
+               if (likely(ring->clean_index < ring->size - 1))
+                       ring->clean_index++;
+               else
+                       ring->clean_index = 0;
        }
 
        u64_stats_update_begin(&priv->syncp);
@@ -1394,6 +1390,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
        netif_tx_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64);
        ring->index = index;
        ring->size = size;
+       ring->clean_index = 0;
        ring->alloc_size = ring->size;
        ring->desc_cpu = p;
        ring->desc_count = ring->size;
index f5a984c1c986535f3421bafd9c851ec995ccf3b0..19c91c76e32763f399ebc8d67c7a0b647da44572 100644 (file)
@@ -706,7 +706,7 @@ struct bcm_sysport_tx_ring {
        unsigned int    desc_count;     /* Number of descriptors */
        unsigned int    curr_desc;      /* Current descriptor */
        unsigned int    c_index;        /* Last consumer index */
-       unsigned int    p_index;        /* Current producer index */
+       unsigned int    clean_index;    /* Current clean index */
        struct bcm_sysport_cb *cbs;     /* Transmit control blocks */
        struct dma_desc *desc_cpu;      /* CPU view of the descriptor */
        struct bcm_sysport_priv *priv;  /* private context backpointer */
index 74fc9af4aadb4358a53858fa93e6b185637a618e..b8388e93520a1a45b6d20b7369f0e6c109c22f36 100644 (file)
@@ -13913,7 +13913,7 @@ static void bnx2x_register_phc(struct bnx2x *bp)
        bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &bp->pdev->dev);
        if (IS_ERR(bp->ptp_clock)) {
                bp->ptp_clock = NULL;
-               BNX2X_ERR("PTP clock registeration failed\n");
+               BNX2X_ERR("PTP clock registration failed\n");
        }
 }
 
index 1500243b988650625c5deeaf5ac9759e2670b514..c7e5e6f09647d5d798e50db2beb1ee7b1e28f277 100644 (file)
@@ -1439,7 +1439,7 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
            (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
                u16 vlan_proto = tpa_info->metadata >>
                        RX_CMP_FLAGS2_METADATA_TPID_SFT;
-               u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_VID_MASK;
+               u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_TCI_MASK;
 
                __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag);
        }
@@ -1623,7 +1623,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons,
             cpu_to_le32(RX_CMP_FLAGS2_META_FORMAT_VLAN)) &&
            (skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
                u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data);
-               u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_VID_MASK;
+               u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_TCI_MASK;
                u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT;
 
                __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag);
@@ -3847,6 +3847,9 @@ static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, u16 vnic_id, u32 tpa_flags)
        struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
        struct hwrm_vnic_tpa_cfg_input req = {0};
 
+       if (vnic->fw_vnic_id == INVALID_HW_RING_ID)
+               return 0;
+
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_TPA_CFG, -1, -1);
 
        if (tpa_flags) {
@@ -4558,18 +4561,17 @@ int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings)
        return rc;
 }
 
-static int
-bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
-                          int ring_grps, int cp_rings, int vnics)
+static void
+__bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, struct hwrm_func_cfg_input *req,
+                            int tx_rings, int rx_rings, int ring_grps,
+                            int cp_rings, int vnics)
 {
-       struct hwrm_func_cfg_input req = {0};
        u32 enables = 0;
-       int rc;
 
-       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
-       req.fid = cpu_to_le16(0xffff);
+       bnxt_hwrm_cmd_hdr_init(bp, req, HWRM_FUNC_CFG, -1, -1);
+       req->fid = cpu_to_le16(0xffff);
        enables |= tx_rings ? FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS : 0;
-       req.num_tx_rings = cpu_to_le16(tx_rings);
+       req->num_tx_rings = cpu_to_le16(tx_rings);
        if (bp->flags & BNXT_FLAG_NEW_RM) {
                enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0;
                enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
@@ -4578,16 +4580,53 @@ bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
                           FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0;
                enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0;
 
-               req.num_rx_rings = cpu_to_le16(rx_rings);
-               req.num_hw_ring_grps = cpu_to_le16(ring_grps);
-               req.num_cmpl_rings = cpu_to_le16(cp_rings);
-               req.num_stat_ctxs = req.num_cmpl_rings;
-               req.num_vnics = cpu_to_le16(vnics);
+               req->num_rx_rings = cpu_to_le16(rx_rings);
+               req->num_hw_ring_grps = cpu_to_le16(ring_grps);
+               req->num_cmpl_rings = cpu_to_le16(cp_rings);
+               req->num_stat_ctxs = req->num_cmpl_rings;
+               req->num_vnics = cpu_to_le16(vnics);
        }
-       if (!enables)
+       req->enables = cpu_to_le32(enables);
+}
+
+static void
+__bnxt_hwrm_reserve_vf_rings(struct bnxt *bp,
+                            struct hwrm_func_vf_cfg_input *req, int tx_rings,
+                            int rx_rings, int ring_grps, int cp_rings,
+                            int vnics)
+{
+       u32 enables = 0;
+
+       bnxt_hwrm_cmd_hdr_init(bp, req, HWRM_FUNC_VF_CFG, -1, -1);
+       enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0;
+       enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS : 0;
+       enables |= cp_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
+                             FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
+       enables |= ring_grps ? FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0;
+       enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0;
+
+       req->num_tx_rings = cpu_to_le16(tx_rings);
+       req->num_rx_rings = cpu_to_le16(rx_rings);
+       req->num_hw_ring_grps = cpu_to_le16(ring_grps);
+       req->num_cmpl_rings = cpu_to_le16(cp_rings);
+       req->num_stat_ctxs = req->num_cmpl_rings;
+       req->num_vnics = cpu_to_le16(vnics);
+
+       req->enables = cpu_to_le32(enables);
+}
+
+static int
+bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
+                          int ring_grps, int cp_rings, int vnics)
+{
+       struct hwrm_func_cfg_input req = {0};
+       int rc;
+
+       __bnxt_hwrm_reserve_pf_rings(bp, &req, tx_rings, rx_rings, ring_grps,
+                                    cp_rings, vnics);
+       if (!req.enables)
                return 0;
 
-       req.enables = cpu_to_le32(enables);
        rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                return -ENOMEM;
@@ -4604,7 +4643,6 @@ bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
                           int ring_grps, int cp_rings, int vnics)
 {
        struct hwrm_func_vf_cfg_input req = {0};
-       u32 enables = 0;
        int rc;
 
        if (!(bp->flags & BNXT_FLAG_NEW_RM)) {
@@ -4612,22 +4650,8 @@ bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
                return 0;
        }
 
-       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1);
-       enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0;
-       enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS : 0;
-       enables |= cp_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
-                             FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
-       enables |= ring_grps ? FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0;
-       enables |= vnics ? FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS : 0;
-
-       req.num_tx_rings = cpu_to_le16(tx_rings);
-       req.num_rx_rings = cpu_to_le16(rx_rings);
-       req.num_hw_ring_grps = cpu_to_le16(ring_grps);
-       req.num_cmpl_rings = cpu_to_le16(cp_rings);
-       req.num_stat_ctxs = req.num_cmpl_rings;
-       req.num_vnics = cpu_to_le16(vnics);
-
-       req.enables = cpu_to_le32(enables);
+       __bnxt_hwrm_reserve_vf_rings(bp, &req, tx_rings, rx_rings, ring_grps,
+                                    cp_rings, vnics);
        rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                return -ENOMEM;
@@ -4743,39 +4767,25 @@ static bool bnxt_need_reserve_rings(struct bnxt *bp)
 }
 
 static int bnxt_hwrm_check_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
-                                   int ring_grps, int cp_rings)
+                                   int ring_grps, int cp_rings, int vnics)
 {
        struct hwrm_func_vf_cfg_input req = {0};
-       u32 flags, enables;
+       u32 flags;
        int rc;
 
        if (!(bp->flags & BNXT_FLAG_NEW_RM))
                return 0;
 
-       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_CFG, -1, -1);
+       __bnxt_hwrm_reserve_vf_rings(bp, &req, tx_rings, rx_rings, ring_grps,
+                                    cp_rings, vnics);
        flags = FUNC_VF_CFG_REQ_FLAGS_TX_ASSETS_TEST |
                FUNC_VF_CFG_REQ_FLAGS_RX_ASSETS_TEST |
                FUNC_VF_CFG_REQ_FLAGS_CMPL_ASSETS_TEST |
                FUNC_VF_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST |
                FUNC_VF_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST |
                FUNC_VF_CFG_REQ_FLAGS_VNIC_ASSETS_TEST;
-       enables = FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS |
-                 FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS |
-                 FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
-                 FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS |
-                 FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS |
-                 FUNC_VF_CFG_REQ_ENABLES_NUM_VNICS;
 
        req.flags = cpu_to_le32(flags);
-       req.enables = cpu_to_le32(enables);
-       req.num_tx_rings = cpu_to_le16(tx_rings);
-       req.num_rx_rings = cpu_to_le16(rx_rings);
-       req.num_cmpl_rings = cpu_to_le16(cp_rings);
-       req.num_hw_ring_grps = cpu_to_le16(ring_grps);
-       req.num_stat_ctxs = cpu_to_le16(cp_rings);
-       req.num_vnics = cpu_to_le16(1);
-       if (bp->flags & BNXT_FLAG_RFS)
-               req.num_vnics = cpu_to_le16(rx_rings + 1);
        rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                return -ENOMEM;
@@ -4783,38 +4793,23 @@ static int bnxt_hwrm_check_vf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
 }
 
 static int bnxt_hwrm_check_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
-                                   int ring_grps, int cp_rings)
+                                   int ring_grps, int cp_rings, int vnics)
 {
        struct hwrm_func_cfg_input req = {0};
-       u32 flags, enables;
+       u32 flags;
        int rc;
 
-       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1);
-       req.fid = cpu_to_le16(0xffff);
+       __bnxt_hwrm_reserve_pf_rings(bp, &req, tx_rings, rx_rings, ring_grps,
+                                    cp_rings, vnics);
        flags = FUNC_CFG_REQ_FLAGS_TX_ASSETS_TEST;
-       enables = FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS;
-       req.num_tx_rings = cpu_to_le16(tx_rings);
-       if (bp->flags & BNXT_FLAG_NEW_RM) {
+       if (bp->flags & BNXT_FLAG_NEW_RM)
                flags |= FUNC_CFG_REQ_FLAGS_RX_ASSETS_TEST |
                         FUNC_CFG_REQ_FLAGS_CMPL_ASSETS_TEST |
                         FUNC_CFG_REQ_FLAGS_RING_GRP_ASSETS_TEST |
                         FUNC_CFG_REQ_FLAGS_STAT_CTX_ASSETS_TEST |
                         FUNC_CFG_REQ_FLAGS_VNIC_ASSETS_TEST;
-               enables |= FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS |
-                          FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
-                          FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS |
-                          FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS |
-                          FUNC_CFG_REQ_ENABLES_NUM_VNICS;
-               req.num_rx_rings = cpu_to_le16(rx_rings);
-               req.num_cmpl_rings = cpu_to_le16(cp_rings);
-               req.num_hw_ring_grps = cpu_to_le16(ring_grps);
-               req.num_stat_ctxs = cpu_to_le16(cp_rings);
-               req.num_vnics = cpu_to_le16(1);
-               if (bp->flags & BNXT_FLAG_RFS)
-                       req.num_vnics = cpu_to_le16(rx_rings + 1);
-       }
+
        req.flags = cpu_to_le32(flags);
-       req.enables = cpu_to_le32(enables);
        rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                return -ENOMEM;
@@ -4822,17 +4817,17 @@ static int bnxt_hwrm_check_pf_rings(struct bnxt *bp, int tx_rings, int rx_rings,
 }
 
 static int bnxt_hwrm_check_rings(struct bnxt *bp, int tx_rings, int rx_rings,
-                                int ring_grps, int cp_rings)
+                                int ring_grps, int cp_rings, int vnics)
 {
        if (bp->hwrm_spec_code < 0x10801)
                return 0;
 
        if (BNXT_PF(bp))
                return bnxt_hwrm_check_pf_rings(bp, tx_rings, rx_rings,
-                                               ring_grps, cp_rings);
+                                               ring_grps, cp_rings, vnics);
 
        return bnxt_hwrm_check_vf_rings(bp, tx_rings, rx_rings, ring_grps,
-                                       cp_rings);
+                                       cp_rings, vnics);
 }
 
 static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
@@ -5865,7 +5860,6 @@ static int bnxt_init_msix(struct bnxt *bp)
                if (rc)
                        goto msix_setup_exit;
 
-               bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
                bp->cp_nr_rings = (min == 1) ?
                                  max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
                                  bp->tx_nr_rings + bp->rx_nr_rings;
@@ -5897,7 +5891,6 @@ static int bnxt_init_inta(struct bnxt *bp)
        bp->rx_nr_rings = 1;
        bp->tx_nr_rings = 1;
        bp->cp_nr_rings = 1;
-       bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
        bp->flags |= BNXT_FLAG_SHARED_RINGS;
        bp->irq_tbl[0].vector = bp->pdev->irq;
        return 0;
@@ -7531,7 +7524,7 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
        int max_rx, max_tx, tx_sets = 1;
        int tx_rings_needed;
        int rx_rings = rx;
-       int cp, rc;
+       int cp, vnics, rc;
 
        if (tcs)
                tx_sets = tcs;
@@ -7547,10 +7540,15 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
        if (max_tx < tx_rings_needed)
                return -ENOMEM;
 
+       vnics = 1;
+       if (bp->flags & BNXT_FLAG_RFS)
+               vnics += rx_rings;
+
        if (bp->flags & BNXT_FLAG_AGG_RINGS)
                rx_rings <<= 1;
        cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx;
-       return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp);
+       return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp,
+                                    vnics);
 }
 
 static void bnxt_unmap_bars(struct bnxt *bp, struct pci_dev *pdev)
@@ -8437,13 +8435,20 @@ int bnxt_restore_pf_fw_resources(struct bnxt *bp)
                return 0;
 
        bnxt_hwrm_func_qcaps(bp);
-       __bnxt_close_nic(bp, true, false);
+
+       if (netif_running(bp->dev))
+               __bnxt_close_nic(bp, true, false);
+
        bnxt_clear_int_mode(bp);
        rc = bnxt_init_int_mode(bp);
-       if (rc)
-               dev_close(bp->dev);
-       else
-               rc = bnxt_open_nic(bp, true, false);
+
+       if (netif_running(bp->dev)) {
+               if (rc)
+                       dev_close(bp->dev);
+               else
+                       rc = bnxt_open_nic(bp, true, false);
+       }
+
        return rc;
 }
 
@@ -8664,6 +8669,11 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                goto init_err_pci_clean;
 
+       /* No TC has been set yet and rings may have been trimmed due to
+        * limited MSIX, so we re-initialize the TX rings per TC.
+        */
+       bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+
        bnxt_get_wol_settings(bp);
        if (bp->flags & BNXT_FLAG_WOL_CAP)
                device_set_wakeup_enable(&pdev->dev, bp->wol);
index 1989c470172cba7ac56e8c030f847cd0c5a32531..5e3d62189cab8e05b5c65f2cae0e11fa6e3cf459 100644 (file)
@@ -189,6 +189,7 @@ struct rx_cmp_ext {
        #define RX_CMP_FLAGS2_T_L4_CS_CALC                      (0x1 << 3)
        #define RX_CMP_FLAGS2_META_FORMAT_VLAN                  (0x1 << 4)
        __le32 rx_cmp_meta_data;
+       #define RX_CMP_FLAGS2_METADATA_TCI_MASK                 0xffff
        #define RX_CMP_FLAGS2_METADATA_VID_MASK                 0xfff
        #define RX_CMP_FLAGS2_METADATA_TPID_MASK                0xffff0000
         #define RX_CMP_FLAGS2_METADATA_TPID_SFT                 16
index fbe6e208e17b9ad190d1ee017c68075d0af70bb9..65c2cee357669a7a7b5784b3c7b9a3805095304f 100644 (file)
@@ -349,6 +349,9 @@ static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp, __le16 flow_handle)
        if (rc)
                netdev_info(bp->dev, "Error: %s: flow_handle=0x%x rc=%d",
                            __func__, flow_handle, rc);
+
+       if (rc)
+               rc = -EIO;
        return rc;
 }
 
@@ -484,13 +487,15 @@ static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow,
        req.action_flags = cpu_to_le16(action_flags);
 
        mutex_lock(&bp->hwrm_cmd_lock);
-
        rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (!rc)
                *flow_handle = resp->flow_handle;
-
        mutex_unlock(&bp->hwrm_cmd_lock);
 
+       if (rc == HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR)
+               rc = -ENOSPC;
+       else if (rc)
+               rc = -EIO;
        return rc;
 }
 
@@ -561,6 +566,8 @@ static int hwrm_cfa_decap_filter_alloc(struct bnxt *bp,
                netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
        mutex_unlock(&bp->hwrm_cmd_lock);
 
+       if (rc)
+               rc = -EIO;
        return rc;
 }
 
@@ -576,6 +583,9 @@ static int hwrm_cfa_decap_filter_free(struct bnxt *bp,
        rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
+
+       if (rc)
+               rc = -EIO;
        return rc;
 }
 
@@ -624,6 +634,8 @@ static int hwrm_cfa_encap_record_alloc(struct bnxt *bp,
                netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
        mutex_unlock(&bp->hwrm_cmd_lock);
 
+       if (rc)
+               rc = -EIO;
        return rc;
 }
 
@@ -639,6 +651,9 @@ static int hwrm_cfa_encap_record_free(struct bnxt *bp,
        rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc);
+
+       if (rc)
+               rc = -EIO;
        return rc;
 }
 
@@ -1269,11 +1284,8 @@ static int bnxt_tc_del_flow(struct bnxt *bp,
        flow_node = rhashtable_lookup_fast(&tc_info->flow_table,
                                           &tc_flow_cmd->cookie,
                                           tc_info->flow_ht_params);
-       if (!flow_node) {
-               netdev_info(bp->dev, "ERROR: no flow_node for cookie %lx",
-                           tc_flow_cmd->cookie);
+       if (!flow_node)
                return -EINVAL;
-       }
 
        return __bnxt_tc_del_flow(bp, flow_node);
 }
@@ -1290,11 +1302,8 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp,
        flow_node = rhashtable_lookup_fast(&tc_info->flow_table,
                                           &tc_flow_cmd->cookie,
                                           tc_info->flow_ht_params);
-       if (!flow_node) {
-               netdev_info(bp->dev, "Error: no flow_node for cookie %lx",
-                           tc_flow_cmd->cookie);
+       if (!flow_node)
                return -1;
-       }
 
        flow = &flow_node->flow;
        curr_stats = &flow->stats;
@@ -1344,8 +1353,10 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows,
        } else {
                netdev_info(bp->dev, "error rc=%d", rc);
        }
-
        mutex_unlock(&bp->hwrm_cmd_lock);
+
+       if (rc)
+               rc = -EIO;
        return rc;
 }
 
index a77ee2f8fb8d223cc121a36a2ffb703cc32a02d9..f2593978ae75fb195f462a957d443eeddbbddb46 100644 (file)
@@ -922,8 +922,8 @@ static int tg3_ape_send_event(struct tg3 *tp, u32 event)
        if (!(apedata & APE_FW_STATUS_READY))
                return -EAGAIN;
 
-       /* Wait for up to 1 millisecond for APE to service previous event. */
-       err = tg3_ape_event_lock(tp, 1000);
+       /* Wait for up to 20 millisecond for APE to service previous event. */
+       err = tg3_ape_event_lock(tp, 20000);
        if (err)
                return err;
 
@@ -946,6 +946,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
 
        switch (kind) {
        case RESET_KIND_INIT:
+               tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++);
                tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG,
                                APE_HOST_SEG_SIG_MAGIC);
                tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN,
@@ -962,13 +963,6 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
                event = APE_EVENT_STATUS_STATE_START;
                break;
        case RESET_KIND_SHUTDOWN:
-               /* With the interface we are currently using,
-                * APE does not track driver state.  Wiping
-                * out the HOST SEGMENT SIGNATURE forces
-                * the APE to assume OS absent status.
-                */
-               tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
-
                if (device_may_wakeup(&tp->pdev->dev) &&
                    tg3_flag(tp, WOL_ENABLE)) {
                        tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED,
@@ -990,6 +984,18 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
        tg3_ape_send_event(tp, event);
 }
 
+static void tg3_send_ape_heartbeat(struct tg3 *tp,
+                                  unsigned long interval)
+{
+       /* Check if hb interval has exceeded */
+       if (!tg3_flag(tp, ENABLE_APE) ||
+           time_before(jiffies, tp->ape_hb_jiffies + interval))
+               return;
+
+       tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++);
+       tp->ape_hb_jiffies = jiffies;
+}
+
 static void tg3_disable_ints(struct tg3 *tp)
 {
        int i;
@@ -7262,6 +7268,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
                }
        }
 
+       tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1);
        return work_done;
 
 tx_recovery:
@@ -7344,6 +7351,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
                }
        }
 
+       tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1);
        return work_done;
 
 tx_recovery:
@@ -10732,7 +10740,7 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
        if (tg3_flag(tp, ENABLE_APE))
                /* Write our heartbeat update interval to APE. */
                tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS,
-                               APE_HOST_HEARTBEAT_INT_DISABLE);
+                               APE_HOST_HEARTBEAT_INT_5SEC);
 
        tg3_write_sig_post_reset(tp, RESET_KIND_INIT);
 
@@ -11077,6 +11085,9 @@ static void tg3_timer(struct timer_list *t)
                tp->asf_counter = tp->asf_multiplier;
        }
 
+       /* Update the APE heartbeat every 5 seconds.*/
+       tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL);
+
        spin_unlock(&tp->lock);
 
 restart_timer:
@@ -16653,6 +16664,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
                                       pci_state_reg);
 
                tg3_ape_lock_init(tp);
+               tp->ape_hb_interval =
+                       msecs_to_jiffies(APE_HOST_HEARTBEAT_INT_5SEC);
        }
 
        /* Set up tp->grc_local_ctrl before calling
index 47f51cc0566d490b1ab3347ddbbebe080156677c..1d61aa3efda177c64c69465f0b72c0df5221ba37 100644 (file)
 #define TG3_APE_LOCK_PHY3              5
 #define TG3_APE_LOCK_GPIO              7
 
+#define TG3_APE_HB_INTERVAL             (tp->ape_hb_interval)
 #define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10
 
 
@@ -3423,6 +3424,10 @@ struct tg3 {
        struct device                   *hwmon_dev;
        bool                            link_up;
        bool                            pcierr_recovery;
+
+       u32                             ape_hb;
+       unsigned long                   ape_hb_interval;
+       unsigned long                   ape_hb_jiffies;
 };
 
 /* Accessor macros for chip and asic attributes
index c87c9c684a337ea3651ac668d693c73a34238a9b..d59497a7bdcebd6e3c93194daf4a073334fab786 100644 (file)
@@ -75,6 +75,8 @@ EXPORT_SYMBOL(cavium_ptp_get);
 
 void cavium_ptp_put(struct cavium_ptp *ptp)
 {
+       if (!ptp)
+               return;
        pci_dev_put(ptp->pdev);
 }
 EXPORT_SYMBOL(cavium_ptp_put);
index b68cde9f17d2b10c08ca60c7a4d8c80f2d095b97..7d9c5ffbd0412191fc112a5eb7174ef318786276 100644 (file)
@@ -67,11 +67,6 @@ module_param(cpi_alg, int, S_IRUGO);
 MODULE_PARM_DESC(cpi_alg,
                 "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)");
 
-struct nicvf_xdp_tx {
-       u64 dma_addr;
-       u8  qidx;
-};
-
 static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx)
 {
        if (nic->sqs_mode)
@@ -507,29 +502,14 @@ static int nicvf_init_resources(struct nicvf *nic)
        return 0;
 }
 
-static void nicvf_unmap_page(struct nicvf *nic, struct page *page, u64 dma_addr)
-{
-       /* Check if it's a recycled page, if not unmap the DMA mapping.
-        * Recycled page holds an extra reference.
-        */
-       if (page_ref_count(page) == 1) {
-               dma_addr &= PAGE_MASK;
-               dma_unmap_page_attrs(&nic->pdev->dev, dma_addr,
-                                    RCV_FRAG_LEN + XDP_HEADROOM,
-                                    DMA_FROM_DEVICE,
-                                    DMA_ATTR_SKIP_CPU_SYNC);
-       }
-}
-
 static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
                                struct cqe_rx_t *cqe_rx, struct snd_queue *sq,
                                struct rcv_queue *rq, struct sk_buff **skb)
 {
        struct xdp_buff xdp;
        struct page *page;
-       struct nicvf_xdp_tx *xdp_tx = NULL;
        u32 action;
-       u16 len, err, offset = 0;
+       u16 len, offset = 0;
        u64 dma_addr, cpu_addr;
        void *orig_data;
 
@@ -543,7 +523,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
        cpu_addr = (u64)phys_to_virt(cpu_addr);
        page = virt_to_page((void *)cpu_addr);
 
-       xdp.data_hard_start = page_address(page) + RCV_BUF_HEADROOM;
+       xdp.data_hard_start = page_address(page);
        xdp.data = (void *)cpu_addr;
        xdp_set_data_meta_invalid(&xdp);
        xdp.data_end = xdp.data + len;
@@ -563,7 +543,18 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
 
        switch (action) {
        case XDP_PASS:
-               nicvf_unmap_page(nic, page, dma_addr);
+               /* Check if it's a recycled page, if not
+                * unmap the DMA mapping.
+                *
+                * Recycled page holds an extra reference.
+                */
+               if (page_ref_count(page) == 1) {
+                       dma_addr &= PAGE_MASK;
+                       dma_unmap_page_attrs(&nic->pdev->dev, dma_addr,
+                                            RCV_FRAG_LEN + XDP_PACKET_HEADROOM,
+                                            DMA_FROM_DEVICE,
+                                            DMA_ATTR_SKIP_CPU_SYNC);
+               }
 
                /* Build SKB and pass on packet to network stack */
                *skb = build_skb(xdp.data,
@@ -576,20 +567,6 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
        case XDP_TX:
                nicvf_xdp_sq_append_pkt(nic, sq, (u64)xdp.data, dma_addr, len);
                return true;
-       case XDP_REDIRECT:
-               /* Save DMA address for use while transmitting */
-               xdp_tx = (struct nicvf_xdp_tx *)page_address(page);
-               xdp_tx->dma_addr = dma_addr;
-               xdp_tx->qidx = nicvf_netdev_qidx(nic, cqe_rx->rq_idx);
-
-               err = xdp_do_redirect(nic->pnicvf->netdev, &xdp, prog);
-               if (!err)
-                       return true;
-
-               /* Free the page on error */
-               nicvf_unmap_page(nic, page, dma_addr);
-               put_page(page);
-               break;
        default:
                bpf_warn_invalid_xdp_action(action);
                /* fall through */
@@ -597,7 +574,18 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
                trace_xdp_exception(nic->netdev, prog, action);
                /* fall through */
        case XDP_DROP:
-               nicvf_unmap_page(nic, page, dma_addr);
+               /* Check if it's a recycled page, if not
+                * unmap the DMA mapping.
+                *
+                * Recycled page holds an extra reference.
+                */
+               if (page_ref_count(page) == 1) {
+                       dma_addr &= PAGE_MASK;
+                       dma_unmap_page_attrs(&nic->pdev->dev, dma_addr,
+                                            RCV_FRAG_LEN + XDP_PACKET_HEADROOM,
+                                            DMA_FROM_DEVICE,
+                                            DMA_ATTR_SKIP_CPU_SYNC);
+               }
                put_page(page);
                return true;
        }
@@ -1864,50 +1852,6 @@ static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
        }
 }
 
-static int nicvf_xdp_xmit(struct net_device *netdev, struct xdp_buff *xdp)
-{
-       struct nicvf *nic = netdev_priv(netdev);
-       struct nicvf *snic = nic;
-       struct nicvf_xdp_tx *xdp_tx;
-       struct snd_queue *sq;
-       struct page *page;
-       int err, qidx;
-
-       if (!netif_running(netdev) || !nic->xdp_prog)
-               return -EINVAL;
-
-       page = virt_to_page(xdp->data);
-       xdp_tx = (struct nicvf_xdp_tx *)page_address(page);
-       qidx = xdp_tx->qidx;
-
-       if (xdp_tx->qidx >= nic->xdp_tx_queues)
-               return -EINVAL;
-
-       /* Get secondary Qset's info */
-       if (xdp_tx->qidx >= MAX_SND_QUEUES_PER_QS) {
-               qidx = xdp_tx->qidx / MAX_SND_QUEUES_PER_QS;
-               snic = (struct nicvf *)nic->snicvf[qidx - 1];
-               if (!snic)
-                       return -EINVAL;
-               qidx = xdp_tx->qidx % MAX_SND_QUEUES_PER_QS;
-       }
-
-       sq = &snic->qs->sq[qidx];
-       err = nicvf_xdp_sq_append_pkt(snic, sq, (u64)xdp->data,
-                                     xdp_tx->dma_addr,
-                                     xdp->data_end - xdp->data);
-       if (err)
-               return -ENOMEM;
-
-       nicvf_xdp_sq_doorbell(snic, sq, qidx);
-       return 0;
-}
-
-static void nicvf_xdp_flush(struct net_device *dev)
-{
-       return;
-}
-
 static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
 {
        struct hwtstamp_config config;
@@ -1986,8 +1930,6 @@ static const struct net_device_ops nicvf_netdev_ops = {
        .ndo_fix_features       = nicvf_fix_features,
        .ndo_set_features       = nicvf_set_features,
        .ndo_bpf                = nicvf_xdp,
-       .ndo_xdp_xmit           = nicvf_xdp_xmit,
-       .ndo_xdp_flush          = nicvf_xdp_flush,
        .ndo_do_ioctl           = nicvf_ioctl,
 };
 
index 3eae9ff9b53a69413c986bb189ece2dc84f597ea..d42704d0748434d92eb17c74b0b0530aaa50f536 100644 (file)
@@ -204,7 +204,7 @@ static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, struct rbdr *rbdr,
 
        /* Reserve space for header modifications by BPF program */
        if (rbdr->is_xdp)
-               buf_len += XDP_HEADROOM;
+               buf_len += XDP_PACKET_HEADROOM;
 
        /* Check if it's recycled */
        if (pgcache)
@@ -224,9 +224,8 @@ ret:
                        nic->rb_page = NULL;
                        return -ENOMEM;
                }
-
                if (pgcache)
-                       pgcache->dma_addr = *rbuf + XDP_HEADROOM;
+                       pgcache->dma_addr = *rbuf + XDP_PACKET_HEADROOM;
                nic->rb_page_offset += buf_len;
        }
 
@@ -1244,7 +1243,7 @@ int nicvf_xdp_sq_append_pkt(struct nicvf *nic, struct snd_queue *sq,
        int qentry;
 
        if (subdesc_cnt > sq->xdp_free_cnt)
-               return -1;
+               return 0;
 
        qentry = nicvf_get_sq_desc(sq, subdesc_cnt);
 
@@ -1255,7 +1254,7 @@ int nicvf_xdp_sq_append_pkt(struct nicvf *nic, struct snd_queue *sq,
 
        sq->xdp_desc_cnt += subdesc_cnt;
 
-       return 0;
+       return 1;
 }
 
 /* Calculate no of SQ subdescriptors needed to transmit all
@@ -1656,7 +1655,7 @@ static void nicvf_unmap_rcv_buffer(struct nicvf *nic, u64 dma_addr,
                if (page_ref_count(page) != 1)
                        return;
 
-               len += XDP_HEADROOM;
+               len += XDP_PACKET_HEADROOM;
                /* Receive buffers in XDP mode are mapped from page start */
                dma_addr &= PAGE_MASK;
        }
index ce1eed7a6d63bd2671b5a3706d03e1f7e9e08010..5e9a03cf1b4d30f220f789934275fb9f2c9ce660 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/netdevice.h>
 #include <linux/iommu.h>
-#include <linux/bpf.h>
 #include <net/xdp.h>
 #include "q_struct.h"
 
@@ -94,9 +93,6 @@
 #define RCV_FRAG_LEN    (SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \
                         SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 
-#define RCV_BUF_HEADROOM       128 /* To store dma address for XDP redirect */
-#define XDP_HEADROOM           (XDP_PACKET_HEADROOM + RCV_BUF_HEADROOM)
-
 #define MAX_CQES_FOR_TX                ((SND_QUEUE_LEN / MIN_SQ_DESC_PER_PKT_XMIT) * \
                                 MAX_CQE_PER_PKT_XMIT)
 
index 557fd8bfd54e575646f083e5c426ba6c28ecf338..00a1d2d13169901becc9ffd4c283a8e696372524 100644 (file)
@@ -472,7 +472,7 @@ int cudbg_collect_cim_la(struct cudbg_init *pdbg_init,
 
        if (is_t6(padap->params.chip)) {
                size = padap->params.cim_la_size / 10 + 1;
-               size *= 11 * sizeof(u32);
+               size *= 10 * sizeof(u32);
        } else {
                size = padap->params.cim_la_size / 8;
                size *= 8 * sizeof(u32);
index 30485f9a598f159fb5d44bba3cdd1d9cf1a36fdb..143686c60234ebfc23fe84762f40dbe4bdf98d18 100644 (file)
@@ -102,7 +102,7 @@ static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
        case CUDBG_CIM_LA:
                if (is_t6(adap->params.chip)) {
                        len = adap->params.cim_la_size / 10 + 1;
-                       len *= 11 * sizeof(u32);
+                       len *= 10 * sizeof(u32);
                } else {
                        len = adap->params.cim_la_size / 8;
                        len *= 8 * sizeof(u32);
index 56bc626ef00688a5a03f4ccdd349e3acd44555b7..61022b5f6743e7e52376bbb44b1cca64d7a64277 100644 (file)
@@ -4970,7 +4970,6 @@ static void cxgb4_mgmt_setup(struct net_device *dev)
        /* Initialize the device structure. */
        dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
        dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
-       dev->needs_free_netdev = true;
 }
 
 static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
@@ -4982,9 +4981,10 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs)
 
        pcie_fw = readl(adap->regs + PCIE_FW_A);
        /* Check if cxgb4 is the MASTER and fw is initialized */
-       if (!(pcie_fw & PCIE_FW_INIT_F) ||
+       if (num_vfs &&
+           (!(pcie_fw & PCIE_FW_INIT_F) ||
            !(pcie_fw & PCIE_FW_MASTER_VLD_F) ||
-           PCIE_FW_MASTER_G(pcie_fw) != CXGB4_UNIFIED_PF) {
+           PCIE_FW_MASTER_G(pcie_fw) != CXGB4_UNIFIED_PF)) {
                dev_warn(&pdev->dev,
                         "cxgb4 driver needs to be MASTER to support SRIOV\n");
                return -EOPNOTSUPP;
@@ -5180,6 +5180,8 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->name = pci_name(pdev);
        adapter->mbox = func;
        adapter->pf = func;
+       adapter->params.chip = chip;
+       adapter->adap_idx = adap_idx;
        adapter->msg_enable = DFLT_MSG_ENABLE;
        adapter->mbox_log = kzalloc(sizeof(*adapter->mbox_log) +
                                    (sizeof(struct mbox_cmd) *
@@ -5599,24 +5601,24 @@ static void remove_one(struct pci_dev *pdev)
 #if IS_ENABLED(CONFIG_IPV6)
                t4_cleanup_clip_tbl(adapter);
 #endif
-               iounmap(adapter->regs);
                if (!is_t4(adapter->params.chip))
                        iounmap(adapter->bar2);
-               pci_disable_pcie_error_reporting(pdev);
-               if ((adapter->flags & DEV_ENABLED)) {
-                       pci_disable_device(pdev);
-                       adapter->flags &= ~DEV_ENABLED;
-               }
-               pci_release_regions(pdev);
-               kfree(adapter->mbox_log);
-               synchronize_rcu();
-               kfree(adapter);
        }
 #ifdef CONFIG_PCI_IOV
        else {
                cxgb4_iov_configure(adapter->pdev, 0);
        }
 #endif
+       iounmap(adapter->regs);
+       pci_disable_pcie_error_reporting(pdev);
+       if ((adapter->flags & DEV_ENABLED)) {
+               pci_disable_device(pdev);
+               adapter->flags &= ~DEV_ENABLED;
+       }
+       pci_release_regions(pdev);
+       kfree(adapter->mbox_log);
+       synchronize_rcu();
+       kfree(adapter);
 }
 
 /* "Shutdown" quiesces the device, stopping Ingress Packet and Interrupt
index 047609ef0515a5019673e3b6f5b2cdad9da15b38..920bccd6bc406515574bafdbd6b573d65fa02e6c 100644 (file)
@@ -2637,7 +2637,6 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
 }
 
 #define EEPROM_STAT_ADDR   0x7bfc
-#define VPD_SIZE           0x800
 #define VPD_BASE           0x400
 #define VPD_BASE_OLD       0
 #define VPD_LEN            1024
@@ -2704,15 +2703,6 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
        if (!vpd)
                return -ENOMEM;
 
-       /* We have two VPD data structures stored in the adapter VPD area.
-        * By default, Linux calculates the size of the VPD area by traversing
-        * the first VPD area at offset 0x0, so we need to tell the OS what
-        * our real VPD size is.
-        */
-       ret = pci_set_vpd_size(adapter->pdev, VPD_SIZE);
-       if (ret < 0)
-               goto out;
-
        /* Card information normally starts at VPD_BASE but early cards had
         * it at 0.
         */
index 5eb999af2c40004fc028ecd67901c492916480c5..bd3f6e4d134138424ec5d627e6ce1937a7529079 100644 (file)
@@ -540,6 +540,7 @@ static int gmac_setup_txqs(struct net_device *netdev)
 
        if (port->txq_dma_base & ~DMA_Q_BASE_MASK) {
                dev_warn(geth->dev, "TX queue base it not aligned\n");
+               kfree(skb_tab);
                return -ENOMEM;
        }
 
index 7caa8da484217e074a9b7938a220a292b536667a..e4ec32a9ca1526daf07b151d69b56090bc218562 100644 (file)
@@ -2008,7 +2008,6 @@ static inline int dpaa_xmit(struct dpaa_priv *priv,
        }
 
        if (unlikely(err < 0)) {
-               percpu_stats->tx_errors++;
                percpu_stats->tx_fifo_errors++;
                return err;
        }
@@ -2278,7 +2277,6 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
        vaddr = phys_to_virt(addr);
        prefetch(vaddr + qm_fd_get_offset(fd));
 
-       fd_format = qm_fd_get_format(fd);
        /* The only FD types that we may receive are contig and S/G */
        WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg));
 
@@ -2311,8 +2309,10 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal,
 
        skb_len = skb->len;
 
-       if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
+       if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) {
+               percpu_stats->rx_dropped++;
                return qman_cb_dqrr_consume;
+       }
 
        percpu_stats->rx_packets++;
        percpu_stats->rx_bytes += skb_len;
@@ -2860,7 +2860,7 @@ static int dpaa_remove(struct platform_device *pdev)
        struct device *dev;
        int err;
 
-       dev = &pdev->dev;
+       dev = pdev->dev.parent;
        net_dev = dev_get_drvdata(dev);
 
        priv = netdev_priv(net_dev);
index 7a7f3a42b2aa1ee12e467d9295b8422a835bdd12..d4604bc8eb5b04742534100c4c285065bda2021e 100644 (file)
@@ -3600,6 +3600,8 @@ fec_drv_remove(struct platform_device *pdev)
        fec_enet_mii_remove(fep);
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
        if (of_phy_is_fixed_link(np))
                of_phy_deregister_fixed_link(np);
        of_node_put(fep->phy_node);
index ea43b497414986c55d07ce9b175082202f951044..7af31ddd093f8520a276a092ffd3481528177999 100644 (file)
@@ -1100,7 +1100,7 @@ int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
        set_bucket(dtsec->regs, bucket, true);
 
        /* Create element to be added to the driver hash table */
-       hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+       hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC);
        if (!hash_entry)
                return -ENOMEM;
        hash_entry->addr = addr;
index 3bdeb295514bde273404c516d07b6c0c024aa025..f27f9bae1a4ac02811590636f55d74dcb0568225 100644 (file)
@@ -2934,29 +2934,17 @@ static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
 {
        int size = lstatus & BD_LENGTH_MASK;
        struct page *page = rxb->page;
-       bool last = !!(lstatus & BD_LFLAG(RXBD_LAST));
-
-       /* Remove the FCS from the packet length */
-       if (last)
-               size -= ETH_FCS_LEN;
 
        if (likely(first)) {
                skb_put(skb, size);
        } else {
                /* the last fragments' length contains the full frame length */
-               if (last)
+               if (lstatus & BD_LFLAG(RXBD_LAST))
                        size -= skb->len;
 
-               /* Add the last fragment if it contains something other than
-                * the FCS, otherwise drop it and trim off any part of the FCS
-                * that was already received.
-                */
-               if (size > 0)
-                       skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
-                                       rxb->page_offset + RXBUF_ALIGNMENT,
-                                       size, GFAR_RXB_TRUESIZE);
-               else if (size < 0)
-                       pskb_trim(skb, skb->len + size);
+               skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+                               rxb->page_offset + RXBUF_ALIGNMENT,
+                               size, GFAR_RXB_TRUESIZE);
        }
 
        /* try reuse page */
@@ -3069,12 +3057,12 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
        if (priv->padding)
                skb_pull(skb, priv->padding);
 
+       /* Trim off the FCS */
+       pskb_trim(skb, skb->len - ETH_FCS_LEN);
+
        if (ndev->features & NETIF_F_RXCSUM)
                gfar_rx_checksum(skb, fcb);
 
-       /* Tell the skb what kind of packet this is */
-       skb->protocol = eth_type_trans(skb, ndev);
-
        /* There's need to check for NETIF_F_HW_VLAN_CTAG_RX here.
         * Even if vlan rx accel is disabled, on some chips
         * RXFCB_VLN is pseudo randomly set.
@@ -3145,13 +3133,15 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
                        continue;
                }
 
+               gfar_process_frame(ndev, skb);
+
                /* Increment the number of packets */
                total_pkts++;
                total_bytes += skb->len;
 
                skb_record_rx_queue(skb, rx_queue->qindex);
 
-               gfar_process_frame(ndev, skb);
+               skb->protocol = eth_type_trans(skb, ndev);
 
                /* Send the packet up the stack */
                napi_gro_receive(&rx_queue->grp->napi_rx, skb);
index 86944bc3b273fd97232a60e68f25046e68042882..74bd260ca02a887869a507f8746dfc928522d4be 100644 (file)
@@ -666,7 +666,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data)
 
 static int hns_gmac_get_sset_count(int stringset)
 {
-       if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
+       if (stringset == ETH_SS_STATS)
                return ARRAY_SIZE(g_gmac_stats_string);
 
        return 0;
index b62816c1574eb840f74a334b904f9fd993733116..93e71e27401b4da815e899753dc7be1a83ff3f14 100644 (file)
@@ -422,7 +422,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb)
 
 int hns_ppe_get_sset_count(int stringset)
 {
-       if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
+       if (stringset == ETH_SS_STATS)
                return ETH_PPE_STATIC_NUM;
        return 0;
 }
index 6f3570cfb501604bea3f22d73374dd8dc28d756f..e2e28532e4dc2d03cf15330c621f8fb49469e382 100644 (file)
@@ -876,7 +876,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data)
  */
 int hns_rcb_get_ring_sset_count(int stringset)
 {
-       if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
+       if (stringset == ETH_SS_STATS)
                return HNS_RING_STATIC_REG_NUM;
 
        return 0;
index 7ea7f8a4aa2a9456f2d71cceccae9eff2b83421a..2e14a3ae1d8be0f9841a5c53f456c4d2e4f4d270 100644 (file)
@@ -993,8 +993,10 @@ int hns_get_sset_count(struct net_device *netdev, int stringset)
                        cnt--;
 
                return cnt;
-       } else {
+       } else if (stringset == ETH_SS_STATS) {
                return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset));
+       } else {
+               return -EOPNOTSUPP;
        }
 }
 
index 27447260215d1bb36a9d0cd5540efadf52514cb6..1b3cc8bb07050f6856eb4f3e7fe28e4296219d49 100644 (file)
@@ -791,6 +791,18 @@ static int ibmvnic_login(struct net_device *netdev)
        return 0;
 }
 
+static void release_login_buffer(struct ibmvnic_adapter *adapter)
+{
+       kfree(adapter->login_buf);
+       adapter->login_buf = NULL;
+}
+
+static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter)
+{
+       kfree(adapter->login_rsp_buf);
+       adapter->login_rsp_buf = NULL;
+}
+
 static void release_resources(struct ibmvnic_adapter *adapter)
 {
        int i;
@@ -813,6 +825,10 @@ static void release_resources(struct ibmvnic_adapter *adapter)
                        }
                }
        }
+       kfree(adapter->napi);
+       adapter->napi = NULL;
+
+       release_login_rsp_buffer(adapter);
 }
 
 static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
@@ -1057,6 +1073,35 @@ static int ibmvnic_open(struct net_device *netdev)
        return rc;
 }
 
+static void clean_rx_pools(struct ibmvnic_adapter *adapter)
+{
+       struct ibmvnic_rx_pool *rx_pool;
+       u64 rx_entries;
+       int rx_scrqs;
+       int i, j;
+
+       if (!adapter->rx_pool)
+               return;
+
+       rx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
+       rx_entries = adapter->req_rx_add_entries_per_subcrq;
+
+       /* Free any remaining skbs in the rx buffer pools */
+       for (i = 0; i < rx_scrqs; i++) {
+               rx_pool = &adapter->rx_pool[i];
+               if (!rx_pool)
+                       continue;
+
+               netdev_dbg(adapter->netdev, "Cleaning rx_pool[%d]\n", i);
+               for (j = 0; j < rx_entries; j++) {
+                       if (rx_pool->rx_buff[j].skb) {
+                               dev_kfree_skb_any(rx_pool->rx_buff[j].skb);
+                               rx_pool->rx_buff[j].skb = NULL;
+                       }
+               }
+       }
+}
+
 static void clean_tx_pools(struct ibmvnic_adapter *adapter)
 {
        struct ibmvnic_tx_pool *tx_pool;
@@ -1134,7 +1179,7 @@ static int __ibmvnic_close(struct net_device *netdev)
                        }
                }
        }
-
+       clean_rx_pools(adapter);
        clean_tx_pools(adapter);
        adapter->state = VNIC_CLOSED;
        return rc;
@@ -1670,8 +1715,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
                return 0;
        }
 
-       netif_carrier_on(netdev);
-
        /* kick napi */
        for (i = 0; i < adapter->req_rx_queues; i++)
                napi_schedule(&adapter->napi[i]);
@@ -1679,6 +1722,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
        if (adapter->reset_reason != VNIC_RESET_FAILOVER)
                netdev_notify_peers(netdev);
 
+       netif_carrier_on(netdev);
+
        return 0;
 }
 
@@ -1853,6 +1898,12 @@ restart_poll:
                                   be16_to_cpu(next->rx_comp.rc));
                        /* free the entry */
                        next->rx_comp.first = 0;
+                       dev_kfree_skb_any(rx_buff->skb);
+                       remove_buff_from_pool(adapter, rx_buff);
+                       continue;
+               } else if (!rx_buff->skb) {
+                       /* free the entry */
+                       next->rx_comp.first = 0;
                        remove_buff_from_pool(adapter, rx_buff);
                        continue;
                }
@@ -3013,6 +3064,7 @@ static void send_login(struct ibmvnic_adapter *adapter)
        struct vnic_login_client_data *vlcd;
        int i;
 
+       release_login_rsp_buffer(adapter);
        client_data_len = vnic_client_data_len(adapter);
 
        buffer_size =
@@ -3738,6 +3790,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
                ibmvnic_remove(adapter->vdev);
                return -EIO;
        }
+       release_login_buffer(adapter);
        complete(&adapter->init_done);
 
        return 0;
index afb7ebe20b2438e9500f5dff2b1126ccde9c4670..824fd44e25f0d694a20bed7733dfebfaff9d0195 100644 (file)
 #define E1000_ICR_RXDMT0        0x00000010 /* Rx desc min. threshold (0) */
 #define E1000_ICR_RXO           0x00000040 /* Receiver Overrun */
 #define E1000_ICR_RXT0          0x00000080 /* Rx timer intr (ring 0) */
+#define E1000_ICR_MDAC          0x00000200 /* MDIO Access Complete */
+#define E1000_ICR_SRPD          0x00010000 /* Small Receive Packet Detected */
+#define E1000_ICR_ACK           0x00020000 /* Receive ACK Frame Detected */
+#define E1000_ICR_MNG           0x00040000 /* Manageability Event Detected */
 #define E1000_ICR_ECCER         0x00400000 /* Uncorrectable ECC Error */
 /* If this bit asserted, the driver should claim the interrupt */
 #define E1000_ICR_INT_ASSERTED 0x80000000
 #define E1000_ICR_RXQ1          0x00200000 /* Rx Queue 1 Interrupt */
 #define E1000_ICR_TXQ0          0x00400000 /* Tx Queue 0 Interrupt */
 #define E1000_ICR_TXQ1          0x00800000 /* Tx Queue 1 Interrupt */
-#define E1000_ICR_OTHER         0x01000000 /* Other Interrupts */
+#define E1000_ICR_OTHER         0x01000000 /* Other Interrupt */
 
 /* PBA ECC Register */
 #define E1000_PBA_ECC_COUNTER_MASK  0xFFF00000 /* ECC counter mask */
        E1000_IMS_RXSEQ  |    \
        E1000_IMS_LSC)
 
+/* These are all of the events related to the OTHER interrupt.
+ */
+#define IMS_OTHER_MASK ( \
+       E1000_IMS_LSC  | \
+       E1000_IMS_RXO  | \
+       E1000_IMS_MDAC | \
+       E1000_IMS_SRPD | \
+       E1000_IMS_ACK  | \
+       E1000_IMS_MNG)
+
 /* Interrupt Mask Set */
 #define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
 #define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
 #define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
 #define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
+#define E1000_IMS_RXO       E1000_ICR_RXO       /* Receiver Overrun */
 #define E1000_IMS_RXT0      E1000_ICR_RXT0      /* Rx timer intr */
+#define E1000_IMS_MDAC      E1000_ICR_MDAC      /* MDIO Access Complete */
+#define E1000_IMS_SRPD      E1000_ICR_SRPD      /* Small Receive Packet */
+#define E1000_IMS_ACK       E1000_ICR_ACK       /* Receive ACK Frame Detected */
+#define E1000_IMS_MNG       E1000_ICR_MNG       /* Manageability Event */
 #define E1000_IMS_ECCER     E1000_ICR_ECCER     /* Uncorrectable ECC Error */
 #define E1000_IMS_RXQ0      E1000_ICR_RXQ0      /* Rx Queue 0 Interrupt */
 #define E1000_IMS_RXQ1      E1000_ICR_RXQ1      /* Rx Queue 1 Interrupt */
index 31277d3bb7dc1241032695d2d9424779654f4f5f..1dddfb7b2de6c988c9686e82c49d8081f91d5f31 100644 (file)
@@ -1367,9 +1367,6 @@ out:
  *  Checks to see of the link status of the hardware has changed.  If a
  *  change in link status has been detected, then we read the PHY registers
  *  to get the current speed/duplex if link exists.
- *
- *  Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link
- *  up).
  **/
 static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 {
@@ -1385,7 +1382,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
         * Change or Rx Sequence Error interrupt.
         */
        if (!mac->get_link_status)
-               return 1;
+               return 0;
+       mac->get_link_status = false;
 
        /* First we want to see if the MII Status Register reports
         * link.  If so, then we want to get the current speed/duplex
@@ -1393,12 +1391,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
         */
        ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
        if (ret_val)
-               return ret_val;
+               goto out;
 
        if (hw->mac.type == e1000_pchlan) {
                ret_val = e1000_k1_gig_workaround_hv(hw, link);
                if (ret_val)
-                       return ret_val;
+                       goto out;
        }
 
        /* When connected at 10Mbps half-duplex, some parts are excessively
@@ -1431,7 +1429,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 
                ret_val = hw->phy.ops.acquire(hw);
                if (ret_val)
-                       return ret_val;
+                       goto out;
 
                if (hw->mac.type == e1000_pch2lan)
                        emi_addr = I82579_RX_CONFIG;
@@ -1453,7 +1451,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                hw->phy.ops.release(hw);
 
                if (ret_val)
-                       return ret_val;
+                       goto out;
 
                if (hw->mac.type >= e1000_pch_spt) {
                        u16 data;
@@ -1462,14 +1460,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                        if (speed == SPEED_1000) {
                                ret_val = hw->phy.ops.acquire(hw);
                                if (ret_val)
-                                       return ret_val;
+                                       goto out;
 
                                ret_val = e1e_rphy_locked(hw,
                                                          PHY_REG(776, 20),
                                                          &data);
                                if (ret_val) {
                                        hw->phy.ops.release(hw);
-                                       return ret_val;
+                                       goto out;
                                }
 
                                ptr_gap = (data & (0x3FF << 2)) >> 2;
@@ -1483,18 +1481,18 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                                }
                                hw->phy.ops.release(hw);
                                if (ret_val)
-                                       return ret_val;
+                                       goto out;
                        } else {
                                ret_val = hw->phy.ops.acquire(hw);
                                if (ret_val)
-                                       return ret_val;
+                                       goto out;
 
                                ret_val = e1e_wphy_locked(hw,
                                                          PHY_REG(776, 20),
                                                          0xC023);
                                hw->phy.ops.release(hw);
                                if (ret_val)
-                                       return ret_val;
+                                       goto out;
 
                        }
                }
@@ -1521,7 +1519,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
            (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) {
                ret_val = e1000_k1_workaround_lpt_lp(hw, link);
                if (ret_val)
-                       return ret_val;
+                       goto out;
        }
        if (hw->mac.type >= e1000_pch_lpt) {
                /* Set platform power management values for
@@ -1529,7 +1527,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                 */
                ret_val = e1000_platform_pm_pch_lpt(hw, link);
                if (ret_val)
-                       return ret_val;
+                       goto out;
        }
 
        /* Clear link partner's EEE ability */
@@ -1552,9 +1550,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
        }
 
        if (!link)
-               return 0;       /* No link detected */
-
-       mac->get_link_status = false;
+               goto out;
 
        switch (hw->mac.type) {
        case e1000_pch2lan:
@@ -1616,12 +1612,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
         * different link partner.
         */
        ret_val = e1000e_config_fc_after_link_up(hw);
-       if (ret_val) {
+       if (ret_val)
                e_dbg("Error configuring flow control\n");
-               return ret_val;
-       }
 
-       return 1;
+       return ret_val;
+
+out:
+       mac->get_link_status = true;
+       return ret_val;
 }
 
 static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
index f457c5703d0c45d4c9f661395acca1a9814de686..5bdc3a2d4fd70aed476c8c0f17c180570b9eafb2 100644 (file)
@@ -410,9 +410,6 @@ void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
  *  Checks to see of the link status of the hardware has changed.  If a
  *  change in link status has been detected, then we read the PHY registers
  *  to get the current speed/duplex if link exists.
- *
- *  Returns a negative error code (-E1000_ERR_*) or 0 (link down) or 1 (link
- *  up).
  **/
 s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
 {
@@ -426,20 +423,16 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
         * Change or Rx Sequence Error interrupt.
         */
        if (!mac->get_link_status)
-               return 1;
+               return 0;
+       mac->get_link_status = false;
 
        /* First we want to see if the MII Status Register reports
         * link.  If so, then we want to get the current speed/duplex
         * of the PHY.
         */
        ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
-       if (ret_val)
-               return ret_val;
-
-       if (!link)
-               return 0;       /* No link detected */
-
-       mac->get_link_status = false;
+       if (ret_val || !link)
+               goto out;
 
        /* Check if there was DownShift, must be checked
         * immediately after link-up
@@ -464,12 +457,14 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
         * different link partner.
         */
        ret_val = e1000e_config_fc_after_link_up(hw);
-       if (ret_val) {
+       if (ret_val)
                e_dbg("Error configuring flow control\n");
-               return ret_val;
-       }
 
-       return 1;
+       return ret_val;
+
+out:
+       mac->get_link_status = true;
+       return ret_val;
 }
 
 /**
index 1298b69f990b40628ef1fbb353e6d9f1bfafdd76..dc853b0863aff1b4f66043a1fe70bca6112d5aeb 100644 (file)
@@ -1914,30 +1914,20 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
        struct net_device *netdev = data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       u32 icr;
-       bool enable = true;
-
-       icr = er32(ICR);
-       if (icr & E1000_ICR_RXO) {
-               ew32(ICR, E1000_ICR_RXO);
-               enable = false;
-               /* napi poll will re-enable Other, make sure it runs */
-               if (napi_schedule_prep(&adapter->napi)) {
-                       adapter->total_rx_bytes = 0;
-                       adapter->total_rx_packets = 0;
-                       __napi_schedule(&adapter->napi);
-               }
-       }
+       u32 icr = er32(ICR);
+
+       if (icr & adapter->eiac_mask)
+               ew32(ICS, (icr & adapter->eiac_mask));
+
        if (icr & E1000_ICR_LSC) {
-               ew32(ICR, E1000_ICR_LSC);
                hw->mac.get_link_status = true;
                /* guard against interrupt when we're going down */
                if (!test_bit(__E1000_DOWN, &adapter->state))
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-       if (enable && !test_bit(__E1000_DOWN, &adapter->state))
-               ew32(IMS, E1000_IMS_OTHER);
+       if (!test_bit(__E1000_DOWN, &adapter->state))
+               ew32(IMS, E1000_IMS_OTHER | IMS_OTHER_MASK);
 
        return IRQ_HANDLED;
 }
@@ -2040,7 +2030,6 @@ static void e1000_configure_msix(struct e1000_adapter *adapter)
                       hw->hw_addr + E1000_EITR_82574(vector));
        else
                writel(1, hw->hw_addr + E1000_EITR_82574(vector));
-       adapter->eiac_mask |= E1000_IMS_OTHER;
 
        /* Cause Tx interrupts on every write back */
        ivar |= BIT(31);
@@ -2265,7 +2254,8 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
 
        if (adapter->msix_entries) {
                ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
-               ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC);
+               ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER |
+                    IMS_OTHER_MASK);
        } else if (hw->mac.type >= e1000_pch_lpt) {
                ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
        } else {
@@ -2333,8 +2323,8 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
 {
        struct pci_dev *pdev = adapter->pdev;
 
-       ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
-                                       GFP_KERNEL);
+       ring->desc = dma_zalloc_coherent(&pdev->dev, ring->size, &ring->dma,
+                                        GFP_KERNEL);
        if (!ring->desc)
                return -ENOMEM;
 
@@ -2707,8 +2697,7 @@ static int e1000e_poll(struct napi_struct *napi, int weight)
                napi_complete_done(napi, work_done);
                if (!test_bit(__E1000_DOWN, &adapter->state)) {
                        if (adapter->msix_entries)
-                               ew32(IMS, adapter->rx_ring->ims_val |
-                                    E1000_IMS_OTHER);
+                               ew32(IMS, adapter->rx_ring->ims_val);
                        else
                                e1000_irq_enable(adapter);
                }
@@ -5101,7 +5090,7 @@ static bool e1000e_has_link(struct e1000_adapter *adapter)
        case e1000_media_type_copper:
                if (hw->mac.get_link_status) {
                        ret_val = hw->mac.ops.check_for_link(hw);
-                       link_active = ret_val > 0;
+                       link_active = !hw->mac.get_link_status;
                } else {
                        link_active = true;
                }
index 0da5aa2c8aba53ae6c7b461aa01f803e9c215406..9fc063af233c31e58ab8926f487e606e12737ffd 100644 (file)
@@ -1888,6 +1888,14 @@ static void ixgbe_dma_sync_frag(struct ixgbe_ring *rx_ring,
                                     ixgbe_rx_pg_size(rx_ring),
                                     DMA_FROM_DEVICE,
                                     IXGBE_RX_DMA_ATTR);
+       } else if (ring_uses_build_skb(rx_ring)) {
+               unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK;
+
+               dma_sync_single_range_for_cpu(rx_ring->dev,
+                                             IXGBE_CB(skb)->dma,
+                                             offset,
+                                             skb_headlen(skb),
+                                             DMA_FROM_DEVICE);
        } else {
                struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
 
index a1d7b88cf0835de86455f21b1f967d739207b572..5a1668cdb461c7437cf510b5592f7ab54134b0f7 100644 (file)
@@ -7137,6 +7137,7 @@ static void mvpp2_set_rx_mode(struct net_device *dev)
        int id = port->id;
        bool allmulti = dev->flags & IFF_ALLMULTI;
 
+retry:
        mvpp2_prs_mac_promisc_set(priv, id, dev->flags & IFF_PROMISC);
        mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_ALL, allmulti);
        mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_IP6, allmulti);
@@ -7144,9 +7145,13 @@ static void mvpp2_set_rx_mode(struct net_device *dev)
        /* Remove all port->id's mcast enries */
        mvpp2_prs_mcast_del_all(priv, id);
 
-       if (allmulti && !netdev_mc_empty(dev)) {
-               netdev_for_each_mc_addr(ha, dev)
-                       mvpp2_prs_mac_da_accept(priv, id, ha->addr, true);
+       if (!allmulti) {
+               netdev_for_each_mc_addr(ha, dev) {
+                       if (mvpp2_prs_mac_da_accept(priv, id, ha->addr, true)) {
+                               allmulti = true;
+                               goto retry;
+                       }
+               }
        }
 }
 
index 0be4575b58a27261084ee25058ed56039611e31b..fd509160c8f6cc2f1ee81ae2594feb8952e37a8e 100644 (file)
@@ -96,10 +96,10 @@ static void print_lyr_2_4_hdrs(struct trace_seq *p,
                                          "%pI4");
                } else if (ethertype.v == ETH_P_IPV6) {
                        static const struct in6_addr full_ones = {
-                               .in6_u.u6_addr32 = {htonl(0xffffffff),
-                                                   htonl(0xffffffff),
-                                                   htonl(0xffffffff),
-                                                   htonl(0xffffffff)},
+                               .in6_u.u6_addr32 = {__constant_htonl(0xffffffff),
+                                                   __constant_htonl(0xffffffff),
+                                                   __constant_htonl(0xffffffff),
+                                                   __constant_htonl(0xffffffff)},
                        };
                        DECLARE_MASK_VAL(struct in6_addr, src_ipv6);
                        DECLARE_MASK_VAL(struct in6_addr, dst_ipv6);
index 47bab842c5eea8656a68002440d616c7c94c4611..da94c8cba5ee1b7e8f6309d81fa7db29a1db10b6 100644 (file)
@@ -1768,13 +1768,16 @@ static void mlx5e_build_rq_param(struct mlx5e_priv *priv,
        param->wq.linear = 1;
 }
 
-static void mlx5e_build_drop_rq_param(struct mlx5e_rq_param *param)
+static void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
+                                     struct mlx5e_rq_param *param)
 {
        void *rqc = param->rqc;
        void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
 
        MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST);
        MLX5_SET(wq, wq, log_wq_stride,    ilog2(sizeof(struct mlx5e_rx_wqe)));
+
+       param->wq.buf_numa_node = dev_to_node(&mdev->pdev->dev);
 }
 
 static void mlx5e_build_sq_param_common(struct mlx5e_priv *priv,
@@ -2634,6 +2637,9 @@ static int mlx5e_alloc_drop_cq(struct mlx5_core_dev *mdev,
                               struct mlx5e_cq *cq,
                               struct mlx5e_cq_param *param)
 {
+       param->wq.buf_numa_node = dev_to_node(&mdev->pdev->dev);
+       param->wq.db_numa_node  = dev_to_node(&mdev->pdev->dev);
+
        return mlx5e_alloc_cq_common(mdev, param, cq);
 }
 
@@ -2645,7 +2651,7 @@ static int mlx5e_open_drop_rq(struct mlx5_core_dev *mdev,
        struct mlx5e_cq *cq = &drop_rq->cq;
        int err;
 
-       mlx5e_build_drop_rq_param(&rq_param);
+       mlx5e_build_drop_rq_param(mdev, &rq_param);
 
        err = mlx5e_alloc_drop_cq(mdev, cq, &cq_param);
        if (err)
@@ -2994,8 +3000,8 @@ static int mlx5e_setup_tc_block(struct net_device *dev,
 }
 #endif
 
-int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
-                  void *type_data)
+static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
+                         void *type_data)
 {
        switch (type) {
 #ifdef CONFIG_MLX5_ESWITCH
index 0d4bb0688faa1349913d25c13f2366b130a06682..e5c3ab46a24a5134de9349a8e761504cfa49a33d 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/tcp.h>
 #include <linux/bpf_trace.h>
 #include <net/busy_poll.h>
+#include <net/ip6_checksum.h>
 #include "en.h"
 #include "en_tc.h"
 #include "eswitch.h"
@@ -546,20 +547,33 @@ bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
        return true;
 }
 
+static void mlx5e_lro_update_tcp_hdr(struct mlx5_cqe64 *cqe, struct tcphdr *tcp)
+{
+       u8 l4_hdr_type = get_cqe_l4_hdr_type(cqe);
+       u8 tcp_ack     = (l4_hdr_type == CQE_L4_HDR_TYPE_TCP_ACK_NO_DATA) ||
+                        (l4_hdr_type == CQE_L4_HDR_TYPE_TCP_ACK_AND_DATA);
+
+       tcp->check                      = 0;
+       tcp->psh                        = get_cqe_lro_tcppsh(cqe);
+
+       if (tcp_ack) {
+               tcp->ack                = 1;
+               tcp->ack_seq            = cqe->lro_ack_seq_num;
+               tcp->window             = cqe->lro_tcp_win;
+       }
+}
+
 static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
                                 u32 cqe_bcnt)
 {
        struct ethhdr   *eth = (struct ethhdr *)(skb->data);
        struct tcphdr   *tcp;
        int network_depth = 0;
+       __wsum check;
        __be16 proto;
        u16 tot_len;
        void *ip_p;
 
-       u8 l4_hdr_type = get_cqe_l4_hdr_type(cqe);
-       u8 tcp_ack = (l4_hdr_type == CQE_L4_HDR_TYPE_TCP_ACK_NO_DATA) ||
-               (l4_hdr_type == CQE_L4_HDR_TYPE_TCP_ACK_AND_DATA);
-
        proto = __vlan_get_protocol(skb, eth->h_proto, &network_depth);
 
        tot_len = cqe_bcnt - network_depth;
@@ -576,23 +590,30 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe,
                ipv4->check             = 0;
                ipv4->check             = ip_fast_csum((unsigned char *)ipv4,
                                                       ipv4->ihl);
+
+               mlx5e_lro_update_tcp_hdr(cqe, tcp);
+               check = csum_partial(tcp, tcp->doff * 4,
+                                    csum_unfold((__force __sum16)cqe->check_sum));
+               /* Almost done, don't forget the pseudo header */
+               tcp->check = csum_tcpudp_magic(ipv4->saddr, ipv4->daddr,
+                                              tot_len - sizeof(struct iphdr),
+                                              IPPROTO_TCP, check);
        } else {
+               u16 payload_len = tot_len - sizeof(struct ipv6hdr);
                struct ipv6hdr *ipv6 = ip_p;
 
                tcp = ip_p + sizeof(struct ipv6hdr);
                skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 
                ipv6->hop_limit         = cqe->lro_min_ttl;
-               ipv6->payload_len       = cpu_to_be16(tot_len -
-                                                     sizeof(struct ipv6hdr));
-       }
-
-       tcp->psh = get_cqe_lro_tcppsh(cqe);
-
-       if (tcp_ack) {
-               tcp->ack                = 1;
-               tcp->ack_seq            = cqe->lro_ack_seq_num;
-               tcp->window             = cqe->lro_tcp_win;
+               ipv6->payload_len       = cpu_to_be16(payload_len);
+
+               mlx5e_lro_update_tcp_hdr(cqe, tcp);
+               check = csum_partial(tcp, tcp->doff * 4,
+                                    csum_unfold((__force __sum16)cqe->check_sum));
+               /* Almost done, don't forget the pseudo header */
+               tcp->check = csum_ipv6_magic(&ipv6->saddr, &ipv6->daddr, payload_len,
+                                            IPPROTO_TCP, check);
        }
 }
 
index 5a4608281f38d236d77d8f86f81f52d683f3eadc..707976482c0987c33b5183804e152309cc57d6d4 100644 (file)
@@ -216,7 +216,8 @@ mlx5e_test_loopback_validate(struct sk_buff *skb,
        if (iph->protocol != IPPROTO_UDP)
                goto out;
 
-       udph = udp_hdr(skb);
+       /* Don't assume skb_transport_header() was set */
+       udph = (struct udphdr *)((u8 *)iph + 4 * iph->ihl);
        if (udph->dest != htons(9))
                goto out;
 
index fd98b0dc610fffce72c7702598271825be6e9160..fa86a1466718037f89a5bdb4b2d67e9bbe2b341e 100644 (file)
@@ -2529,7 +2529,8 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
                        if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
                                attr->action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
                        } else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
-                               if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q))
+                               if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
+                                   tcf_vlan_push_prio(a))
                                        return -EOPNOTSUPP;
 
                                attr->action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
index 569b42a010265bec16510b1a860c456b3f76a0e3..11b4f1089d1ceffc05b703118e911895d08644c8 100644 (file)
@@ -176,7 +176,7 @@ static inline u16 mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
        default:
                hlen = mlx5e_skb_l2_header_offset(skb);
        }
-       return min_t(u16, hlen, skb->len);
+       return min_t(u16, hlen, skb_headlen(skb));
 }
 
 static inline void mlx5e_tx_skb_pull_inline(unsigned char **skb_data,
index 5ecf2cddc16dfef2e53df1d8617e15fced37c377..c2b1d7d351fc29362e4ce4de641a280b92b96284 100644 (file)
@@ -1529,6 +1529,10 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
 
        esw_debug(esw->dev, "Enabling VPORT(%d)\n", vport_num);
 
+       /* Create steering drop counters for ingress and egress ACLs */
+       if (vport_num && esw->mode == SRIOV_LEGACY)
+               esw_vport_create_drop_counters(vport);
+
        /* Restore old vport configuration */
        esw_apply_vport_conf(esw, vport);
 
@@ -1545,10 +1549,6 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
        if (!vport_num)
                vport->info.trusted = true;
 
-       /* create steering drop counters for ingress and egress ACLs */
-       if (vport_num && esw->mode == SRIOV_LEGACY)
-               esw_vport_create_drop_counters(vport);
-
        esw_vport_change_handle_locked(vport);
 
        esw->enabled_vports++;
index c025c98700e4cd627a503d8a982f7854421da5b6..31fc2cfac3b3beea8c8bc28851cd5172f880926e 100644 (file)
@@ -1429,7 +1429,8 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
 
        if (xored_actions & (MLX5_FLOW_CONTEXT_ACTION_DROP  |
                             MLX5_FLOW_CONTEXT_ACTION_ENCAP |
-                            MLX5_FLOW_CONTEXT_ACTION_DECAP))
+                            MLX5_FLOW_CONTEXT_ACTION_DECAP |
+                            MLX5_FLOW_CONTEXT_ACTION_MOD_HDR))
                return true;
 
        return false;
@@ -1758,8 +1759,11 @@ search_again_locked:
 
        /* Collect all fgs which has a matching match_criteria */
        err = build_match_list(&match_head, ft, spec);
-       if (err)
+       if (err) {
+               if (take_write)
+                       up_write_ref_node(&ft->node);
                return ERR_PTR(err);
+       }
 
        if (!take_write)
                up_read_ref_node(&ft->node);
@@ -1768,8 +1772,11 @@ search_again_locked:
                                      dest_num, version);
        free_match_list(&match_head);
        if (!IS_ERR(rule) ||
-           (PTR_ERR(rule) != -ENOENT && PTR_ERR(rule) != -EAGAIN))
+           (PTR_ERR(rule) != -ENOENT && PTR_ERR(rule) != -EAGAIN)) {
+               if (take_write)
+                       up_write_ref_node(&ft->node);
                return rule;
+       }
 
        if (!take_write) {
                nested_down_write_ref_node(&ft->node, FS_LOCK_GRANDPARENT);
index 21d29f7936f6c5d1e26c6e0d3f10644fd0f096c8..d39b0b7011b2d9cf194180813a5a30d9fe226b6d 100644 (file)
@@ -124,7 +124,7 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force)
                trigger_cmd_completions(dev);
        }
 
-       mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 0);
+       mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 1);
        mlx5_core_err(dev, "end\n");
 
 unlock:
index e159243e0fcfb2dadbb79cb1f0895c172ec43cf2..857035583ccdd156c7913c001c1509e0cde044bb 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/highmem.h>
 #include <rdma/mlx5-abi.h>
 #include "en.h"
+#include "clock.h"
 
 enum {
        MLX5_CYCLES_SHIFT       = 23
index 2ef641c91c267ceec1cacb744f492ef2a1ff8dc0..ae391e4b70706ec81e2dedaf003858c24be57954 100644 (file)
@@ -551,7 +551,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
                MLX5_SET(cmd_hca_cap,
                         set_hca_cap,
                         cache_line_128byte,
-                        cache_line_size() == 128 ? 1 : 0);
+                        cache_line_size() >= 128 ? 1 : 0);
 
        if (MLX5_CAP_GEN_MAX(dev, dct))
                MLX5_SET(cmd_hca_cap, set_hca_cap, dct, 1);
index b698fb481b2ecb4d7f79da60775b063f7da58dfc..996dc099cd584c23167e4100b11701ba3025809a 100644 (file)
@@ -443,6 +443,17 @@ int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id)
 }
 EXPORT_SYMBOL(mlxsw_afa_block_jump);
 
+int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block)
+{
+       if (block->finished)
+               return -EINVAL;
+       mlxsw_afa_set_goto_set(block->cur_set,
+                              MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0);
+       block->finished = true;
+       return 0;
+}
+EXPORT_SYMBOL(mlxsw_afa_block_terminate);
+
 static struct mlxsw_afa_fwd_entry *
 mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u8 local_port)
 {
index 43132293475ce9ce916eac0b49b8a9c822ffb214..b91f2b0829b04a417c5799ed2d353163f81db844 100644 (file)
@@ -65,6 +65,7 @@ char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block);
 u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block);
 int mlxsw_afa_block_continue(struct mlxsw_afa_block *block);
 int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id);
+int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block);
 int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block);
 int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
 int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
index f6963b0b4a550cc2997183d980b8a4300f637baa..122506daa586070321c079d53c9d9ff6a9037c45 100644 (file)
@@ -107,20 +107,20 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
        MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
        MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
        MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
-       MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x14, 0, 8),
-       MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x14, 9, 2),
-       MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x14, 11, 6),
-       MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x18, 0, 32),
-       MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x1C, 0, 32),
-       MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x18, 8),
-       MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_LO, 0x20, 8),
-       MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_HI, 0x28, 8),
-       MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_LO, 0x30, 8),
        MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
        MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
+       MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
+       MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
+       MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
+       MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x20, 0, 32),
+       MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x24, 0, 32),
+       MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x20, 8),
+       MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_LO, 0x28, 8),
+       MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_HI, 0x30, 8),
+       MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_LO, 0x38, 8),
 };
 
-#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x38
+#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
 
 struct mlxsw_afk_element_inst { /* element instance in actual block */
        const struct mlxsw_afk_element_info *info;
index 3dcc58d615067e5c61a4d646870205e6386eec76..bf400c75fcc8bc82253fe5237a476655ce323bf4 100644 (file)
@@ -655,13 +655,17 @@ static int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
 }
 
 static struct mlxsw_sp_span_inspected_port *
-mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port,
-                                   struct mlxsw_sp_span_entry *span_entry)
+mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry,
+                                   enum mlxsw_sp_span_type type,
+                                   struct mlxsw_sp_port *port,
+                                   bool bind)
 {
        struct mlxsw_sp_span_inspected_port *p;
 
        list_for_each_entry(p, &span_entry->bound_ports_list, list)
-               if (port->local_port == p->local_port)
+               if (type == p->type &&
+                   port->local_port == p->local_port &&
+                   bind == p->bound)
                        return p;
        return NULL;
 }
@@ -691,8 +695,22 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
        struct mlxsw_sp_span_inspected_port *inspected_port;
        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
        char sbib_pl[MLXSW_REG_SBIB_LEN];
+       int i;
        int err;
 
+       /* A given (source port, direction) can only be bound to one analyzer,
+        * so if a binding is requested, check for conflicts.
+        */
+       if (bind)
+               for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
+                       struct mlxsw_sp_span_entry *curr =
+                               &mlxsw_sp->span.entries[i];
+
+                       if (mlxsw_sp_span_entry_bound_port_find(curr, type,
+                                                               port, bind))
+                               return -EEXIST;
+               }
+
        /* if it is an egress SPAN, bind a shared buffer to it */
        if (type == MLXSW_SP_SPAN_EGRESS) {
                u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp,
@@ -720,6 +738,7 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
        }
        inspected_port->local_port = port->local_port;
        inspected_port->type = type;
+       inspected_port->bound = bind;
        list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
 
        return 0;
@@ -746,7 +765,8 @@ mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
        struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
        char sbib_pl[MLXSW_REG_SBIB_LEN];
 
-       inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry);
+       inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type,
+                                                            port, bind);
        if (!inspected_port)
                return;
 
@@ -1459,6 +1479,7 @@ mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
        }
 
        mlxsw_sp_port_vlan->mlxsw_sp_port = mlxsw_sp_port;
+       mlxsw_sp_port_vlan->ref_count = 1;
        mlxsw_sp_port_vlan->vid = vid;
        list_add(&mlxsw_sp_port_vlan->list, &mlxsw_sp_port->vlans_list);
 
@@ -1486,8 +1507,10 @@ mlxsw_sp_port_vlan_get(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
        struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
 
        mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
-       if (mlxsw_sp_port_vlan)
+       if (mlxsw_sp_port_vlan) {
+               mlxsw_sp_port_vlan->ref_count++;
                return mlxsw_sp_port_vlan;
+       }
 
        return mlxsw_sp_port_vlan_create(mlxsw_sp_port, vid);
 }
@@ -1496,6 +1519,9 @@ void mlxsw_sp_port_vlan_put(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
 {
        struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
 
+       if (--mlxsw_sp_port_vlan->ref_count != 0)
+               return;
+
        if (mlxsw_sp_port_vlan->bridge_port)
                mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
        else if (fid)
@@ -4207,13 +4233,12 @@ static struct devlink_resource_ops mlxsw_sp_resource_kvd_hash_double_ops = {
        .size_validate = mlxsw_sp_resource_kvd_hash_double_size_validate,
 };
 
-static struct devlink_resource_size_params mlxsw_sp_kvd_size_params;
-static struct devlink_resource_size_params mlxsw_sp_linear_size_params;
-static struct devlink_resource_size_params mlxsw_sp_hash_single_size_params;
-static struct devlink_resource_size_params mlxsw_sp_hash_double_size_params;
-
 static void
-mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core)
+mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core,
+                                     struct devlink_resource_size_params *kvd_size_params,
+                                     struct devlink_resource_size_params *linear_size_params,
+                                     struct devlink_resource_size_params *hash_double_size_params,
+                                     struct devlink_resource_size_params *hash_single_size_params)
 {
        u32 single_size_min = MLXSW_CORE_RES_GET(mlxsw_core,
                                                 KVD_SINGLE_MIN_SIZE);
@@ -4222,37 +4247,35 @@ mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core)
        u32 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
        u32 linear_size_min = 0;
 
-       /* KVD top resource */
-       mlxsw_sp_kvd_size_params.size_min = kvd_size;
-       mlxsw_sp_kvd_size_params.size_max = kvd_size;
-       mlxsw_sp_kvd_size_params.size_granularity = MLXSW_SP_KVD_GRANULARITY;
-       mlxsw_sp_kvd_size_params.unit = DEVLINK_RESOURCE_UNIT_ENTRY;
-
-       /* Linear part init */
-       mlxsw_sp_linear_size_params.size_min = linear_size_min;
-       mlxsw_sp_linear_size_params.size_max = kvd_size - single_size_min -
-                                              double_size_min;
-       mlxsw_sp_linear_size_params.size_granularity = MLXSW_SP_KVD_GRANULARITY;
-       mlxsw_sp_linear_size_params.unit = DEVLINK_RESOURCE_UNIT_ENTRY;
-
-       /* Hash double part init */
-       mlxsw_sp_hash_double_size_params.size_min = double_size_min;
-       mlxsw_sp_hash_double_size_params.size_max = kvd_size - single_size_min -
-                                                   linear_size_min;
-       mlxsw_sp_hash_double_size_params.size_granularity = MLXSW_SP_KVD_GRANULARITY;
-       mlxsw_sp_hash_double_size_params.unit = DEVLINK_RESOURCE_UNIT_ENTRY;
-
-       /* Hash single part init */
-       mlxsw_sp_hash_single_size_params.size_min = single_size_min;
-       mlxsw_sp_hash_single_size_params.size_max = kvd_size - double_size_min -
-                                                   linear_size_min;
-       mlxsw_sp_hash_single_size_params.size_granularity = MLXSW_SP_KVD_GRANULARITY;
-       mlxsw_sp_hash_single_size_params.unit = DEVLINK_RESOURCE_UNIT_ENTRY;
+       devlink_resource_size_params_init(kvd_size_params, kvd_size, kvd_size,
+                                         MLXSW_SP_KVD_GRANULARITY,
+                                         DEVLINK_RESOURCE_UNIT_ENTRY);
+       devlink_resource_size_params_init(linear_size_params, linear_size_min,
+                                         kvd_size - single_size_min -
+                                         double_size_min,
+                                         MLXSW_SP_KVD_GRANULARITY,
+                                         DEVLINK_RESOURCE_UNIT_ENTRY);
+       devlink_resource_size_params_init(hash_double_size_params,
+                                         double_size_min,
+                                         kvd_size - single_size_min -
+                                         linear_size_min,
+                                         MLXSW_SP_KVD_GRANULARITY,
+                                         DEVLINK_RESOURCE_UNIT_ENTRY);
+       devlink_resource_size_params_init(hash_single_size_params,
+                                         single_size_min,
+                                         kvd_size - double_size_min -
+                                         linear_size_min,
+                                         MLXSW_SP_KVD_GRANULARITY,
+                                         DEVLINK_RESOURCE_UNIT_ENTRY);
 }
 
 static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
 {
        struct devlink *devlink = priv_to_devlink(mlxsw_core);
+       struct devlink_resource_size_params hash_single_size_params;
+       struct devlink_resource_size_params hash_double_size_params;
+       struct devlink_resource_size_params linear_size_params;
+       struct devlink_resource_size_params kvd_size_params;
        u32 kvd_size, single_size, double_size, linear_size;
        const struct mlxsw_config_profile *profile;
        int err;
@@ -4261,13 +4284,17 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
        if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE))
                return -EIO;
 
-       mlxsw_sp_resource_size_params_prepare(mlxsw_core);
+       mlxsw_sp_resource_size_params_prepare(mlxsw_core, &kvd_size_params,
+                                             &linear_size_params,
+                                             &hash_double_size_params,
+                                             &hash_single_size_params);
+
        kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
        err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD,
                                        true, kvd_size,
                                        MLXSW_SP_RESOURCE_KVD,
                                        DEVLINK_RESOURCE_ID_PARENT_TOP,
-                                       &mlxsw_sp_kvd_size_params,
+                                       &kvd_size_params,
                                        &mlxsw_sp_resource_kvd_ops);
        if (err)
                return err;
@@ -4277,7 +4304,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
                                        false, linear_size,
                                        MLXSW_SP_RESOURCE_KVD_LINEAR,
                                        MLXSW_SP_RESOURCE_KVD,
-                                       &mlxsw_sp_linear_size_params,
+                                       &linear_size_params,
                                        &mlxsw_sp_resource_kvd_linear_ops);
        if (err)
                return err;
@@ -4291,7 +4318,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
                                        false, double_size,
                                        MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
                                        MLXSW_SP_RESOURCE_KVD,
-                                       &mlxsw_sp_hash_double_size_params,
+                                       &hash_double_size_params,
                                        &mlxsw_sp_resource_kvd_hash_double_ops);
        if (err)
                return err;
@@ -4301,7 +4328,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
                                        false, single_size,
                                        MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
                                        MLXSW_SP_RESOURCE_KVD,
-                                       &mlxsw_sp_hash_single_size_params,
+                                       &hash_single_size_params,
                                        &mlxsw_sp_resource_kvd_hash_single_ops);
        if (err)
                return err;
index bdd8f94a452cc8057a17effb672d8e7a55ee288a..92064db2ae442136141b01e64832b1487acbe43d 100644 (file)
@@ -120,6 +120,9 @@ struct mlxsw_sp_span_inspected_port {
        struct list_head list;
        enum mlxsw_sp_span_type type;
        u8 local_port;
+
+       /* Whether this is a directly bound mirror (port-to-port) or an ACL. */
+       bool bound;
 };
 
 struct mlxsw_sp_span_entry {
@@ -211,6 +214,7 @@ struct mlxsw_sp_port_vlan {
        struct list_head list;
        struct mlxsw_sp_port *mlxsw_sp_port;
        struct mlxsw_sp_fid *fid;
+       unsigned int ref_count;
        u16 vid;
        struct mlxsw_sp_bridge_port *bridge_port;
        struct list_head bridge_vlan_node;
@@ -552,6 +556,7 @@ void mlxsw_sp_acl_rulei_keymask_buf(struct mlxsw_sp_acl_rule_info *rulei,
 int mlxsw_sp_acl_rulei_act_continue(struct mlxsw_sp_acl_rule_info *rulei);
 int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei,
                                u16 group_id);
+int mlxsw_sp_acl_rulei_act_terminate(struct mlxsw_sp_acl_rule_info *rulei);
 int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei);
 int mlxsw_sp_acl_rulei_act_trap(struct mlxsw_sp_acl_rule_info *rulei);
 int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp,
index 0897a5435cc2e205957d2158d184b3bc465a71ac..92d90ed7207e622ee70943e33d01f698b5d679f4 100644 (file)
@@ -528,6 +528,11 @@ int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei,
        return mlxsw_afa_block_jump(rulei->act_block, group_id);
 }
 
+int mlxsw_sp_acl_rulei_act_terminate(struct mlxsw_sp_acl_rule_info *rulei)
+{
+       return mlxsw_afa_block_terminate(rulei->act_block);
+}
+
 int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei)
 {
        return mlxsw_afa_block_append_drop(rulei->act_block);
index 93728c694e6df9985cadfccf72ab6f3a9f52f8da..0a9adc5962fb72b8dbeb3b61b3e0a28093982197 100644 (file)
@@ -385,13 +385,13 @@ static const struct mlxsw_sp_sb_cm mlxsw_sp_sb_cms_egress[] = {
 
 static const struct mlxsw_sp_sb_cm mlxsw_sp_cpu_port_sb_cms[] = {
        MLXSW_SP_CPU_PORT_SB_CM,
+       MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
+       MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
+       MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
+       MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
+       MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
        MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_CPU_PORT_SB_CM,
-       MLXSW_SP_SB_CM(10000, 0, 0),
+       MLXSW_SP_SB_CM(MLXSW_PORT_MAX_MTU, 0, 0),
        MLXSW_SP_CPU_PORT_SB_CM,
        MLXSW_SP_CPU_PORT_SB_CM,
        MLXSW_SP_CPU_PORT_SB_CM,
index bbd238e50f05488b3bcdfc133cb08d69bcec7c3b..54262af4e98f713b7533cb758c2dd6eda181eabc 100644 (file)
@@ -112,11 +112,11 @@ static const int mlxsw_sp_sfgc_bc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
        [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_NON_IP]     = 1,
        [MLXSW_REG_SFGC_TYPE_IPV4_LINK_LOCAL]                   = 1,
        [MLXSW_REG_SFGC_TYPE_IPV6_ALL_HOST]                     = 1,
+       [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6]       = 1,
 };
 
 static const int mlxsw_sp_sfgc_mc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
        [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV4]       = 1,
-       [MLXSW_REG_SFGC_TYPE_UNREGISTERED_MULTICAST_IPV6]       = 1,
 };
 
 static const int *mlxsw_sp_packet_type_sfgc_types[] = {
index 6ce00e28d4eac8043abb8a77c86a0aabe30531b3..89dbf569dff50c0db7d97d3b4e80e8bd7cf494d6 100644 (file)
@@ -65,7 +65,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
        tcf_exts_to_list(exts, &actions);
        list_for_each_entry(a, &actions, list) {
                if (is_tcf_gact_ok(a)) {
-                       err = mlxsw_sp_acl_rulei_act_continue(rulei);
+                       err = mlxsw_sp_acl_rulei_act_terminate(rulei);
                        if (err)
                                return err;
                } else if (is_tcf_gact_shot(a)) {
index f0b25baba09a66fe3a1011f91e2c3e8e96637498..f7948e983637da5e887d47cd3af80ebdc599c872 100644 (file)
@@ -788,6 +788,9 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
                                              u32 tb_id,
                                              struct netlink_ext_ack *extack)
 {
+       struct mlxsw_sp_mr_table *mr4_table;
+       struct mlxsw_sp_fib *fib4;
+       struct mlxsw_sp_fib *fib6;
        struct mlxsw_sp_vr *vr;
        int err;
 
@@ -796,29 +799,30 @@ static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
                NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers");
                return ERR_PTR(-EBUSY);
        }
-       vr->fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
-       if (IS_ERR(vr->fib4))
-               return ERR_CAST(vr->fib4);
-       vr->fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
-       if (IS_ERR(vr->fib6)) {
-               err = PTR_ERR(vr->fib6);
+       fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
+       if (IS_ERR(fib4))
+               return ERR_CAST(fib4);
+       fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
+       if (IS_ERR(fib6)) {
+               err = PTR_ERR(fib6);
                goto err_fib6_create;
        }
-       vr->mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
-                                                MLXSW_SP_L3_PROTO_IPV4);
-       if (IS_ERR(vr->mr4_table)) {
-               err = PTR_ERR(vr->mr4_table);
+       mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
+                                            MLXSW_SP_L3_PROTO_IPV4);
+       if (IS_ERR(mr4_table)) {
+               err = PTR_ERR(mr4_table);
                goto err_mr_table_create;
        }
+       vr->fib4 = fib4;
+       vr->fib6 = fib6;
+       vr->mr4_table = mr4_table;
        vr->tb_id = tb_id;
        return vr;
 
 err_mr_table_create:
-       mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib6);
-       vr->fib6 = NULL;
+       mlxsw_sp_fib_destroy(mlxsw_sp, fib6);
 err_fib6_create:
-       mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib4);
-       vr->fib4 = NULL;
+       mlxsw_sp_fib_destroy(mlxsw_sp, fib4);
        return ERR_PTR(err);
 }
 
@@ -3790,6 +3794,9 @@ mlxsw_sp_fib4_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry)
        struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group;
        int i;
 
+       if (!list_is_singular(&nh_grp->fib_list))
+               return;
+
        for (i = 0; i < nh_grp->count; i++) {
                struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i];
 
index 593ad31be7490d6af8abf3f5c3929de925c0ca77..161bcdc012f07652eac9165e42e299457da05c7b 100644 (file)
@@ -1203,6 +1203,7 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
                                     bool dynamic)
 {
        char *sfd_pl;
+       u8 num_rec;
        int err;
 
        sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
@@ -1212,9 +1213,16 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
        mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
        mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
                              mac, fid, action, local_port);
+       num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
-       kfree(sfd_pl);
+       if (err)
+               goto out;
+
+       if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
+               err = -EBUSY;
 
+out:
+       kfree(sfd_pl);
        return err;
 }
 
@@ -1239,6 +1247,7 @@ static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id,
                                       bool adding, bool dynamic)
 {
        char *sfd_pl;
+       u8 num_rec;
        int err;
 
        sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
@@ -1249,9 +1258,16 @@ static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id,
        mlxsw_reg_sfd_uc_lag_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
                                  mac, fid, MLXSW_REG_SFD_REC_ACTION_NOP,
                                  lag_vid, lag_id);
+       num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
-       kfree(sfd_pl);
+       if (err)
+               goto out;
+
+       if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
+               err = -EBUSY;
 
+out:
+       kfree(sfd_pl);
        return err;
 }
 
@@ -1296,6 +1312,7 @@ static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr,
                                u16 fid, u16 mid_idx, bool adding)
 {
        char *sfd_pl;
+       u8 num_rec;
        int err;
 
        sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
@@ -1305,7 +1322,15 @@ static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr,
        mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
        mlxsw_reg_sfd_mc_pack(sfd_pl, 0, addr, fid,
                              MLXSW_REG_SFD_REC_ACTION_NOP, mid_idx);
+       num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
+       if (err)
+               goto out;
+
+       if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
+               err = -EBUSY;
+
+out:
        kfree(sfd_pl);
        return err;
 }
index a10ef50e4f12c3c949f0f2120c71d3562d8a0559..017fb23225897983b0440e1bf67db2ab0ae31fc1 100644 (file)
@@ -1,16 +1,16 @@
 #
-# National Semi-conductor device configuration
+# National Semiconductor device configuration
 #
 
 config NET_VENDOR_NATSEMI
-       bool "National Semi-conductor devices"
+       bool "National Semiconductor devices"
        default y
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
 
          Note that the answer to this question doesn't directly affect the
          kernel: saying N will just cause the configurator to skip all
-         the questions about National Semi-conductor devices. If you say Y,
+         the questions about National Semiconductor devices. If you say Y,
          you will be asked for your specific card in the following questions.
 
 if NET_VENDOR_NATSEMI
index cc664977596e2426de92453285d028bebd868ddf..a759aa09ef5960b979b951e00c4497fbb4bf2276 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 #
-# Makefile for the National Semi-conductor Sonic devices.
+# Makefile for the National Semiconductor Sonic devices.
 #
 
 obj-$(CONFIG_MACSONIC) += macsonic.o
index 6f546e869d8d69fd17c7eaeeec579d1134d3364d..00f41c145d4d01674d146fe1eda41a346b3cc5a1 100644 (file)
@@ -2480,7 +2480,10 @@ int qed_cxt_free_proto_ilt(struct qed_hwfn *p_hwfn, enum protocol_type proto)
        if (rc)
                return rc;
 
-       /* Free Task CXT */
+       /* Free Task CXT ( Intentionally RoCE as task-id is shared between
+        * RoCE and iWARP )
+        */
+       proto = PROTOCOLID_ROCE;
        rc = qed_cxt_free_ilt_range(p_hwfn, QED_ELEM_TASK, 0,
                                    qed_cxt_get_proto_tid_count(p_hwfn, proto));
        if (rc)
index ca4a81dc1ace685f4bb1cda85dc0e85746b4583a..d5d02be7294741a2adc46ac97f91f07d5ffea491 100644 (file)
@@ -1703,6 +1703,13 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn,
        iph = (struct iphdr *)((u8 *)(ethh) + eth_hlen);
 
        if (eth_type == ETH_P_IP) {
+               if (iph->protocol != IPPROTO_TCP) {
+                       DP_NOTICE(p_hwfn,
+                                 "Unexpected ip protocol on ll2 %x\n",
+                                 iph->protocol);
+                       return -EINVAL;
+               }
+
                cm_info->local_ip[0] = ntohl(iph->daddr);
                cm_info->remote_ip[0] = ntohl(iph->saddr);
                cm_info->ip_version = TCP_IPV4;
@@ -1711,6 +1718,14 @@ qed_iwarp_parse_rx_pkt(struct qed_hwfn *p_hwfn,
                *payload_len = ntohs(iph->tot_len) - ip_hlen;
        } else if (eth_type == ETH_P_IPV6) {
                ip6h = (struct ipv6hdr *)iph;
+
+               if (ip6h->nexthdr != IPPROTO_TCP) {
+                       DP_NOTICE(p_hwfn,
+                                 "Unexpected ip protocol on ll2 %x\n",
+                                 iph->protocol);
+                       return -EINVAL;
+               }
+
                for (i = 0; i < 4; i++) {
                        cm_info->local_ip[i] =
                            ntohl(ip6h->daddr.in6_u.u6_addr32[i]);
@@ -1928,8 +1943,8 @@ qed_iwarp_update_fpdu_length(struct qed_hwfn *p_hwfn,
                /* Missing lower byte is now available */
                mpa_len = fpdu->fpdu_length | *mpa_data;
                fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len);
-               fpdu->mpa_frag_len = fpdu->fpdu_length;
                /* one byte of hdr */
+               fpdu->mpa_frag_len = 1;
                fpdu->incomplete_bytes = fpdu->fpdu_length - 1;
                DP_VERBOSE(p_hwfn,
                           QED_MSG_RDMA,
index 5d040b873137d0917637b6df42eddc4e0e031595..a411f9c702a16ae6963aa5c7eda112cc5a72404d 100644 (file)
@@ -379,6 +379,7 @@ static void qed_rdma_free(struct qed_hwfn *p_hwfn)
        DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Freeing RDMA\n");
 
        qed_rdma_free_reserved_lkey(p_hwfn);
+       qed_cxt_free_proto_ilt(p_hwfn, p_hwfn->p_rdma_info->proto);
        qed_rdma_resc_free(p_hwfn);
 }
 
index 2db70eabddfec1edfe38b524233c3baaa9f883f5..a01e7d6e5442f079e9006811b82b4feb02dc23bc 100644 (file)
@@ -288,7 +288,7 @@ int __init qede_init(void)
        }
 
        /* Must register notifier before pci ops, since we might miss
-        * interface rename after pci probe and netdev registeration.
+        * interface rename after pci probe and netdev registration.
         */
        ret = register_netdevice_notifier(&qede_netdev_notifier);
        if (ret) {
@@ -988,7 +988,7 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
        if (rc)
                goto err3;
 
-       /* Prepare the lock prior to the registeration of the netdev,
+       /* Prepare the lock prior to the registration of the netdev,
         * as once it's registered we might reach flows requiring it
         * [it's even possible to reach a flow needing it directly
         * from there, although it's unlikely].
@@ -2067,8 +2067,6 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode,
        link_params.link_up = true;
        edev->ops->common->set_link(edev->cdev, &link_params);
 
-       qede_rdma_dev_event_open(edev);
-
        edev->state = QEDE_STATE_OPEN;
 
        DP_INFO(edev, "Ending successfully qede load\n");
@@ -2169,12 +2167,14 @@ static void qede_link_update(void *dev, struct qed_link_output *link)
                        DP_NOTICE(edev, "Link is up\n");
                        netif_tx_start_all_queues(edev->ndev);
                        netif_carrier_on(edev->ndev);
+                       qede_rdma_dev_event_open(edev);
                }
        } else {
                if (netif_carrier_ok(edev->ndev)) {
                        DP_NOTICE(edev, "Link is down\n");
                        netif_tx_disable(edev->ndev);
                        netif_carrier_off(edev->ndev);
+                       qede_rdma_dev_event_close(edev);
                }
        }
 }
index 9b2280badaf77666ceab5cf0409f484ed08719b8..02adb513f4756cb58c423936213bdcb4158d1dfa 100644 (file)
@@ -485,7 +485,7 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc)
        ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev);
        if (IS_ERR(ptp->clock)) {
                rc = -EINVAL;
-               DP_ERR(edev, "PTP clock registeration failed\n");
+               DP_ERR(edev, "PTP clock registration failed\n");
                goto err2;
        }
 
index 9cbb27263742bf0506684bd2e76d517037217475..d5a32b7c7dc5a4d97c89ba9d33ca769e51c00daf 100644 (file)
@@ -1194,9 +1194,9 @@ void emac_mac_tx_process(struct emac_adapter *adpt, struct emac_tx_queue *tx_q)
        while (tx_q->tpd.consume_idx != hw_consume_idx) {
                tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.consume_idx);
                if (tpbuf->dma_addr) {
-                       dma_unmap_single(adpt->netdev->dev.parent,
-                                        tpbuf->dma_addr, tpbuf->length,
-                                        DMA_TO_DEVICE);
+                       dma_unmap_page(adpt->netdev->dev.parent,
+                                      tpbuf->dma_addr, tpbuf->length,
+                                      DMA_TO_DEVICE);
                        tpbuf->dma_addr = 0;
                }
 
@@ -1353,9 +1353,11 @@ static void emac_tx_fill_tpd(struct emac_adapter *adpt,
 
                tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx);
                tpbuf->length = mapped_len;
-               tpbuf->dma_addr = dma_map_single(adpt->netdev->dev.parent,
-                                                skb->data, tpbuf->length,
-                                                DMA_TO_DEVICE);
+               tpbuf->dma_addr = dma_map_page(adpt->netdev->dev.parent,
+                                              virt_to_page(skb->data),
+                                              offset_in_page(skb->data),
+                                              tpbuf->length,
+                                              DMA_TO_DEVICE);
                ret = dma_mapping_error(adpt->netdev->dev.parent,
                                        tpbuf->dma_addr);
                if (ret)
@@ -1371,9 +1373,12 @@ static void emac_tx_fill_tpd(struct emac_adapter *adpt,
        if (mapped_len < len) {
                tpbuf = GET_TPD_BUFFER(tx_q, tx_q->tpd.produce_idx);
                tpbuf->length = len - mapped_len;
-               tpbuf->dma_addr = dma_map_single(adpt->netdev->dev.parent,
-                                                skb->data + mapped_len,
-                                                tpbuf->length, DMA_TO_DEVICE);
+               tpbuf->dma_addr = dma_map_page(adpt->netdev->dev.parent,
+                                              virt_to_page(skb->data +
+                                                           mapped_len),
+                                              offset_in_page(skb->data +
+                                                             mapped_len),
+                                              tpbuf->length, DMA_TO_DEVICE);
                ret = dma_mapping_error(adpt->netdev->dev.parent,
                                        tpbuf->dma_addr);
                if (ret)
index 7e7704daf5f1e4928d69c1fa397a5f13354af2b8..c4949183eef3f0654cf8e5855ba6b85bce6b35f3 100644 (file)
 
 /* Local Definitions and Declarations */
 
-struct rmnet_walk_data {
-       struct net_device *real_dev;
-       struct list_head *head;
-       struct rmnet_port *port;
-};
-
 static int rmnet_is_real_dev_registered(const struct net_device *real_dev)
 {
        return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler;
@@ -112,17 +106,14 @@ static int rmnet_register_real_device(struct net_device *real_dev)
 static void rmnet_unregister_bridge(struct net_device *dev,
                                    struct rmnet_port *port)
 {
-       struct net_device *rmnet_dev, *bridge_dev;
        struct rmnet_port *bridge_port;
+       struct net_device *bridge_dev;
 
        if (port->rmnet_mode != RMNET_EPMODE_BRIDGE)
                return;
 
        /* bridge slave handling */
        if (!port->nr_rmnet_devs) {
-               rmnet_dev = netdev_master_upper_dev_get_rcu(dev);
-               netdev_upper_dev_unlink(dev, rmnet_dev);
-
                bridge_dev = port->bridge_ep;
 
                bridge_port = rmnet_get_port_rtnl(bridge_dev);
@@ -132,9 +123,6 @@ static void rmnet_unregister_bridge(struct net_device *dev,
                bridge_dev = port->bridge_ep;
 
                bridge_port = rmnet_get_port_rtnl(bridge_dev);
-               rmnet_dev = netdev_master_upper_dev_get_rcu(bridge_dev);
-               netdev_upper_dev_unlink(bridge_dev, rmnet_dev);
-
                rmnet_unregister_real_device(bridge_dev, bridge_port);
        }
 }
@@ -173,10 +161,6 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
        if (err)
                goto err1;
 
-       err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL, extack);
-       if (err)
-               goto err2;
-
        port->rmnet_mode = mode;
 
        hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
@@ -193,8 +177,6 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
 
        return 0;
 
-err2:
-       rmnet_vnd_dellink(mux_id, port, ep);
 err1:
        rmnet_unregister_real_device(real_dev, port);
 err0:
@@ -204,14 +186,13 @@ err0:
 
 static void rmnet_dellink(struct net_device *dev, struct list_head *head)
 {
+       struct rmnet_priv *priv = netdev_priv(dev);
        struct net_device *real_dev;
        struct rmnet_endpoint *ep;
        struct rmnet_port *port;
        u8 mux_id;
 
-       rcu_read_lock();
-       real_dev = netdev_master_upper_dev_get_rcu(dev);
-       rcu_read_unlock();
+       real_dev = priv->real_dev;
 
        if (!real_dev || !rmnet_is_real_dev_registered(real_dev))
                return;
@@ -219,7 +200,6 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
        port = rmnet_get_port_rtnl(real_dev);
 
        mux_id = rmnet_vnd_get_mux(dev);
-       netdev_upper_dev_unlink(dev, real_dev);
 
        ep = rmnet_get_endpoint(port, mux_id);
        if (ep) {
@@ -233,30 +213,13 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
        unregister_netdevice_queue(dev, head);
 }
 
-static int rmnet_dev_walk_unreg(struct net_device *rmnet_dev, void *data)
-{
-       struct rmnet_walk_data *d = data;
-       struct rmnet_endpoint *ep;
-       u8 mux_id;
-
-       mux_id = rmnet_vnd_get_mux(rmnet_dev);
-       ep = rmnet_get_endpoint(d->port, mux_id);
-       if (ep) {
-               hlist_del_init_rcu(&ep->hlnode);
-               rmnet_vnd_dellink(mux_id, d->port, ep);
-               kfree(ep);
-       }
-       netdev_upper_dev_unlink(rmnet_dev, d->real_dev);
-       unregister_netdevice_queue(rmnet_dev, d->head);
-
-       return 0;
-}
-
 static void rmnet_force_unassociate_device(struct net_device *dev)
 {
        struct net_device *real_dev = dev;
-       struct rmnet_walk_data d;
+       struct hlist_node *tmp_ep;
+       struct rmnet_endpoint *ep;
        struct rmnet_port *port;
+       unsigned long bkt_ep;
        LIST_HEAD(list);
 
        if (!rmnet_is_real_dev_registered(real_dev))
@@ -264,16 +227,19 @@ static void rmnet_force_unassociate_device(struct net_device *dev)
 
        ASSERT_RTNL();
 
-       d.real_dev = real_dev;
-       d.head = &list;
-
        port = rmnet_get_port_rtnl(dev);
-       d.port = port;
 
        rcu_read_lock();
        rmnet_unregister_bridge(dev, port);
 
-       netdev_walk_all_lower_dev_rcu(real_dev, rmnet_dev_walk_unreg, &d);
+       hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
+               unregister_netdevice_queue(ep->egress_dev, &list);
+               rmnet_vnd_dellink(ep->mux_id, port, ep);
+
+               hlist_del_init_rcu(&ep->hlnode);
+               kfree(ep);
+       }
+
        rcu_read_unlock();
        unregister_netdevice_many(&list);
 
@@ -422,11 +388,6 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
        if (err)
                return -EBUSY;
 
-       err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL,
-                                          extack);
-       if (err)
-               return -EINVAL;
-
        slave_port = rmnet_get_port(slave_dev);
        slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE;
        slave_port->bridge_ep = real_dev;
@@ -449,7 +410,6 @@ int rmnet_del_bridge(struct net_device *rmnet_dev,
        port->rmnet_mode = RMNET_EPMODE_VND;
        port->bridge_ep = NULL;
 
-       netdev_upper_dev_unlink(slave_dev, rmnet_dev);
        slave_port = rmnet_get_port(slave_dev);
        rmnet_unregister_real_device(slave_dev, slave_port);
 
index 6bc328fb88e13fba1f635ae9e7337e1395ce56d4..b0dbca070c008d386699824ce72a6d6f4c0e2d73 100644 (file)
@@ -38,6 +38,11 @@ static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
        }
 
        ep = rmnet_get_endpoint(port, mux_id);
+       if (!ep) {
+               kfree_skb(skb);
+               return RX_HANDLER_CONSUMED;
+       }
+
        vnd = ep->egress_dev;
 
        ip_family = cmd->flow_control.ip_family;
index 570a227acdd8073ebe50649a8e3dd8a7d32a38a8..346d310914df17791018108d5ddd67715b04ce92 100644 (file)
@@ -121,7 +121,7 @@ static void rmnet_get_stats64(struct net_device *dev,
        memset(&total_stats, 0, sizeof(struct rmnet_vnd_stats));
 
        for_each_possible_cpu(cpu) {
-               pcpu_ptr = this_cpu_ptr(priv->pcpu_stats);
+               pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu);
 
                do {
                        start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp);
index c87f57ca44371586d30f56985010a115a38c8aa1..a95fbd5510d92e7b0beec7f72042ba5796caeee7 100644 (file)
@@ -2255,9 +2255,6 @@ static int ravb_wol_setup(struct net_device *ndev)
        /* Enable MagicPacket */
        ravb_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE);
 
-       /* Increased clock usage so device won't be suspended */
-       clk_enable(priv->clk);
-
        return enable_irq_wake(priv->emac_irq);
 }
 
@@ -2276,9 +2273,6 @@ static int ravb_wol_restore(struct net_device *ndev)
        if (ret < 0)
                return ret;
 
-       /* Restore clock usage count */
-       clk_disable(priv->clk);
-
        return disable_irq_wake(priv->emac_irq);
 }
 
index a197e11f3a564470168dd64244f736b49f52c749..14c839bb09e7ac3a9a5563027ad256f78b187553 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
-#include <linux/clk.h>
 #include <linux/sh_eth.h>
 #include <linux/of_mdio.h>
 
@@ -440,6 +439,17 @@ static void sh_eth_modify(struct net_device *ndev, int enum_index, u32 clear,
                     enum_index);
 }
 
+static void sh_eth_tsu_write(struct sh_eth_private *mdp, u32 data,
+                            int enum_index)
+{
+       iowrite32(data, mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
+static u32 sh_eth_tsu_read(struct sh_eth_private *mdp, int enum_index)
+{
+       return ioread32(mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
 static bool sh_eth_is_gether(struct sh_eth_private *mdp)
 {
        return mdp->reg_offset == sh_eth_offset_gigabit;
@@ -2304,7 +2314,7 @@ static void sh_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
        wol->supported = 0;
        wol->wolopts = 0;
 
-       if (mdp->cd->magic && mdp->clk) {
+       if (mdp->cd->magic) {
                wol->supported = WAKE_MAGIC;
                wol->wolopts = mdp->wol_enabled ? WAKE_MAGIC : 0;
        }
@@ -2314,7 +2324,7 @@ static int sh_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
-       if (!mdp->cd->magic || !mdp->clk || wol->wolopts & ~WAKE_MAGIC)
+       if (!mdp->cd->magic || wol->wolopts & ~WAKE_MAGIC)
                return -EOPNOTSUPP;
 
        mdp->wol_enabled = !!(wol->wolopts & WAKE_MAGIC);
@@ -3153,11 +3163,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
                goto out_release;
        }
 
-       /* Get clock, if not found that's OK but Wake-On-Lan is unavailable */
-       mdp->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(mdp->clk))
-               mdp->clk = NULL;
-
        ndev->base_addr = res->start;
 
        spin_lock_init(&mdp->lock);
@@ -3278,7 +3283,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        if (ret)
                goto out_napi_del;
 
-       if (mdp->cd->magic && mdp->clk)
+       if (mdp->cd->magic)
                device_set_wakeup_capable(&pdev->dev, 1);
 
        /* print device information */
@@ -3331,9 +3336,6 @@ static int sh_eth_wol_setup(struct net_device *ndev)
        /* Enable MagicPacket */
        sh_eth_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE);
 
-       /* Increased clock usage so device won't be suspended */
-       clk_enable(mdp->clk);
-
        return enable_irq_wake(ndev->irq);
 }
 
@@ -3359,9 +3361,6 @@ static int sh_eth_wol_restore(struct net_device *ndev)
        if (ret < 0)
                return ret;
 
-       /* Restore clock usage count */
-       clk_disable(mdp->clk);
-
        return disable_irq_wake(ndev->irq);
 }
 
index a6753ccba711cd0dc331e132eaa7d0f20795f10c..e5fe701346905edc593034cbb9acb9c06698f857 100644 (file)
@@ -567,15 +567,4 @@ static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp,
        return mdp->tsu_addr + mdp->reg_offset[enum_index];
 }
 
-static inline void sh_eth_tsu_write(struct sh_eth_private *mdp, u32 data,
-                                   int enum_index)
-{
-       iowrite32(data, mdp->tsu_addr + mdp->reg_offset[enum_index]);
-}
-
-static inline u32 sh_eth_tsu_read(struct sh_eth_private *mdp, int enum_index)
-{
-       return ioread32(mdp->tsu_addr + mdp->reg_offset[enum_index]);
-}
-
 #endif /* #ifndef __SH_ETH_H__ */
index 63aca9f847e12b869cdbdc6ec159c606cdd7e4b2..4c2f612e4414d6dcddeb0303f7358ded9dbc75a3 100644 (file)
@@ -20,7 +20,7 @@ if NET_VENDOR_SMSC
 
 config SMC9194
        tristate "SMC 9194 support"
-       depends on (ISA || MAC && BROKEN)
+       depends on ISA
        select CRC32
        ---help---
          This is support for the SMC9xxx based Ethernet cards. Choose this
index 012fb66eed8dd618d63fbeaad184accb0c08fc39..f0afb88d7bc2b02de3dc1054ec2ec5803f452a35 100644 (file)
@@ -2335,14 +2335,14 @@ static int smsc911x_drv_remove(struct platform_device *pdev)
        pdata = netdev_priv(dev);
        BUG_ON(!pdata);
        BUG_ON(!pdata->ioaddr);
-       WARN_ON(dev->phydev);
 
        SMSC_TRACE(pdata, ifdown, "Stopping driver");
 
+       unregister_netdev(dev);
+
        mdiobus_unregister(pdata->mii_bus);
        mdiobus_free(pdata->mii_bus);
 
-       unregister_netdev(dev);
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                           "smsc911x-memory");
        if (!res)
index 111e7ca9df5600c0ecd29bca11cf25a7f3e7e616..f5c5984afefb988c6c0ecd75234473f7084a2c32 100644 (file)
@@ -1295,7 +1295,7 @@ static int ave_open(struct net_device *ndev)
        val |= AVE_IIRQC_EN0 | (AVE_INTM_COUNT << 16);
        writel(val, priv->base + AVE_IIRQC);
 
-       val = AVE_GI_RXIINT | AVE_GI_RXOVF | AVE_GI_TX;
+       val = AVE_GI_RXIINT | AVE_GI_RXOVF | AVE_GI_TX | AVE_GI_RXDROP;
        ave_irq_restore(ndev, val);
 
        napi_enable(&priv->napi_rx);
index 63d3d6b215f3096da6da95fe489bf1172c831a28..a94f50442613e9f77cec6aff24fbf19a5a33756b 100644 (file)
@@ -312,7 +312,7 @@ static struct vnet *vnet_new(const u64 *local_mac,
        dev->ethtool_ops = &vnet_ethtool_ops;
        dev->watchdog_timeo = VNET_TX_TIMEOUT;
 
-       dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GSO_SOFTWARE |
+       dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_ALL_TSO |
                           NETIF_F_HW_CSUM | NETIF_F_SG;
        dev->features = dev->hw_features;
 
index 1b1b78fdc1384975856fe6a3d8368fe868dfbc23..b2b30c9df037700728a51f2eb1ae007f8368ba3e 100644 (file)
@@ -1014,7 +1014,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
                /* set speed_in input in case RMII mode is used in 100Mbps */
                if (phy->speed == 100)
                        mac_control |= BIT(15);
-               else if (phy->speed == 10)
+               /* in band mode only works in 10Mbps RGMII mode */
+               else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
                        mac_control |= BIT(18); /* In Band mode */
 
                if (priv->rx_pause)
index 0db3bd1ea06f5a71eb6fc67ba00abb066c7f3414..32861036c3fcc9ec9e34938e0f916198307b419c 100644 (file)
@@ -173,6 +173,7 @@ struct rndis_device {
        struct list_head req_list;
 
        struct work_struct mcast_work;
+       u32 filter;
 
        bool link_state;        /* 0 - link up, 1 - link down */
 
@@ -211,7 +212,6 @@ void netvsc_channel_cb(void *context);
 int netvsc_poll(struct napi_struct *napi, int budget);
 
 void rndis_set_subchannel(struct work_struct *w);
-bool rndis_filter_opened(const struct netvsc_device *nvdev);
 int rndis_filter_open(struct netvsc_device *nvdev);
 int rndis_filter_close(struct netvsc_device *nvdev);
 struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
index 17e529af79dcd2664e19651c4065a8b4fec7b597..7472172823f3edffb0dfd481dc67f03c12a6a6b9 100644 (file)
@@ -90,6 +90,11 @@ static void free_netvsc_device(struct rcu_head *head)
                = container_of(head, struct netvsc_device, rcu);
        int i;
 
+       kfree(nvdev->extension);
+       vfree(nvdev->recv_buf);
+       vfree(nvdev->send_buf);
+       kfree(nvdev->send_section_map);
+
        for (i = 0; i < VRSS_CHANNEL_MAX; i++)
                vfree(nvdev->chan_table[i].mrc.slots);
 
@@ -211,12 +216,6 @@ static void netvsc_teardown_gpadl(struct hv_device *device,
                net_device->recv_buf_gpadl_handle = 0;
        }
 
-       if (net_device->recv_buf) {
-               /* Free up the receive buffer */
-               vfree(net_device->recv_buf);
-               net_device->recv_buf = NULL;
-       }
-
        if (net_device->send_buf_gpadl_handle) {
                ret = vmbus_teardown_gpadl(device->channel,
                                           net_device->send_buf_gpadl_handle);
@@ -231,12 +230,6 @@ static void netvsc_teardown_gpadl(struct hv_device *device,
                }
                net_device->send_buf_gpadl_handle = 0;
        }
-       if (net_device->send_buf) {
-               /* Free up the send buffer */
-               vfree(net_device->send_buf);
-               net_device->send_buf = NULL;
-       }
-       kfree(net_device->send_section_map);
 }
 
 int netvsc_alloc_recv_comp_ring(struct netvsc_device *net_device, u32 q_idx)
@@ -562,26 +555,29 @@ void netvsc_device_remove(struct hv_device *device)
                = rtnl_dereference(net_device_ctx->nvdev);
        int i;
 
-       cancel_work_sync(&net_device->subchan_work);
-
        netvsc_revoke_buf(device, net_device);
 
        RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
 
+       /* And disassociate NAPI context from device */
+       for (i = 0; i < net_device->num_chn; i++)
+               netif_napi_del(&net_device->chan_table[i].napi);
+
        /*
         * At this point, no one should be accessing net_device
         * except in here
         */
        netdev_dbg(ndev, "net device safe to remove\n");
 
+       /* older versions require that buffer be revoked before close */
+       if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_4)
+               netvsc_teardown_gpadl(device, net_device);
+
        /* Now, we can close the channel safely */
        vmbus_close(device->channel);
 
-       netvsc_teardown_gpadl(device, net_device);
-
-       /* And dissassociate NAPI context from device */
-       for (i = 0; i < net_device->num_chn; i++)
-               netif_napi_del(&net_device->chan_table[i].napi);
+       if (net_device->nvsp_version >= NVSP_PROTOCOL_VERSION_4)
+               netvsc_teardown_gpadl(device, net_device);
 
        /* Release all resources */
        free_netvsc_device_rcu(net_device);
@@ -645,14 +641,18 @@ static void netvsc_send_tx_complete(struct netvsc_device *net_device,
        queue_sends =
                atomic_dec_return(&net_device->chan_table[q_idx].queue_sends);
 
-       if (net_device->destroy && queue_sends == 0)
-               wake_up(&net_device->wait_drain);
+       if (unlikely(net_device->destroy)) {
+               if (queue_sends == 0)
+                       wake_up(&net_device->wait_drain);
+       } else {
+               struct netdev_queue *txq = netdev_get_tx_queue(ndev, q_idx);
 
-       if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
-           (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
-            queue_sends < 1)) {
-               netif_tx_wake_queue(netdev_get_tx_queue(ndev, q_idx));
-               ndev_ctx->eth_stats.wake_queue++;
+               if (netif_tx_queue_stopped(txq) &&
+                   (hv_ringbuf_avail_percent(&channel->outbound) > RING_AVAIL_PERCENT_HIWATER ||
+                    queue_sends < 1)) {
+                       netif_tx_wake_queue(txq);
+                       ndev_ctx->eth_stats.wake_queue++;
+               }
        }
 }
 
@@ -852,13 +852,6 @@ int netvsc_send(struct net_device *ndev,
        if (unlikely(!net_device || net_device->destroy))
                return -ENODEV;
 
-       /* We may race with netvsc_connect_vsp()/netvsc_init_buf() and get
-        * here before the negotiation with the host is finished and
-        * send_section_map may not be allocated yet.
-        */
-       if (unlikely(!net_device->send_section_map))
-               return -EAGAIN;
-
        nvchan = &net_device->chan_table[packet->q_idx];
        packet->send_buf_index = NETVSC_INVALID_INDEX;
        packet->cp_partial = false;
@@ -866,10 +859,8 @@ int netvsc_send(struct net_device *ndev,
        /* Send control message directly without accessing msd (Multi-Send
         * Data) field which may be changed during data packet processing.
         */
-       if (!skb) {
-               cur_send = packet;
-               goto send_now;
-       }
+       if (!skb)
+               return netvsc_send_pkt(device, packet, net_device, pb, skb);
 
        /* batch packets in send buffer if possible */
        msdp = &nvchan->msd;
@@ -953,7 +944,6 @@ int netvsc_send(struct net_device *ndev,
                }
        }
 
-send_now:
        if (cur_send)
                ret = netvsc_send_pkt(device, cur_send, net_device, pb, skb);
 
@@ -1217,9 +1207,10 @@ int netvsc_poll(struct napi_struct *napi, int budget)
        if (send_recv_completions(ndev, net_device, nvchan) == 0 &&
            work_done < budget &&
            napi_complete_done(napi, work_done) &&
-           hv_end_read(&channel->inbound)) {
+           hv_end_read(&channel->inbound) &&
+           napi_schedule_prep(napi)) {
                hv_begin_read(&channel->inbound);
-               napi_reschedule(napi);
+               __napi_schedule(napi);
        }
 
        /* Driver may overshoot since multiple packets per descriptor */
@@ -1242,7 +1233,7 @@ void netvsc_channel_cb(void *context)
                /* disable interupts from host */
                hv_begin_read(rbi);
 
-               __napi_schedule(&nvchan->napi);
+               __napi_schedule_irqoff(&nvchan->napi);
        }
 }
 
@@ -1296,7 +1287,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
                         netvsc_channel_cb, net_device->chan_table);
 
        if (ret != 0) {
-               netif_napi_del(&net_device->chan_table[0].napi);
                netdev_err(ndev, "unable to open channel: %d\n", ret);
                goto cleanup;
        }
@@ -1306,11 +1296,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
 
        napi_enable(&net_device->chan_table[0].napi);
 
-       /* Writing nvdev pointer unlocks netvsc_send(), make sure chn_table is
-        * populated.
-        */
-       rcu_assign_pointer(net_device_ctx->nvdev, net_device);
-
        /* Connect with the NetVsp */
        ret = netvsc_connect_vsp(device, net_device, device_info);
        if (ret != 0) {
@@ -1319,6 +1304,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
                goto close;
        }
 
+       /* Writing nvdev pointer unlocks netvsc_send(), make sure chn_table is
+        * populated.
+        */
+       rcu_assign_pointer(net_device_ctx->nvdev, net_device);
+
        return net_device;
 
 close:
@@ -1329,6 +1319,7 @@ close:
        vmbus_close(device->channel);
 
 cleanup:
+       netif_napi_del(&net_device->chan_table[0].napi);
        free_netvsc_device(&net_device->rcu);
 
        return ERR_PTR(ret);
index c5584c2d440e033b649193b39435d0a458aaf694..f28c85d212cee1ecfe2cf5f70717d4091acc5197 100644 (file)
 
 #include "hyperv_net.h"
 
-#define RING_SIZE_MIN          64
+#define RING_SIZE_MIN  64
+#define RETRY_US_LO    5000
+#define RETRY_US_HI    10000
+#define RETRY_MAX      2000    /* >10 sec */
 
 #define LINKCHANGE_INT (2 * HZ)
 #define VF_TAKEOVER_INT (HZ / 10)
@@ -66,12 +69,43 @@ static int debug = -1;
 module_param(debug, int, S_IRUGO);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
-static void netvsc_set_multicast_list(struct net_device *net)
+static void netvsc_change_rx_flags(struct net_device *net, int change)
 {
-       struct net_device_context *net_device_ctx = netdev_priv(net);
-       struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
+       struct net_device_context *ndev_ctx = netdev_priv(net);
+       struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
+       int inc;
+
+       if (!vf_netdev)
+               return;
+
+       if (change & IFF_PROMISC) {
+               inc = (net->flags & IFF_PROMISC) ? 1 : -1;
+               dev_set_promiscuity(vf_netdev, inc);
+       }
+
+       if (change & IFF_ALLMULTI) {
+               inc = (net->flags & IFF_ALLMULTI) ? 1 : -1;
+               dev_set_allmulti(vf_netdev, inc);
+       }
+}
 
-       rndis_filter_update(nvdev);
+static void netvsc_set_rx_mode(struct net_device *net)
+{
+       struct net_device_context *ndev_ctx = netdev_priv(net);
+       struct net_device *vf_netdev;
+       struct netvsc_device *nvdev;
+
+       rcu_read_lock();
+       vf_netdev = rcu_dereference(ndev_ctx->vf_netdev);
+       if (vf_netdev) {
+               dev_uc_sync(vf_netdev, net);
+               dev_mc_sync(vf_netdev, net);
+       }
+
+       nvdev = rcu_dereference(ndev_ctx->nvdev);
+       if (nvdev)
+               rndis_filter_update(nvdev);
+       rcu_read_unlock();
 }
 
 static int netvsc_open(struct net_device *net)
@@ -91,10 +125,7 @@ static int netvsc_open(struct net_device *net)
                return ret;
        }
 
-       netif_tx_wake_all_queues(net);
-
        rdev = nvdev->extension;
-
        if (!rdev->link_state)
                netif_carrier_on(net);
 
@@ -112,36 +143,25 @@ static int netvsc_open(struct net_device *net)
        return 0;
 }
 
-static int netvsc_close(struct net_device *net)
+static int netvsc_wait_until_empty(struct netvsc_device *nvdev)
 {
-       struct net_device_context *net_device_ctx = netdev_priv(net);
-       struct net_device *vf_netdev
-               = rtnl_dereference(net_device_ctx->vf_netdev);
-       struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
-       int ret = 0;
-       u32 aread, i, msec = 10, retry = 0, retry_max = 20;
-       struct vmbus_channel *chn;
-
-       netif_tx_disable(net);
-
-       /* No need to close rndis filter if it is removed already */
-       if (!nvdev)
-               goto out;
-
-       ret = rndis_filter_close(nvdev);
-       if (ret != 0) {
-               netdev_err(net, "unable to close device (ret %d).\n", ret);
-               return ret;
-       }
+       unsigned int retry = 0;
+       int i;
 
        /* Ensure pending bytes in ring are read */
-       while (true) {
-               aread = 0;
+       for (;;) {
+               u32 aread = 0;
+
                for (i = 0; i < nvdev->num_chn; i++) {
-                       chn = nvdev->chan_table[i].channel;
+                       struct vmbus_channel *chn
+                               = nvdev->chan_table[i].channel;
+
                        if (!chn)
                                continue;
 
+                       /* make sure receive not running now */
+                       napi_synchronize(&nvdev->chan_table[i].napi);
+
                        aread = hv_get_bytes_to_read(&chn->inbound);
                        if (aread)
                                break;
@@ -151,22 +171,40 @@ static int netvsc_close(struct net_device *net)
                                break;
                }
 
-               retry++;
-               if (retry > retry_max || aread == 0)
-                       break;
+               if (aread == 0)
+                       return 0;
 
-               msleep(msec);
+               if (++retry > RETRY_MAX)
+                       return -ETIMEDOUT;
 
-               if (msec < 1000)
-                       msec *= 2;
+               usleep_range(RETRY_US_LO, RETRY_US_HI);
        }
+}
 
-       if (aread) {
-               netdev_err(net, "Ring buffer not empty after closing rndis\n");
-               ret = -ETIMEDOUT;
+static int netvsc_close(struct net_device *net)
+{
+       struct net_device_context *net_device_ctx = netdev_priv(net);
+       struct net_device *vf_netdev
+               = rtnl_dereference(net_device_ctx->vf_netdev);
+       struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
+       int ret;
+
+       netif_tx_disable(net);
+
+       /* No need to close rndis filter if it is removed already */
+       if (!nvdev)
+               return 0;
+
+       ret = rndis_filter_close(nvdev);
+       if (ret != 0) {
+               netdev_err(net, "unable to close device (ret %d).\n", ret);
+               return ret;
        }
 
-out:
+       ret = netvsc_wait_until_empty(nvdev);
+       if (ret)
+               netdev_err(net, "Ring buffer not empty after closing rndis\n");
+
        if (vf_netdev)
                dev_close(vf_netdev);
 
@@ -299,8 +337,19 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
        rcu_read_lock();
        vf_netdev = rcu_dereference(ndc->vf_netdev);
        if (vf_netdev) {
-               txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
-               qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
+               const struct net_device_ops *vf_ops = vf_netdev->netdev_ops;
+
+               if (vf_ops->ndo_select_queue)
+                       txq = vf_ops->ndo_select_queue(vf_netdev, skb,
+                                                      accel_priv, fallback);
+               else
+                       txq = fallback(vf_netdev, skb);
+
+               /* Record the queue selected by VF so that it can be
+                * used for common case where VF has more queues than
+                * the synthetic device.
+                */
+               qdisc_skb_cb(skb)->slave_dev_queue_mapping = txq;
        } else {
                txq = netvsc_pick_tx(ndev, skb);
        }
@@ -804,16 +853,81 @@ static void netvsc_get_channels(struct net_device *net,
        }
 }
 
+static int netvsc_detach(struct net_device *ndev,
+                        struct netvsc_device *nvdev)
+{
+       struct net_device_context *ndev_ctx = netdev_priv(ndev);
+       struct hv_device *hdev = ndev_ctx->device_ctx;
+       int ret;
+
+       /* Don't try continuing to try and setup sub channels */
+       if (cancel_work_sync(&nvdev->subchan_work))
+               nvdev->num_chn = 1;
+
+       /* If device was up (receiving) then shutdown */
+       if (netif_running(ndev)) {
+               netif_tx_disable(ndev);
+
+               ret = rndis_filter_close(nvdev);
+               if (ret) {
+                       netdev_err(ndev,
+                                  "unable to close device (ret %d).\n", ret);
+                       return ret;
+               }
+
+               ret = netvsc_wait_until_empty(nvdev);
+               if (ret) {
+                       netdev_err(ndev,
+                                  "Ring buffer not empty after closing rndis\n");
+                       return ret;
+               }
+       }
+
+       netif_device_detach(ndev);
+
+       rndis_filter_device_remove(hdev, nvdev);
+
+       return 0;
+}
+
+static int netvsc_attach(struct net_device *ndev,
+                        struct netvsc_device_info *dev_info)
+{
+       struct net_device_context *ndev_ctx = netdev_priv(ndev);
+       struct hv_device *hdev = ndev_ctx->device_ctx;
+       struct netvsc_device *nvdev;
+       struct rndis_device *rdev;
+       int ret;
+
+       nvdev = rndis_filter_device_add(hdev, dev_info);
+       if (IS_ERR(nvdev))
+               return PTR_ERR(nvdev);
+
+       /* Note: enable and attach happen when sub-channels setup */
+
+       netif_carrier_off(ndev);
+
+       if (netif_running(ndev)) {
+               ret = rndis_filter_open(nvdev);
+               if (ret)
+                       return ret;
+
+               rdev = nvdev->extension;
+               if (!rdev->link_state)
+                       netif_carrier_on(ndev);
+       }
+
+       return 0;
+}
+
 static int netvsc_set_channels(struct net_device *net,
                               struct ethtool_channels *channels)
 {
        struct net_device_context *net_device_ctx = netdev_priv(net);
-       struct hv_device *dev = net_device_ctx->device_ctx;
        struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
        unsigned int orig, count = channels->combined_count;
        struct netvsc_device_info device_info;
-       bool was_opened;
-       int ret = 0;
+       int ret;
 
        /* We do not support separate count for rx, tx, or other */
        if (count == 0 ||
@@ -830,9 +944,6 @@ static int netvsc_set_channels(struct net_device *net,
                return -EINVAL;
 
        orig = nvdev->num_chn;
-       was_opened = rndis_filter_opened(nvdev);
-       if (was_opened)
-               rndis_filter_close(nvdev);
 
        memset(&device_info, 0, sizeof(device_info));
        device_info.num_chn = count;
@@ -841,28 +952,17 @@ static int netvsc_set_channels(struct net_device *net,
        device_info.recv_sections = nvdev->recv_section_cnt;
        device_info.recv_section_size = nvdev->recv_section_size;
 
-       rndis_filter_device_remove(dev, nvdev);
+       ret = netvsc_detach(net, nvdev);
+       if (ret)
+               return ret;
 
-       nvdev = rndis_filter_device_add(dev, &device_info);
-       if (IS_ERR(nvdev)) {
-               ret = PTR_ERR(nvdev);
+       ret = netvsc_attach(net, &device_info);
+       if (ret) {
                device_info.num_chn = orig;
-               nvdev = rndis_filter_device_add(dev, &device_info);
-
-               if (IS_ERR(nvdev)) {
-                       netdev_err(net, "restoring channel setting failed: %ld\n",
-                                  PTR_ERR(nvdev));
-                       return ret;
-               }
+               if (netvsc_attach(net, &device_info))
+                       netdev_err(net, "restoring channel setting failed\n");
        }
 
-       if (was_opened)
-               rndis_filter_open(nvdev);
-
-       /* We may have missed link change notifications */
-       net_device_ctx->last_reconfig = 0;
-       schedule_delayed_work(&net_device_ctx->dwork, 0);
-
        return ret;
 }
 
@@ -928,10 +1028,8 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
        struct net_device_context *ndevctx = netdev_priv(ndev);
        struct net_device *vf_netdev = rtnl_dereference(ndevctx->vf_netdev);
        struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
-       struct hv_device *hdev = ndevctx->device_ctx;
        int orig_mtu = ndev->mtu;
        struct netvsc_device_info device_info;
-       bool was_opened;
        int ret = 0;
 
        if (!nvdev || nvdev->destroy)
@@ -944,11 +1042,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
                        return ret;
        }
 
-       netif_device_detach(ndev);
-       was_opened = rndis_filter_opened(nvdev);
-       if (was_opened)
-               rndis_filter_close(nvdev);
-
        memset(&device_info, 0, sizeof(device_info));
        device_info.num_chn = nvdev->num_chn;
        device_info.send_sections = nvdev->send_section_cnt;
@@ -956,35 +1049,27 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
        device_info.recv_sections = nvdev->recv_section_cnt;
        device_info.recv_section_size = nvdev->recv_section_size;
 
-       rndis_filter_device_remove(hdev, nvdev);
+       ret = netvsc_detach(ndev, nvdev);
+       if (ret)
+               goto rollback_vf;
 
        ndev->mtu = mtu;
 
-       nvdev = rndis_filter_device_add(hdev, &device_info);
-       if (IS_ERR(nvdev)) {
-               ret = PTR_ERR(nvdev);
-
-               /* Attempt rollback to original MTU */
-               ndev->mtu = orig_mtu;
-               nvdev = rndis_filter_device_add(hdev, &device_info);
-
-               if (vf_netdev)
-                       dev_set_mtu(vf_netdev, orig_mtu);
-
-               if (IS_ERR(nvdev)) {
-                       netdev_err(ndev, "restoring mtu failed: %ld\n",
-                                  PTR_ERR(nvdev));
-                       return ret;
-               }
-       }
+       ret = netvsc_attach(ndev, &device_info);
+       if (ret)
+               goto rollback;
 
-       if (was_opened)
-               rndis_filter_open(nvdev);
+       return 0;
 
-       netif_device_attach(ndev);
+rollback:
+       /* Attempt rollback to original MTU */
+       ndev->mtu = orig_mtu;
 
-       /* We may have missed link change notifications */
-       schedule_delayed_work(&ndevctx->dwork, 0);
+       if (netvsc_attach(ndev, &device_info))
+               netdev_err(ndev, "restoring mtu failed\n");
+rollback_vf:
+       if (vf_netdev)
+               dev_set_mtu(vf_netdev, orig_mtu);
 
        return ret;
 }
@@ -1490,11 +1575,9 @@ static int netvsc_set_ringparam(struct net_device *ndev,
 {
        struct net_device_context *ndevctx = netdev_priv(ndev);
        struct netvsc_device *nvdev = rtnl_dereference(ndevctx->nvdev);
-       struct hv_device *hdev = ndevctx->device_ctx;
        struct netvsc_device_info device_info;
        struct ethtool_ringparam orig;
        u32 new_tx, new_rx;
-       bool was_opened;
        int ret = 0;
 
        if (!nvdev || nvdev->destroy)
@@ -1519,34 +1602,18 @@ static int netvsc_set_ringparam(struct net_device *ndev,
        device_info.recv_sections = new_rx;
        device_info.recv_section_size = nvdev->recv_section_size;
 
-       netif_device_detach(ndev);
-       was_opened = rndis_filter_opened(nvdev);
-       if (was_opened)
-               rndis_filter_close(nvdev);
-
-       rndis_filter_device_remove(hdev, nvdev);
-
-       nvdev = rndis_filter_device_add(hdev, &device_info);
-       if (IS_ERR(nvdev)) {
-               ret = PTR_ERR(nvdev);
+       ret = netvsc_detach(ndev, nvdev);
+       if (ret)
+               return ret;
 
+       ret = netvsc_attach(ndev, &device_info);
+       if (ret) {
                device_info.send_sections = orig.tx_pending;
                device_info.recv_sections = orig.rx_pending;
-               nvdev = rndis_filter_device_add(hdev, &device_info);
-               if (IS_ERR(nvdev)) {
-                       netdev_err(ndev, "restoring ringparam failed: %ld\n",
-                                  PTR_ERR(nvdev));
-                       return ret;
-               }
-       }
 
-       if (was_opened)
-               rndis_filter_open(nvdev);
-       netif_device_attach(ndev);
-
-       /* We may have missed link change notifications */
-       ndevctx->last_reconfig = 0;
-       schedule_delayed_work(&ndevctx->dwork, 0);
+               if (netvsc_attach(ndev, &device_info))
+                       netdev_err(ndev, "restoring ringparam failed");
+       }
 
        return ret;
 }
@@ -1576,7 +1643,8 @@ static const struct net_device_ops device_ops = {
        .ndo_open =                     netvsc_open,
        .ndo_stop =                     netvsc_close,
        .ndo_start_xmit =               netvsc_start_xmit,
-       .ndo_set_rx_mode =              netvsc_set_multicast_list,
+       .ndo_change_rx_flags =          netvsc_change_rx_flags,
+       .ndo_set_rx_mode =              netvsc_set_rx_mode,
        .ndo_change_mtu =               netvsc_change_mtu,
        .ndo_validate_addr =            eth_validate_addr,
        .ndo_set_mac_address =          netvsc_set_mac_addr,
@@ -1807,6 +1875,15 @@ static void __netvsc_vf_setup(struct net_device *ndev,
                netdev_warn(vf_netdev,
                            "unable to change mtu to %u\n", ndev->mtu);
 
+       /* set multicast etc flags on VF */
+       dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE);
+
+       /* sync address list from ndev to VF */
+       netif_addr_lock_bh(ndev);
+       dev_uc_sync(vf_netdev, ndev);
+       dev_mc_sync(vf_netdev, ndev);
+       netif_addr_unlock_bh(ndev);
+
        if (netif_running(ndev)) {
                ret = dev_open(vf_netdev);
                if (ret)
@@ -2021,8 +2098,8 @@ no_net:
 static int netvsc_remove(struct hv_device *dev)
 {
        struct net_device_context *ndev_ctx;
-       struct net_device *vf_netdev;
-       struct net_device *net;
+       struct net_device *vf_netdev, *net;
+       struct netvsc_device *nvdev;
 
        net = hv_get_drvdata(dev);
        if (net == NULL) {
@@ -2032,10 +2109,14 @@ static int netvsc_remove(struct hv_device *dev)
 
        ndev_ctx = netdev_priv(net);
 
-       netif_device_detach(net);
-
        cancel_delayed_work_sync(&ndev_ctx->dwork);
 
+       rcu_read_lock();
+       nvdev = rcu_dereference(ndev_ctx->nvdev);
+
+       if  (nvdev)
+               cancel_work_sync(&nvdev->subchan_work);
+
        /*
         * Call to the vsc driver to let it know that the device is being
         * removed. Also blocks mtu and channel changes.
@@ -2045,11 +2126,13 @@ static int netvsc_remove(struct hv_device *dev)
        if (vf_netdev)
                netvsc_unregister_vf(vf_netdev);
 
+       if (nvdev)
+               rndis_filter_device_remove(dev, nvdev);
+
        unregister_netdevice(net);
 
-       rndis_filter_device_remove(dev,
-                                  rtnl_dereference(ndev_ctx->nvdev));
        rtnl_unlock();
+       rcu_read_unlock();
 
        hv_set_drvdata(dev, NULL);
 
index c3ca191fea7fe6bc629ae45be0759cdf1f062956..a6ec41c399d6c980b86ac1242179e99de542e5ea 100644 (file)
@@ -264,13 +264,23 @@ static void rndis_set_link_state(struct rndis_device *rdev,
        }
 }
 
-static void rndis_filter_receive_response(struct rndis_device *dev,
-                                      struct rndis_message *resp)
+static void rndis_filter_receive_response(struct net_device *ndev,
+                                         struct netvsc_device *nvdev,
+                                         const struct rndis_message *resp)
 {
+       struct rndis_device *dev = nvdev->extension;
        struct rndis_request *request = NULL;
        bool found = false;
        unsigned long flags;
-       struct net_device *ndev = dev->ndev;
+
+       /* This should never happen, it means control message
+        * response received after device removed.
+        */
+       if (dev->state == RNDIS_DEV_UNINITIALIZED) {
+               netdev_err(ndev,
+                          "got rndis message uninitialized\n");
+               return;
+       }
 
        spin_lock_irqsave(&dev->request_lock, flags);
        list_for_each_entry(request, &dev->req_list, list_ent) {
@@ -352,7 +362,6 @@ static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
 
 static int rndis_filter_receive_data(struct net_device *ndev,
                                     struct netvsc_device *nvdev,
-                                    struct rndis_device *dev,
                                     struct rndis_message *msg,
                                     struct vmbus_channel *channel,
                                     void *data, u32 data_buflen)
@@ -372,7 +381,7 @@ static int rndis_filter_receive_data(struct net_device *ndev,
         * should be the data packet size plus the trailer padding size
         */
        if (unlikely(data_buflen < rndis_pkt->data_len)) {
-               netdev_err(dev->ndev, "rndis message buffer "
+               netdev_err(ndev, "rndis message buffer "
                           "overflow detected (got %u, min %u)"
                           "...dropping this message!\n",
                           data_buflen, rndis_pkt->data_len);
@@ -400,35 +409,20 @@ int rndis_filter_receive(struct net_device *ndev,
                         void *data, u32 buflen)
 {
        struct net_device_context *net_device_ctx = netdev_priv(ndev);
-       struct rndis_device *rndis_dev = net_dev->extension;
        struct rndis_message *rndis_msg = data;
 
-       /* Make sure the rndis device state is initialized */
-       if (unlikely(!rndis_dev)) {
-               netif_dbg(net_device_ctx, rx_err, ndev,
-                         "got rndis message but no rndis device!\n");
-               return NVSP_STAT_FAIL;
-       }
-
-       if (unlikely(rndis_dev->state == RNDIS_DEV_UNINITIALIZED)) {
-               netif_dbg(net_device_ctx, rx_err, ndev,
-                         "got rndis message uninitialized\n");
-               return NVSP_STAT_FAIL;
-       }
-
        if (netif_msg_rx_status(net_device_ctx))
                dump_rndis_message(ndev, rndis_msg);
 
        switch (rndis_msg->ndis_msg_type) {
        case RNDIS_MSG_PACKET:
-               return rndis_filter_receive_data(ndev, net_dev,
-                                                rndis_dev, rndis_msg,
+               return rndis_filter_receive_data(ndev, net_dev, rndis_msg,
                                                 channel, data, buflen);
        case RNDIS_MSG_INIT_C:
        case RNDIS_MSG_QUERY_C:
        case RNDIS_MSG_SET_C:
                /* completion msgs */
-               rndis_filter_receive_response(rndis_dev, rndis_msg);
+               rndis_filter_receive_response(ndev, net_dev, rndis_msg);
                break;
 
        case RNDIS_MSG_INDICATE:
@@ -825,13 +819,15 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,
        struct rndis_set_request *set;
        int ret;
 
+       if (dev->filter == new_filter)
+               return 0;
+
        request = get_rndis_request(dev, RNDIS_MSG_SET,
                        RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
                        sizeof(u32));
        if (!request)
                return -ENOMEM;
 
-
        /* Setup the rndis set */
        set = &request->request_msg.msg.set_req;
        set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
@@ -842,8 +838,10 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,
               &new_filter, sizeof(u32));
 
        ret = rndis_filter_send_request(dev, request);
-       if (ret == 0)
+       if (ret == 0) {
                wait_for_completion(&request->wait_event);
+               dev->filter = new_filter;
+       }
 
        put_rndis_request(dev, request);
 
@@ -854,15 +852,19 @@ static void rndis_set_multicast(struct work_struct *w)
 {
        struct rndis_device *rdev
                = container_of(w, struct rndis_device, mcast_work);
+       u32 filter = NDIS_PACKET_TYPE_DIRECTED;
+       unsigned int flags = rdev->ndev->flags;
 
-       if (rdev->ndev->flags & IFF_PROMISC)
-               rndis_filter_set_packet_filter(rdev,
-                                              NDIS_PACKET_TYPE_PROMISCUOUS);
-       else
-               rndis_filter_set_packet_filter(rdev,
-                                              NDIS_PACKET_TYPE_BROADCAST |
-                                              NDIS_PACKET_TYPE_ALL_MULTICAST |
-                                              NDIS_PACKET_TYPE_DIRECTED);
+       if (flags & IFF_PROMISC) {
+               filter = NDIS_PACKET_TYPE_PROMISCUOUS;
+       } else {
+               if (flags & IFF_ALLMULTI)
+                       filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+               if (flags & IFF_BROADCAST)
+                       filter |= NDIS_PACKET_TYPE_BROADCAST;
+       }
+
+       rndis_filter_set_packet_filter(rdev, filter);
 }
 
 void rndis_filter_update(struct netvsc_device *nvdev)
@@ -1116,6 +1118,7 @@ void rndis_set_subchannel(struct work_struct *w)
        for (i = 0; i < VRSS_SEND_TAB_SIZE; i++)
                ndev_ctx->tx_table[i] = i % nvdev->num_chn;
 
+       netif_device_attach(ndev);
        rtnl_unlock();
        return;
 
@@ -1126,6 +1129,8 @@ failed:
 
        nvdev->max_chn = 1;
        nvdev->num_chn = 1;
+
+       netif_device_attach(ndev);
 unlock:
        rtnl_unlock();
 }
@@ -1328,6 +1333,10 @@ out:
                net_device->num_chn = 1;
        }
 
+       /* No sub channels, device is ready */
+       if (net_device->num_chn == 1)
+               netif_device_attach(net);
+
        return net_device;
 
 err_dev_remv:
@@ -1346,7 +1355,6 @@ void rndis_filter_device_remove(struct hv_device *dev,
        net_dev->extension = NULL;
 
        netvsc_device_remove(dev);
-       kfree(rndis_dev);
 }
 
 int rndis_filter_open(struct netvsc_device *nvdev)
@@ -1364,10 +1372,3 @@ int rndis_filter_close(struct netvsc_device *nvdev)
 
        return rndis_filter_close_device(nvdev->extension);
 }
-
-bool rndis_filter_opened(const struct netvsc_device *nvdev)
-{
-       const struct rndis_device *dev = nvdev->extension;
-
-       return dev->state == RNDIS_DEV_DATAINITIALIZED;
-}
index 7de88b33d5b96d7f18a5f7c242a54c935b587086..9cbb0c8a896aff9d192850ad15734dc2872c0dfb 100644 (file)
@@ -3277,7 +3277,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 
        err = netdev_upper_dev_link(real_dev, dev, extack);
        if (err < 0)
-               goto unregister;
+               goto put_dev;
 
        /* need to be already registered so that ->init has run and
         * the MAC addr is set
@@ -3316,7 +3316,8 @@ del_dev:
        macsec_del_dev(macsec);
 unlink:
        netdev_upper_dev_unlink(real_dev, dev);
-unregister:
+put_dev:
+       dev_put(real_dev);
        unregister_netdevice(dev);
        return err;
 }
index a0f2be81d52e4a4fd24585d8957b181a3cf9a103..725f4b4afc6da946e967d4070b9cf76143360332 100644 (file)
@@ -1036,7 +1036,7 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev,
        lowerdev_features &= (features | ~NETIF_F_LRO);
        features = netdev_increment_features(lowerdev_features, features, mask);
        features |= ALWAYS_ON_FEATURES;
-       features &= ~NETIF_F_NETNS_LOCAL;
+       features &= (ALWAYS_ON_FEATURES | MACVLAN_FEATURES);
 
        return features;
 }
@@ -1451,7 +1451,7 @@ destroy_macvlan_port:
        /* the macvlan port may be freed by macvlan_uninit when fail to register.
         * so we destroy the macvlan port only when it's valid.
         */
-       if (create && macvlan_port_get_rtnl(dev))
+       if (create && macvlan_port_get_rtnl(lowerdev))
                macvlan_port_destroy(port->dev);
        return err;
 }
index 171010eb4d9c5c36da0be9888fb75cc54e136768..5ad130c3da43c869b39dc8ec83ec6795aa82be7d 100644 (file)
@@ -341,8 +341,8 @@ void bcm_phy_get_strings(struct phy_device *phydev, u8 *data)
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
-               memcpy(data + i * ETH_GSTRING_LEN,
-                      bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
+               strlcpy(data + i * ETH_GSTRING_LEN,
+                       bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
 }
 EXPORT_SYMBOL_GPL(bcm_phy_get_strings);
 
index 22d9bc9c33a4bce864505babe6b3060348542a62..0e0978d8a0eb332bc488bcb1be0f916af784cfa1 100644 (file)
@@ -1452,8 +1452,8 @@ static void marvell_get_strings(struct phy_device *phydev, u8 *data)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
-               memcpy(data + i * ETH_GSTRING_LEN,
-                      marvell_hw_stats[i].string, ETH_GSTRING_LEN);
+               strlcpy(data + i * ETH_GSTRING_LEN,
+                       marvell_hw_stats[i].string, ETH_GSTRING_LEN);
        }
 }
 
index 0f45310300f667bab84655d301d64eb8196ae128..f41b224a9cdbf49ccf82d72b5052686548c005a7 100644 (file)
@@ -635,25 +635,6 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev)
        return 0;
 }
 
-/* This routine returns -1 as an indication to the caller that the
- * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE
- * MMD extended PHY registers.
- */
-static int
-ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum)
-{
-       return -1;
-}
-
-/* This routine does nothing since the Micrel ksz9021 does not support
- * standard IEEE MMD extended PHY registers.
- */
-static int
-ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int devad, u16 regnum, u16 val)
-{
-       return -1;
-}
-
 static int kszphy_get_sset_count(struct phy_device *phydev)
 {
        return ARRAY_SIZE(kszphy_hw_stats);
@@ -664,8 +645,8 @@ static void kszphy_get_strings(struct phy_device *phydev, u8 *data)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) {
-               memcpy(data + i * ETH_GSTRING_LEN,
-                      kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
+               strlcpy(data + i * ETH_GSTRING_LEN,
+                       kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
        }
 }
 
@@ -946,8 +927,8 @@ static struct phy_driver ksphy_driver[] = {
        .get_stats      = kszphy_get_stats,
        .suspend        = genphy_suspend,
        .resume         = genphy_resume,
-       .read_mmd       = ksz9021_rd_mmd_phyreg,
-       .write_mmd      = ksz9021_wr_mmd_phyreg,
+       .read_mmd       = genphy_read_mmd_unsupported,
+       .write_mmd      = genphy_write_mmd_unsupported,
 }, {
        .phy_id         = PHY_ID_KSZ9031,
        .phy_id_mask    = MICREL_PHY_ID_MASK,
index e3e29c2b028b58d84034a534d34427b243513460..9aabfa1a455a89e364fe38e8d99b0d1a5d3e9944 100644 (file)
@@ -617,6 +617,77 @@ static void phy_error(struct phy_device *phydev)
        phy_trigger_machine(phydev, false);
 }
 
+/**
+ * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
+ * @phydev: target phy_device struct
+ */
+static int phy_disable_interrupts(struct phy_device *phydev)
+{
+       int err;
+
+       /* Disable PHY interrupts */
+       err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
+       if (err)
+               goto phy_err;
+
+       /* Clear the interrupt */
+       err = phy_clear_interrupt(phydev);
+       if (err)
+               goto phy_err;
+
+       return 0;
+
+phy_err:
+       phy_error(phydev);
+
+       return err;
+}
+
+/**
+ * phy_change - Called by the phy_interrupt to handle PHY changes
+ * @phydev: phy_device struct that interrupted
+ */
+static irqreturn_t phy_change(struct phy_device *phydev)
+{
+       if (phy_interrupt_is_valid(phydev)) {
+               if (phydev->drv->did_interrupt &&
+                   !phydev->drv->did_interrupt(phydev))
+                       return IRQ_NONE;
+
+               if (phydev->state == PHY_HALTED)
+                       if (phy_disable_interrupts(phydev))
+                               goto phy_err;
+       }
+
+       mutex_lock(&phydev->lock);
+       if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
+               phydev->state = PHY_CHANGELINK;
+       mutex_unlock(&phydev->lock);
+
+       /* reschedule state queue work to run as soon as possible */
+       phy_trigger_machine(phydev, true);
+
+       if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev))
+               goto phy_err;
+       return IRQ_HANDLED;
+
+phy_err:
+       phy_error(phydev);
+       return IRQ_NONE;
+}
+
+/**
+ * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes
+ * @work: work_struct that describes the work to be done
+ */
+void phy_change_work(struct work_struct *work)
+{
+       struct phy_device *phydev =
+               container_of(work, struct phy_device, phy_queue);
+
+       phy_change(phydev);
+}
+
 /**
  * phy_interrupt - PHY interrupt handler
  * @irq: interrupt line
@@ -632,9 +703,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
        if (PHY_HALTED == phydev->state)
                return IRQ_NONE;                /* It can't be ours.  */
 
-       phy_change(phydev);
-
-       return IRQ_HANDLED;
+       return phy_change(phydev);
 }
 
 /**
@@ -651,32 +720,6 @@ static int phy_enable_interrupts(struct phy_device *phydev)
        return phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
 }
 
-/**
- * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
- * @phydev: target phy_device struct
- */
-static int phy_disable_interrupts(struct phy_device *phydev)
-{
-       int err;
-
-       /* Disable PHY interrupts */
-       err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
-       if (err)
-               goto phy_err;
-
-       /* Clear the interrupt */
-       err = phy_clear_interrupt(phydev);
-       if (err)
-               goto phy_err;
-
-       return 0;
-
-phy_err:
-       phy_error(phydev);
-
-       return err;
-}
-
 /**
  * phy_start_interrupts - request and enable interrupts for a PHY device
  * @phydev: target phy_device struct
@@ -719,50 +762,6 @@ int phy_stop_interrupts(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_stop_interrupts);
 
-/**
- * phy_change - Called by the phy_interrupt to handle PHY changes
- * @phydev: phy_device struct that interrupted
- */
-void phy_change(struct phy_device *phydev)
-{
-       if (phy_interrupt_is_valid(phydev)) {
-               if (phydev->drv->did_interrupt &&
-                   !phydev->drv->did_interrupt(phydev))
-                       return;
-
-               if (phydev->state == PHY_HALTED)
-                       if (phy_disable_interrupts(phydev))
-                               goto phy_err;
-       }
-
-       mutex_lock(&phydev->lock);
-       if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
-               phydev->state = PHY_CHANGELINK;
-       mutex_unlock(&phydev->lock);
-
-       /* reschedule state queue work to run as soon as possible */
-       phy_trigger_machine(phydev, true);
-
-       if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev))
-               goto phy_err;
-       return;
-
-phy_err:
-       phy_error(phydev);
-}
-
-/**
- * phy_change_work - Scheduled by the phy_mac_interrupt to handle PHY changes
- * @work: work_struct that describes the work to be done
- */
-void phy_change_work(struct work_struct *work)
-{
-       struct phy_device *phydev =
-               container_of(work, struct phy_device, phy_queue);
-
-       phy_change(phydev);
-}
-
 /**
  * phy_stop - Bring down the PHY link, and stop checking the status
  * @phydev: target phy_device struct
@@ -819,7 +818,7 @@ void phy_start(struct phy_device *phydev)
                break;
        case PHY_HALTED:
                /* if phy was suspended, bring the physical link up again */
-               phy_resume(phydev);
+               __phy_resume(phydev);
 
                /* make sure interrupts are re-enabled for the PHY */
                if (phy_interrupt_is_valid(phydev)) {
index b13eed21c87dac6fcad78c4240cf76200a1c4288..74664a6c0cdc31092e9aee5f189ac053d116846e 100644 (file)
@@ -135,9 +135,7 @@ static int mdio_bus_phy_resume(struct device *dev)
        if (!mdio_bus_phy_may_suspend(phydev))
                goto no_resume;
 
-       mutex_lock(&phydev->lock);
        ret = phy_resume(phydev);
-       mutex_unlock(&phydev->lock);
        if (ret < 0)
                return ret;
 
@@ -1014,10 +1012,17 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
        err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
                                "attached_dev");
        if (!err) {
-               err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
-                                       "phydev");
-               if (err)
-                       goto error;
+               err = sysfs_create_link_nowarn(&dev->dev.kobj,
+                                              &phydev->mdio.dev.kobj,
+                                              "phydev");
+               if (err) {
+                       dev_err(&dev->dev, "could not add device link to %s err %d\n",
+                               kobject_name(&phydev->mdio.dev.kobj),
+                               err);
+                       /* non-fatal - some net drivers can use one netdevice
+                        * with more then one phy
+                        */
+               }
 
                phydev->sysfs_links = true;
        }
@@ -1041,9 +1046,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
        if (err)
                goto error;
 
-       mutex_lock(&phydev->lock);
        phy_resume(phydev);
-       mutex_unlock(&phydev->lock);
        phy_led_triggers_register(phydev);
 
        return err;
@@ -1172,7 +1175,7 @@ int phy_suspend(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_suspend);
 
-int phy_resume(struct phy_device *phydev)
+int __phy_resume(struct phy_device *phydev)
 {
        struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
        int ret = 0;
@@ -1189,6 +1192,18 @@ int phy_resume(struct phy_device *phydev)
 
        return ret;
 }
+EXPORT_SYMBOL(__phy_resume);
+
+int phy_resume(struct phy_device *phydev)
+{
+       int ret;
+
+       mutex_lock(&phydev->lock);
+       ret = __phy_resume(phydev);
+       mutex_unlock(&phydev->lock);
+
+       return ret;
+}
 EXPORT_SYMBOL(phy_resume);
 
 int phy_loopback(struct phy_device *phydev, bool enable)
@@ -1382,7 +1397,7 @@ int genphy_setup_forced(struct phy_device *phydev)
                ctl |= BMCR_FULLDPLX;
 
        return phy_modify(phydev, MII_BMCR,
-                         BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN, ctl);
+                         ~(BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN), ctl);
 }
 EXPORT_SYMBOL(genphy_setup_forced);
 
@@ -1658,6 +1673,23 @@ int genphy_config_init(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(genphy_config_init);
 
+/* This is used for the phy device which doesn't support the MMD extended
+ * register access, but it does have side effect when we are trying to access
+ * the MMD register via indirect method.
+ */
+int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum)
+{
+       return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(genphy_read_mmd_unsupported);
+
+int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
+                                u16 regnum, u16 val)
+{
+       return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(genphy_write_mmd_unsupported);
+
 int genphy_suspend(struct phy_device *phydev)
 {
        return phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
index ee3ca4a2f12b415c9e532a9aaf218e89b9664cc9..9f48ecf9c62700ea815492fb91a960ba11e7b248 100644 (file)
@@ -172,6 +172,8 @@ static struct phy_driver realtek_drvs[] = {
                .flags          = PHY_HAS_INTERRUPT,
                .ack_interrupt  = &rtl821x_ack_interrupt,
                .config_intr    = &rtl8211b_config_intr,
+               .read_mmd       = &genphy_read_mmd_unsupported,
+               .write_mmd      = &genphy_write_mmd_unsupported,
        }, {
                .phy_id         = 0x001cc914,
                .name           = "RTL8211DN Gigabit Ethernet",
index 255a5def56e941939e02642d0ee9868ec1fff5bd..da1937832c9902c9f5d47f9095d33e5fdf4ab518 100644 (file)
@@ -257,7 +257,7 @@ struct ppp_net {
 /* Prototypes. */
 static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
                        struct file *file, unsigned int cmd, unsigned long arg);
-static void ppp_xmit_process(struct ppp *ppp);
+static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb);
 static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
 static void ppp_push(struct ppp *ppp);
 static void ppp_channel_push(struct channel *pch);
@@ -513,13 +513,12 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,
                goto out;
        }
 
-       skb_queue_tail(&pf->xq, skb);
-
        switch (pf->kind) {
        case INTERFACE:
-               ppp_xmit_process(PF_TO_PPP(pf));
+               ppp_xmit_process(PF_TO_PPP(pf), skb);
                break;
        case CHANNEL:
+               skb_queue_tail(&pf->xq, skb);
                ppp_channel_push(PF_TO_CHANNEL(pf));
                break;
        }
@@ -1267,8 +1266,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
        put_unaligned_be16(proto, pp);
 
        skb_scrub_packet(skb, !net_eq(ppp->ppp_net, dev_net(dev)));
-       skb_queue_tail(&ppp->file.xq, skb);
-       ppp_xmit_process(ppp);
+       ppp_xmit_process(ppp, skb);
+
        return NETDEV_TX_OK;
 
  outf:
@@ -1420,13 +1419,14 @@ static void ppp_setup(struct net_device *dev)
  */
 
 /* Called to do any work queued up on the transmit side that can now be done */
-static void __ppp_xmit_process(struct ppp *ppp)
+static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
 {
-       struct sk_buff *skb;
-
        ppp_xmit_lock(ppp);
        if (!ppp->closing) {
                ppp_push(ppp);
+
+               if (skb)
+                       skb_queue_tail(&ppp->file.xq, skb);
                while (!ppp->xmit_pending &&
                       (skb = skb_dequeue(&ppp->file.xq)))
                        ppp_send_frame(ppp, skb);
@@ -1440,7 +1440,7 @@ static void __ppp_xmit_process(struct ppp *ppp)
        ppp_xmit_unlock(ppp);
 }
 
-static void ppp_xmit_process(struct ppp *ppp)
+static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
 {
        local_bh_disable();
 
@@ -1448,7 +1448,7 @@ static void ppp_xmit_process(struct ppp *ppp)
                goto err;
 
        (*this_cpu_ptr(ppp->xmit_recursion))++;
-       __ppp_xmit_process(ppp);
+       __ppp_xmit_process(ppp, skb);
        (*this_cpu_ptr(ppp->xmit_recursion))--;
 
        local_bh_enable();
@@ -1458,6 +1458,8 @@ static void ppp_xmit_process(struct ppp *ppp)
 err:
        local_bh_enable();
 
+       kfree_skb(skb);
+
        if (net_ratelimit())
                netdev_err(ppp->dev, "recursion detected\n");
 }
@@ -1942,7 +1944,7 @@ static void __ppp_channel_push(struct channel *pch)
        if (skb_queue_empty(&pch->file.xq)) {
                ppp = pch->ppp;
                if (ppp)
-                       __ppp_xmit_process(ppp);
+                       __ppp_xmit_process(ppp, NULL);
        }
 }
 
@@ -3161,6 +3163,15 @@ ppp_connect_channel(struct channel *pch, int unit)
                goto outl;
 
        ppp_lock(ppp);
+       spin_lock_bh(&pch->downl);
+       if (!pch->chan) {
+               /* Don't connect unregistered channels */
+               spin_unlock_bh(&pch->downl);
+               ppp_unlock(ppp);
+               ret = -ENOTCONN;
+               goto outl;
+       }
+       spin_unlock_bh(&pch->downl);
        if (pch->file.hdrlen > ppp->file.hdrlen)
                ppp->file.hdrlen = pch->file.hdrlen;
        hdrlen = pch->file.hdrlen + 2;  /* for protocol bytes */
index a468439969df7f7166c3116bfaa543f82ae52c91..56c701b73c127c15db191b151b8f5e084782f892 100644 (file)
@@ -2395,7 +2395,7 @@ send_done:
        if (!nlh) {
                err = __send_and_alloc_skb(&skb, team, portid, send_func);
                if (err)
-                       goto errout;
+                       return err;
                goto send_done;
        }
 
@@ -2681,7 +2681,7 @@ send_done:
        if (!nlh) {
                err = __send_and_alloc_skb(&skb, team, portid, send_func);
                if (err)
-                       goto errout;
+                       return err;
                goto send_done;
        }
 
index ca5e375de27c131534ce1bd2768b787be2fb908f..e0d6760f321951da99e38dd6dc8eb3749848e115 100644 (file)
@@ -166,6 +166,8 @@ struct tbnet_ring {
  * @connected_work: Worker that finalizes the ThunderboltIP connection
  *                 setup and enables DMA paths for high speed data
  *                 transfers
+ * @disconnect_work: Worker that handles tearing down the ThunderboltIP
+ *                  connection
  * @rx_hdr: Copy of the currently processed Rx frame. Used when a
  *         network packet consists of multiple Thunderbolt frames.
  *         In host byte order.
@@ -190,6 +192,7 @@ struct tbnet {
        int login_retries;
        struct delayed_work login_work;
        struct work_struct connected_work;
+       struct work_struct disconnect_work;
        struct thunderbolt_ip_frame_header rx_hdr;
        struct tbnet_ring rx_ring;
        atomic_t frame_id;
@@ -445,7 +448,7 @@ static int tbnet_handle_packet(const void *buf, size_t size, void *data)
        case TBIP_LOGOUT:
                ret = tbnet_logout_response(net, route, sequence, command_id);
                if (!ret)
-                       tbnet_tear_down(net, false);
+                       queue_work(system_long_wq, &net->disconnect_work);
                break;
 
        default:
@@ -659,6 +662,13 @@ static void tbnet_login_work(struct work_struct *work)
        }
 }
 
+static void tbnet_disconnect_work(struct work_struct *work)
+{
+       struct tbnet *net = container_of(work, typeof(*net), disconnect_work);
+
+       tbnet_tear_down(net, false);
+}
+
 static bool tbnet_check_frame(struct tbnet *net, const struct tbnet_frame *tf,
                              const struct thunderbolt_ip_frame_header *hdr)
 {
@@ -881,6 +891,7 @@ static int tbnet_stop(struct net_device *dev)
 
        napi_disable(&net->napi);
 
+       cancel_work_sync(&net->disconnect_work);
        tbnet_tear_down(net, true);
 
        tb_ring_free(net->rx_ring.ring);
@@ -1195,6 +1206,7 @@ static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id)
        net = netdev_priv(dev);
        INIT_DELAYED_WORK(&net->login_work, tbnet_login_work);
        INIT_WORK(&net->connected_work, tbnet_connected_work);
+       INIT_WORK(&net->disconnect_work, tbnet_disconnect_work);
        mutex_init(&net->connection_lock);
        atomic_set(&net->command_id, 0);
        atomic_set(&net->frame_id, 0);
@@ -1270,10 +1282,7 @@ static int __maybe_unused tbnet_suspend(struct device *dev)
        stop_login(net);
        if (netif_running(net->dev)) {
                netif_device_detach(net->dev);
-               tb_ring_stop(net->rx_ring.ring);
-               tb_ring_stop(net->tx_ring.ring);
-               tbnet_free_buffers(&net->rx_ring);
-               tbnet_free_buffers(&net->tx_ring);
+               tbnet_tear_down(net, true);
        }
 
        return 0;
index 81e6cc951e7fc7c983919365c34842c34bcaedcf..28cfa642e39a250ba8a85213fe32555797f10b1b 100644 (file)
@@ -181,7 +181,6 @@ struct tun_file {
        struct tun_struct *detached;
        struct ptr_ring tx_ring;
        struct xdp_rxq_info xdp_rxq;
-       int xdp_pending_pkts;
 };
 
 struct tun_flow_entry {
@@ -656,7 +655,7 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile)
        return tun;
 }
 
-static void tun_ptr_free(void *ptr)
+void tun_ptr_free(void *ptr)
 {
        if (!ptr)
                return;
@@ -668,6 +667,7 @@ static void tun_ptr_free(void *ptr)
                __skb_array_destroy_skb(ptr);
        }
 }
+EXPORT_SYMBOL_GPL(tun_ptr_free);
 
 static void tun_queue_purge(struct tun_file *tfile)
 {
@@ -1489,27 +1489,23 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
        skb->truesize += skb->data_len;
 
        for (i = 1; i < it->nr_segs; i++) {
+               struct page_frag *pfrag = &current->task_frag;
                size_t fragsz = it->iov[i].iov_len;
-               unsigned long offset;
-               struct page *page;
-               void *data;
 
                if (fragsz == 0 || fragsz > PAGE_SIZE) {
                        err = -EINVAL;
                        goto free;
                }
 
-               local_bh_disable();
-               data = napi_alloc_frag(fragsz);
-               local_bh_enable();
-               if (!data) {
+               if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) {
                        err = -ENOMEM;
                        goto free;
                }
 
-               page = virt_to_head_page(data);
-               offset = data - page_address(page);
-               skb_fill_page_desc(skb, i - 1, page, offset, fragsz);
+               skb_fill_page_desc(skb, i - 1, pfrag->page,
+                                  pfrag->offset, fragsz);
+               page_ref_inc(pfrag->page);
+               pfrag->offset += fragsz;
        }
 
        return skb;
@@ -1647,6 +1643,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
        else
                *skb_xdp = 0;
 
+       preempt_disable();
        rcu_read_lock();
        xdp_prog = rcu_dereference(tun->xdp_prog);
        if (xdp_prog && !*skb_xdp) {
@@ -1666,11 +1663,12 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
                case XDP_REDIRECT:
                        get_page(alloc_frag->page);
                        alloc_frag->offset += buflen;
-                       ++tfile->xdp_pending_pkts;
                        err = xdp_do_redirect(tun->dev, &xdp, xdp_prog);
+                       xdp_do_flush_map();
                        if (err)
                                goto err_redirect;
                        rcu_read_unlock();
+                       preempt_enable();
                        return NULL;
                case XDP_TX:
                        xdp_xmit = true;
@@ -1692,6 +1690,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
        skb = build_skb(buf, buflen);
        if (!skb) {
                rcu_read_unlock();
+               preempt_enable();
                return ERR_PTR(-ENOMEM);
        }
 
@@ -1704,10 +1703,12 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
                skb->dev = tun->dev;
                generic_xdp_tx(skb, xdp_prog);
                rcu_read_unlock();
+               preempt_enable();
                return NULL;
        }
 
        rcu_read_unlock();
+       preempt_enable();
 
        return skb;
 
@@ -1715,6 +1716,7 @@ err_redirect:
        put_page(alloc_frag->page);
 err_xdp:
        rcu_read_unlock();
+       preempt_enable();
        this_cpu_inc(tun->pcpu_stats->rx_dropped);
        return NULL;
 }
@@ -1988,11 +1990,6 @@ static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
        result = tun_get_user(tun, tfile, NULL, from,
                              file->f_flags & O_NONBLOCK, false);
 
-       if (tfile->xdp_pending_pkts) {
-               tfile->xdp_pending_pkts = 0;
-               xdp_do_flush_map();
-       }
-
        tun_put(tun);
        return result;
 }
@@ -2329,13 +2326,6 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
        ret = tun_get_user(tun, tfile, m->msg_control, &m->msg_iter,
                           m->msg_flags & MSG_DONTWAIT,
                           m->msg_flags & MSG_MORE);
-
-       if (tfile->xdp_pending_pkts >= NAPI_POLL_WEIGHT ||
-           !(m->msg_flags & MSG_MORE)) {
-               tfile->xdp_pending_pkts = 0;
-               xdp_do_flush_map();
-       }
-
        tun_put(tun);
        return ret;
 }
@@ -3167,7 +3157,6 @@ static int tun_chr_open(struct inode *inode, struct file * file)
        sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
 
        memset(&tfile->tx_ring, 0, sizeof(tfile->tx_ring));
-       tfile->xdp_pending_pkts = 0;
 
        return 0;
 }
index 05dca3e5c93d4baf7fb975a6fef30d3d322f1aaf..fff4b13eece29cd3d742309a0f7d57436ec22699 100644 (file)
@@ -895,6 +895,12 @@ static const struct usb_device_id  products[] = {
                                      USB_CDC_SUBCLASS_ETHERNET,
                                      USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long)&wwan_info,
+}, {
+       /* Cinterion PLS8 modem by GEMALTO */
+       USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0061, USB_CLASS_COMM,
+                                     USB_CDC_SUBCLASS_ETHERNET,
+                                     USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long)&wwan_info,
 }, {
        USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
                        USB_CDC_PROTO_NONE),
index 958b2e8b90f689249abfea6c713e491300a7dc94..86f7196f9d91fbf55c791fff88687a43518d66d8 100644 (file)
@@ -1794,7 +1794,7 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 
                tx_data += len;
                agg->skb_len += len;
-               agg->skb_num++;
+               agg->skb_num += skb_shinfo(skb)->gso_segs ?: 1;
 
                dev_kfree_skb_any(skb);
 
index d0a113743195acae86931c51eea50b94ddadd487..7a6a1fe793090b8e28f5ef075f5ebc2ad385b5eb 100644 (file)
@@ -954,10 +954,11 @@ static int smsc75xx_set_features(struct net_device *netdev,
        /* it's racing here! */
 
        ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
-       if (ret < 0)
+       if (ret < 0) {
                netdev_warn(dev->net, "Error writing RFE_CTL\n");
-
-       return ret;
+               return ret;
+       }
+       return 0;
 }
 
 static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm)
index 8a22ff67b0268a588428c61c6a6211e3c6c2a02a..d9eea8cfe6cb9a3bf8d0d4ce9198af9bccf9c757 100644 (file)
@@ -315,6 +315,7 @@ static void __usbnet_status_stop_force(struct usbnet *dev)
 void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
 {
        struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
+       unsigned long flags;
        int     status;
 
        if (test_bit(EVENT_RX_PAUSED, &dev->flags)) {
@@ -326,10 +327,10 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
        if (skb->protocol == 0)
                skb->protocol = eth_type_trans (skb, dev->net);
 
-       u64_stats_update_begin(&stats64->syncp);
+       flags = u64_stats_update_begin_irqsave(&stats64->syncp);
        stats64->rx_packets++;
        stats64->rx_bytes += skb->len;
-       u64_stats_update_end(&stats64->syncp);
+       u64_stats_update_end_irqrestore(&stats64->syncp, flags);
 
        netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n",
                  skb->len + sizeof (struct ethhdr), skb->protocol);
@@ -1248,11 +1249,12 @@ static void tx_complete (struct urb *urb)
 
        if (urb->status == 0) {
                struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
+               unsigned long flags;
 
-               u64_stats_update_begin(&stats64->syncp);
+               flags = u64_stats_update_begin_irqsave(&stats64->syncp);
                stats64->tx_packets += entry->packets;
                stats64->tx_bytes += entry->length;
-               u64_stats_update_end(&stats64->syncp);
+               u64_stats_update_end_irqrestore(&stats64->syncp, flags);
        } else {
                dev->net->stats.tx_errors++;
 
index 626c27352ae243fe6364d59d5274a718475a7587..23374603e4d900850afd3b667eb25cdd082743b5 100644 (file)
@@ -443,12 +443,8 @@ static bool __virtnet_xdp_xmit(struct virtnet_info *vi,
        sg_init_one(sq->sg, xdp->data, xdp->data_end - xdp->data);
 
        err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdp->data, GFP_ATOMIC);
-       if (unlikely(err)) {
-               struct page *page = virt_to_head_page(xdp->data);
-
-               put_page(page);
-               return false;
-       }
+       if (unlikely(err))
+               return false; /* Caller handle free/refcnt */
 
        return true;
 }
@@ -456,8 +452,18 @@ static bool __virtnet_xdp_xmit(struct virtnet_info *vi,
 static int virtnet_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp)
 {
        struct virtnet_info *vi = netdev_priv(dev);
-       bool sent = __virtnet_xdp_xmit(vi, xdp);
+       struct receive_queue *rq = vi->rq;
+       struct bpf_prog *xdp_prog;
+       bool sent;
+
+       /* Only allow ndo_xdp_xmit if XDP is loaded on dev, as this
+        * indicate XDP resources have been successfully allocated.
+        */
+       xdp_prog = rcu_dereference(rq->xdp_prog);
+       if (!xdp_prog)
+               return -ENXIO;
 
+       sent = __virtnet_xdp_xmit(vi, xdp);
        if (!sent)
                return -ENOSPC;
        return 0;
@@ -498,6 +504,7 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
        page_off += *len;
 
        while (--*num_buf) {
+               int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
                unsigned int buflen;
                void *buf;
                int off;
@@ -512,7 +519,7 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
                /* guard against a misconfigured or uncooperative backend that
                 * is sending packet larger than the MTU.
                 */
-               if ((page_off + buflen) > PAGE_SIZE) {
+               if ((page_off + buflen + tailroom) > PAGE_SIZE) {
                        put_page(p);
                        goto err_buf;
                }
@@ -546,8 +553,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
        unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
                              SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
        struct page *page = virt_to_head_page(buf);
-       unsigned int delta = 0, err;
+       unsigned int delta = 0;
        struct page *xdp_page;
+       bool sent;
+       int err;
+
        len -= vi->hdr_len;
 
        rcu_read_lock();
@@ -558,7 +568,7 @@ static struct sk_buff *receive_small(struct net_device *dev,
                void *orig_data;
                u32 act;
 
-               if (unlikely(hdr->hdr.gso_type || hdr->hdr.flags))
+               if (unlikely(hdr->hdr.gso_type))
                        goto err_xdp;
 
                if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
@@ -596,16 +606,19 @@ static struct sk_buff *receive_small(struct net_device *dev,
                        delta = orig_data - xdp.data;
                        break;
                case XDP_TX:
-                       if (unlikely(!__virtnet_xdp_xmit(vi, &xdp)))
+                       sent = __virtnet_xdp_xmit(vi, &xdp);
+                       if (unlikely(!sent)) {
                                trace_xdp_exception(vi->dev, xdp_prog, act);
-                       else
-                               *xdp_xmit = true;
+                               goto err_xdp;
+                       }
+                       *xdp_xmit = true;
                        rcu_read_unlock();
                        goto xdp_xmit;
                case XDP_REDIRECT:
                        err = xdp_do_redirect(dev, &xdp, xdp_prog);
-                       if (!err)
-                               *xdp_xmit = true;
+                       if (err)
+                               goto err_xdp;
+                       *xdp_xmit = true;
                        rcu_read_unlock();
                        goto xdp_xmit;
                default:
@@ -677,6 +690,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
        struct bpf_prog *xdp_prog;
        unsigned int truesize;
        unsigned int headroom = mergeable_ctx_to_headroom(ctx);
+       bool sent;
        int err;
 
        head_skb = NULL;
@@ -689,7 +703,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                void *data;
                u32 act;
 
-               /* This happens when rx buffer size is underestimated */
+               /* This happens when rx buffer size is underestimated
+                * or headroom is not enough because of the buffer
+                * was refilled before XDP is set. This should only
+                * happen for the first several packets, so we don't
+                * care much about its performance.
+                */
                if (unlikely(num_buf > 1 ||
                             headroom < virtnet_get_headroom(vi))) {
                        /* linearize data for XDP */
@@ -724,9 +743,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 
                act = bpf_prog_run_xdp(xdp_prog, &xdp);
 
-               if (act != XDP_PASS)
-                       ewma_pkt_len_add(&rq->mrg_avg_pkt_len, len);
-
                switch (act) {
                case XDP_PASS:
                        /* recalculate offset to account for any header
@@ -746,18 +762,28 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                        }
                        break;
                case XDP_TX:
-                       if (unlikely(!__virtnet_xdp_xmit(vi, &xdp)))
+                       sent = __virtnet_xdp_xmit(vi, &xdp);
+                       if (unlikely(!sent)) {
                                trace_xdp_exception(vi->dev, xdp_prog, act);
-                       else
-                               *xdp_xmit = true;
+                               if (unlikely(xdp_page != page))
+                                       put_page(xdp_page);
+                               goto err_xdp;
+                       }
+                       *xdp_xmit = true;
                        if (unlikely(xdp_page != page))
                                goto err_xdp;
                        rcu_read_unlock();
                        goto xdp_xmit;
                case XDP_REDIRECT:
                        err = xdp_do_redirect(dev, &xdp, xdp_prog);
-                       if (!err)
-                               *xdp_xmit = true;
+                       if (err) {
+                               if (unlikely(xdp_page != page))
+                                       put_page(xdp_page);
+                               goto err_xdp;
+                       }
+                       *xdp_xmit = true;
+                       if (unlikely(xdp_page != page))
+                               goto err_xdp;
                        rcu_read_unlock();
                        goto xdp_xmit;
                default:
@@ -1003,13 +1029,18 @@ static int add_recvbuf_big(struct virtnet_info *vi, struct receive_queue *rq,
 }
 
 static unsigned int get_mergeable_buf_len(struct receive_queue *rq,
-                                         struct ewma_pkt_len *avg_pkt_len)
+                                         struct ewma_pkt_len *avg_pkt_len,
+                                         unsigned int room)
 {
        const size_t hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
        unsigned int len;
 
-       len = hdr_len + clamp_t(unsigned int, ewma_pkt_len_read(avg_pkt_len),
+       if (room)
+               return PAGE_SIZE - room;
+
+       len = hdr_len + clamp_t(unsigned int, ewma_pkt_len_read(avg_pkt_len),
                                rq->min_buf_len, PAGE_SIZE - hdr_len);
+
        return ALIGN(len, L1_CACHE_BYTES);
 }
 
@@ -1018,21 +1049,27 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
 {
        struct page_frag *alloc_frag = &rq->alloc_frag;
        unsigned int headroom = virtnet_get_headroom(vi);
+       unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
+       unsigned int room = SKB_DATA_ALIGN(headroom + tailroom);
        char *buf;
        void *ctx;
        int err;
        unsigned int len, hole;
 
-       len = get_mergeable_buf_len(rq, &rq->mrg_avg_pkt_len);
-       if (unlikely(!skb_page_frag_refill(len + headroom, alloc_frag, gfp)))
+       /* Extra tailroom is needed to satisfy XDP's assumption. This
+        * means rx frags coalescing won't work, but consider we've
+        * disabled GSO for XDP, it won't be a big issue.
+        */
+       len = get_mergeable_buf_len(rq, &rq->mrg_avg_pkt_len, room);
+       if (unlikely(!skb_page_frag_refill(len + room, alloc_frag, gfp)))
                return -ENOMEM;
 
        buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
        buf += headroom; /* advance address leaving hole at front of pkt */
        get_page(alloc_frag->page);
-       alloc_frag->offset += len + headroom;
+       alloc_frag->offset += len + room;
        hole = alloc_frag->size - alloc_frag->offset;
-       if (hole < len + headroom) {
+       if (hole < len + room) {
                /* To avoid internal fragmentation, if there is very likely not
                 * enough space for another buffer, add the remaining space to
                 * the current buffer.
@@ -2175,8 +2212,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
        }
 
        /* Make sure NAPI is not using any XDP TX queues for RX. */
-       for (i = 0; i < vi->max_queue_pairs; i++)
-               napi_disable(&vi->rq[i].napi);
+       if (netif_running(dev))
+               for (i = 0; i < vi->max_queue_pairs; i++)
+                       napi_disable(&vi->rq[i].napi);
 
        netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp);
        err = _virtnet_set_queues(vi, curr_qp + xdp_qp);
@@ -2195,7 +2233,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
                }
                if (old_prog)
                        bpf_prog_put(old_prog);
-               virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi);
+               if (netif_running(dev))
+                       virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi);
        }
 
        return 0;
@@ -2566,12 +2605,15 @@ static ssize_t mergeable_rx_buffer_size_show(struct netdev_rx_queue *queue,
 {
        struct virtnet_info *vi = netdev_priv(queue->dev);
        unsigned int queue_index = get_netdev_rx_queue_index(queue);
+       unsigned int headroom = virtnet_get_headroom(vi);
+       unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
        struct ewma_pkt_len *avg;
 
        BUG_ON(queue_index >= vi->max_queue_pairs);
        avg = &vi->rq[queue_index].mrg_avg_pkt_len;
        return sprintf(buf, "%u\n",
-                      get_mergeable_buf_len(&vi->rq[queue_index], avg));
+                      get_mergeable_buf_len(&vi->rq[queue_index], avg,
+                                      SKB_DATA_ALIGN(headroom + tailroom)));
 }
 
 static struct rx_queue_attribute mergeable_rx_buffer_size_attribute =
index 8b39c160743d41170c2e64bdd36c45f98c7df051..e04937f44f33313eb3eebf3bc1ea598686965950 100644 (file)
@@ -977,6 +977,8 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
 {
        int ret;
        u32 count;
+       int num_pkts;
+       int tx_num_deferred;
        unsigned long flags;
        struct vmxnet3_tx_ctx ctx;
        union Vmxnet3_GenericDesc *gdesc;
@@ -1075,12 +1077,12 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
 #else
        gdesc = ctx.sop_txd;
 #endif
+       tx_num_deferred = le32_to_cpu(tq->shared->txNumDeferred);
        if (ctx.mss) {
                gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
                gdesc->txd.om = VMXNET3_OM_TSO;
                gdesc->txd.msscof = ctx.mss;
-               le32_add_cpu(&tq->shared->txNumDeferred, (skb->len -
-                            gdesc->txd.hlen + ctx.mss - 1) / ctx.mss);
+               num_pkts = (skb->len - gdesc->txd.hlen + ctx.mss - 1) / ctx.mss;
        } else {
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
                        gdesc->txd.hlen = ctx.eth_ip_hdr_size;
@@ -1091,8 +1093,10 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
                        gdesc->txd.om = 0;
                        gdesc->txd.msscof = 0;
                }
-               le32_add_cpu(&tq->shared->txNumDeferred, 1);
+               num_pkts = 1;
        }
+       le32_add_cpu(&tq->shared->txNumDeferred, num_pkts);
+       tx_num_deferred += num_pkts;
 
        if (skb_vlan_tag_present(skb)) {
                gdesc->txd.ti = 1;
@@ -1118,8 +1122,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
 
        spin_unlock_irqrestore(&tq->tx_lock, flags);
 
-       if (le32_to_cpu(tq->shared->txNumDeferred) >=
-                                       le32_to_cpu(tq->shared->txThreshold)) {
+       if (tx_num_deferred >= le32_to_cpu(tq->shared->txThreshold)) {
                tq->shared->txNumDeferred = 0;
                VMXNET3_WRITE_BAR0_REG(adapter,
                                       VMXNET3_REG_TXPROD + tq->qid * 8,
@@ -1470,7 +1473,8 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                        vmxnet3_rx_csum(adapter, skb,
                                        (union Vmxnet3_GenericDesc *)rcd);
                        skb->protocol = eth_type_trans(skb, adapter->netdev);
-                       if (!rcd->tcp || !adapter->lro)
+                       if (!rcd->tcp ||
+                           !(adapter->netdev->features & NETIF_F_LRO))
                                goto not_lro;
 
                        if (segCnt != 0 && mss != 0) {
index 5ba222920e8009d39e73d78ab4132ade53b3c2dd..59ec34052a651ee831bbcbacee467965c5aaba36 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.11.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.13.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040b00
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040d00
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
@@ -342,9 +342,6 @@ struct vmxnet3_adapter {
        u8                      __iomem *hw_addr1; /* for BAR 1 */
        u8                              version;
 
-       bool                            rxcsum;
-       bool                            lro;
-
 #ifdef VMXNET3_RSS
        struct UPT1_RSSConf             *rss_conf;
        bool                            rss;
index afeca6bcdade60a45fb6588cb69e69e32014cc7f..ab8b3cbbb205cc42f2bea15259bee0b77c2ff055 100644 (file)
@@ -574,7 +574,10 @@ static void ppp_timer(struct timer_list *t)
                        ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
                                     0, NULL);
                        proto->restart_counter--;
-               } else
+               } else if (netif_carrier_ok(proto->dev))
+                       ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
+                                    0, NULL);
+               else
                        ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0,
                                     0, NULL);
                break;
index e89e5ef2c2a4edd467ee842ce7316031f2e1c9d2..f246e9ed4a814d783f2543e02d0ff6b4dfec1a02 100644 (file)
@@ -729,6 +729,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
        ieee80211_hw_set(hw, SPECTRUM_MGMT);
        ieee80211_hw_set(hw, SIGNAL_DBM);
        ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+       ieee80211_hw_set(hw, DOESNT_SUPPORT_QOS_NDP);
 
        if (ath9k_ps_enable)
                ieee80211_hw_set(hw, SUPPORTS_PS);
index df8a1ecb99241588384fa4a8503822137e12b39b..232dcbb8331111e362a78c0042580e67e6233b6c 100644 (file)
@@ -181,6 +181,7 @@ enum brcmf_netif_stop_reason {
  * @netif_stop_lock: spinlock for update netif_stop from multiple sources.
  * @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
  * @pend_8021x_wait: used for signalling change in count.
+ * @fwil_fwerr: flag indicating fwil layer should return firmware error codes.
  */
 struct brcmf_if {
        struct brcmf_pub *drvr;
@@ -198,6 +199,7 @@ struct brcmf_if {
        wait_queue_head_t pend_8021x_wait;
        struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES];
        u8 ipv6addr_idx;
+       bool fwil_fwerr;
 };
 
 int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
index 47de35a338532f65f4817b11b98b1f51b2c4344f..bede7b7fd9962c01a62eb2e8f43f6c281ce0d976 100644 (file)
@@ -104,6 +104,9 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
        u32 data;
        int err;
 
+       /* we need to know firmware error */
+       ifp->fwil_fwerr = true;
+
        err = brcmf_fil_iovar_int_get(ifp, name, &data);
        if (err == 0) {
                brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
@@ -112,6 +115,8 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
                brcmf_dbg(TRACE, "%s feature check failed: %d\n",
                          brcmf_feat_names[id], err);
        }
+
+       ifp->fwil_fwerr = false;
 }
 
 static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
@@ -120,6 +125,9 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
 {
        int err;
 
+       /* we need to know firmware error */
+       ifp->fwil_fwerr = true;
+
        err = brcmf_fil_iovar_data_set(ifp, name, data, len);
        if (err != -BRCMF_FW_UNSUPPORTED) {
                brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
@@ -128,6 +136,8 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
                brcmf_dbg(TRACE, "%s feature check failed: %d\n",
                          brcmf_feat_names[id], err);
        }
+
+       ifp->fwil_fwerr = false;
 }
 
 #define MAX_CAPS_BUFFER_SIZE   512
index f2cfdd3b2bf1a252f75240f393e2d462b8c3cfb0..fc5751116d99bf89f46769eb57bee290f6ae35c8 100644 (file)
@@ -131,6 +131,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
                          brcmf_fil_get_errstr((u32)(-fwerr)), fwerr);
                err = -EBADE;
        }
+       if (ifp->fwil_fwerr)
+               return fwerr;
+
        return err;
 }
 
index 2ee54133efa1c05a3f30aacb1491cde4d270dfef..82064e90978497cce2ce98759cf099829a757bf1 100644 (file)
@@ -462,25 +462,23 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
  * @dev_addr: optional device address.
  *
  * P2P needs mac addresses for P2P device and interface. If no device
- * address it specified, these are derived from the primary net device, ie.
- * the permanent ethernet address of the device.
+ * address it specified, these are derived from a random ethernet
+ * address.
  */
 static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr)
 {
-       struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
-       bool local_admin = false;
+       bool random_addr = false;
 
-       if (!dev_addr || is_zero_ether_addr(dev_addr)) {
-               dev_addr = pri_ifp->mac_addr;
-               local_admin = true;
-       }
+       if (!dev_addr || is_zero_ether_addr(dev_addr))
+               random_addr = true;
 
-       /* Generate the P2P Device Address.  This consists of the device's
-        * primary MAC address with the locally administered bit set.
+       /* Generate the P2P Device Address obtaining a random ethernet
+        * address with the locally administered bit set.
         */
-       memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
-       if (local_admin)
-               p2p->dev_addr[0] |= 0x02;
+       if (random_addr)
+               eth_random_addr(p2p->dev_addr);
+       else
+               memcpy(p2p->dev_addr, dev_addr, ETH_ALEN);
 
        /* Generate the P2P Interface Address.  If the discovery and connection
         * BSSCFGs need to simultaneously co-exist, then this address must be
index c5f2ddf9b0fe5fafb8633ce7a7905bd5f8fb61d8..e5a2fc738ac3616fe64f04c1472bc1d044f0c0d7 100644 (file)
@@ -91,7 +91,6 @@ config IWLWIFI_BCAST_FILTERING
 config IWLWIFI_PCIE_RTPM
        bool "Enable runtime power management mode for PCIe devices"
        depends on IWLMVM && PM && EXPERT
-       default false
        help
          Say Y here to enable runtime power management for PCIe
          devices.  If enabled, the device will go into low power mode
index 3721a3ed358b830fb94925c01273aba1a4e633cf..f824bebceb06081e915a07d746420b602f024fd5 100644 (file)
@@ -211,7 +211,7 @@ enum {
  * @TE_V2_NOTIF_HOST_FRAG_END:request/receive notification on frag end
  * @TE_V2_NOTIF_INTERNAL_FRAG_START: internal FW use.
  * @TE_V2_NOTIF_INTERNAL_FRAG_END: internal FW use.
- * @T2_V2_START_IMMEDIATELY: start time event immediately
+ * @TE_V2_START_IMMEDIATELY: start time event immediately
  * @TE_V2_DEP_OTHER: depends on another time event
  * @TE_V2_DEP_TSF: depends on a specific time
  * @TE_V2_EVENT_SOCIOPATHIC: can't co-exist with other events of tha same MAC
@@ -230,7 +230,7 @@ enum iwl_time_event_policy {
        TE_V2_NOTIF_HOST_FRAG_END = BIT(5),
        TE_V2_NOTIF_INTERNAL_FRAG_START = BIT(6),
        TE_V2_NOTIF_INTERNAL_FRAG_END = BIT(7),
-       T2_V2_START_IMMEDIATELY = BIT(11),
+       TE_V2_START_IMMEDIATELY = BIT(11),
 
        /* placement characteristics */
        TE_V2_DEP_OTHER = BIT(TE_V2_PLACEMENT_POS),
index 67aefc8fc9acc51a61070cc828a3c27019746409..7bd704a3e6409b3cab2f8032eddc63afb1e41a5c 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -942,7 +944,6 @@ dump_trans_data:
 
 out:
        iwl_fw_free_dump_desc(fwrt);
-       fwrt->dump.trig = NULL;
        clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
        IWL_DEBUG_INFO(fwrt, "WRT dump done\n");
 }
@@ -1112,6 +1113,14 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
            fwrt->ops->dump_start(fwrt->ops_ctx))
                return;
 
+       if (fwrt->ops && fwrt->ops->fw_running &&
+           !fwrt->ops->fw_running(fwrt->ops_ctx)) {
+               IWL_ERR(fwrt, "Firmware not running - cannot dump error\n");
+               iwl_fw_free_dump_desc(fwrt);
+               clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
+               goto out;
+       }
+
        if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
                /* stop recording */
                iwl_fw_dbg_stop_recording(fwrt);
@@ -1145,7 +1154,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
                        iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, out_ctrl);
                }
        }
-
+out:
        if (fwrt->ops && fwrt->ops->dump_end)
                fwrt->ops->dump_end(fwrt->ops_ctx);
 }
index 223fb77a3aa9d64456244dd4c5156b8885cec6fd..72259bff9922f7308a3d78250247ccfd29d84a8c 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,6 +93,7 @@ static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt)
        if (fwrt->dump.desc != &iwl_dump_desc_assert)
                kfree(fwrt->dump.desc);
        fwrt->dump.desc = NULL;
+       fwrt->dump.trig = NULL;
 }
 
 void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
index e57ff92a68ae2062721e3ad9bbec32997a263e79..3da468d2cc92f50697649adc7cc12d63c473ccb3 100644 (file)
@@ -75,6 +75,20 @@ static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt)
        cancel_delayed_work_sync(&fwrt->timestamp.wk);
 }
 
+static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt)
+{
+       cancel_delayed_work_sync(&fwrt->timestamp.wk);
+}
+
+static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt)
+{
+       if (!fwrt->timestamp.delay)
+               return;
+
+       schedule_delayed_work(&fwrt->timestamp.wk,
+                             round_jiffies_relative(fwrt->timestamp.delay));
+}
+
 #else
 static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
                                          struct dentry *dbgfs_dir)
@@ -84,4 +98,8 @@ static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
 
 static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) {}
 
+static inline void iwl_fw_suspend_timestamp(struct iwl_fw_runtime *fwrt) {}
+
+static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
+
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
index c39fe84bb4c4a9741497dbea4a143ccd3aeacca7..2efac307909e1c6cfae6b7d80ac28eaa555c1100 100644 (file)
@@ -77,8 +77,14 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
 }
 IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
 
-void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt)
+void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
 {
-       iwl_fw_cancel_timestamp(fwrt);
+       iwl_fw_suspend_timestamp(fwrt);
 }
-IWL_EXPORT_SYMBOL(iwl_fw_runtime_exit);
+IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
+
+void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt)
+{
+       iwl_fw_resume_timestamp(fwrt);
+}
+IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume);
index e25c049f980f27e33bb90e2234b5015f5f52b298..3fb940ebd74aae826076657daab9b0d2d39e3044 100644 (file)
@@ -6,6 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -26,6 +27,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -68,6 +70,7 @@
 struct iwl_fw_runtime_ops {
        int (*dump_start)(void *ctx);
        void (*dump_end)(void *ctx);
+       bool (*fw_running)(void *ctx);
 };
 
 #define MAX_NUM_LMAC 2
@@ -150,6 +153,10 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
 
 void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt);
 
+void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
+
+void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt);
+
 static inline void iwl_fw_set_current_image(struct iwl_fw_runtime *fwrt,
                                            enum iwl_ucode_type cur_fw_img)
 {
index 0e6cf39285f405d8c42e65ea2d0ef7d4e86179f0..2efe9b099556d862c946f2aeaff9746cfc3dded5 100644 (file)
@@ -1098,6 +1098,8 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        /* make sure the d0i3 exit work is not pending */
        flush_work(&mvm->d0i3_exit_work);
 
+       iwl_fw_runtime_suspend(&mvm->fwrt);
+
        ret = iwl_trans_suspend(trans);
        if (ret)
                return ret;
@@ -2012,6 +2014,8 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
 
        mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
 
+       iwl_fw_runtime_resume(&mvm->fwrt);
+
        return ret;
 }
 
@@ -2038,6 +2042,8 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
 
        mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
 
+       iwl_fw_runtime_suspend(&mvm->fwrt);
+
        /* start pseudo D3 */
        rtnl_lock();
        err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
@@ -2098,6 +2104,8 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
        __iwl_mvm_resume(mvm, true);
        rtnl_unlock();
 
+       iwl_fw_runtime_resume(&mvm->fwrt);
+
        mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
 
        iwl_abort_notification_waits(&mvm->notif_wait);
index a7892c1254a293f8184b470d5b97d7c425051d7c..9c436d8d001d39f47880e16e1d14fb64d574587d 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1281,9 +1283,6 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
 {
        int ret;
 
-       if (!iwl_mvm_firmware_running(mvm))
-               return -EIO;
-
        ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
        if (ret)
                return ret;
index 2f22e14e00fe881bc9868a22c25ba41286a9ea51..8ba16fc24e3af0bd6bc07b6de7195e375d3f0cb1 100644 (file)
@@ -438,7 +438,8 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        }
 
        /* Allocate the CAB queue for softAP and GO interfaces */
-       if (vif->type == NL80211_IFTYPE_AP) {
+       if (vif->type == NL80211_IFTYPE_AP ||
+           vif->type == NL80211_IFTYPE_ADHOC) {
                /*
                 * For TVQM this will be overwritten later with the FW assigned
                 * queue value (when queue is enabled).
index 8aed40a8bc385fa6553e815027972f73feccdbe1..ebf511150f4d02561362d8f3973ec2751cb8d3ef 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -2106,15 +2107,40 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
        if (ret)
                goto out_remove;
 
-       ret = iwl_mvm_add_mcast_sta(mvm, vif);
-       if (ret)
-               goto out_unbind;
-
-       /* Send the bcast station. At this stage the TBTT and DTIM time events
-        * are added and applied to the scheduler */
-       ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
-       if (ret)
-               goto out_rm_mcast;
+       /*
+        * This is not very nice, but the simplest:
+        * For older FWs adding the mcast sta before the bcast station may
+        * cause assert 0x2b00.
+        * This is fixed in later FW so make the order of removal depend on
+        * the TLV
+        */
+       if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE)) {
+               ret = iwl_mvm_add_mcast_sta(mvm, vif);
+               if (ret)
+                       goto out_unbind;
+               /*
+                * Send the bcast station. At this stage the TBTT and DTIM time
+                * events are added and applied to the scheduler
+                */
+               ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
+               if (ret) {
+                       iwl_mvm_rm_mcast_sta(mvm, vif);
+                       goto out_unbind;
+               }
+       } else {
+               /*
+                * Send the bcast station. At this stage the TBTT and DTIM time
+                * events are added and applied to the scheduler
+                */
+               iwl_mvm_send_add_bcast_sta(mvm, vif);
+               if (ret)
+                       goto out_unbind;
+               iwl_mvm_add_mcast_sta(mvm, vif);
+               if (ret) {
+                       iwl_mvm_send_rm_bcast_sta(mvm, vif);
+                       goto out_unbind;
+               }
+       }
 
        /* must be set before quota calculations */
        mvmvif->ap_ibss_active = true;
@@ -2144,7 +2170,6 @@ out_quota_failed:
        iwl_mvm_power_update_mac(mvm);
        mvmvif->ap_ibss_active = false;
        iwl_mvm_send_rm_bcast_sta(mvm, vif);
-out_rm_mcast:
        iwl_mvm_rm_mcast_sta(mvm, vif);
 out_unbind:
        iwl_mvm_binding_remove_vif(mvm, vif);
@@ -2682,6 +2707,10 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
 
                /* enable beacon filtering */
                WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
+
+               iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+                                    false);
+
                ret = 0;
        } else if (old_state == IEEE80211_STA_AUTHORIZED &&
                   new_state == IEEE80211_STA_ASSOC) {
index 2d28e08042186e7ad0a060a267569e972b3c7feb..89ff02d7c87663ce7a1351940308292234f85a48 100644 (file)
@@ -90,6 +90,7 @@
 #include "fw/runtime.h"
 #include "fw/dbg.h"
 #include "fw/acpi.h"
+#include "fw/debugfs.h"
 
 #define IWL_MVM_MAX_ADDRESSES          5
 /* RSSI offset for WkP */
@@ -1783,6 +1784,7 @@ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
 
 static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
 {
+       iwl_fw_cancel_timestamp(&mvm->fwrt);
        iwl_free_fw_paging(&mvm->fwrt);
        clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
        iwl_fw_dump_conf_clear(&mvm->fwrt);
index 5d525a0023dc3ff4ea1ee074093f547aa6232016..ab7fb5aad984a509a788f1355056da1f2aa45765 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018        Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -552,9 +554,15 @@ static void iwl_mvm_fwrt_dump_end(void *ctx)
        iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
 }
 
+static bool iwl_mvm_fwrt_fw_running(void *ctx)
+{
+       return iwl_mvm_firmware_running(ctx);
+}
+
 static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = {
        .dump_start = iwl_mvm_fwrt_dump_start,
        .dump_end = iwl_mvm_fwrt_dump_end,
+       .fw_running = iwl_mvm_fwrt_fw_running,
 };
 
 static struct iwl_op_mode *
@@ -802,7 +810,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
        iwl_mvm_leds_exit(mvm);
        iwl_mvm_thermal_exit(mvm);
  out_free:
-       iwl_fw_runtime_exit(&mvm->fwrt);
        iwl_fw_flush_dump(&mvm->fwrt);
 
        if (iwlmvm_mod_params.init_dbg)
@@ -843,7 +850,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
        kfree(mvm->d3_resume_sram);
 #endif
-       iwl_fw_runtime_exit(&mvm->fwrt);
        iwl_trans_op_mode_leave(mvm->trans);
 
        iwl_phy_db_free(mvm->phy_db);
index 60abb0084ee5905dd38f89a694542ddf1094a742..47f4c7a1d80d26ca22ba118914be3c44ce373c13 100644 (file)
@@ -2684,7 +2684,8 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
                                struct ieee80211_sta *sta,
                                struct iwl_lq_sta *lq_sta,
                                enum nl80211_band band,
-                               struct rs_rate *rate)
+                               struct rs_rate *rate,
+                               bool init)
 {
        int i, nentries;
        unsigned long active_rate;
@@ -2738,14 +2739,25 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
         */
        if (sta->vht_cap.vht_supported &&
            best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {
-               switch (sta->bandwidth) {
-               case IEEE80211_STA_RX_BW_160:
-               case IEEE80211_STA_RX_BW_80:
-               case IEEE80211_STA_RX_BW_40:
+               /*
+                * In AP mode, when a new station associates, rs is initialized
+                * immediately upon association completion, before the phy
+                * context is updated with the association parameters, so the
+                * sta bandwidth might be wider than the phy context allows.
+                * To avoid this issue, always initialize rs with 20mhz
+                * bandwidth rate, and after authorization, when the phy context
+                * is already up-to-date, re-init rs with the correct bw.
+                */
+               u32 bw = init ? RATE_MCS_CHAN_WIDTH_20 : rs_bw_from_sta_bw(sta);
+
+               switch (bw) {
+               case RATE_MCS_CHAN_WIDTH_40:
+               case RATE_MCS_CHAN_WIDTH_80:
+               case RATE_MCS_CHAN_WIDTH_160:
                        initial_rates = rs_optimal_rates_vht;
                        nentries = ARRAY_SIZE(rs_optimal_rates_vht);
                        break;
-               case IEEE80211_STA_RX_BW_20:
+               case RATE_MCS_CHAN_WIDTH_20:
                        initial_rates = rs_optimal_rates_vht_20mhz;
                        nentries = ARRAY_SIZE(rs_optimal_rates_vht_20mhz);
                        break;
@@ -2756,7 +2768,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
 
                active_rate = lq_sta->active_siso_rate;
                rate->type = LQ_VHT_SISO;
-               rate->bw = rs_bw_from_sta_bw(sta);
+               rate->bw = bw;
        } else if (sta->ht_cap.ht_supported &&
                   best_rssi > IWL_RS_LOW_RSSI_THRESHOLD) {
                initial_rates = rs_optimal_rates_ht;
@@ -2839,7 +2851,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
        tbl = &(lq_sta->lq_info[active_tbl]);
        rate = &tbl->rate;
 
-       rs_get_initial_rate(mvm, sta, lq_sta, band, rate);
+       rs_get_initial_rate(mvm, sta, lq_sta, band, rate, init);
        rs_init_optimal_rate(mvm, sta, lq_sta);
 
        WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B,
index a3f7c1bf3cc858b9166d33707fac43a5b1cf1037..580de5851fc7f6a129980337a0c6e844d63374c1 100644 (file)
@@ -71,6 +71,7 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_rx_status *stats = IEEE80211_SKB_RXCB(skb);
        struct iwl_mvm_key_pn *ptk_pn;
+       int res;
        u8 tid, keyidx;
        u8 pn[IEEE80211_CCMP_PN_LEN];
        u8 *extiv;
@@ -127,12 +128,13 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb,
        pn[4] = extiv[1];
        pn[5] = extiv[0];
 
-       if (memcmp(pn, ptk_pn->q[queue].pn[tid],
-                  IEEE80211_CCMP_PN_LEN) <= 0)
+       res = memcmp(pn, ptk_pn->q[queue].pn[tid], IEEE80211_CCMP_PN_LEN);
+       if (res < 0)
+               return -1;
+       if (!res && !(stats->flag & RX_FLAG_ALLOW_SAME_PN))
                return -1;
 
-       if (!(stats->flag & RX_FLAG_AMSDU_MORE))
-               memcpy(ptk_pn->q[queue].pn[tid], pn, IEEE80211_CCMP_PN_LEN);
+       memcpy(ptk_pn->q[queue].pn[tid], pn, IEEE80211_CCMP_PN_LEN);
        stats->flag |= RX_FLAG_PN_VALIDATED;
 
        return 0;
@@ -314,28 +316,21 @@ static void iwl_mvm_rx_csum(struct ieee80211_sta *sta,
 }
 
 /*
- * returns true if a packet outside BA session is a duplicate and
- * should be dropped
+ * returns true if a packet is a duplicate and should be dropped.
+ * Updates AMSDU PN tracking info
  */
-static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue,
-                                 struct ieee80211_rx_status *rx_status,
-                                 struct ieee80211_hdr *hdr,
-                                 struct iwl_rx_mpdu_desc *desc)
+static bool iwl_mvm_is_dup(struct ieee80211_sta *sta, int queue,
+                          struct ieee80211_rx_status *rx_status,
+                          struct ieee80211_hdr *hdr,
+                          struct iwl_rx_mpdu_desc *desc)
 {
        struct iwl_mvm_sta *mvm_sta;
        struct iwl_mvm_rxq_dup_data *dup_data;
-       u8 baid, tid, sub_frame_idx;
+       u8 tid, sub_frame_idx;
 
        if (WARN_ON(IS_ERR_OR_NULL(sta)))
                return false;
 
-       baid = (le32_to_cpu(desc->reorder_data) &
-               IWL_RX_MPDU_REORDER_BAID_MASK) >>
-               IWL_RX_MPDU_REORDER_BAID_SHIFT;
-
-       if (baid != IWL_RX_REORDER_DATA_INVALID_BAID)
-               return false;
-
        mvm_sta = iwl_mvm_sta_from_mac80211(sta);
        dup_data = &mvm_sta->dup_data[queue];
 
@@ -365,6 +360,12 @@ static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue,
                     dup_data->last_sub_frame[tid] >= sub_frame_idx))
                return true;
 
+       /* Allow same PN as the first subframe for following sub frames */
+       if (dup_data->last_seq[tid] == hdr->seq_ctrl &&
+           sub_frame_idx > dup_data->last_sub_frame[tid] &&
+           desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU)
+               rx_status->flag |= RX_FLAG_ALLOW_SAME_PN;
+
        dup_data->last_seq[tid] = hdr->seq_ctrl;
        dup_data->last_sub_frame[tid] = sub_frame_idx;
 
@@ -971,7 +972,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
                if (ieee80211_is_data(hdr->frame_control))
                        iwl_mvm_rx_csum(sta, skb, desc);
 
-               if (iwl_mvm_is_nonagg_dup(sta, queue, rx_status, hdr, desc)) {
+               if (iwl_mvm_is_dup(sta, queue, rx_status, hdr, desc)) {
                        kfree_skb(skb);
                        goto out;
                }
index 6b2674e0260682e6bc52df8dabedec9270c99f4d..630e23cb0ffb55f9cbbc4ef4496beba4d4bc62c2 100644 (file)
@@ -2039,7 +2039,7 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        struct iwl_trans_txq_scd_cfg cfg = {
                .fifo = IWL_MVM_TX_FIFO_MCAST,
                .sta_id = msta->sta_id,
-               .tid = IWL_MAX_TID_COUNT,
+               .tid = 0,
                .aggregate = false,
                .frame_limit = IWL_FRAME_LIMIT,
        };
@@ -2052,6 +2052,17 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
                    vif->type != NL80211_IFTYPE_ADHOC))
                return -ENOTSUPP;
 
+       /*
+        * In IBSS, ieee80211_check_queues() sets the cab_queue to be
+        * invalid, so make sure we use the queue we want.
+        * Note that this is done here as we want to avoid making DQA
+        * changes in mac80211 layer.
+        */
+       if (vif->type == NL80211_IFTYPE_ADHOC) {
+               vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
+               mvmvif->cab_queue = vif->cab_queue;
+       }
+
        /*
         * While in previous FWs we had to exclude cab queue from TFD queue
         * mask, now it is needed as any other queue.
@@ -2079,24 +2090,13 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        if (iwl_mvm_has_new_tx_api(mvm)) {
                int queue = iwl_mvm_tvqm_enable_txq(mvm, vif->cab_queue,
                                                    msta->sta_id,
-                                                   IWL_MAX_TID_COUNT,
+                                                   0,
                                                    timeout);
                mvmvif->cab_queue = queue;
        } else if (!fw_has_api(&mvm->fw->ucode_capa,
-                              IWL_UCODE_TLV_API_STA_TYPE)) {
-               /*
-                * In IBSS, ieee80211_check_queues() sets the cab_queue to be
-                * invalid, so make sure we use the queue we want.
-                * Note that this is done here as we want to avoid making DQA
-                * changes in mac80211 layer.
-                */
-               if (vif->type == NL80211_IFTYPE_ADHOC) {
-                       vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
-                       mvmvif->cab_queue = vif->cab_queue;
-               }
+                              IWL_UCODE_TLV_API_STA_TYPE))
                iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0,
                                   &cfg, timeout);
-       }
 
        return 0;
 }
@@ -2115,7 +2115,7 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true, 0);
 
        iwl_mvm_disable_txq(mvm, mvmvif->cab_queue, vif->cab_queue,
-                           IWL_MAX_TID_COUNT, 0);
+                           0, 0);
 
        ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id);
        if (ret)
@@ -3170,8 +3170,9 @@ static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id,
        int ret, size;
        u32 status;
 
+       /* This is a valid situation for GTK removal */
        if (sta_id == IWL_MVM_INVALID_STA)
-               return -EINVAL;
+               return 0;
 
        key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
                                 STA_KEY_FLG_KEYID_MSK);
index 200ab50ec86b2f22a0b2eeacf102a60c1c293f1c..acb217e666dbc6c38a88e88bb84f8992f01c8082 100644 (file)
@@ -616,7 +616,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
        time_cmd.repeat = 1;
        time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
                                      TE_V2_NOTIF_HOST_EVENT_END |
-                                     T2_V2_START_IMMEDIATELY);
+                                     TE_V2_START_IMMEDIATELY);
 
        if (!wait_for_notif) {
                iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
@@ -803,7 +803,7 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        time_cmd.repeat = 1;
        time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
                                      TE_V2_NOTIF_HOST_EVENT_END |
-                                     T2_V2_START_IMMEDIATELY);
+                                     TE_V2_START_IMMEDIATELY);
 
        return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
 }
@@ -913,6 +913,8 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
        time_cmd.interval = cpu_to_le32(1);
        time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
                                      TE_V2_ABSENCE);
+       if (!apply_time)
+               time_cmd.policy |= cpu_to_le16(TE_V2_START_IMMEDIATELY);
 
        return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
 }
index dda77b327c9861d09c06aa56f5ab24b762764717..af6dfceab6b855baad6cfb2878dc431ce924f79c 100644 (file)
@@ -419,11 +419,11 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
 {
        struct ieee80211_key_conf *keyconf = info->control.hw_key;
        u8 *crypto_hdr = skb_frag->data + hdrlen;
+       enum iwl_tx_cmd_sec_ctrl type = TX_CMD_SEC_CCM;
        u64 pn;
 
        switch (keyconf->cipher) {
        case WLAN_CIPHER_SUITE_CCMP:
-       case WLAN_CIPHER_SUITE_CCMP_256:
                iwl_mvm_set_tx_cmd_ccmp(info, tx_cmd);
                iwl_mvm_set_tx_cmd_pn(info, crypto_hdr);
                break;
@@ -447,13 +447,16 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
                break;
        case WLAN_CIPHER_SUITE_GCMP:
        case WLAN_CIPHER_SUITE_GCMP_256:
+               type = TX_CMD_SEC_GCMP;
+               /* Fall through */
+       case WLAN_CIPHER_SUITE_CCMP_256:
                /* TODO: Taking the key from the table might introduce a race
                 * when PTK rekeying is done, having an old packets with a PN
                 * based on the old key but the message encrypted with a new
                 * one.
                 * Need to handle this.
                 */
-               tx_cmd->sec_ctl |= TX_CMD_SEC_GCMP | TX_CMD_SEC_KEY_FROM_TABLE;
+               tx_cmd->sec_ctl |= type | TX_CMD_SEC_KEY_FROM_TABLE;
                tx_cmd->key[0] = keyconf->hw_key_idx;
                iwl_mvm_set_tx_cmd_pn(info, crypto_hdr);
                break;
@@ -645,7 +648,11 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
                if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
                    info.control.vif->type == NL80211_IFTYPE_AP ||
                    info.control.vif->type == NL80211_IFTYPE_ADHOC) {
-                       sta_id = mvmvif->bcast_sta.sta_id;
+                       if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE)
+                               sta_id = mvmvif->bcast_sta.sta_id;
+                       else
+                               sta_id = mvmvif->mcast_sta.sta_id;
+
                        queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info,
                                                           hdr->frame_control);
                        if (queue < 0)
index 6d0a907d5ba58f8666d06e65744d1c179edf3013..fabae0f6068390c1a054deb5cc5bbf9da7f63354 100644 (file)
@@ -147,7 +147,7 @@ static void iwl_pcie_gen2_tfd_unmap(struct iwl_trans *trans,
        /* Sanity check on number of chunks */
        num_tbs = iwl_pcie_gen2_get_num_tbs(trans, tfd);
 
-       if (num_tbs >= trans_pcie->max_tbs) {
+       if (num_tbs > trans_pcie->max_tbs) {
                IWL_ERR(trans, "Too many chunks: %i\n", num_tbs);
                return;
        }
index 3f85713c41dcc9291130f25873ef97bd702335f1..1a566287993d5d9054f3aa22b4a329d405feb854 100644 (file)
@@ -378,7 +378,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
        /* Sanity check on number of chunks */
        num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd);
 
-       if (num_tbs >= trans_pcie->max_tbs) {
+       if (num_tbs > trans_pcie->max_tbs) {
                IWL_ERR(trans, "Too many chunks: %i\n", num_tbs);
                /* @todo issue fatal error, it is quite serious situation */
                return;
index 1cf22e62e3dddafcbf3136f8ba07aa397b9bb088..35b21f8152bb333d3d42fcc4c3eb92fe742fa782 100644 (file)
@@ -2727,6 +2727,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
        mutex_init(&data->mutex);
 
        data->netgroup = hwsim_net_get_netgroup(net);
+       data->wmediumd = hwsim_net_get_wmediumd(net);
 
        /* Enable frame retransmissions for lossy channels */
        hw->max_rates = 4;
@@ -3516,7 +3517,7 @@ static int __init init_mac80211_hwsim(void)
 
        spin_lock_init(&hwsim_radio_lock);
 
-       hwsim_wq = alloc_workqueue("hwsim_wq",WQ_MEM_RECLAIM,0);
+       hwsim_wq = alloc_workqueue("hwsim_wq", 0, 0);
        if (!hwsim_wq)
                return -ENOMEM;
        rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params);
index f9ccd13c79f94e230bfaaa3b40d23e78dc09226c..e7bbbc95cdb1f6ef5611c93f4bf97e269624bdc3 100644 (file)
@@ -1125,7 +1125,8 @@ static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
 
        /* Configuration Space offset 0x70f BIT7 is used to control L0S */
        tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
-       _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
+       _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7) |
+                            ASPM_L1_LATENCY << 3);
 
        /* Configuration Space offset 0x719 Bit3 is for L1
         * BIT4 is for clock request
index 8328d395e332919b5f5736dc2fc1a519b8951896..3127bc8633ca511889e8098d1a996c30c6d28b3f 100644 (file)
@@ -2005,7 +2005,10 @@ static void netback_changed(struct xenbus_device *dev,
        case XenbusStateInitialised:
        case XenbusStateReconfiguring:
        case XenbusStateReconfigured:
+               break;
+
        case XenbusStateUnknown:
+               wake_up_all(&module_unload_q);
                break;
 
        case XenbusStateInitWait:
@@ -2136,7 +2139,9 @@ static int xennet_remove(struct xenbus_device *dev)
                xenbus_switch_state(dev, XenbusStateClosing);
                wait_event(module_unload_q,
                           xenbus_read_driver_state(dev->otherend) ==
-                          XenbusStateClosing);
+                          XenbusStateClosing ||
+                          xenbus_read_driver_state(dev->otherend) ==
+                          XenbusStateUnknown);
 
                xenbus_switch_state(dev, XenbusStateClosed);
                wait_event(module_unload_q,
index 345acca576b3c077b68e339437dd2e54ae76384a..1bd7b3734751c36820bd8f3a3cc107a1cac0b8ef 100644 (file)
@@ -278,8 +278,6 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
        disk->queue             = q;
        disk->flags             = GENHD_FL_EXT_DEVT;
        nvdimm_namespace_disk_name(&nsblk->common, disk->disk_name);
-       set_capacity(disk, 0);
-       device_add_disk(dev, disk);
 
        if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
                return -ENOMEM;
@@ -292,6 +290,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
        }
 
        set_capacity(disk, available_disk_size >> SECTOR_SHIFT);
+       device_add_disk(dev, disk);
        revalidate_disk(disk);
        return 0;
 }
index 2ef544f10ec8a3b2016bac8e9bc38475113eb5ef..4b95ac513de2131e480445bae0f7b6b319b5bf7f 100644 (file)
@@ -1545,8 +1545,6 @@ static int btt_blk_init(struct btt *btt)
        queue_flag_set_unlocked(QUEUE_FLAG_NONROT, btt->btt_queue);
        btt->btt_queue->queuedata = btt;
 
-       set_capacity(btt->btt_disk, 0);
-       device_add_disk(&btt->nd_btt->dev, btt->btt_disk);
        if (btt_meta_size(btt)) {
                int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
 
@@ -1558,6 +1556,7 @@ static int btt_blk_init(struct btt *btt)
                }
        }
        set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
+       device_add_disk(&btt->nd_btt->dev, btt->btt_disk);
        btt->nd_btt->size = btt->nlba * (u64)btt->sector_size;
        revalidate_disk(btt->btt_disk);
 
index f5c4e8c6e29d49bc5d42be0cf6c5ceffd98da1f5..2f4d18752c9772b08aa4d8e22a023fc526a7248b 100644 (file)
@@ -304,7 +304,7 @@ static const struct attribute_group *nd_pfn_attribute_groups[] = {
 struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn,
                struct nd_namespace_common *ndns)
 {
-       struct device *dev = &nd_pfn->dev;
+       struct device *dev;
 
        if (!nd_pfn)
                return NULL;
index 10041ac4032c038db09109b8f757a8719d26f902..06f8dcc52ca648983de46b035dfcbeee6a29fca6 100644 (file)
@@ -335,8 +335,7 @@ 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) &&
-               !test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags);
+       wbc = nvdimm_has_cache(nd_region);
 
        if (!devm_request_mem_region(dev, res->start, resource_size(res),
                                dev_name(&ndns->dev))) {
index e6d01911e0920db0ed1b577b5422d64d81a129ed..1593e1806b16c6b413ea1e5555987b88c6740286 100644 (file)
@@ -532,11 +532,13 @@ 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 " : "");
+       if (test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags))
+               return sprintf(buf, "cpu_cache\n");
+       else if (test_bit(ND_REGION_PERSIST_MEMCTRL, &nd_region->flags))
+               return sprintf(buf, "memory_controller\n");
+       else
+               return sprintf(buf, "\n");
 }
 static DEVICE_ATTR_RO(persistence_domain);
 
@@ -593,6 +595,13 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n)
                        return 0;
        }
 
+       if (a == &dev_attr_persistence_domain.attr) {
+               if ((nd_region->flags & (BIT(ND_REGION_PERSIST_CACHE)
+                                       | BIT(ND_REGION_PERSIST_MEMCTRL))) == 0)
+                       return 0;
+               return a->mode;
+       }
+
        if (a != &dev_attr_set_cookie.attr
                        && a != &dev_attr_available_size.attr)
                return a->mode;
index f431c32774f3612f5903ff88cb7541b246626ff2..7aeca5db791613f345f733513f2558d4de14e2ae 100644 (file)
@@ -120,8 +120,12 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl)
        int ret;
 
        ret = nvme_reset_ctrl(ctrl);
-       if (!ret)
+       if (!ret) {
                flush_work(&ctrl->reset_work);
+               if (ctrl->state != NVME_CTRL_LIVE)
+                       ret = -ENETRESET;
+       }
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(nvme_reset_ctrl_sync);
@@ -265,7 +269,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
        switch (new_state) {
        case NVME_CTRL_ADMIN_ONLY:
                switch (old_state) {
-               case NVME_CTRL_RECONNECTING:
+               case NVME_CTRL_CONNECTING:
                        changed = true;
                        /* FALLTHRU */
                default:
@@ -276,7 +280,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
                switch (old_state) {
                case NVME_CTRL_NEW:
                case NVME_CTRL_RESETTING:
-               case NVME_CTRL_RECONNECTING:
+               case NVME_CTRL_CONNECTING:
                        changed = true;
                        /* FALLTHRU */
                default:
@@ -294,9 +298,9 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
                        break;
                }
                break;
-       case NVME_CTRL_RECONNECTING:
+       case NVME_CTRL_CONNECTING:
                switch (old_state) {
-               case NVME_CTRL_LIVE:
+               case NVME_CTRL_NEW:
                case NVME_CTRL_RESETTING:
                        changed = true;
                        /* FALLTHRU */
@@ -309,7 +313,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
                case NVME_CTRL_LIVE:
                case NVME_CTRL_ADMIN_ONLY:
                case NVME_CTRL_RESETTING:
-               case NVME_CTRL_RECONNECTING:
+               case NVME_CTRL_CONNECTING:
                        changed = true;
                        /* FALLTHRU */
                default:
@@ -518,9 +522,11 @@ static blk_status_t nvme_setup_discard(struct nvme_ns *ns, struct request *req,
                u64 slba = nvme_block_nr(ns, bio->bi_iter.bi_sector);
                u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift;
 
-               range[n].cattr = cpu_to_le32(0);
-               range[n].nlb = cpu_to_le32(nlb);
-               range[n].slba = cpu_to_le64(slba);
+               if (n < segments) {
+                       range[n].cattr = cpu_to_le32(0);
+                       range[n].nlb = cpu_to_le32(nlb);
+                       range[n].slba = cpu_to_le64(slba);
+               }
                n++;
        }
 
@@ -794,13 +800,9 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status)
 
 static int nvme_keep_alive(struct nvme_ctrl *ctrl)
 {
-       struct nvme_command c;
        struct request *rq;
 
-       memset(&c, 0, sizeof(c));
-       c.common.opcode = nvme_admin_keep_alive;
-
-       rq = nvme_alloc_request(ctrl->admin_q, &c, BLK_MQ_REQ_RESERVED,
+       rq = nvme_alloc_request(ctrl->admin_q, &ctrl->ka_cmd, BLK_MQ_REQ_RESERVED,
                        NVME_QID_ANY);
        if (IS_ERR(rq))
                return PTR_ERR(rq);
@@ -832,6 +834,8 @@ void nvme_start_keep_alive(struct nvme_ctrl *ctrl)
                return;
 
        INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work);
+       memset(&ctrl->ka_cmd, 0, sizeof(ctrl->ka_cmd));
+       ctrl->ka_cmd.common.opcode = nvme_admin_keep_alive;
        schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ);
 }
 EXPORT_SYMBOL_GPL(nvme_start_keep_alive);
@@ -1117,14 +1121,19 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 
 static void nvme_update_formats(struct nvme_ctrl *ctrl)
 {
-       struct nvme_ns *ns;
+       struct nvme_ns *ns, *next;
+       LIST_HEAD(rm_list);
 
        mutex_lock(&ctrl->namespaces_mutex);
        list_for_each_entry(ns, &ctrl->namespaces, list) {
-               if (ns->disk && nvme_revalidate_disk(ns->disk))
-                       nvme_ns_remove(ns);
+               if (ns->disk && nvme_revalidate_disk(ns->disk)) {
+                       list_move_tail(&ns->list, &rm_list);
+               }
        }
        mutex_unlock(&ctrl->namespaces_mutex);
+
+       list_for_each_entry_safe(ns, next, &rm_list, list)
+               nvme_ns_remove(ns);
 }
 
 static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects)
@@ -2687,7 +2696,7 @@ static ssize_t nvme_sysfs_show_state(struct device *dev,
                [NVME_CTRL_LIVE]        = "live",
                [NVME_CTRL_ADMIN_ONLY]  = "only-admin",
                [NVME_CTRL_RESETTING]   = "resetting",
-               [NVME_CTRL_RECONNECTING]= "reconnecting",
+               [NVME_CTRL_CONNECTING]  = "connecting",
                [NVME_CTRL_DELETING]    = "deleting",
                [NVME_CTRL_DEAD]        = "dead",
        };
@@ -2835,7 +2844,7 @@ out:
 }
 
 static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
-               struct nvme_id_ns *id, bool *new)
+               struct nvme_id_ns *id)
 {
        struct nvme_ctrl *ctrl = ns->ctrl;
        bool is_shared = id->nmic & (1 << 0);
@@ -2851,8 +2860,6 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
                        ret = PTR_ERR(head);
                        goto out_unlock;
                }
-
-               *new = true;
        } else {
                struct nvme_ns_ids ids;
 
@@ -2864,8 +2871,6 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
                        ret = -EINVAL;
                        goto out_unlock;
                }
-
-               *new = false;
        }
 
        list_add_tail(&ns->siblings, &head->list);
@@ -2936,7 +2941,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
        struct nvme_id_ns *id;
        char disk_name[DISK_NAME_LEN];
        int node = dev_to_node(ctrl->dev), flags = GENHD_FL_EXT_DEVT;
-       bool new = true;
 
        ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
        if (!ns)
@@ -2962,7 +2966,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
        if (id->ncap == 0)
                goto out_free_id;
 
-       if (nvme_init_ns_head(ns, nsid, id, &new))
+       if (nvme_init_ns_head(ns, nsid, id))
                goto out_free_id;
        nvme_setup_streams_ns(ctrl, ns);
        
@@ -3028,9 +3032,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
                pr_warn("%s: failed to register lightnvm sysfs group for identification\n",
                        ns->disk->disk_name);
 
-       if (new)
-               nvme_mpath_add_disk(ns->head);
-       nvme_mpath_add_disk_links(ns);
+       nvme_mpath_add_disk(ns->head);
        return;
  out_unlink_ns:
        mutex_lock(&ctrl->subsys->lock);
@@ -3050,7 +3052,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
                return;
 
        if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
-               nvme_mpath_remove_disk_links(ns);
                sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
                                        &nvme_ns_id_attr_group);
                if (ns->ndev)
index 5dd4ceefed8fe0d0897aa8dadb1d266174b2eb02..8f0f34d06d46965168e4472ea2f9f5b5daca6a20 100644 (file)
@@ -493,7 +493,7 @@ EXPORT_SYMBOL_GPL(nvmf_should_reconnect);
  */
 int nvmf_register_transport(struct nvmf_transport_ops *ops)
 {
-       if (!ops->create_ctrl || !ops->module)
+       if (!ops->create_ctrl)
                return -EINVAL;
 
        down_write(&nvmf_transports_rwsem);
@@ -650,6 +650,11 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
                                ret = -EINVAL;
                                goto out;
                        }
+                       if (opts->discovery_nqn) {
+                               pr_debug("Ignoring nr_io_queues value for discovery controller\n");
+                               break;
+                       }
+
                        opts->nr_io_queues = min_t(unsigned int,
                                        num_online_cpus(), token);
                        break;
index 25b19f722f5b20508ed35d408305dde734498432..a3145d90c1d2c20f8c555067a989cf4a428a1790 100644 (file)
@@ -171,13 +171,14 @@ static inline blk_status_t nvmf_check_init_req(struct nvme_ctrl *ctrl,
            cmd->common.opcode != nvme_fabrics_command ||
            cmd->fabrics.fctype != nvme_fabrics_type_connect) {
                /*
-                * Reconnecting state means transport disruption, which can take
-                * a long time and even might fail permanently, fail fast to
-                * give upper layers a chance to failover.
+                * Connecting state means transport disruption or initial
+                * establishment, which can take a long time and even might
+                * fail permanently, fail fast to give upper layers a chance
+                * to failover.
                 * Deleting state means that the ctrl will never accept commands
                 * again, fail it permanently.
                 */
-               if (ctrl->state == NVME_CTRL_RECONNECTING ||
+               if (ctrl->state == NVME_CTRL_CONNECTING ||
                    ctrl->state == NVME_CTRL_DELETING) {
                        nvme_req(rq)->status = NVME_SC_ABORT_REQ;
                        return BLK_STS_IOERR;
index b856d7c919d298062e2e55d8495ca18891d4f0f2..1dc1387b71342e67bb0f6848104e2ee4ab901661 100644 (file)
@@ -55,9 +55,7 @@ struct nvme_fc_queue {
 
 enum nvme_fcop_flags {
        FCOP_FLAGS_TERMIO       = (1 << 0),
-       FCOP_FLAGS_RELEASED     = (1 << 1),
-       FCOP_FLAGS_COMPLETE     = (1 << 2),
-       FCOP_FLAGS_AEN          = (1 << 3),
+       FCOP_FLAGS_AEN          = (1 << 1),
 };
 
 struct nvmefc_ls_req_op {
@@ -532,7 +530,7 @@ nvme_fc_resume_controller(struct nvme_fc_ctrl *ctrl)
 {
        switch (ctrl->ctrl.state) {
        case NVME_CTRL_NEW:
-       case NVME_CTRL_RECONNECTING:
+       case NVME_CTRL_CONNECTING:
                /*
                 * As all reconnects were suppressed, schedule a
                 * connect.
@@ -777,7 +775,7 @@ nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl)
                }
                break;
 
-       case NVME_CTRL_RECONNECTING:
+       case NVME_CTRL_CONNECTING:
                /*
                 * The association has already been terminated and the
                 * controller is attempting reconnects.  No need to do anything
@@ -1208,7 +1206,7 @@ nvme_fc_connect_admin_queue(struct nvme_fc_ctrl *ctrl,
                                sizeof(struct fcnvme_lsdesc_cr_assoc_cmd));
 
        assoc_rqst->assoc_cmd.ersp_ratio = cpu_to_be16(ersp_ratio);
-       assoc_rqst->assoc_cmd.sqsize = cpu_to_be16(qsize);
+       assoc_rqst->assoc_cmd.sqsize = cpu_to_be16(qsize - 1);
        /* Linux supports only Dynamic controllers */
        assoc_rqst->assoc_cmd.cntlid = cpu_to_be16(0xffff);
        uuid_copy(&assoc_rqst->assoc_cmd.hostid, &ctrl->ctrl.opts->host->id);
@@ -1323,7 +1321,7 @@ nvme_fc_connect_queue(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
                                sizeof(struct fcnvme_lsdesc_cr_conn_cmd));
        conn_rqst->connect_cmd.ersp_ratio = cpu_to_be16(ersp_ratio);
        conn_rqst->connect_cmd.qid  = cpu_to_be16(queue->qnum);
-       conn_rqst->connect_cmd.sqsize = cpu_to_be16(qsize);
+       conn_rqst->connect_cmd.sqsize = cpu_to_be16(qsize - 1);
 
        lsop->queue = queue;
        lsreq->rqstaddr = conn_rqst;
@@ -1470,7 +1468,6 @@ nvme_fc_xmt_disconnect_assoc(struct nvme_fc_ctrl *ctrl)
 
 /* *********************** NVME Ctrl Routines **************************** */
 
-static void __nvme_fc_final_op_cleanup(struct request *rq);
 static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg);
 
 static int
@@ -1512,13 +1509,19 @@ nvme_fc_exit_request(struct blk_mq_tag_set *set, struct request *rq,
 static int
 __nvme_fc_abort_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_fcp_op *op)
 {
-       int state;
+       unsigned long flags;
+       int opstate;
+
+       spin_lock_irqsave(&ctrl->lock, flags);
+       opstate = atomic_xchg(&op->state, FCPOP_STATE_ABORTED);
+       if (opstate != FCPOP_STATE_ACTIVE)
+               atomic_set(&op->state, opstate);
+       else if (ctrl->flags & FCCTRL_TERMIO)
+               ctrl->iocnt++;
+       spin_unlock_irqrestore(&ctrl->lock, flags);
 
-       state = atomic_xchg(&op->state, FCPOP_STATE_ABORTED);
-       if (state != FCPOP_STATE_ACTIVE) {
-               atomic_set(&op->state, state);
+       if (opstate != FCPOP_STATE_ACTIVE)
                return -ECANCELED;
-       }
 
        ctrl->lport->ops->fcp_abort(&ctrl->lport->localport,
                                        &ctrl->rport->remoteport,
@@ -1532,60 +1535,26 @@ static void
 nvme_fc_abort_aen_ops(struct nvme_fc_ctrl *ctrl)
 {
        struct nvme_fc_fcp_op *aen_op = ctrl->aen_ops;
-       unsigned long flags;
-       int i, ret;
-
-       for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) {
-               if (atomic_read(&aen_op->state) != FCPOP_STATE_ACTIVE)
-                       continue;
-
-               spin_lock_irqsave(&ctrl->lock, flags);
-               if (ctrl->flags & FCCTRL_TERMIO) {
-                       ctrl->iocnt++;
-                       aen_op->flags |= FCOP_FLAGS_TERMIO;
-               }
-               spin_unlock_irqrestore(&ctrl->lock, flags);
-
-               ret = __nvme_fc_abort_op(ctrl, aen_op);
-               if (ret) {
-                       /*
-                        * if __nvme_fc_abort_op failed the io wasn't
-                        * active. Thus this call path is running in
-                        * parallel to the io complete. Treat as non-error.
-                        */
+       int i;
 
-                       /* back out the flags/counters */
-                       spin_lock_irqsave(&ctrl->lock, flags);
-                       if (ctrl->flags & FCCTRL_TERMIO)
-                               ctrl->iocnt--;
-                       aen_op->flags &= ~FCOP_FLAGS_TERMIO;
-                       spin_unlock_irqrestore(&ctrl->lock, flags);
-                       return;
-               }
-       }
+       for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++)
+               __nvme_fc_abort_op(ctrl, aen_op);
 }
 
-static inline int
+static inline void
 __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *ctrl,
-               struct nvme_fc_fcp_op *op)
+               struct nvme_fc_fcp_op *op, int opstate)
 {
        unsigned long flags;
-       bool complete_rq = false;
 
-       spin_lock_irqsave(&ctrl->lock, flags);
-       if (unlikely(op->flags & FCOP_FLAGS_TERMIO)) {
+       if (opstate == FCPOP_STATE_ABORTED) {
+               spin_lock_irqsave(&ctrl->lock, flags);
                if (ctrl->flags & FCCTRL_TERMIO) {
                        if (!--ctrl->iocnt)
                                wake_up(&ctrl->ioabort_wait);
                }
+               spin_unlock_irqrestore(&ctrl->lock, flags);
        }
-       if (op->flags & FCOP_FLAGS_RELEASED)
-               complete_rq = true;
-       else
-               op->flags |= FCOP_FLAGS_COMPLETE;
-       spin_unlock_irqrestore(&ctrl->lock, flags);
-
-       return complete_rq;
 }
 
 static void
@@ -1601,6 +1570,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
        __le16 status = cpu_to_le16(NVME_SC_SUCCESS << 1);
        union nvme_result result;
        bool terminate_assoc = true;
+       int opstate;
 
        /*
         * WARNING:
@@ -1639,11 +1609,12 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
         * association to be terminated.
         */
 
+       opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE);
+
        fc_dma_sync_single_for_cpu(ctrl->lport->dev, op->fcp_req.rspdma,
                                sizeof(op->rsp_iu), DMA_FROM_DEVICE);
 
-       if (atomic_read(&op->state) == FCPOP_STATE_ABORTED ||
-                       op->flags & FCOP_FLAGS_TERMIO)
+       if (opstate == FCPOP_STATE_ABORTED)
                status = cpu_to_le16(NVME_SC_ABORT_REQ << 1);
        else if (freq->status)
                status = cpu_to_le16(NVME_SC_INTERNAL << 1);
@@ -1708,7 +1679,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
 done:
        if (op->flags & FCOP_FLAGS_AEN) {
                nvme_complete_async_event(&queue->ctrl->ctrl, status, &result);
-               __nvme_fc_fcpop_chk_teardowns(ctrl, op);
+               __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate);
                atomic_set(&op->state, FCPOP_STATE_IDLE);
                op->flags = FCOP_FLAGS_AEN;     /* clear other flags */
                nvme_fc_ctrl_put(ctrl);
@@ -1722,13 +1693,11 @@ done:
        if (status &&
            (blk_queue_dying(rq->q) ||
             ctrl->ctrl.state == NVME_CTRL_NEW ||
-            ctrl->ctrl.state == NVME_CTRL_RECONNECTING))
+            ctrl->ctrl.state == NVME_CTRL_CONNECTING))
                status |= cpu_to_le16(NVME_SC_DNR << 1);
 
-       if (__nvme_fc_fcpop_chk_teardowns(ctrl, op))
-               __nvme_fc_final_op_cleanup(rq);
-       else
-               nvme_end_request(rq, status, result);
+       __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate);
+       nvme_end_request(rq, status, result);
 
 check_error:
        if (terminate_assoc)
@@ -2415,46 +2384,16 @@ nvme_fc_submit_async_event(struct nvme_ctrl *arg)
 }
 
 static void
-__nvme_fc_final_op_cleanup(struct request *rq)
+nvme_fc_complete_rq(struct request *rq)
 {
        struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq);
        struct nvme_fc_ctrl *ctrl = op->ctrl;
 
        atomic_set(&op->state, FCPOP_STATE_IDLE);
-       op->flags &= ~(FCOP_FLAGS_TERMIO | FCOP_FLAGS_RELEASED |
-                       FCOP_FLAGS_COMPLETE);
 
        nvme_fc_unmap_data(ctrl, rq, op);
        nvme_complete_rq(rq);
        nvme_fc_ctrl_put(ctrl);
-
-}
-
-static void
-nvme_fc_complete_rq(struct request *rq)
-{
-       struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq);
-       struct nvme_fc_ctrl *ctrl = op->ctrl;
-       unsigned long flags;
-       bool completed = false;
-
-       /*
-        * the core layer, on controller resets after calling
-        * nvme_shutdown_ctrl(), calls complete_rq without our
-        * calling blk_mq_complete_request(), thus there may still
-        * be live i/o outstanding with the LLDD. Means transport has
-        * to track complete calls vs fcpio_done calls to know what
-        * path to take on completes and dones.
-        */
-       spin_lock_irqsave(&ctrl->lock, flags);
-       if (op->flags & FCOP_FLAGS_COMPLETE)
-               completed = true;
-       else
-               op->flags |= FCOP_FLAGS_RELEASED;
-       spin_unlock_irqrestore(&ctrl->lock, flags);
-
-       if (completed)
-               __nvme_fc_final_op_cleanup(rq);
 }
 
 /*
@@ -2476,35 +2415,11 @@ nvme_fc_terminate_exchange(struct request *req, void *data, bool reserved)
        struct nvme_ctrl *nctrl = data;
        struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl);
        struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(req);
-       unsigned long flags;
-       int status;
 
        if (!blk_mq_request_started(req))
                return;
 
-       spin_lock_irqsave(&ctrl->lock, flags);
-       if (ctrl->flags & FCCTRL_TERMIO) {
-               ctrl->iocnt++;
-               op->flags |= FCOP_FLAGS_TERMIO;
-       }
-       spin_unlock_irqrestore(&ctrl->lock, flags);
-
-       status = __nvme_fc_abort_op(ctrl, op);
-       if (status) {
-               /*
-                * if __nvme_fc_abort_op failed the io wasn't
-                * active. Thus this call path is running in
-                * parallel to the io complete. Treat as non-error.
-                */
-
-               /* back out the flags/counters */
-               spin_lock_irqsave(&ctrl->lock, flags);
-               if (ctrl->flags & FCCTRL_TERMIO)
-                       ctrl->iocnt--;
-               op->flags &= ~FCOP_FLAGS_TERMIO;
-               spin_unlock_irqrestore(&ctrl->lock, flags);
-               return;
-       }
+       __nvme_fc_abort_op(ctrl, op);
 }
 
 
@@ -2566,11 +2481,11 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl)
                goto out_free_tag_set;
        }
 
-       ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.opts->queue_size);
+       ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.sqsize + 1);
        if (ret)
                goto out_cleanup_blk_queue;
 
-       ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.opts->queue_size);
+       ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.sqsize + 1);
        if (ret)
                goto out_delete_hw_queues;
 
@@ -2617,11 +2532,11 @@ nvme_fc_reinit_io_queues(struct nvme_fc_ctrl *ctrl)
        if (ret)
                goto out_free_io_queues;
 
-       ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.opts->queue_size);
+       ret = nvme_fc_create_hw_io_queues(ctrl, ctrl->ctrl.sqsize + 1);
        if (ret)
                goto out_free_io_queues;
 
-       ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.opts->queue_size);
+       ret = nvme_fc_connect_io_queues(ctrl, ctrl->ctrl.sqsize + 1);
        if (ret)
                goto out_delete_hw_queues;
 
@@ -2717,13 +2632,12 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
        nvme_fc_init_queue(ctrl, 0);
 
        ret = __nvme_fc_create_hw_queue(ctrl, &ctrl->queues[0], 0,
-                               NVME_AQ_BLK_MQ_DEPTH);
+                               NVME_AQ_DEPTH);
        if (ret)
                goto out_free_queue;
 
        ret = nvme_fc_connect_admin_queue(ctrl, &ctrl->queues[0],
-                               NVME_AQ_BLK_MQ_DEPTH,
-                               (NVME_AQ_BLK_MQ_DEPTH / 4));
+                               NVME_AQ_DEPTH, (NVME_AQ_DEPTH / 4));
        if (ret)
                goto out_delete_hw_queue;
 
@@ -2751,7 +2665,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
        }
 
        ctrl->ctrl.sqsize =
-               min_t(int, NVME_CAP_MQES(ctrl->ctrl.cap) + 1, ctrl->ctrl.sqsize);
+               min_t(int, NVME_CAP_MQES(ctrl->ctrl.cap), ctrl->ctrl.sqsize);
 
        ret = nvme_enable_ctrl(&ctrl->ctrl, ctrl->ctrl.cap);
        if (ret)
@@ -2784,6 +2698,14 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
                opts->queue_size = ctrl->ctrl.maxcmd;
        }
 
+       if (opts->queue_size > ctrl->ctrl.sqsize + 1) {
+               /* warn if sqsize is lower than queue_size */
+               dev_warn(ctrl->ctrl.device,
+                       "queue_size %zu > ctrl sqsize %u, clamping down\n",
+                       opts->queue_size, ctrl->ctrl.sqsize + 1);
+               opts->queue_size = ctrl->ctrl.sqsize + 1;
+       }
+
        ret = nvme_fc_init_aen_ops(ctrl);
        if (ret)
                goto out_term_aen_ops;
@@ -2943,7 +2865,7 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status)
        unsigned long recon_delay = ctrl->ctrl.opts->reconnect_delay * HZ;
        bool recon = true;
 
-       if (ctrl->ctrl.state != NVME_CTRL_RECONNECTING)
+       if (ctrl->ctrl.state != NVME_CTRL_CONNECTING)
                return;
 
        if (portptr->port_state == FC_OBJSTATE_ONLINE)
@@ -2991,10 +2913,10 @@ nvme_fc_reset_ctrl_work(struct work_struct *work)
        /* will block will waiting for io to terminate */
        nvme_fc_delete_association(ctrl);
 
-       if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
+       if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
                dev_err(ctrl->ctrl.device,
                        "NVME-FC{%d}: error_recovery: Couldn't change state "
-                       "to RECONNECTING\n", ctrl->cnum);
+                       "to CONNECTING\n", ctrl->cnum);
                return;
        }
 
@@ -3195,7 +3117,7 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
         * transport errors (frame drop, LS failure) inherently must kill
         * the association. The transport is coded so that any command used
         * to create the association (prior to a LIVE state transition
-        * while NEW or RECONNECTING) will fail if it completes in error or
+        * while NEW or CONNECTING) will fail if it completes in error or
         * times out.
         *
         * As such: as the connect request was mostly likely due to a
index 3b211d9e58b8419855b29a87f1019b0d687714d4..060f69e0342761c4767c90afc09a73a10546e1dd 100644 (file)
@@ -198,30 +198,16 @@ void nvme_mpath_add_disk(struct nvme_ns_head *head)
 {
        if (!head->disk)
                return;
-       device_add_disk(&head->subsys->dev, head->disk);
-       if (sysfs_create_group(&disk_to_dev(head->disk)->kobj,
-                       &nvme_ns_id_attr_group))
-               pr_warn("%s: failed to create sysfs group for identification\n",
-                       head->disk->disk_name);
-}
-
-void nvme_mpath_add_disk_links(struct nvme_ns *ns)
-{
-       struct kobject *slave_disk_kobj, *holder_disk_kobj;
-
-       if (!ns->head->disk)
-               return;
-
-       slave_disk_kobj = &disk_to_dev(ns->disk)->kobj;
-       if (sysfs_create_link(ns->head->disk->slave_dir, slave_disk_kobj,
-                       kobject_name(slave_disk_kobj)))
-               return;
 
-       holder_disk_kobj = &disk_to_dev(ns->head->disk)->kobj;
-       if (sysfs_create_link(ns->disk->part0.holder_dir, holder_disk_kobj,
-                       kobject_name(holder_disk_kobj)))
-               sysfs_remove_link(ns->head->disk->slave_dir,
-                       kobject_name(slave_disk_kobj));
+       mutex_lock(&head->subsys->lock);
+       if (!(head->disk->flags & GENHD_FL_UP)) {
+               device_add_disk(&head->subsys->dev, head->disk);
+               if (sysfs_create_group(&disk_to_dev(head->disk)->kobj,
+                               &nvme_ns_id_attr_group))
+                       pr_warn("%s: failed to create sysfs group for identification\n",
+                               head->disk->disk_name);
+       }
+       mutex_unlock(&head->subsys->lock);
 }
 
 void nvme_mpath_remove_disk(struct nvme_ns_head *head)
@@ -238,14 +224,3 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
        blk_cleanup_queue(head->disk->queue);
        put_disk(head->disk);
 }
-
-void nvme_mpath_remove_disk_links(struct nvme_ns *ns)
-{
-       if (!ns->head->disk)
-               return;
-
-       sysfs_remove_link(ns->disk->part0.holder_dir,
-                       kobject_name(&disk_to_dev(ns->head->disk)->kobj));
-       sysfs_remove_link(ns->head->disk->slave_dir,
-                       kobject_name(&disk_to_dev(ns->disk)->kobj));
-}
index 8e4550fa08f8bd775e7e5e8e0c169e287845509a..d733b14ede9dc10022e0ae14da8cb4550c46831b 100644 (file)
@@ -123,7 +123,7 @@ enum nvme_ctrl_state {
        NVME_CTRL_LIVE,
        NVME_CTRL_ADMIN_ONLY,    /* Only admin queue live */
        NVME_CTRL_RESETTING,
-       NVME_CTRL_RECONNECTING,
+       NVME_CTRL_CONNECTING,
        NVME_CTRL_DELETING,
        NVME_CTRL_DEAD,
 };
@@ -183,6 +183,7 @@ struct nvme_ctrl {
        struct work_struct scan_work;
        struct work_struct async_event_work;
        struct delayed_work ka_work;
+       struct nvme_command ka_cmd;
        struct work_struct fw_act_work;
 
        /* Power saving configuration */
@@ -409,9 +410,7 @@ bool nvme_req_needs_failover(struct request *req, blk_status_t error);
 void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl);
 int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head);
 void nvme_mpath_add_disk(struct nvme_ns_head *head);
-void nvme_mpath_add_disk_links(struct nvme_ns *ns);
 void nvme_mpath_remove_disk(struct nvme_ns_head *head);
-void nvme_mpath_remove_disk_links(struct nvme_ns *ns);
 
 static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns)
 {
@@ -453,12 +452,6 @@ static inline void nvme_mpath_add_disk(struct nvme_ns_head *head)
 static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head)
 {
 }
-static inline void nvme_mpath_add_disk_links(struct nvme_ns *ns)
-{
-}
-static inline void nvme_mpath_remove_disk_links(struct nvme_ns *ns)
-{
-}
 static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns)
 {
 }
index 6fe7af00a1f42a7dcb3354ac49db499cef6f9c88..b6f43b738f03ae3b6008cd188d467623c1e70ecf 100644 (file)
@@ -1141,7 +1141,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
        /* If there is a reset/reinit ongoing, we shouldn't reset again. */
        switch (dev->ctrl.state) {
        case NVME_CTRL_RESETTING:
-       case NVME_CTRL_RECONNECTING:
+       case NVME_CTRL_CONNECTING:
                return false;
        default:
                break;
@@ -1153,12 +1153,6 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
        if (!(csts & NVME_CSTS_CFS) && !nssro)
                return false;
 
-       /* If PCI error recovery process is happening, we cannot reset or
-        * the recovery mechanism will surely fail.
-        */
-       if (pci_channel_offline(to_pci_dev(dev->dev)))
-               return false;
-
        return true;
 }
 
@@ -1189,6 +1183,13 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
        struct nvme_command cmd;
        u32 csts = readl(dev->bar + NVME_REG_CSTS);
 
+       /* If PCI error recovery process is happening, we cannot reset or
+        * the recovery mechanism will surely fail.
+        */
+       mb();
+       if (pci_channel_offline(to_pci_dev(dev->dev)))
+               return BLK_EH_RESET_TIMER;
+
        /*
         * Reset immediately if the controller is failed
         */
@@ -1215,13 +1216,17 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
         * cancellation error. All outstanding requests are completed on
         * shutdown, so we return BLK_EH_HANDLED.
         */
-       if (dev->ctrl.state == NVME_CTRL_RESETTING) {
+       switch (dev->ctrl.state) {
+       case NVME_CTRL_CONNECTING:
+       case NVME_CTRL_RESETTING:
                dev_warn(dev->ctrl.device,
                         "I/O %d QID %d timeout, disable controller\n",
                         req->tag, nvmeq->qid);
                nvme_dev_disable(dev, false);
                nvme_req(req)->flags |= NVME_REQ_CANCELLED;
                return BLK_EH_HANDLED;
+       default:
+               break;
        }
 
        /*
@@ -1364,18 +1369,14 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,
 static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
                                int qid, int depth)
 {
-       if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) {
-               unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth),
-                                                     dev->ctrl.page_size);
-               nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;
-               nvmeq->sq_cmds_io = dev->cmb + offset;
-       } else {
-               nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth),
-                                       &nvmeq->sq_dma_addr, GFP_KERNEL);
-               if (!nvmeq->sq_cmds)
-                       return -ENOMEM;
-       }
+       /* CMB SQEs will be mapped before creation */
+       if (qid && dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS))
+               return 0;
 
+       nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth),
+                                           &nvmeq->sq_dma_addr, GFP_KERNEL);
+       if (!nvmeq->sq_cmds)
+               return -ENOMEM;
        return 0;
 }
 
@@ -1449,10 +1450,17 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
        struct nvme_dev *dev = nvmeq->dev;
        int result;
 
+       if (dev->cmb && use_cmb_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) {
+               unsigned offset = (qid - 1) * roundup(SQ_SIZE(nvmeq->q_depth),
+                                                     dev->ctrl.page_size);
+               nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;
+               nvmeq->sq_cmds_io = dev->cmb + offset;
+       }
+
        nvmeq->cq_vector = qid - 1;
        result = adapter_alloc_cq(dev, qid, nvmeq);
        if (result < 0)
-               return result;
+               goto release_vector;
 
        result = adapter_alloc_sq(dev, qid, nvmeq);
        if (result < 0)
@@ -1466,9 +1474,12 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
        return result;
 
  release_sq:
+       dev->online_queues--;
        adapter_delete_sq(dev, qid);
  release_cq:
        adapter_delete_cq(dev, qid);
+ release_vector:
+       nvmeq->cq_vector = -1;
        return result;
 }
 
@@ -1903,7 +1914,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        int result, nr_io_queues;
        unsigned long size;
 
-       nr_io_queues = num_present_cpus();
+       nr_io_queues = num_possible_cpus();
        result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues);
        if (result < 0)
                return result;
@@ -2288,12 +2299,12 @@ static void nvme_reset_work(struct work_struct *work)
                nvme_dev_disable(dev, false);
 
        /*
-        * Introduce RECONNECTING state from nvme-fc/rdma transports to mark the
+        * Introduce CONNECTING state from nvme-fc/rdma transports to mark the
         * initializing procedure here.
         */
-       if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RECONNECTING)) {
+       if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_CONNECTING)) {
                dev_warn(dev->ctrl.device,
-                       "failed to mark controller RECONNECTING\n");
+                       "failed to mark controller CONNECTING\n");
                goto out;
        }
 
index 2bc059f7d73c7da7ea13273aa9a0b92d1cbf2b63..4d84a73ee12d06907ea94ef77e3e654d6e2b2033 100644 (file)
@@ -887,7 +887,7 @@ free_ctrl:
 static void nvme_rdma_reconnect_or_remove(struct nvme_rdma_ctrl *ctrl)
 {
        /* If we are resetting/deleting then do nothing */
-       if (ctrl->ctrl.state != NVME_CTRL_RECONNECTING) {
+       if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) {
                WARN_ON_ONCE(ctrl->ctrl.state == NVME_CTRL_NEW ||
                        ctrl->ctrl.state == NVME_CTRL_LIVE);
                return;
@@ -973,7 +973,7 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)
        blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);
        nvme_start_queues(&ctrl->ctrl);
 
-       if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
+       if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
                /* state change failure should never happen */
                WARN_ON_ONCE(1);
                return;
@@ -1051,7 +1051,7 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue *queue,
        struct nvme_rdma_device *dev = queue->device;
        struct ib_device *ibdev = dev->dev;
 
-       if (!blk_rq_bytes(rq))
+       if (!blk_rq_payload_bytes(rq))
                return;
 
        if (req->mr) {
@@ -1166,7 +1166,7 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue *queue,
 
        c->common.flags |= NVME_CMD_SGL_METABUF;
 
-       if (!blk_rq_bytes(rq))
+       if (!blk_rq_payload_bytes(rq))
                return nvme_rdma_set_sg_null(c);
 
        req->sg_table.sgl = req->first_sgl;
@@ -1756,7 +1756,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
        nvme_stop_ctrl(&ctrl->ctrl);
        nvme_rdma_shutdown_ctrl(ctrl, false);
 
-       if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
+       if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) {
                /* state change failure should never happen */
                WARN_ON_ONCE(1);
                return;
@@ -1784,11 +1784,8 @@ static void nvme_rdma_reset_ctrl_work(struct work_struct *work)
        return;
 
 out_fail:
-       dev_warn(ctrl->ctrl.device, "Removing after reset failure\n");
-       nvme_remove_namespaces(&ctrl->ctrl);
-       nvme_rdma_shutdown_ctrl(ctrl, true);
-       nvme_uninit_ctrl(&ctrl->ctrl);
-       nvme_put_ctrl(&ctrl->ctrl);
+       ++ctrl->ctrl.nr_reconnects;
+       nvme_rdma_reconnect_or_remove(ctrl);
 }
 
 static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
@@ -1942,6 +1939,9 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
        if (!ctrl->queues)
                goto out_uninit_ctrl;
 
+       changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING);
+       WARN_ON_ONCE(!changed);
+
        ret = nvme_rdma_configure_admin_queue(ctrl, true);
        if (ret)
                goto out_kfree_queues;
index 0bd737117a80a172745aab1868fb8a4ecf6f1e8c..a78029e4e5f481b58bd628537315d3e7e9882f1a 100644 (file)
@@ -520,9 +520,12 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
                goto fail;
        }
 
-       /* either variant of SGLs is fine, as we don't support metadata */
-       if (unlikely((flags & NVME_CMD_SGL_ALL) != NVME_CMD_SGL_METABUF &&
-                    (flags & NVME_CMD_SGL_ALL) != NVME_CMD_SGL_METASEG)) {
+       /*
+        * For fabrics, PSDT field shall describe metadata pointer (MPTR) that
+        * contains an address of a single contiguous physical buffer that is
+        * byte aligned.
+        */
+       if (unlikely((flags & NVME_CMD_SGL_ALL) != NVME_CMD_SGL_METABUF)) {
                status = NVME_SC_INVALID_FIELD | NVME_SC_DNR;
                goto fail;
        }
index 0a4372a016f21fdb9e9e29ed293dd8fe0524d26b..28bbdff4a88baa27cb2398597cc02529c49e19f4 100644 (file)
@@ -105,10 +105,13 @@ static void nvmet_execute_flush(struct nvmet_req *req)
 static u16 nvmet_discard_range(struct nvmet_ns *ns,
                struct nvme_dsm_range *range, struct bio **bio)
 {
-       if (__blkdev_issue_discard(ns->bdev,
+       int ret;
+
+       ret = __blkdev_issue_discard(ns->bdev,
                        le64_to_cpu(range->slba) << (ns->blksize_shift - 9),
                        le32_to_cpu(range->nlb) << (ns->blksize_shift - 9),
-                       GFP_KERNEL, 0, bio))
+                       GFP_KERNEL, 0, bio);
+       if (ret && ret != -EOPNOTSUPP)
                return NVME_SC_INTERNAL | NVME_SC_DNR;
        return 0;
 }
index 7991ec3a17db9238c4fddaadc2faaa9fb32ce0cb..861d1509b22bf412e2a9bfaee408a4fcb3ad3de4 100644 (file)
@@ -184,7 +184,7 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,
                return BLK_STS_OK;
        }
 
-       if (blk_rq_bytes(req)) {
+       if (blk_rq_payload_bytes(req)) {
                iod->sg_table.sgl = iod->first_sgl;
                if (sg_alloc_table_chained(&iod->sg_table,
                                blk_rq_nr_phys_segments(req),
@@ -193,7 +193,7 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,
 
                iod->req.sg = iod->sg_table.sgl;
                iod->req.sg_cnt = blk_rq_map_sg(req->q, req, iod->sg_table.sgl);
-               iod->req.transfer_len = blk_rq_bytes(req);
+               iod->req.transfer_len = blk_rq_payload_bytes(req);
        }
 
        blk_mq_start_request(req);
index 36ed84e26d9c262c32c6c600938f6ec53573c683..f46828e3b082b87966d5c5be3d7df1637f0391a9 100644 (file)
@@ -977,11 +977,11 @@ static int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
        return 0;
 }
 
-static void *
+static const void *
 of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
                                const struct device *dev)
 {
-       return (void *)of_device_get_match_data(dev);
+       return of_device_get_match_data(dev);
 }
 
 const struct fwnode_operations of_fwnode_ops = {
index 2d87bc1adf38b682d5416a72987115eb68737000..0c09107094350456162cd9573c37fa7f9f134df0 100644 (file)
@@ -55,7 +55,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
        if (max_opps <= 0)
                return max_opps ? max_opps : -ENODATA;
 
-       freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_ATOMIC);
+       freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_KERNEL);
        if (!freq_table)
                return -ENOMEM;
 
index 8de2d5c69b1d9a6b892f97f7a240099dac9cf988..dc9303abda4242f8ab42997b1a062e5ba1d599a2 100644 (file)
@@ -613,7 +613,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
        /* setup bus numbers */
        val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
        val &= 0xff000000;
-       val |= 0x00010100;
+       val |= 0x00ff0100;
        dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
 
        /* setup command register */
index fc734014206fb0845e9d6549e2b7b554f8845919..46d47bd6ca1fce28e294a82374e6572e59a5cb50 100644 (file)
@@ -3419,22 +3419,29 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
 
 static void quirk_chelsio_extend_vpd(struct pci_dev *dev)
 {
-       pci_set_vpd_size(dev, 8192);
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd);
+       int chip = (dev->device & 0xf000) >> 12;
+       int func = (dev->device & 0x0f00) >>  8;
+       int prod = (dev->device & 0x00ff) >>  0;
+
+       /*
+        * If this is a T3-based adapter, there's a 1KB VPD area at offset
+        * 0xc00 which contains the preferred VPD values.  If this is a T4 or
+        * later based adapter, the special VPD is at offset 0x400 for the
+        * Physical Functions (the SR-IOV Virtual Functions have no VPD
+        * Capabilities).  The PCI VPD Access core routines will normally
+        * compute the size of the VPD by parsing the VPD Data Structure at
+        * offset 0x000.  This will result in silent failures when attempting
+        * to accesses these other VPD areas which are beyond those computed
+        * limits.
+        */
+       if (chip == 0x0 && prod >= 0x20)
+               pci_set_vpd_size(dev, 8192);
+       else if (chip >= 0x4 && func < 0x8)
+               pci_set_vpd_size(dev, 2048);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
+                       quirk_chelsio_extend_vpd);
 
 #ifdef CONFIG_ACPI
 /*
@@ -3901,6 +3908,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230,
                         quirk_dma_func1_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642,
                         quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645,
+                        quirk_dma_func1_alias);
 /* https://bugs.gentoo.org/show_bug.cgi?id=497630 */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
                         PCI_DEVICE_ID_JMICRON_JMB388_ESD,
index 369d48d6c6f1a53d4bc6ab5dd0b13a33eeccd90b..365447240d95fe2bb2d484bddca71da3572daaa9 100644 (file)
@@ -401,6 +401,10 @@ void pci_release_resource(struct pci_dev *dev, int resno)
        struct resource *res = dev->resource + resno;
 
        pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
+
+       if (!res->parent)
+               return;
+
        release_resource(res);
        res->end = resource_size(res) - 1;
        res->start = 0;
index 7bc5eee96b310756f625499b805385f2ea95689a..f63db346c21970489c5892847891926b926a50f4 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/perf/arm_pmu.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/sched/clock.h>
 #include <linux/spinlock.h>
@@ -26,6 +25,9 @@
 
 #include <asm/irq_regs.h>
 
+static DEFINE_PER_CPU(struct arm_pmu *, cpu_armpmu);
+static DEFINE_PER_CPU(int, cpu_irq);
+
 static int
 armpmu_map_cache_event(const unsigned (*cache_map)
                                      [PERF_COUNT_HW_CACHE_MAX]
@@ -320,17 +322,9 @@ validate_group(struct perf_event *event)
        return 0;
 }
 
-static struct arm_pmu_platdata *armpmu_get_platdata(struct arm_pmu *armpmu)
-{
-       struct platform_device *pdev = armpmu->plat_device;
-
-       return pdev ? dev_get_platdata(&pdev->dev) : NULL;
-}
-
 static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
 {
        struct arm_pmu *armpmu;
-       struct arm_pmu_platdata *plat;
        int ret;
        u64 start_clock, finish_clock;
 
@@ -341,14 +335,11 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
         * dereference.
         */
        armpmu = *(void **)dev;
-
-       plat = armpmu_get_platdata(armpmu);
+       if (WARN_ON_ONCE(!armpmu))
+               return IRQ_NONE;
 
        start_clock = sched_clock();
-       if (plat && plat->handle_irq)
-               ret = plat->handle_irq(irq, armpmu, armpmu->handle_irq);
-       else
-               ret = armpmu->handle_irq(irq, armpmu);
+       ret = armpmu->handle_irq(irq, armpmu);
        finish_clock = sched_clock();
 
        perf_sample_event_took(finish_clock - start_clock);
@@ -531,54 +522,41 @@ int perf_num_counters(void)
 }
 EXPORT_SYMBOL_GPL(perf_num_counters);
 
-void armpmu_free_irq(struct arm_pmu *armpmu, int cpu)
+static int armpmu_count_irq_users(const int irq)
 {
-       struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
-       int irq = per_cpu(hw_events->irq, cpu);
+       int cpu, count = 0;
 
-       if (!cpumask_test_and_clear_cpu(cpu, &armpmu->active_irqs))
-               return;
-
-       if (irq_is_percpu_devid(irq)) {
-               free_percpu_irq(irq, &hw_events->percpu_pmu);
-               cpumask_clear(&armpmu->active_irqs);
-               return;
+       for_each_possible_cpu(cpu) {
+               if (per_cpu(cpu_irq, cpu) == irq)
+                       count++;
        }
 
-       free_irq(irq, per_cpu_ptr(&hw_events->percpu_pmu, cpu));
+       return count;
 }
 
-void armpmu_free_irqs(struct arm_pmu *armpmu)
+void armpmu_free_irq(int irq, int cpu)
 {
-       int cpu;
+       if (per_cpu(cpu_irq, cpu) == 0)
+               return;
+       if (WARN_ON(irq != per_cpu(cpu_irq, cpu)))
+               return;
+
+       if (!irq_is_percpu_devid(irq))
+               free_irq(irq, per_cpu_ptr(&cpu_armpmu, cpu));
+       else if (armpmu_count_irq_users(irq) == 1)
+               free_percpu_irq(irq, &cpu_armpmu);
 
-       for_each_cpu(cpu, &armpmu->supported_cpus)
-               armpmu_free_irq(armpmu, cpu);
+       per_cpu(cpu_irq, cpu) = 0;
 }
 
-int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
+int armpmu_request_irq(int irq, int cpu)
 {
        int err = 0;
-       struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
        const irq_handler_t handler = armpmu_dispatch_irq;
-       int irq = per_cpu(hw_events->irq, cpu);
        if (!irq)
                return 0;
 
-       if (irq_is_percpu_devid(irq) && cpumask_empty(&armpmu->active_irqs)) {
-               err = request_percpu_irq(irq, handler, "arm-pmu",
-                                        &hw_events->percpu_pmu);
-       } else if (irq_is_percpu_devid(irq)) {
-               int other_cpu = cpumask_first(&armpmu->active_irqs);
-               int other_irq = per_cpu(hw_events->irq, other_cpu);
-
-               if (irq != other_irq) {
-                       pr_warn("mismatched PPIs detected.\n");
-                       err = -EINVAL;
-                       goto err_out;
-               }
-       } else {
-               struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu);
+       if (!irq_is_percpu_devid(irq)) {
                unsigned long irq_flags;
 
                err = irq_force_affinity(irq, cpumask_of(cpu));
@@ -589,22 +567,22 @@ int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
                        goto err_out;
                }
 
-               if (platdata && platdata->irq_flags) {
-                       irq_flags = platdata->irq_flags;
-               } else {
-                       irq_flags = IRQF_PERCPU |
-                                   IRQF_NOBALANCING |
-                                   IRQF_NO_THREAD;
-               }
+               irq_flags = IRQF_PERCPU |
+                           IRQF_NOBALANCING |
+                           IRQF_NO_THREAD;
 
+               irq_set_status_flags(irq, IRQ_NOAUTOEN);
                err = request_irq(irq, handler, irq_flags, "arm-pmu",
-                                 per_cpu_ptr(&hw_events->percpu_pmu, cpu));
+                                 per_cpu_ptr(&cpu_armpmu, cpu));
+       } else if (armpmu_count_irq_users(irq) == 0) {
+               err = request_percpu_irq(irq, handler, "arm-pmu",
+                                        &cpu_armpmu);
        }
 
        if (err)
                goto err_out;
 
-       cpumask_set_cpu(cpu, &armpmu->active_irqs);
+       per_cpu(cpu_irq, cpu) = irq;
        return 0;
 
 err_out:
@@ -612,19 +590,6 @@ err_out:
        return err;
 }
 
-int armpmu_request_irqs(struct arm_pmu *armpmu)
-{
-       int cpu, err;
-
-       for_each_cpu(cpu, &armpmu->supported_cpus) {
-               err = armpmu_request_irq(armpmu, cpu);
-               if (err)
-                       break;
-       }
-
-       return err;
-}
-
 static int armpmu_get_cpu_irq(struct arm_pmu *pmu, int cpu)
 {
        struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
@@ -647,12 +612,14 @@ static int arm_perf_starting_cpu(unsigned int cpu, struct hlist_node *node)
        if (pmu->reset)
                pmu->reset(pmu);
 
+       per_cpu(cpu_armpmu, cpu) = pmu;
+
        irq = armpmu_get_cpu_irq(pmu, cpu);
        if (irq) {
-               if (irq_is_percpu_devid(irq)) {
+               if (irq_is_percpu_devid(irq))
                        enable_percpu_irq(irq, IRQ_TYPE_NONE);
-                       return 0;
-               }
+               else
+                       enable_irq(irq);
        }
 
        return 0;
@@ -667,8 +634,14 @@ static int arm_perf_teardown_cpu(unsigned int cpu, struct hlist_node *node)
                return 0;
 
        irq = armpmu_get_cpu_irq(pmu, cpu);
-       if (irq && irq_is_percpu_devid(irq))
-               disable_percpu_irq(irq);
+       if (irq) {
+               if (irq_is_percpu_devid(irq))
+                       disable_percpu_irq(irq);
+               else
+                       disable_irq_nosync(irq);
+       }
+
+       per_cpu(cpu_armpmu, cpu) = NULL;
 
        return 0;
 }
@@ -800,18 +773,18 @@ static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
                                            &cpu_pmu->node);
 }
 
-struct arm_pmu *armpmu_alloc(void)
+static struct arm_pmu *__armpmu_alloc(gfp_t flags)
 {
        struct arm_pmu *pmu;
        int cpu;
 
-       pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
+       pmu = kzalloc(sizeof(*pmu), flags);
        if (!pmu) {
                pr_info("failed to allocate PMU device!\n");
                goto out;
        }
 
-       pmu->hw_events = alloc_percpu(struct pmu_hw_events);
+       pmu->hw_events = alloc_percpu_gfp(struct pmu_hw_events, flags);
        if (!pmu->hw_events) {
                pr_info("failed to allocate per-cpu PMU data.\n");
                goto out_free_pmu;
@@ -857,6 +830,17 @@ out:
        return NULL;
 }
 
+struct arm_pmu *armpmu_alloc(void)
+{
+       return __armpmu_alloc(GFP_KERNEL);
+}
+
+struct arm_pmu *armpmu_alloc_atomic(void)
+{
+       return __armpmu_alloc(GFP_ATOMIC);
+}
+
+
 void armpmu_free(struct arm_pmu *pmu)
 {
        free_percpu(pmu->hw_events);
index 705f1a390e3123a2d305e0468cec8194d972ed39..0f197516d7089cf970926501aca996a9ab79a7f8 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/acpi.h>
 #include <linux/cpumask.h>
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
 #include <linux/percpu.h>
 #include <linux/perf/arm_pmu.h>
 
@@ -87,7 +89,13 @@ static int arm_pmu_acpi_parse_irqs(void)
                        pr_warn("No ACPI PMU IRQ for CPU%d\n", cpu);
                }
 
+               /*
+                * Log and request the IRQ so the core arm_pmu code can manage
+                * it. We'll have to sanity-check IRQs later when we associate
+                * them with their PMUs.
+                */
                per_cpu(pmu_irqs, cpu) = irq;
+               armpmu_request_irq(irq, cpu);
        }
 
        return 0;
@@ -127,7 +135,7 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void)
                return pmu;
        }
 
-       pmu = armpmu_alloc();
+       pmu = armpmu_alloc_atomic();
        if (!pmu) {
                pr_warn("Unable to allocate PMU for CPU%d\n",
                        smp_processor_id());
@@ -139,6 +147,35 @@ static struct arm_pmu *arm_pmu_acpi_find_alloc_pmu(void)
        return pmu;
 }
 
+/*
+ * Check whether the new IRQ is compatible with those already associated with
+ * the PMU (e.g. we don't have mismatched PPIs).
+ */
+static bool pmu_irq_matches(struct arm_pmu *pmu, int irq)
+{
+       struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
+       int cpu;
+
+       if (!irq)
+               return true;
+
+       for_each_cpu(cpu, &pmu->supported_cpus) {
+               int other_irq = per_cpu(hw_events->irq, cpu);
+               if (!other_irq)
+                       continue;
+
+               if (irq == other_irq)
+                       continue;
+               if (!irq_is_percpu_devid(irq) && !irq_is_percpu_devid(other_irq))
+                       continue;
+
+               pr_warn("mismatched PPIs detected\n");
+               return false;
+       }
+
+       return true;
+}
+
 /*
  * This must run before the common arm_pmu hotplug logic, so that we can
  * associate a CPU and its interrupt before the common code tries to manage the
@@ -164,19 +201,14 @@ static int arm_pmu_acpi_cpu_starting(unsigned int cpu)
        if (!pmu)
                return -ENOMEM;
 
-       cpumask_set_cpu(cpu, &pmu->supported_cpus);
-
        per_cpu(probed_pmus, cpu) = pmu;
 
-       /*
-        * Log and request the IRQ so the core arm_pmu code can manage it.  In
-        * some situations (e.g. mismatched PPIs), we may fail to request the
-        * IRQ. However, it may be too late for us to do anything about it.
-        * The common ARM PMU code will log a warning in this case.
-        */
-       hw_events = pmu->hw_events;
-       per_cpu(hw_events->irq, cpu) = irq;
-       armpmu_request_irq(pmu, cpu);
+       if (pmu_irq_matches(pmu, irq)) {
+               hw_events = pmu->hw_events;
+               per_cpu(hw_events->irq, cpu) = irq;
+       }
+
+       cpumask_set_cpu(cpu, &pmu->supported_cpus);
 
        /*
         * Ideally, we'd probe the PMU here when we find the first matching
@@ -247,11 +279,6 @@ static int arm_pmu_acpi_init(void)
        if (acpi_disabled)
                return 0;
 
-       /*
-        * We can't request IRQs yet, since we don't know the cookie value
-        * until we know which CPUs share the same logical PMU. We'll handle
-        * that in arm_pmu_acpi_cpu_starting().
-        */
        ret = arm_pmu_acpi_parse_irqs();
        if (ret)
                return ret;
index 46501cc79fd7c3f3b0ac4557ce4a06811636f338..7729eda5909df180ae686ee8206e35a75b9ca476 100644 (file)
@@ -127,13 +127,6 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
                        pdev->dev.of_node);
        }
 
-       /*
-        * Some platforms have all PMU IRQs OR'd into a single IRQ, with a
-        * special platdata function that attempts to demux them.
-        */
-       if (dev_get_platdata(&pdev->dev))
-               cpumask_setall(&pmu->supported_cpus);
-
        for (i = 0; i < num_irqs; i++) {
                int cpu, irq;
 
@@ -164,6 +157,36 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
        return 0;
 }
 
+static int armpmu_request_irqs(struct arm_pmu *armpmu)
+{
+       struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
+       int cpu, err;
+
+       for_each_cpu(cpu, &armpmu->supported_cpus) {
+               int irq = per_cpu(hw_events->irq, cpu);
+               if (!irq)
+                       continue;
+
+               err = armpmu_request_irq(irq, cpu);
+               if (err)
+                       break;
+       }
+
+       return err;
+}
+
+static void armpmu_free_irqs(struct arm_pmu *armpmu)
+{
+       int cpu;
+       struct pmu_hw_events __percpu *hw_events = armpmu->hw_events;
+
+       for_each_cpu(cpu, &armpmu->supported_cpus) {
+               int irq = per_cpu(hw_events->irq, cpu);
+
+               armpmu_free_irq(irq, cpu);
+       }
+}
+
 int arm_pmu_device_probe(struct platform_device *pdev,
                         const struct of_device_id *of_table,
                         const struct pmu_probe_info *probe_table)
index c5ff4525edef517fb36bb417a31a6c8db544b276..c5493ea5128287c12a572f0383fdc5cc742a7970 100644 (file)
@@ -675,3 +675,8 @@ int ufs_qcom_phy_power_off(struct phy *generic_phy)
        return 0;
 }
 EXPORT_SYMBOL_GPL(ufs_qcom_phy_power_off);
+
+MODULE_AUTHOR("Yaniv Gardi <ygardi@codeaurora.org>");
+MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
+MODULE_DESCRIPTION("Universal Flash Storage (UFS) QCOM PHY");
+MODULE_LICENSE("GPL v2");
index 1fda9d6c7ea3f39b3768f142136b7e11f9e0c870..4b91ff74779bead16a60f96bf2566e947989e179 100644 (file)
@@ -716,7 +716,7 @@ static const char * const uart_b_groups[] = {
        "uart_tx_b_x", "uart_rx_b_x", "uart_cts_b_x", "uart_rts_b_x",
 };
 
-static const char * const uart_ao_b_gpioz_groups[] = {
+static const char * const uart_ao_b_z_groups[] = {
        "uart_ao_tx_b_z", "uart_ao_rx_b_z",
        "uart_ao_cts_b_z", "uart_ao_rts_b_z",
 };
@@ -855,7 +855,7 @@ static struct meson_pmx_func meson_axg_periphs_functions[] = {
        FUNCTION(nand),
        FUNCTION(uart_a),
        FUNCTION(uart_b),
-       FUNCTION(uart_ao_b_gpioz),
+       FUNCTION(uart_ao_b_z),
        FUNCTION(i2c0),
        FUNCTION(i2c1),
        FUNCTION(i2c2),
index c32399faff5724c388aedf1890bb68cb67940423..90c274490181aa1fc9916980c47f1c4ad1e92435 100644 (file)
@@ -124,7 +124,7 @@ static const struct samsung_pin_bank_data s5pv210_pin_bank[] __initconst = {
        EXYNOS_PIN_BANK_EINTW(8, 0xc60, "gph3", 0x0c),
 };
 
-const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = s5pv210_pin_bank,
@@ -137,6 +137,11 @@ const struct samsung_pin_ctrl s5pv210_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data s5pv210_of_data __initconst = {
+       .ctrl           = s5pv210_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(s5pv210_pin_ctrl),
+};
+
 /* Pad retention control code for accessing PMU regmap */
 static atomic_t exynos_shared_retention_refcnt;
 
@@ -199,7 +204,7 @@ static const struct samsung_retention_data exynos3250_retention_data __initconst
  * Samsung pinctrl driver data for Exynos3250 SoC. Exynos3250 SoC includes
  * two gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos3250_pin_banks0,
@@ -220,6 +225,11 @@ const struct samsung_pin_ctrl exynos3250_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos3250_of_data __initconst = {
+       .ctrl           = exynos3250_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos3250_pin_ctrl),
+};
+
 /* pin banks of exynos4210 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos4210_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
@@ -303,7 +313,7 @@ static const struct samsung_retention_data exynos4_audio_retention_data __initco
  * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
  * three gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos4210_pin_banks0,
@@ -329,6 +339,11 @@ const struct samsung_pin_ctrl exynos4210_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos4210_of_data __initconst = {
+       .ctrl           = exynos4210_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos4210_pin_ctrl),
+};
+
 /* pin banks of exynos4x12 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos4x12_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
@@ -391,7 +406,7 @@ static const struct samsung_pin_bank_data exynos4x12_pin_banks3[] __initconst =
  * Samsung pinctrl driver data for Exynos4x12 SoC. Exynos4x12 SoC includes
  * four gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos4x12_pin_banks0,
@@ -427,6 +442,11 @@ const struct samsung_pin_ctrl exynos4x12_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos4x12_of_data __initconst = {
+       .ctrl           = exynos4x12_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos4x12_pin_ctrl),
+};
+
 /* pin banks of exynos5250 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos5250_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
@@ -487,7 +507,7 @@ static const struct samsung_pin_bank_data exynos5250_pin_banks3[] __initconst =
  * Samsung pinctrl driver data for Exynos5250 SoC. Exynos5250 SoC includes
  * four gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos5250_pin_banks0,
@@ -523,6 +543,11 @@ const struct samsung_pin_ctrl exynos5250_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos5250_of_data __initconst = {
+       .ctrl           = exynos5250_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos5250_pin_ctrl),
+};
+
 /* pin banks of exynos5260 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos5260_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpa0", 0x00),
@@ -567,7 +592,7 @@ static const struct samsung_pin_bank_data exynos5260_pin_banks2[] __initconst =
  * Samsung pinctrl driver data for Exynos5260 SoC. Exynos5260 SoC includes
  * three gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos5260_pin_banks0,
@@ -587,6 +612,11 @@ const struct samsung_pin_ctrl exynos5260_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos5260_of_data __initconst = {
+       .ctrl           = exynos5260_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos5260_pin_ctrl),
+};
+
 /* pin banks of exynos5410 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos5410_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
@@ -657,7 +687,7 @@ static const struct samsung_pin_bank_data exynos5410_pin_banks3[] __initconst =
  * Samsung pinctrl driver data for Exynos5410 SoC. Exynos5410 SoC includes
  * four gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos5410_pin_banks0,
@@ -690,6 +720,11 @@ const struct samsung_pin_ctrl exynos5410_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos5410_of_data __initconst = {
+       .ctrl           = exynos5410_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos5410_pin_ctrl),
+};
+
 /* pin banks of exynos5420 pin-controller 0 */
 static const struct samsung_pin_bank_data exynos5420_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),
@@ -774,7 +809,7 @@ static const struct samsung_retention_data exynos5420_retention_data __initconst
  * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
  * four gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos5420_pin_banks0,
@@ -808,3 +843,8 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
                .retention_data = &exynos4_audio_retention_data,
        },
 };
+
+const struct samsung_pinctrl_of_match_data exynos5420_of_data __initconst = {
+       .ctrl           = exynos5420_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos5420_pin_ctrl),
+};
index fc8f7833bec0b29120bf559681e68ef41b09b7b4..71c9d1d9f34511c71c8269d81588d8f8ee16a710 100644 (file)
@@ -175,7 +175,7 @@ static const struct samsung_retention_data exynos5433_fsys_retention_data __init
  * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes
  * ten gpio/pin-mux/pinconfig controllers.
  */
-const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 data */
                .pin_banks      = exynos5433_pin_banks0,
@@ -260,6 +260,11 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data exynos5433_of_data __initconst = {
+       .ctrl           = exynos5433_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos5433_pin_ctrl),
+};
+
 /* pin banks of exynos7 pin-controller - ALIVE */
 static const struct samsung_pin_bank_data exynos7_pin_banks0[] __initconst = {
        EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
@@ -339,7 +344,7 @@ static const struct samsung_pin_bank_data exynos7_pin_banks9[] __initconst = {
        EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
 };
 
-const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 Alive data */
                .pin_banks      = exynos7_pin_banks0,
@@ -392,3 +397,8 @@ const struct samsung_pin_ctrl exynos7_pin_ctrl[] __initconst = {
                .eint_gpio_init = exynos_eint_gpio_init,
        },
 };
+
+const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = {
+       .ctrl           = exynos7_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(exynos7_pin_ctrl),
+};
index 10187cb0e9b9d9d74bd207f3207ec00ad125bb86..7e824e4d20f44e59856f3679b9f466f0b857088d 100644 (file)
@@ -565,7 +565,7 @@ static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = {
        PIN_BANK_2BIT(13, 0x080, "gpj"),
 };
 
-const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = {
        {
                .pin_banks      = s3c2412_pin_banks,
                .nr_banks       = ARRAY_SIZE(s3c2412_pin_banks),
@@ -573,6 +573,11 @@ const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data s3c2412_of_data __initconst = {
+       .ctrl           = s3c2412_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(s3c2412_pin_ctrl),
+};
+
 static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = {
        PIN_BANK_A(27, 0x000, "gpa"),
        PIN_BANK_2BIT(11, 0x010, "gpb"),
@@ -587,7 +592,7 @@ static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = {
        PIN_BANK_2BIT(2, 0x100, "gpm"),
 };
 
-const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = {
        {
                .pin_banks      = s3c2416_pin_banks,
                .nr_banks       = ARRAY_SIZE(s3c2416_pin_banks),
@@ -595,6 +600,11 @@ const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data s3c2416_of_data __initconst = {
+       .ctrl           = s3c2416_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(s3c2416_pin_ctrl),
+};
+
 static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = {
        PIN_BANK_A(25, 0x000, "gpa"),
        PIN_BANK_2BIT(11, 0x010, "gpb"),
@@ -607,7 +617,7 @@ static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = {
        PIN_BANK_2BIT(13, 0x0d0, "gpj"),
 };
 
-const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = {
        {
                .pin_banks      = s3c2440_pin_banks,
                .nr_banks       = ARRAY_SIZE(s3c2440_pin_banks),
@@ -615,6 +625,11 @@ const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = {
        },
 };
 
+const struct samsung_pinctrl_of_match_data s3c2440_of_data __initconst = {
+       .ctrl           = s3c2440_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(s3c2440_pin_ctrl),
+};
+
 static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = {
        PIN_BANK_A(28, 0x000, "gpa"),
        PIN_BANK_2BIT(11, 0x010, "gpb"),
@@ -630,10 +645,15 @@ static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = {
        PIN_BANK_2BIT(2, 0x100, "gpm"),
 };
 
-const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = {
        {
                .pin_banks      = s3c2450_pin_banks,
                .nr_banks       = ARRAY_SIZE(s3c2450_pin_banks),
                .eint_wkup_init = s3c24xx_eint_init,
        },
 };
+
+const struct samsung_pinctrl_of_match_data s3c2450_of_data __initconst = {
+       .ctrl           = s3c2450_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(s3c2450_pin_ctrl),
+};
index 679628ac4b31a7c9af210e812d9c8420b6e245ea..288e6567ceb1bf233a748d838dd03eae71270cb5 100644 (file)
@@ -789,7 +789,7 @@ static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = {
  * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
  * one gpio/pin-mux/pinconfig controller.
  */
-const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 1 data */
                .pin_banks      = s3c64xx_pin_banks0,
@@ -798,3 +798,8 @@ const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
                .eint_wkup_init = s3c64xx_eint_eint0_init,
        },
 };
+
+const struct samsung_pinctrl_of_match_data s3c64xx_of_data __initconst = {
+       .ctrl           = s3c64xx_pin_ctrl,
+       .num_ctrl       = ARRAY_SIZE(s3c64xx_pin_ctrl),
+};
index da58e4554137419a77b6848b5b2e9f96b126d346..336e88d7bdb9bbe69496c25cc510007aec858cc3 100644 (file)
@@ -942,12 +942,33 @@ static int samsung_gpiolib_register(struct platform_device *pdev,
        return 0;
 }
 
+static const struct samsung_pin_ctrl *
+samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       const struct samsung_pinctrl_of_match_data *of_data;
+       int id;
+
+       id = of_alias_get_id(node, "pinctrl");
+       if (id < 0) {
+               dev_err(&pdev->dev, "failed to get alias id\n");
+               return NULL;
+       }
+
+       of_data = of_device_get_match_data(&pdev->dev);
+       if (id >= of_data->num_ctrl) {
+               dev_err(&pdev->dev, "invalid alias id %d\n", id);
+               return NULL;
+       }
+
+       return &(of_data->ctrl[id]);
+}
+
 /* retrieve the soc specific data */
 static const struct samsung_pin_ctrl *
 samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
                             struct platform_device *pdev)
 {
-       int id;
        struct device_node *node = pdev->dev.of_node;
        struct device_node *np;
        const struct samsung_pin_bank_data *bdata;
@@ -957,13 +978,9 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
        void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES];
        unsigned int i;
 
-       id = of_alias_get_id(node, "pinctrl");
-       if (id < 0) {
-               dev_err(&pdev->dev, "failed to get alias id\n");
+       ctrl = samsung_pinctrl_get_soc_data_for_of_alias(pdev);
+       if (!ctrl)
                return ERR_PTR(-ENOENT);
-       }
-       ctrl = of_device_get_match_data(&pdev->dev);
-       ctrl += id;
 
        d->suspend = ctrl->suspend;
        d->resume = ctrl->resume;
@@ -1188,41 +1205,41 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
 static const struct of_device_id samsung_pinctrl_dt_match[] = {
 #ifdef CONFIG_PINCTRL_EXYNOS_ARM
        { .compatible = "samsung,exynos3250-pinctrl",
-               .data = exynos3250_pin_ctrl },
+               .data = &exynos3250_of_data },
        { .compatible = "samsung,exynos4210-pinctrl",
-               .data = exynos4210_pin_ctrl },
+               .data = &exynos4210_of_data },
        { .compatible = "samsung,exynos4x12-pinctrl",
-               .data = exynos4x12_pin_ctrl },
+               .data = &exynos4x12_of_data },
        { .compatible = "samsung,exynos5250-pinctrl",
-               .data = exynos5250_pin_ctrl },
+               .data = &exynos5250_of_data },
        { .compatible = "samsung,exynos5260-pinctrl",
-               .data = exynos5260_pin_ctrl },
+               .data = &exynos5260_of_data },
        { .compatible = "samsung,exynos5410-pinctrl",
-               .data = exynos5410_pin_ctrl },
+               .data = &exynos5410_of_data },
        { .compatible = "samsung,exynos5420-pinctrl",
-               .data = exynos5420_pin_ctrl },
+               .data = &exynos5420_of_data },
        { .compatible = "samsung,s5pv210-pinctrl",
-               .data = s5pv210_pin_ctrl },
+               .data = &s5pv210_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_EXYNOS_ARM64
        { .compatible = "samsung,exynos5433-pinctrl",
-               .data = exynos5433_pin_ctrl },
+               .data = &exynos5433_of_data },
        { .compatible = "samsung,exynos7-pinctrl",
-               .data = exynos7_pin_ctrl },
+               .data = &exynos7_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
        { .compatible = "samsung,s3c64xx-pinctrl",
-               .data = s3c64xx_pin_ctrl },
+               .data = &s3c64xx_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C24XX
        { .compatible = "samsung,s3c2412-pinctrl",
-               .data = s3c2412_pin_ctrl },
+               .data = &s3c2412_of_data },
        { .compatible = "samsung,s3c2416-pinctrl",
-               .data = s3c2416_pin_ctrl },
+               .data = &s3c2416_of_data },
        { .compatible = "samsung,s3c2440-pinctrl",
-               .data = s3c2440_pin_ctrl },
+               .data = &s3c2440_of_data },
        { .compatible = "samsung,s3c2450-pinctrl",
-               .data = s3c2450_pin_ctrl },
+               .data = &s3c2450_of_data },
 #endif
        {},
 };
index e204f609823bad288850dd540b7ee7a367df4e95..f0cda9424dfe29a26cee88741d092740ed8969cc 100644 (file)
@@ -281,6 +281,16 @@ struct samsung_pinctrl_drv_data {
        void (*resume)(struct samsung_pinctrl_drv_data *);
 };
 
+/**
+ * struct samsung_pinctrl_of_match_data: OF match device specific configuration data.
+ * @ctrl: array of pin controller data.
+ * @num_ctrl: size of array @ctrl.
+ */
+struct samsung_pinctrl_of_match_data {
+       const struct samsung_pin_ctrl   *ctrl;
+       unsigned int                    num_ctrl;
+};
+
 /**
  * struct samsung_pin_group: represent group of pins of a pinmux function.
  * @name: name of the pin group, used to lookup the group.
@@ -309,20 +319,20 @@ struct samsung_pmx_func {
 };
 
 /* list of all exported SoC specific data */
-extern const struct samsung_pin_ctrl exynos3250_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos4210_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos5250_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos5260_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos5410_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos5420_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos5433_pin_ctrl[];
-extern const struct samsung_pin_ctrl exynos7_pin_ctrl[];
-extern const struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
-extern const struct samsung_pin_ctrl s3c2412_pin_ctrl[];
-extern const struct samsung_pin_ctrl s3c2416_pin_ctrl[];
-extern const struct samsung_pin_ctrl s3c2440_pin_ctrl[];
-extern const struct samsung_pin_ctrl s3c2450_pin_ctrl[];
-extern const struct samsung_pin_ctrl s5pv210_pin_ctrl[];
+extern const struct samsung_pinctrl_of_match_data exynos3250_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos4210_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos4x12_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos5250_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos5260_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos5410_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos5420_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos5433_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
+extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
+extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
+extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
+extern const struct samsung_pinctrl_of_match_data s3c2440_of_data;
+extern const struct samsung_pinctrl_of_match_data s3c2450_of_data;
+extern const struct samsung_pinctrl_of_match_data s5pv210_of_data;
 
 #endif /* __PINCTRL_SAMSUNG_H */
index 18aeee592fdcf24694909230c15974696f8b4a43..35951e7b89d2fae33377dd56529811f8c0c3ad06 100644 (file)
@@ -1538,7 +1538,6 @@ static const struct sh_pfc_pin pinmux_pins[] = {
        SH_PFC_PIN_NAMED_CFG('B', 18, AVB_TD1, CFG_FLAGS),
        SH_PFC_PIN_NAMED_CFG('B', 19, AVB_RXC, CFG_FLAGS),
        SH_PFC_PIN_NAMED_CFG('C',  1, PRESETOUT#, CFG_FLAGS),
-       SH_PFC_PIN_NAMED_CFG('F',  1, CLKOUT, CFG_FLAGS),
        SH_PFC_PIN_NAMED_CFG('H', 37, MLB_REF, CFG_FLAGS),
        SH_PFC_PIN_NAMED_CFG('V',  3, QSPI1_SPCLK, CFG_FLAGS),
        SH_PFC_PIN_NAMED_CFG('V',  5, QSPI1_SSL, CFG_FLAGS),
index 6dec6ab1330074227a0361f9a25fcb7713b5213c..d8599736a41a268eba0eeeabb594d4d21499901f 100644 (file)
@@ -423,7 +423,7 @@ static int chromeos_laptop_probe(struct platform_device *pdev)
        return ret;
 }
 
-static const struct chromeos_laptop samsung_series_5_550 = {
+static struct chromeos_laptop samsung_series_5_550 = {
        .i2c_peripherals = {
                /* Touchpad. */
                { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS },
@@ -432,14 +432,14 @@ static const struct chromeos_laptop samsung_series_5_550 = {
        },
 };
 
-static const struct chromeos_laptop samsung_series_5 = {
+static struct chromeos_laptop samsung_series_5 = {
        .i2c_peripherals = {
                /* Light Sensor. */
                { .add = setup_tsl2583_als, I2C_ADAPTER_SMBUS },
        },
 };
 
-static const struct chromeos_laptop chromebook_pixel = {
+static struct chromeos_laptop chromebook_pixel = {
        .i2c_peripherals = {
                /* Touch Screen. */
                { .add = setup_atmel_1664s_ts, I2C_ADAPTER_PANEL },
@@ -450,14 +450,14 @@ static const struct chromeos_laptop chromebook_pixel = {
        },
 };
 
-static const struct chromeos_laptop hp_chromebook_14 = {
+static struct chromeos_laptop hp_chromebook_14 = {
        .i2c_peripherals = {
                /* Touchpad. */
                { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 },
        },
 };
 
-static const struct chromeos_laptop dell_chromebook_11 = {
+static struct chromeos_laptop dell_chromebook_11 = {
        .i2c_peripherals = {
                /* Touchpad. */
                { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 },
@@ -466,28 +466,28 @@ static const struct chromeos_laptop dell_chromebook_11 = {
        },
 };
 
-static const struct chromeos_laptop toshiba_cb35 = {
+static struct chromeos_laptop toshiba_cb35 = {
        .i2c_peripherals = {
                /* Touchpad. */
                { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 },
        },
 };
 
-static const struct chromeos_laptop acer_c7_chromebook = {
+static struct chromeos_laptop acer_c7_chromebook = {
        .i2c_peripherals = {
                /* Touchpad. */
                { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS },
        },
 };
 
-static const struct chromeos_laptop acer_ac700 = {
+static struct chromeos_laptop acer_ac700 = {
        .i2c_peripherals = {
                /* Light Sensor. */
                { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS },
        },
 };
 
-static const struct chromeos_laptop acer_c720 = {
+static struct chromeos_laptop acer_c720 = {
        .i2c_peripherals = {
                /* Touchscreen. */
                { .add = setup_atmel_1664s_ts, I2C_ADAPTER_DESIGNWARE_1 },
@@ -500,14 +500,14 @@ static const struct chromeos_laptop acer_c720 = {
        },
 };
 
-static const struct chromeos_laptop hp_pavilion_14_chromebook = {
+static struct chromeos_laptop hp_pavilion_14_chromebook = {
        .i2c_peripherals = {
                /* Touchpad. */
                { .add = setup_cyapa_tp, I2C_ADAPTER_SMBUS },
        },
 };
 
-static const struct chromeos_laptop cr48 = {
+static struct chromeos_laptop cr48 = {
        .i2c_peripherals = {
                /* Light Sensor. */
                { .add = setup_tsl2563_als, I2C_ADAPTER_SMBUS },
index 9a8f96465cdc3c04783f6296dcc778128c231df5..51ebc5a6053fbf847618f4fa9c07e016c3c50f09 100644 (file)
@@ -105,31 +105,45 @@ config ASUS_LAPTOP
 
          If you have an ACPI-compatible ASUS laptop, say Y or M here.
 
+#
+# The DELL_SMBIOS driver depends on ACPI_WMI and/or DCDBAS if those
+# backends are selected. The "depends" line prevents a configuration
+# where DELL_SMBIOS=y while either of those dependencies =m.
+#
 config DELL_SMBIOS
-       tristate
+       tristate "Dell SMBIOS driver"
+       depends on DCDBAS || DCDBAS=n
+       depends on ACPI_WMI || ACPI_WMI=n
+       ---help---
+       This provides support for the Dell SMBIOS calling interface.
+       If you have a Dell computer you should enable this option.
+
+       Be sure to select at least one backend for it to work properly.
 
 config DELL_SMBIOS_WMI
-       tristate "Dell SMBIOS calling interface (WMI implementation)"
+       bool "Dell SMBIOS driver WMI backend"
+       default y
        depends on ACPI_WMI
        select DELL_WMI_DESCRIPTOR
-       select DELL_SMBIOS
+       depends on DELL_SMBIOS
        ---help---
        This provides an implementation for the Dell SMBIOS calling interface
        communicated over ACPI-WMI.
 
-       If you have a Dell computer from >2007 you should say Y or M here.
+       If you have a Dell computer from >2007 you should say Y here.
        If you aren't sure and this module doesn't work for your computer
        it just won't load.
 
 config DELL_SMBIOS_SMM
-       tristate "Dell SMBIOS calling interface (SMM implementation)"
+       bool "Dell SMBIOS driver SMM backend"
+       default y
        depends on DCDBAS
-       select DELL_SMBIOS
+       depends on DELL_SMBIOS
        ---help---
        This provides an implementation for the Dell SMBIOS calling interface
        communicated over SMI/SMM.
 
-       If you have a Dell computer from <=2017 you should say Y or M here.
+       If you have a Dell computer from <=2017 you should say Y here.
        If you aren't sure and this module doesn't work for your computer
        it just won't load.
 
index c388608ad2a3942ef2c949c87b18f76a33f0c66f..2ba6cb7953384e8af9b150adca7775c3bea6ec29 100644 (file)
@@ -13,8 +13,9 @@ obj-$(CONFIG_MSI_LAPTOP)      += msi-laptop.o
 obj-$(CONFIG_ACPI_CMPC)                += classmate-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)    += compal-laptop.o
 obj-$(CONFIG_DELL_SMBIOS)      += dell-smbios.o
-obj-$(CONFIG_DELL_SMBIOS_WMI)  += dell-smbios-wmi.o
-obj-$(CONFIG_DELL_SMBIOS_SMM)  += dell-smbios-smm.o
+dell-smbios-objs               := dell-smbios-base.o
+dell-smbios-$(CONFIG_DELL_SMBIOS_WMI)  += dell-smbios-wmi.o
+dell-smbios-$(CONFIG_DELL_SMBIOS_SMM)  += dell-smbios-smm.o
 obj-$(CONFIG_DELL_LAPTOP)      += dell-laptop.o
 obj-$(CONFIG_DELL_WMI)         += dell-wmi.o
 obj-$(CONFIG_DELL_WMI_DESCRIPTOR)      += dell-wmi-descriptor.o
index 2a68f59d2228c921e8609ccba97832e07cbaa582..c52c6723374b50b26041d7681c3d9ae3564d50ce 100644 (file)
@@ -126,24 +126,6 @@ static const struct dmi_system_id dell_device_table[] __initconst = {
                        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 = {
@@ -1279,7 +1261,7 @@ static int kbd_get_state(struct kbd_state *state)
        struct calling_interface_buffer buffer;
        int ret;
 
-       dell_fill_request(&buffer, 0, 0, 0, 0);
+       dell_fill_request(&buffer, 0x1, 0, 0, 0);
        ret = dell_send_request(&buffer,
                                CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
        if (ret)
diff --git a/drivers/platform/x86/dell-smbios-base.c b/drivers/platform/x86/dell-smbios-base.c
new file mode 100644 (file)
index 0000000..2485c80
--- /dev/null
@@ -0,0 +1,648 @@
+/*
+ *  Common functions for kernel modules using Dell SMBIOS
+ *
+ *  Copyright (c) Red Hat <mjg@redhat.com>
+ *  Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com>
+ *  Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com>
+ *
+ *  Based on documentation in the libsmbios package:
+ *  Copyright (C) 2005-2014 Dell 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.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/capability.h>
+#include <linux/dmi.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "dell-smbios.h"
+
+static u32 da_supported_commands;
+static int da_num_tokens;
+static struct platform_device *platform_device;
+static struct calling_interface_token *da_tokens;
+static struct device_attribute *token_location_attrs;
+static struct device_attribute *token_value_attrs;
+static struct attribute **token_attrs;
+static DEFINE_MUTEX(smbios_mutex);
+
+struct smbios_device {
+       struct list_head list;
+       struct device *device;
+       int (*call_fn)(struct calling_interface_buffer *arg);
+};
+
+struct smbios_call {
+       u32 need_capability;
+       int cmd_class;
+       int cmd_select;
+};
+
+/* calls that are whitelisted for given capabilities */
+static struct smbios_call call_whitelist[] = {
+       /* generally tokens are allowed, but may be further filtered or
+        * restricted by token blacklist or whitelist
+        */
+       {CAP_SYS_ADMIN, CLASS_TOKEN_READ,       SELECT_TOKEN_STD},
+       {CAP_SYS_ADMIN, CLASS_TOKEN_READ,       SELECT_TOKEN_AC},
+       {CAP_SYS_ADMIN, CLASS_TOKEN_READ,       SELECT_TOKEN_BAT},
+       {CAP_SYS_ADMIN, CLASS_TOKEN_WRITE,      SELECT_TOKEN_STD},
+       {CAP_SYS_ADMIN, CLASS_TOKEN_WRITE,      SELECT_TOKEN_AC},
+       {CAP_SYS_ADMIN, CLASS_TOKEN_WRITE,      SELECT_TOKEN_BAT},
+       /* used by userspace: fwupdate */
+       {CAP_SYS_ADMIN, CLASS_ADMIN_PROP,       SELECT_ADMIN_PROP},
+       /* used by userspace: fwupd */
+       {CAP_SYS_ADMIN, CLASS_INFO,             SELECT_DOCK},
+       {CAP_SYS_ADMIN, CLASS_FLASH_INTERFACE,  SELECT_FLASH_INTERFACE},
+};
+
+/* calls that are explicitly blacklisted */
+static struct smbios_call call_blacklist[] = {
+       {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 */
+       {0x0000, CLASS_INFO, SELECT_RFKILL},
+       {0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
+};
+
+struct token_range {
+       u32 need_capability;
+       u16 min;
+       u16 max;
+};
+
+/* tokens that are whitelisted for given capabilities */
+static struct token_range token_whitelist[] = {
+       /* used by userspace: fwupdate */
+       {CAP_SYS_ADMIN, CAPSULE_EN_TOKEN,       CAPSULE_DIS_TOKEN},
+       /* can indicate to userspace that WMI is needed */
+       {0x0000,        WSMT_EN_TOKEN,          WSMT_DIS_TOKEN}
+};
+
+/* tokens that are explicitly blacklisted */
+static struct token_range token_blacklist[] = {
+       {0x0000, 0x0058, 0x0059}, /* ME use */
+       {0x0000, 0x00CD, 0x00D0}, /* raid shadow copy */
+       {0x0000, 0x013A, 0x01FF}, /* sata shadow copy */
+       {0x0000, 0x0175, 0x0176}, /* write once */
+       {0x0000, 0x0195, 0x0197}, /* diagnostics */
+       {0x0000, 0x01DC, 0x01DD}, /* manufacturing use */
+       {0x0000, 0x027D, 0x0284}, /* diagnostics */
+       {0x0000, 0x02E3, 0x02E3}, /* manufacturing use */
+       {0x0000, 0x02FF, 0x02FF}, /* manufacturing use */
+       {0x0000, 0x0300, 0x0302}, /* manufacturing use */
+       {0x0000, 0x0325, 0x0326}, /* manufacturing use */
+       {0x0000, 0x0332, 0x0335}, /* fan control */
+       {0x0000, 0x0350, 0x0350}, /* manufacturing use */
+       {0x0000, 0x0363, 0x0363}, /* manufacturing use */
+       {0x0000, 0x0368, 0x0368}, /* manufacturing use */
+       {0x0000, 0x03F6, 0x03F7}, /* manufacturing use */
+       {0x0000, 0x049E, 0x049F}, /* manufacturing use */
+       {0x0000, 0x04A0, 0x04A3}, /* disagnostics */
+       {0x0000, 0x04E6, 0x04E7}, /* manufacturing use */
+       {0x0000, 0x4000, 0x7FFF}, /* internal BIOS use */
+       {0x0000, 0x9000, 0x9001}, /* internal BIOS use */
+       {0x0000, 0xA000, 0xBFFF}, /* write only */
+       {0x0000, 0xEFF0, 0xEFFF}, /* internal BIOS use */
+       /* handled by kernel: dell-laptop */
+       {0x0000, BRIGHTNESS_TOKEN,      BRIGHTNESS_TOKEN},
+       {0x0000, KBD_LED_OFF_TOKEN,     KBD_LED_AUTO_TOKEN},
+       {0x0000, KBD_LED_AC_TOKEN,      KBD_LED_AC_TOKEN},
+       {0x0000, KBD_LED_AUTO_25_TOKEN, KBD_LED_AUTO_75_TOKEN},
+       {0x0000, KBD_LED_AUTO_100_TOKEN,        KBD_LED_AUTO_100_TOKEN},
+       {0x0000, GLOBAL_MIC_MUTE_ENABLE,        GLOBAL_MIC_MUTE_DISABLE},
+};
+
+static LIST_HEAD(smbios_device_list);
+
+int dell_smbios_error(int value)
+{
+       switch (value) {
+       case 0: /* Completed successfully */
+               return 0;
+       case -1: /* Completed with error */
+               return -EIO;
+       case -2: /* Function not supported */
+               return -ENXIO;
+       default: /* Unknown error */
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL_GPL(dell_smbios_error);
+
+int dell_smbios_register_device(struct device *d, void *call_fn)
+{
+       struct smbios_device *priv;
+
+       priv = devm_kzalloc(d, sizeof(struct smbios_device), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       get_device(d);
+       priv->device = d;
+       priv->call_fn = call_fn;
+       mutex_lock(&smbios_mutex);
+       list_add_tail(&priv->list, &smbios_device_list);
+       mutex_unlock(&smbios_mutex);
+       dev_dbg(d, "Added device: %s\n", d->driver->name);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dell_smbios_register_device);
+
+void dell_smbios_unregister_device(struct device *d)
+{
+       struct smbios_device *priv;
+
+       mutex_lock(&smbios_mutex);
+       list_for_each_entry(priv, &smbios_device_list, list) {
+               if (priv->device == d) {
+                       list_del(&priv->list);
+                       put_device(d);
+                       break;
+               }
+       }
+       mutex_unlock(&smbios_mutex);
+       dev_dbg(d, "Remove device: %s\n", d->driver->name);
+}
+EXPORT_SYMBOL_GPL(dell_smbios_unregister_device);
+
+int dell_smbios_call_filter(struct device *d,
+                           struct calling_interface_buffer *buffer)
+{
+       u16 t = 0;
+       int i;
+
+       /* can't make calls over 30 */
+       if (buffer->cmd_class > 30) {
+               dev_dbg(d, "class too big: %u\n", buffer->cmd_class);
+               return -EINVAL;
+       }
+
+       /* supported calls on the particular system */
+       if (!(da_supported_commands & (1 << buffer->cmd_class))) {
+               dev_dbg(d, "invalid command, supported commands: 0x%8x\n",
+                       da_supported_commands);
+               return -EINVAL;
+       }
+
+       /* match against call blacklist  */
+       for (i = 0; i < ARRAY_SIZE(call_blacklist); i++) {
+               if (buffer->cmd_class != call_blacklist[i].cmd_class)
+                       continue;
+               if (buffer->cmd_select != call_blacklist[i].cmd_select &&
+                   call_blacklist[i].cmd_select != -1)
+                       continue;
+               dev_dbg(d, "blacklisted command: %u/%u\n",
+                       buffer->cmd_class, buffer->cmd_select);
+               return -EINVAL;
+       }
+
+       /* if a token call, find token ID */
+
+       if ((buffer->cmd_class == CLASS_TOKEN_READ ||
+            buffer->cmd_class == CLASS_TOKEN_WRITE) &&
+            buffer->cmd_select < 3) {
+               /* find the matching token ID */
+               for (i = 0; i < da_num_tokens; i++) {
+                       if (da_tokens[i].location != buffer->input[0])
+                               continue;
+                       t = da_tokens[i].tokenID;
+                       break;
+               }
+
+               /* token call; but token didn't exist */
+               if (!t) {
+                       dev_dbg(d, "token at location %04x doesn't exist\n",
+                               buffer->input[0]);
+                       return -EINVAL;
+               }
+
+               /* match against token blacklist */
+               for (i = 0; i < ARRAY_SIZE(token_blacklist); i++) {
+                       if (!token_blacklist[i].min || !token_blacklist[i].max)
+                               continue;
+                       if (t >= token_blacklist[i].min &&
+                           t <= token_blacklist[i].max)
+                               return -EINVAL;
+               }
+
+               /* match against token whitelist */
+               for (i = 0; i < ARRAY_SIZE(token_whitelist); i++) {
+                       if (!token_whitelist[i].min || !token_whitelist[i].max)
+                               continue;
+                       if (t < token_whitelist[i].min ||
+                           t > token_whitelist[i].max)
+                               continue;
+                       if (!token_whitelist[i].need_capability ||
+                           capable(token_whitelist[i].need_capability)) {
+                               dev_dbg(d, "whitelisted token: %x\n", t);
+                               return 0;
+                       }
+
+               }
+       }
+       /* match against call whitelist */
+       for (i = 0; i < ARRAY_SIZE(call_whitelist); i++) {
+               if (buffer->cmd_class != call_whitelist[i].cmd_class)
+                       continue;
+               if (buffer->cmd_select != call_whitelist[i].cmd_select)
+                       continue;
+               if (!call_whitelist[i].need_capability ||
+                   capable(call_whitelist[i].need_capability)) {
+                       dev_dbg(d, "whitelisted capable command: %u/%u\n",
+                       buffer->cmd_class, buffer->cmd_select);
+                       return 0;
+               }
+               dev_dbg(d, "missing capability %d for %u/%u\n",
+                       call_whitelist[i].need_capability,
+                       buffer->cmd_class, buffer->cmd_select);
+
+       }
+
+       /* not in a whitelist, only allow processes with capabilities */
+       if (capable(CAP_SYS_RAWIO)) {
+               dev_dbg(d, "Allowing %u/%u due to CAP_SYS_RAWIO\n",
+                       buffer->cmd_class, buffer->cmd_select);
+               return 0;
+       }
+
+       return -EACCES;
+}
+EXPORT_SYMBOL_GPL(dell_smbios_call_filter);
+
+int dell_smbios_call(struct calling_interface_buffer *buffer)
+{
+       int (*call_fn)(struct calling_interface_buffer *) = NULL;
+       struct device *selected_dev = NULL;
+       struct smbios_device *priv;
+       int ret;
+
+       mutex_lock(&smbios_mutex);
+       list_for_each_entry(priv, &smbios_device_list, list) {
+               if (!selected_dev || priv->device->id >= selected_dev->id) {
+                       dev_dbg(priv->device, "Trying device ID: %d\n",
+                               priv->device->id);
+                       call_fn = priv->call_fn;
+                       selected_dev = priv->device;
+               }
+       }
+
+       if (!selected_dev) {
+               ret = -ENODEV;
+               pr_err("No dell-smbios drivers are loaded\n");
+               goto out_smbios_call;
+       }
+
+       ret = call_fn(buffer);
+
+out_smbios_call:
+       mutex_unlock(&smbios_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dell_smbios_call);
+
+struct calling_interface_token *dell_smbios_find_token(int tokenid)
+{
+       int i;
+
+       for (i = 0; i < da_num_tokens; i++) {
+               if (da_tokens[i].tokenID == tokenid)
+                       return &da_tokens[i];
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(dell_smbios_find_token);
+
+static BLOCKING_NOTIFIER_HEAD(dell_laptop_chain_head);
+
+int dell_laptop_register_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_register(&dell_laptop_chain_head, nb);
+}
+EXPORT_SYMBOL_GPL(dell_laptop_register_notifier);
+
+int dell_laptop_unregister_notifier(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_unregister(&dell_laptop_chain_head, nb);
+}
+EXPORT_SYMBOL_GPL(dell_laptop_unregister_notifier);
+
+void dell_laptop_call_notifier(unsigned long action, void *data)
+{
+       blocking_notifier_call_chain(&dell_laptop_chain_head, action, data);
+}
+EXPORT_SYMBOL_GPL(dell_laptop_call_notifier);
+
+static void __init parse_da_table(const struct dmi_header *dm)
+{
+       /* Final token is a terminator, so we don't want to copy it */
+       int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1;
+       struct calling_interface_token *new_da_tokens;
+       struct calling_interface_structure *table =
+               container_of(dm, struct calling_interface_structure, header);
+
+       /*
+        * 4 bytes of table header, plus 7 bytes of Dell header
+        * plus at least 6 bytes of entry
+        */
+
+       if (dm->length < 17)
+               return;
+
+       da_supported_commands = table->supportedCmds;
+
+       new_da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) *
+                                sizeof(struct calling_interface_token),
+                                GFP_KERNEL);
+
+       if (!new_da_tokens)
+               return;
+       da_tokens = new_da_tokens;
+
+       memcpy(da_tokens+da_num_tokens, table->tokens,
+              sizeof(struct calling_interface_token) * tokens);
+
+       da_num_tokens += tokens;
+}
+
+static void zero_duplicates(struct device *dev)
+{
+       int i, j;
+
+       for (i = 0; i < da_num_tokens; i++) {
+               if (da_tokens[i].tokenID == 0)
+                       continue;
+               for (j = i+1; j < da_num_tokens; j++) {
+                       if (da_tokens[j].tokenID == 0)
+                               continue;
+                       if (da_tokens[i].tokenID == da_tokens[j].tokenID) {
+                               dev_dbg(dev, "Zeroing dup token ID %x(%x/%x)\n",
+                                       da_tokens[j].tokenID,
+                                       da_tokens[j].location,
+                                       da_tokens[j].value);
+                               da_tokens[j].tokenID = 0;
+                       }
+               }
+       }
+}
+
+static void __init find_tokens(const struct dmi_header *dm, void *dummy)
+{
+       switch (dm->type) {
+       case 0xd4: /* Indexed IO */
+       case 0xd5: /* Protected Area Type 1 */
+       case 0xd6: /* Protected Area Type 2 */
+               break;
+       case 0xda: /* Calling interface */
+               parse_da_table(dm);
+               break;
+       }
+}
+
+static int match_attribute(struct device *dev,
+                          struct device_attribute *attr)
+{
+       int i;
+
+       for (i = 0; i < da_num_tokens * 2; i++) {
+               if (!token_attrs[i])
+                       continue;
+               if (strcmp(token_attrs[i]->name, attr->attr.name) == 0)
+                       return i/2;
+       }
+       dev_dbg(dev, "couldn't match: %s\n", attr->attr.name);
+       return -EINVAL;
+}
+
+static ssize_t location_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       int i;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       i = match_attribute(dev, attr);
+       if (i > 0)
+               return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].location);
+       return 0;
+}
+
+static ssize_t value_show(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       int i;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       i = match_attribute(dev, attr);
+       if (i > 0)
+               return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].value);
+       return 0;
+}
+
+static struct attribute_group smbios_attribute_group = {
+       .name = "tokens"
+};
+
+static struct platform_driver platform_driver = {
+       .driver = {
+               .name = "dell-smbios",
+       },
+};
+
+static int build_tokens_sysfs(struct platform_device *dev)
+{
+       char *location_name;
+       char *value_name;
+       size_t size;
+       int ret;
+       int i, j;
+
+       /* (number of tokens  + 1 for null terminated */
+       size = sizeof(struct device_attribute) * (da_num_tokens + 1);
+       token_location_attrs = kzalloc(size, GFP_KERNEL);
+       if (!token_location_attrs)
+               return -ENOMEM;
+       token_value_attrs = kzalloc(size, GFP_KERNEL);
+       if (!token_value_attrs)
+               goto out_allocate_value;
+
+       /* need to store both location and value + terminator*/
+       size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1);
+       token_attrs = kzalloc(size, GFP_KERNEL);
+       if (!token_attrs)
+               goto out_allocate_attrs;
+
+       for (i = 0, j = 0; i < da_num_tokens; i++) {
+               /* skip empty */
+               if (da_tokens[i].tokenID == 0)
+                       continue;
+               /* add location */
+               location_name = kasprintf(GFP_KERNEL, "%04x_location",
+                                         da_tokens[i].tokenID);
+               if (location_name == NULL)
+                       goto out_unwind_strings;
+               sysfs_attr_init(&token_location_attrs[i].attr);
+               token_location_attrs[i].attr.name = location_name;
+               token_location_attrs[i].attr.mode = 0444;
+               token_location_attrs[i].show = location_show;
+               token_attrs[j++] = &token_location_attrs[i].attr;
+
+               /* add value */
+               value_name = kasprintf(GFP_KERNEL, "%04x_value",
+                                      da_tokens[i].tokenID);
+               if (value_name == NULL)
+                       goto loop_fail_create_value;
+               sysfs_attr_init(&token_value_attrs[i].attr);
+               token_value_attrs[i].attr.name = value_name;
+               token_value_attrs[i].attr.mode = 0444;
+               token_value_attrs[i].show = value_show;
+               token_attrs[j++] = &token_value_attrs[i].attr;
+               continue;
+
+loop_fail_create_value:
+               kfree(value_name);
+               goto out_unwind_strings;
+       }
+       smbios_attribute_group.attrs = token_attrs;
+
+       ret = sysfs_create_group(&dev->dev.kobj, &smbios_attribute_group);
+       if (ret)
+               goto out_unwind_strings;
+       return 0;
+
+out_unwind_strings:
+       for (i = i-1; i > 0; i--) {
+               kfree(token_location_attrs[i].attr.name);
+               kfree(token_value_attrs[i].attr.name);
+       }
+       kfree(token_attrs);
+out_allocate_attrs:
+       kfree(token_value_attrs);
+out_allocate_value:
+       kfree(token_location_attrs);
+
+       return -ENOMEM;
+}
+
+static void free_group(struct platform_device *pdev)
+{
+       int i;
+
+       sysfs_remove_group(&pdev->dev.kobj,
+                               &smbios_attribute_group);
+       for (i = 0; i < da_num_tokens; i++) {
+               kfree(token_location_attrs[i].attr.name);
+               kfree(token_value_attrs[i].attr.name);
+       }
+       kfree(token_attrs);
+       kfree(token_value_attrs);
+       kfree(token_location_attrs);
+}
+
+static int __init dell_smbios_init(void)
+{
+       const struct dmi_device *valid;
+       int ret, wmi, smm;
+
+       valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL);
+       if (!valid) {
+               pr_err("Unable to run on non-Dell system\n");
+               return -ENODEV;
+       }
+
+       dmi_walk(find_tokens, NULL);
+
+       if (!da_tokens)  {
+               pr_info("Unable to find dmi tokens\n");
+               return -ENODEV;
+       }
+
+       ret = platform_driver_register(&platform_driver);
+       if (ret)
+               goto fail_platform_driver;
+
+       platform_device = platform_device_alloc("dell-smbios", 0);
+       if (!platform_device) {
+               ret = -ENOMEM;
+               goto fail_platform_device_alloc;
+       }
+       ret = platform_device_add(platform_device);
+       if (ret)
+               goto fail_platform_device_add;
+
+       /* duplicate tokens will cause problems building sysfs files */
+       zero_duplicates(&platform_device->dev);
+
+       ret = build_tokens_sysfs(platform_device);
+       if (ret)
+               goto fail_create_group;
+
+       /* register backends */
+       wmi = init_dell_smbios_wmi();
+       if (wmi)
+               pr_debug("Failed to initialize WMI backend: %d\n", wmi);
+       smm = init_dell_smbios_smm();
+       if (smm)
+               pr_debug("Failed to initialize SMM backend: %d\n", smm);
+       if (wmi && smm) {
+               pr_err("No SMBIOS backends available (wmi: %d, smm: %d)\n",
+                       wmi, smm);
+               goto fail_sysfs;
+       }
+
+       return 0;
+
+fail_sysfs:
+       free_group(platform_device);
+
+fail_create_group:
+       platform_device_del(platform_device);
+
+fail_platform_device_add:
+       platform_device_put(platform_device);
+
+fail_platform_device_alloc:
+       platform_driver_unregister(&platform_driver);
+
+fail_platform_driver:
+       kfree(da_tokens);
+       return ret;
+}
+
+static void __exit dell_smbios_exit(void)
+{
+       exit_dell_smbios_wmi();
+       exit_dell_smbios_smm();
+       mutex_lock(&smbios_mutex);
+       if (platform_device) {
+               free_group(platform_device);
+               platform_device_unregister(platform_device);
+               platform_driver_unregister(&platform_driver);
+       }
+       kfree(da_tokens);
+       mutex_unlock(&smbios_mutex);
+}
+
+module_init(dell_smbios_init);
+module_exit(dell_smbios_exit);
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
+MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
+MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
+MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS");
+MODULE_LICENSE("GPL");
index 89f65c4651a04151aa1002afd65f8a0736f7a776..e9e9da556318703275ac6cb9eef59ae7426d4776 100644 (file)
@@ -58,7 +58,7 @@ static const struct dmi_system_id dell_device_table[] __initconst = {
 };
 MODULE_DEVICE_TABLE(dmi, dell_device_table);
 
-static void __init parse_da_table(const struct dmi_header *dm)
+static void parse_da_table(const struct dmi_header *dm)
 {
        struct calling_interface_structure *table =
                container_of(dm, struct calling_interface_structure, header);
@@ -73,7 +73,7 @@ static void __init parse_da_table(const struct dmi_header *dm)
        da_command_code = table->cmdIOCode;
 }
 
-static void __init find_cmd_address(const struct dmi_header *dm, void *dummy)
+static void find_cmd_address(const struct dmi_header *dm, void *dummy)
 {
        switch (dm->type) {
        case 0xda: /* Calling interface */
@@ -128,7 +128,7 @@ static bool test_wsmt_enabled(void)
        return false;
 }
 
-static int __init dell_smbios_smm_init(void)
+int init_dell_smbios_smm(void)
 {
        int ret;
        /*
@@ -176,7 +176,7 @@ fail_platform_device_alloc:
        return ret;
 }
 
-static void __exit dell_smbios_smm_exit(void)
+void exit_dell_smbios_smm(void)
 {
        if (platform_device) {
                dell_smbios_unregister_device(&platform_device->dev);
@@ -184,13 +184,3 @@ static void __exit dell_smbios_smm_exit(void)
                free_page((unsigned long)buffer);
        }
 }
-
-subsys_initcall(dell_smbios_smm_init);
-module_exit(dell_smbios_smm_exit);
-
-MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
-MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
-MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
-MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
-MODULE_DESCRIPTION("Dell SMBIOS communications over SMI");
-MODULE_LICENSE("GPL");
index 609557aa58684375b7534a39e21f9fe9eadd97e6..fbefedb1c17237c5a926446bb9162ef2a8fcb993 100644 (file)
@@ -228,7 +228,7 @@ static const struct wmi_device_id dell_smbios_wmi_id_table[] = {
        { },
 };
 
-static void __init parse_b1_table(const struct dmi_header *dm)
+static void parse_b1_table(const struct dmi_header *dm)
 {
        struct misc_bios_flags_structure *flags =
        container_of(dm, struct misc_bios_flags_structure, header);
@@ -242,7 +242,7 @@ static void __init parse_b1_table(const struct dmi_header *dm)
                wmi_supported = 1;
 }
 
-static void __init find_b1(const struct dmi_header *dm, void *dummy)
+static void find_b1(const struct dmi_header *dm, void *dummy)
 {
        switch (dm->type) {
        case 0xb1: /* misc bios flags */
@@ -261,7 +261,7 @@ static struct wmi_driver dell_smbios_wmi_driver = {
        .filter_callback = dell_smbios_wmi_filter,
 };
 
-static int __init init_dell_smbios_wmi(void)
+int init_dell_smbios_wmi(void)
 {
        dmi_walk(find_b1, NULL);
 
@@ -271,15 +271,9 @@ static int __init init_dell_smbios_wmi(void)
        return wmi_driver_register(&dell_smbios_wmi_driver);
 }
 
-static void __exit exit_dell_smbios_wmi(void)
+void exit_dell_smbios_wmi(void)
 {
        wmi_driver_unregister(&dell_smbios_wmi_driver);
 }
 
-module_init(init_dell_smbios_wmi);
-module_exit(exit_dell_smbios_wmi);
-
 MODULE_ALIAS("wmi:" DELL_WMI_SMBIOS_GUID);
-MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
-MODULE_DESCRIPTION("Dell SMBIOS communications over WMI");
-MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c
deleted file mode 100644 (file)
index 8541cde..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- *  Common functions for kernel modules using Dell SMBIOS
- *
- *  Copyright (c) Red Hat <mjg@redhat.com>
- *  Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com>
- *  Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com>
- *
- *  Based on documentation in the libsmbios package:
- *  Copyright (C) 2005-2014 Dell 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.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/capability.h>
-#include <linux/dmi.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include "dell-smbios.h"
-
-static u32 da_supported_commands;
-static int da_num_tokens;
-static struct platform_device *platform_device;
-static struct calling_interface_token *da_tokens;
-static struct device_attribute *token_location_attrs;
-static struct device_attribute *token_value_attrs;
-static struct attribute **token_attrs;
-static DEFINE_MUTEX(smbios_mutex);
-
-struct smbios_device {
-       struct list_head list;
-       struct device *device;
-       int (*call_fn)(struct calling_interface_buffer *);
-};
-
-struct smbios_call {
-       u32 need_capability;
-       int cmd_class;
-       int cmd_select;
-};
-
-/* calls that are whitelisted for given capabilities */
-static struct smbios_call call_whitelist[] = {
-       /* generally tokens are allowed, but may be further filtered or
-        * restricted by token blacklist or whitelist
-        */
-       {CAP_SYS_ADMIN, CLASS_TOKEN_READ,       SELECT_TOKEN_STD},
-       {CAP_SYS_ADMIN, CLASS_TOKEN_READ,       SELECT_TOKEN_AC},
-       {CAP_SYS_ADMIN, CLASS_TOKEN_READ,       SELECT_TOKEN_BAT},
-       {CAP_SYS_ADMIN, CLASS_TOKEN_WRITE,      SELECT_TOKEN_STD},
-       {CAP_SYS_ADMIN, CLASS_TOKEN_WRITE,      SELECT_TOKEN_AC},
-       {CAP_SYS_ADMIN, CLASS_TOKEN_WRITE,      SELECT_TOKEN_BAT},
-       /* used by userspace: fwupdate */
-       {CAP_SYS_ADMIN, CLASS_ADMIN_PROP,       SELECT_ADMIN_PROP},
-       /* used by userspace: fwupd */
-       {CAP_SYS_ADMIN, CLASS_INFO,             SELECT_DOCK},
-       {CAP_SYS_ADMIN, CLASS_FLASH_INTERFACE,  SELECT_FLASH_INTERFACE},
-};
-
-/* calls that are explicitly blacklisted */
-static struct smbios_call call_blacklist[] = {
-       {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 */
-       {0x0000, CLASS_INFO, SELECT_RFKILL},
-       {0x0000, CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT},
-};
-
-struct token_range {
-       u32 need_capability;
-       u16 min;
-       u16 max;
-};
-
-/* tokens that are whitelisted for given capabilities */
-static struct token_range token_whitelist[] = {
-       /* used by userspace: fwupdate */
-       {CAP_SYS_ADMIN, CAPSULE_EN_TOKEN,       CAPSULE_DIS_TOKEN},
-       /* can indicate to userspace that WMI is needed */
-       {0x0000,        WSMT_EN_TOKEN,          WSMT_DIS_TOKEN}
-};
-
-/* tokens that are explicitly blacklisted */
-static struct token_range token_blacklist[] = {
-       {0x0000, 0x0058, 0x0059}, /* ME use */
-       {0x0000, 0x00CD, 0x00D0}, /* raid shadow copy */
-       {0x0000, 0x013A, 0x01FF}, /* sata shadow copy */
-       {0x0000, 0x0175, 0x0176}, /* write once */
-       {0x0000, 0x0195, 0x0197}, /* diagnostics */
-       {0x0000, 0x01DC, 0x01DD}, /* manufacturing use */
-       {0x0000, 0x027D, 0x0284}, /* diagnostics */
-       {0x0000, 0x02E3, 0x02E3}, /* manufacturing use */
-       {0x0000, 0x02FF, 0x02FF}, /* manufacturing use */
-       {0x0000, 0x0300, 0x0302}, /* manufacturing use */
-       {0x0000, 0x0325, 0x0326}, /* manufacturing use */
-       {0x0000, 0x0332, 0x0335}, /* fan control */
-       {0x0000, 0x0350, 0x0350}, /* manufacturing use */
-       {0x0000, 0x0363, 0x0363}, /* manufacturing use */
-       {0x0000, 0x0368, 0x0368}, /* manufacturing use */
-       {0x0000, 0x03F6, 0x03F7}, /* manufacturing use */
-       {0x0000, 0x049E, 0x049F}, /* manufacturing use */
-       {0x0000, 0x04A0, 0x04A3}, /* disagnostics */
-       {0x0000, 0x04E6, 0x04E7}, /* manufacturing use */
-       {0x0000, 0x4000, 0x7FFF}, /* internal BIOS use */
-       {0x0000, 0x9000, 0x9001}, /* internal BIOS use */
-       {0x0000, 0xA000, 0xBFFF}, /* write only */
-       {0x0000, 0xEFF0, 0xEFFF}, /* internal BIOS use */
-       /* handled by kernel: dell-laptop */
-       {0x0000, BRIGHTNESS_TOKEN,      BRIGHTNESS_TOKEN},
-       {0x0000, KBD_LED_OFF_TOKEN,     KBD_LED_AUTO_TOKEN},
-       {0x0000, KBD_LED_AC_TOKEN,      KBD_LED_AC_TOKEN},
-       {0x0000, KBD_LED_AUTO_25_TOKEN, KBD_LED_AUTO_75_TOKEN},
-       {0x0000, KBD_LED_AUTO_100_TOKEN,        KBD_LED_AUTO_100_TOKEN},
-       {0x0000, GLOBAL_MIC_MUTE_ENABLE,        GLOBAL_MIC_MUTE_DISABLE},
-};
-
-static LIST_HEAD(smbios_device_list);
-
-int dell_smbios_error(int value)
-{
-       switch (value) {
-       case 0: /* Completed successfully */
-               return 0;
-       case -1: /* Completed with error */
-               return -EIO;
-       case -2: /* Function not supported */
-               return -ENXIO;
-       default: /* Unknown error */
-               return -EINVAL;
-       }
-}
-EXPORT_SYMBOL_GPL(dell_smbios_error);
-
-int dell_smbios_register_device(struct device *d, void *call_fn)
-{
-       struct smbios_device *priv;
-
-       priv = devm_kzalloc(d, sizeof(struct smbios_device), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-       get_device(d);
-       priv->device = d;
-       priv->call_fn = call_fn;
-       mutex_lock(&smbios_mutex);
-       list_add_tail(&priv->list, &smbios_device_list);
-       mutex_unlock(&smbios_mutex);
-       dev_dbg(d, "Added device: %s\n", d->driver->name);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(dell_smbios_register_device);
-
-void dell_smbios_unregister_device(struct device *d)
-{
-       struct smbios_device *priv;
-
-       mutex_lock(&smbios_mutex);
-       list_for_each_entry(priv, &smbios_device_list, list) {
-               if (priv->device == d) {
-                       list_del(&priv->list);
-                       put_device(d);
-                       break;
-               }
-       }
-       mutex_unlock(&smbios_mutex);
-       dev_dbg(d, "Remove device: %s\n", d->driver->name);
-}
-EXPORT_SYMBOL_GPL(dell_smbios_unregister_device);
-
-int dell_smbios_call_filter(struct device *d,
-                           struct calling_interface_buffer *buffer)
-{
-       u16 t = 0;
-       int i;
-
-       /* can't make calls over 30 */
-       if (buffer->cmd_class > 30) {
-               dev_dbg(d, "class too big: %u\n", buffer->cmd_class);
-               return -EINVAL;
-       }
-
-       /* supported calls on the particular system */
-       if (!(da_supported_commands & (1 << buffer->cmd_class))) {
-               dev_dbg(d, "invalid command, supported commands: 0x%8x\n",
-                       da_supported_commands);
-               return -EINVAL;
-       }
-
-       /* match against call blacklist  */
-       for (i = 0; i < ARRAY_SIZE(call_blacklist); i++) {
-               if (buffer->cmd_class != call_blacklist[i].cmd_class)
-                       continue;
-               if (buffer->cmd_select != call_blacklist[i].cmd_select &&
-                   call_blacklist[i].cmd_select != -1)
-                       continue;
-               dev_dbg(d, "blacklisted command: %u/%u\n",
-                       buffer->cmd_class, buffer->cmd_select);
-               return -EINVAL;
-       }
-
-       /* if a token call, find token ID */
-
-       if ((buffer->cmd_class == CLASS_TOKEN_READ ||
-            buffer->cmd_class == CLASS_TOKEN_WRITE) &&
-            buffer->cmd_select < 3) {
-               /* find the matching token ID */
-               for (i = 0; i < da_num_tokens; i++) {
-                       if (da_tokens[i].location != buffer->input[0])
-                               continue;
-                       t = da_tokens[i].tokenID;
-                       break;
-               }
-
-               /* token call; but token didn't exist */
-               if (!t) {
-                       dev_dbg(d, "token at location %04x doesn't exist\n",
-                               buffer->input[0]);
-                       return -EINVAL;
-               }
-
-               /* match against token blacklist */
-               for (i = 0; i < ARRAY_SIZE(token_blacklist); i++) {
-                       if (!token_blacklist[i].min || !token_blacklist[i].max)
-                               continue;
-                       if (t >= token_blacklist[i].min &&
-                           t <= token_blacklist[i].max)
-                               return -EINVAL;
-               }
-
-               /* match against token whitelist */
-               for (i = 0; i < ARRAY_SIZE(token_whitelist); i++) {
-                       if (!token_whitelist[i].min || !token_whitelist[i].max)
-                               continue;
-                       if (t < token_whitelist[i].min ||
-                           t > token_whitelist[i].max)
-                               continue;
-                       if (!token_whitelist[i].need_capability ||
-                           capable(token_whitelist[i].need_capability)) {
-                               dev_dbg(d, "whitelisted token: %x\n", t);
-                               return 0;
-                       }
-
-               }
-       }
-       /* match against call whitelist */
-       for (i = 0; i < ARRAY_SIZE(call_whitelist); i++) {
-               if (buffer->cmd_class != call_whitelist[i].cmd_class)
-                       continue;
-               if (buffer->cmd_select != call_whitelist[i].cmd_select)
-                       continue;
-               if (!call_whitelist[i].need_capability ||
-                   capable(call_whitelist[i].need_capability)) {
-                       dev_dbg(d, "whitelisted capable command: %u/%u\n",
-                       buffer->cmd_class, buffer->cmd_select);
-                       return 0;
-               }
-               dev_dbg(d, "missing capability %d for %u/%u\n",
-                       call_whitelist[i].need_capability,
-                       buffer->cmd_class, buffer->cmd_select);
-
-       }
-
-       /* not in a whitelist, only allow processes with capabilities */
-       if (capable(CAP_SYS_RAWIO)) {
-               dev_dbg(d, "Allowing %u/%u due to CAP_SYS_RAWIO\n",
-                       buffer->cmd_class, buffer->cmd_select);
-               return 0;
-       }
-
-       return -EACCES;
-}
-EXPORT_SYMBOL_GPL(dell_smbios_call_filter);
-
-int dell_smbios_call(struct calling_interface_buffer *buffer)
-{
-       int (*call_fn)(struct calling_interface_buffer *) = NULL;
-       struct device *selected_dev = NULL;
-       struct smbios_device *priv;
-       int ret;
-
-       mutex_lock(&smbios_mutex);
-       list_for_each_entry(priv, &smbios_device_list, list) {
-               if (!selected_dev || priv->device->id >= selected_dev->id) {
-                       dev_dbg(priv->device, "Trying device ID: %d\n",
-                               priv->device->id);
-                       call_fn = priv->call_fn;
-                       selected_dev = priv->device;
-               }
-       }
-
-       if (!selected_dev) {
-               ret = -ENODEV;
-               pr_err("No dell-smbios drivers are loaded\n");
-               goto out_smbios_call;
-       }
-
-       ret = call_fn(buffer);
-
-out_smbios_call:
-       mutex_unlock(&smbios_mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(dell_smbios_call);
-
-struct calling_interface_token *dell_smbios_find_token(int tokenid)
-{
-       int i;
-
-       for (i = 0; i < da_num_tokens; i++) {
-               if (da_tokens[i].tokenID == tokenid)
-                       return &da_tokens[i];
-       }
-
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(dell_smbios_find_token);
-
-static BLOCKING_NOTIFIER_HEAD(dell_laptop_chain_head);
-
-int dell_laptop_register_notifier(struct notifier_block *nb)
-{
-       return blocking_notifier_chain_register(&dell_laptop_chain_head, nb);
-}
-EXPORT_SYMBOL_GPL(dell_laptop_register_notifier);
-
-int dell_laptop_unregister_notifier(struct notifier_block *nb)
-{
-       return blocking_notifier_chain_unregister(&dell_laptop_chain_head, nb);
-}
-EXPORT_SYMBOL_GPL(dell_laptop_unregister_notifier);
-
-void dell_laptop_call_notifier(unsigned long action, void *data)
-{
-       blocking_notifier_call_chain(&dell_laptop_chain_head, action, data);
-}
-EXPORT_SYMBOL_GPL(dell_laptop_call_notifier);
-
-static void __init parse_da_table(const struct dmi_header *dm)
-{
-       /* Final token is a terminator, so we don't want to copy it */
-       int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1;
-       struct calling_interface_token *new_da_tokens;
-       struct calling_interface_structure *table =
-               container_of(dm, struct calling_interface_structure, header);
-
-       /* 4 bytes of table header, plus 7 bytes of Dell header, plus at least
-          6 bytes of entry */
-
-       if (dm->length < 17)
-               return;
-
-       da_supported_commands = table->supportedCmds;
-
-       new_da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) *
-                                sizeof(struct calling_interface_token),
-                                GFP_KERNEL);
-
-       if (!new_da_tokens)
-               return;
-       da_tokens = new_da_tokens;
-
-       memcpy(da_tokens+da_num_tokens, table->tokens,
-              sizeof(struct calling_interface_token) * tokens);
-
-       da_num_tokens += tokens;
-}
-
-static void zero_duplicates(struct device *dev)
-{
-       int i, j;
-
-       for (i = 0; i < da_num_tokens; i++) {
-               if (da_tokens[i].tokenID == 0)
-                       continue;
-               for (j = i+1; j < da_num_tokens; j++) {
-                       if (da_tokens[j].tokenID == 0)
-                               continue;
-                       if (da_tokens[i].tokenID == da_tokens[j].tokenID) {
-                               dev_dbg(dev, "Zeroing dup token ID %x(%x/%x)\n",
-                                       da_tokens[j].tokenID,
-                                       da_tokens[j].location,
-                                       da_tokens[j].value);
-                               da_tokens[j].tokenID = 0;
-                       }
-               }
-       }
-}
-
-static void __init find_tokens(const struct dmi_header *dm, void *dummy)
-{
-       switch (dm->type) {
-       case 0xd4: /* Indexed IO */
-       case 0xd5: /* Protected Area Type 1 */
-       case 0xd6: /* Protected Area Type 2 */
-               break;
-       case 0xda: /* Calling interface */
-               parse_da_table(dm);
-               break;
-       }
-}
-
-static int match_attribute(struct device *dev,
-                          struct device_attribute *attr)
-{
-       int i;
-
-       for (i = 0; i < da_num_tokens * 2; i++) {
-               if (!token_attrs[i])
-                       continue;
-               if (strcmp(token_attrs[i]->name, attr->attr.name) == 0)
-                       return i/2;
-       }
-       dev_dbg(dev, "couldn't match: %s\n", attr->attr.name);
-       return -EINVAL;
-}
-
-static ssize_t location_show(struct device *dev,
-                            struct device_attribute *attr, char *buf)
-{
-       int i;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       i = match_attribute(dev, attr);
-       if (i > 0)
-               return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].location);
-       return 0;
-}
-
-static ssize_t value_show(struct device *dev,
-                         struct device_attribute *attr, char *buf)
-{
-       int i;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       i = match_attribute(dev, attr);
-       if (i > 0)
-               return scnprintf(buf, PAGE_SIZE, "%08x", da_tokens[i].value);
-       return 0;
-}
-
-static struct attribute_group smbios_attribute_group = {
-       .name = "tokens"
-};
-
-static struct platform_driver platform_driver = {
-       .driver = {
-               .name = "dell-smbios",
-       },
-};
-
-static int build_tokens_sysfs(struct platform_device *dev)
-{
-       char *location_name;
-       char *value_name;
-       size_t size;
-       int ret;
-       int i, j;
-
-       /* (number of tokens  + 1 for null terminated */
-       size = sizeof(struct device_attribute) * (da_num_tokens + 1);
-       token_location_attrs = kzalloc(size, GFP_KERNEL);
-       if (!token_location_attrs)
-               return -ENOMEM;
-       token_value_attrs = kzalloc(size, GFP_KERNEL);
-       if (!token_value_attrs)
-               goto out_allocate_value;
-
-       /* need to store both location and value + terminator*/
-       size = sizeof(struct attribute *) * ((2 * da_num_tokens) + 1);
-       token_attrs = kzalloc(size, GFP_KERNEL);
-       if (!token_attrs)
-               goto out_allocate_attrs;
-
-       for (i = 0, j = 0; i < da_num_tokens; i++) {
-               /* skip empty */
-               if (da_tokens[i].tokenID == 0)
-                       continue;
-               /* add location */
-               location_name = kasprintf(GFP_KERNEL, "%04x_location",
-                                         da_tokens[i].tokenID);
-               if (location_name == NULL)
-                       goto out_unwind_strings;
-               sysfs_attr_init(&token_location_attrs[i].attr);
-               token_location_attrs[i].attr.name = location_name;
-               token_location_attrs[i].attr.mode = 0444;
-               token_location_attrs[i].show = location_show;
-               token_attrs[j++] = &token_location_attrs[i].attr;
-
-               /* add value */
-               value_name = kasprintf(GFP_KERNEL, "%04x_value",
-                                      da_tokens[i].tokenID);
-               if (value_name == NULL)
-                       goto loop_fail_create_value;
-               sysfs_attr_init(&token_value_attrs[i].attr);
-               token_value_attrs[i].attr.name = value_name;
-               token_value_attrs[i].attr.mode = 0444;
-               token_value_attrs[i].show = value_show;
-               token_attrs[j++] = &token_value_attrs[i].attr;
-               continue;
-
-loop_fail_create_value:
-               kfree(value_name);
-               goto out_unwind_strings;
-       }
-       smbios_attribute_group.attrs = token_attrs;
-
-       ret = sysfs_create_group(&dev->dev.kobj, &smbios_attribute_group);
-       if (ret)
-               goto out_unwind_strings;
-       return 0;
-
-out_unwind_strings:
-       for (i = i-1; i > 0; i--) {
-               kfree(token_location_attrs[i].attr.name);
-               kfree(token_value_attrs[i].attr.name);
-       }
-       kfree(token_attrs);
-out_allocate_attrs:
-       kfree(token_value_attrs);
-out_allocate_value:
-       kfree(token_location_attrs);
-
-       return -ENOMEM;
-}
-
-static void free_group(struct platform_device *pdev)
-{
-       int i;
-
-       sysfs_remove_group(&pdev->dev.kobj,
-                               &smbios_attribute_group);
-       for (i = 0; i < da_num_tokens; i++) {
-               kfree(token_location_attrs[i].attr.name);
-               kfree(token_value_attrs[i].attr.name);
-       }
-       kfree(token_attrs);
-       kfree(token_value_attrs);
-       kfree(token_location_attrs);
-}
-
-static int __init dell_smbios_init(void)
-{
-       const struct dmi_device *valid;
-       int ret;
-
-       valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL);
-       if (!valid) {
-               pr_err("Unable to run on non-Dell system\n");
-               return -ENODEV;
-       }
-
-       dmi_walk(find_tokens, NULL);
-
-       if (!da_tokens)  {
-               pr_info("Unable to find dmi tokens\n");
-               return -ENODEV;
-       }
-
-       ret = platform_driver_register(&platform_driver);
-       if (ret)
-               goto fail_platform_driver;
-
-       platform_device = platform_device_alloc("dell-smbios", 0);
-       if (!platform_device) {
-               ret = -ENOMEM;
-               goto fail_platform_device_alloc;
-       }
-       ret = platform_device_add(platform_device);
-       if (ret)
-               goto fail_platform_device_add;
-
-       /* duplicate tokens will cause problems building sysfs files */
-       zero_duplicates(&platform_device->dev);
-
-       ret = build_tokens_sysfs(platform_device);
-       if (ret)
-               goto fail_create_group;
-
-       return 0;
-
-fail_create_group:
-       platform_device_del(platform_device);
-
-fail_platform_device_add:
-       platform_device_put(platform_device);
-
-fail_platform_device_alloc:
-       platform_driver_unregister(&platform_driver);
-
-fail_platform_driver:
-       kfree(da_tokens);
-       return ret;
-}
-
-static void __exit dell_smbios_exit(void)
-{
-       mutex_lock(&smbios_mutex);
-       if (platform_device) {
-               free_group(platform_device);
-               platform_device_unregister(platform_device);
-               platform_driver_unregister(&platform_driver);
-       }
-       kfree(da_tokens);
-       mutex_unlock(&smbios_mutex);
-}
-
-subsys_initcall(dell_smbios_init);
-module_exit(dell_smbios_exit);
-
-MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
-MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
-MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
-MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS");
-MODULE_LICENSE("GPL");
index 138d478d9adc91bdceee7194567cbe40718ec1f7..d8adaf9597409e1ee4ebf9cc6043e6e1f7095cb4 100644 (file)
@@ -75,4 +75,29 @@ int dell_laptop_register_notifier(struct notifier_block *nb);
 int dell_laptop_unregister_notifier(struct notifier_block *nb);
 void dell_laptop_call_notifier(unsigned long action, void *data);
 
-#endif
+/* for the supported backends */
+#ifdef CONFIG_DELL_SMBIOS_WMI
+int init_dell_smbios_wmi(void);
+void exit_dell_smbios_wmi(void);
+#else /* CONFIG_DELL_SMBIOS_WMI */
+static inline int init_dell_smbios_wmi(void)
+{
+       return -ENODEV;
+}
+static inline void exit_dell_smbios_wmi(void)
+{}
+#endif /* CONFIG_DELL_SMBIOS_WMI */
+
+#ifdef CONFIG_DELL_SMBIOS_SMM
+int init_dell_smbios_smm(void);
+void exit_dell_smbios_smm(void);
+#else /* CONFIG_DELL_SMBIOS_SMM */
+static inline int init_dell_smbios_smm(void)
+{
+       return -ENODEV;
+}
+static inline void exit_dell_smbios_smm(void)
+{}
+#endif /* CONFIG_DELL_SMBIOS_SMM */
+
+#endif /* _DELL_SMBIOS_H_ */
index 2c9927430d8525bc7df26c50de85e5a2fd8863d1..8d102195a3927fa4bf76f4230d069d6038414923 100644 (file)
@@ -714,7 +714,7 @@ static int __init dell_wmi_init(void)
 
        return wmi_driver_register(&dell_wmi_driver);
 }
-module_init(dell_wmi_init);
+late_initcall(dell_wmi_init);
 
 static void __exit dell_wmi_exit(void)
 {
index 5b6f18b188012dcc94b19c9156ee54b42650473b..535199c9e6bc6fa182ea9612fcabf85a7ba02ba8 100644 (file)
@@ -113,7 +113,7 @@ MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
 /*
  * ACPI Helpers
  */
-#define IDEAPAD_EC_TIMEOUT (100) /* in ms */
+#define IDEAPAD_EC_TIMEOUT (200) /* in ms */
 
 static int read_method_int(acpi_handle handle, const char *method, int *val)
 {
index d1a01311c1a2937b6863bea6b696566e376f8ac1..5e3df194723e1a1f1757fff08dd3c89069381350 100644 (file)
@@ -376,6 +376,7 @@ static int intel_hid_remove(struct platform_device *device)
 {
        acpi_handle handle = ACPI_HANDLE(&device->dev);
 
+       device_init_wakeup(&device->dev, false);
        acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
        intel_hid_set_enable(&device->dev, false);
        intel_button_array_enable(&device->dev, false);
index b703d6f5b099b3d0d74b77d60d2e5401ff3b816e..c13780b8dabbe089c24a2b5c323f1510f589153e 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 #include <linux/kernel.h>
@@ -97,9 +98,35 @@ out_unknown:
        dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
 }
 
-static int intel_vbtn_probe(struct platform_device *device)
+static void detect_tablet_mode(struct platform_device *device)
 {
+       const char *chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
+       struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+       acpi_handle handle = ACPI_HANDLE(&device->dev);
        struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *obj;
+       acpi_status status;
+       int m;
+
+       if (!(chassis_type && strcmp(chassis_type, "31") == 0))
+               goto out;
+
+       status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output);
+       if (ACPI_FAILURE(status))
+               goto out;
+
+       obj = vgbs_output.pointer;
+       if (!(obj && obj->type == ACPI_TYPE_INTEGER))
+               goto out;
+
+       m = !(obj->integer.value & TABLET_MODE_FLAG);
+       input_report_switch(priv->input_dev, SW_TABLET_MODE, m);
+out:
+       kfree(vgbs_output.pointer);
+}
+
+static int intel_vbtn_probe(struct platform_device *device)
+{
        acpi_handle handle = ACPI_HANDLE(&device->dev);
        struct intel_vbtn_priv *priv;
        acpi_status status;
@@ -122,22 +149,7 @@ 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);
+       detect_tablet_mode(device);
 
        status = acpi_install_notify_handler(handle,
                                             ACPI_DEVICE_NOTIFY,
@@ -154,6 +166,7 @@ static int intel_vbtn_remove(struct platform_device *device)
 {
        acpi_handle handle = ACPI_HANDLE(&device->dev);
 
+       device_init_wakeup(&device->dev, false);
        acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);
 
        /*
index daa68acbc9003b34615fc43b810c5fb77dd87ecf..8796211ef24acdab6e20f976716c18577d5a8fed 100644 (file)
@@ -933,7 +933,7 @@ static int wmi_dev_probe(struct device *dev)
                        goto probe_failure;
                }
 
-               buf = kmalloc(strlen(wdriver->driver.name) + 4, GFP_KERNEL);
+               buf = kmalloc(strlen(wdriver->driver.name) + 5, GFP_KERNEL);
                if (!buf) {
                        ret = -ENOMEM;
                        goto probe_string_failure;
@@ -945,7 +945,7 @@ static int wmi_dev_probe(struct device *dev)
                wblock->char_dev.mode = 0444;
                ret = misc_register(&wblock->char_dev);
                if (ret) {
-                       dev_warn(dev, "failed to register char dev: %d", ret);
+                       dev_warn(dev, "failed to register char dev: %d\n", ret);
                        ret = -ENOMEM;
                        goto probe_misc_failure;
                }
@@ -1048,7 +1048,7 @@ static int wmi_create_device(struct device *wmi_bus_dev,
 
        if (result) {
                dev_warn(wmi_bus_dev,
-                        "%s data block query control method not found",
+                        "%s data block query control method not found\n",
                         method);
                return result;
        }
@@ -1198,7 +1198,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
 
                retval = device_add(&wblock->dev.dev);
                if (retval) {
-                       dev_err(wmi_bus_dev, "failed to register %pULL\n",
+                       dev_err(wmi_bus_dev, "failed to register %pUL\n",
                                wblock->gblock.guid);
                        if (debug_event)
                                wmi_method_enable(wblock, 0);
index dd4708c58480d277e0346f9b287831b080f8af6b..1fc0c0811da4e9f2e528c21cbc4578bbe5a32077 100644 (file)
@@ -4310,7 +4310,7 @@ static int _regulator_resume_early(struct device *dev, void *data)
 
        rstate = regulator_get_suspend_state(rdev, *state);
        if (rstate == NULL)
-               return -EINVAL;
+               return 0;
 
        mutex_lock(&rdev->mutex);
 
index 72c8b3e1022b4da5c83e90d20b0166f577aeced6..e0a9c445ed67ba39554e26d29dd9dc5dec3a5efd 100644 (file)
@@ -51,7 +51,7 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
         * arbitrary timeout.
         */
        ret = readl_poll_timeout(priv->base + STM32_VREFBUF_CSR, val,
-                                !(val & STM32_VRR), 650, 10000);
+                                val & STM32_VRR, 650, 10000);
        if (ret) {
                dev_err(&rdev->dev, "stm32 vrefbuf timed out!\n");
                val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
index a7c15f0085e2999787a391327db0f6398d4c2cf0..ecef8e73d40b2f845a9048151870778032fb6f18 100644 (file)
@@ -2581,8 +2581,6 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
        case DASD_CQR_QUEUED:
                /* request was not started - just set to cleared */
                cqr->status = DASD_CQR_CLEARED;
-               if (cqr->callback_data == DASD_SLEEPON_START_TAG)
-                       cqr->callback_data = DASD_SLEEPON_END_TAG;
                break;
        case DASD_CQR_IN_IO:
                /* request in IO - terminate IO and release again */
@@ -3902,9 +3900,12 @@ static int dasd_generic_requeue_all_requests(struct dasd_device *device)
                wait_event(dasd_flush_wq,
                           (cqr->status != DASD_CQR_CLEAR_PENDING));
 
-               /* mark sleepon requests as ended */
-               if (cqr->callback_data == DASD_SLEEPON_START_TAG)
-                       cqr->callback_data = DASD_SLEEPON_END_TAG;
+               /*
+                * requeue requests to blocklayer will only work
+                * for block device requests
+                */
+               if (_dasd_requeue_request(cqr))
+                       continue;
 
                /* remove requests from device and block queue */
                list_del_init(&cqr->devlist);
@@ -3917,13 +3918,6 @@ static int dasd_generic_requeue_all_requests(struct dasd_device *device)
                        cqr = refers;
                }
 
-               /*
-                * requeue requests to blocklayer will only work
-                * for block device requests
-                */
-               if (_dasd_requeue_request(cqr))
-                       continue;
-
                if (cqr->block)
                        list_del_init(&cqr->blocklist);
                cqr->block->base->discipline->free_cp(
@@ -3940,8 +3934,7 @@ static int dasd_generic_requeue_all_requests(struct dasd_device *device)
                list_splice_tail(&requeue_queue, &device->ccw_queue);
                spin_unlock_irq(get_ccwdev_lock(device->cdev));
        }
-       /* wake up generic waitqueue for eventually ended sleepon requests */
-       wake_up(&generic_waitq);
+       dasd_schedule_device_bh(device);
        return rc;
 }
 
index 1319122e9d1231920ef0325a9e56a4c6de91ff80..9169af7dbb434ff5269406a85200c9796c04a8e4 100644 (file)
@@ -795,6 +795,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
 
        ccw_device_set_timeout(cdev, 0);
        cdev->private->iretry = 255;
+       cdev->private->async_kill_io_rc = -ETIMEDOUT;
        ret = ccw_device_cancel_halt_clear(cdev);
        if (ret == -EBUSY) {
                ccw_device_set_timeout(cdev, 3*HZ);
@@ -871,7 +872,7 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
        /* OK, i/o is dead now. Call interrupt handler. */
        if (cdev->handler)
                cdev->handler(cdev, cdev->private->intparm,
-                             ERR_PTR(-EIO));
+                             ERR_PTR(cdev->private->async_kill_io_rc));
 }
 
 static void
@@ -888,14 +889,16 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
        ccw_device_online_verify(cdev, 0);
        if (cdev->handler)
                cdev->handler(cdev, cdev->private->intparm,
-                             ERR_PTR(-EIO));
+                             ERR_PTR(cdev->private->async_kill_io_rc));
 }
 
 void ccw_device_kill_io(struct ccw_device *cdev)
 {
        int ret;
 
+       ccw_device_set_timeout(cdev, 0);
        cdev->private->iretry = 255;
+       cdev->private->async_kill_io_rc = -EIO;
        ret = ccw_device_cancel_halt_clear(cdev);
        if (ret == -EBUSY) {
                ccw_device_set_timeout(cdev, 3*HZ);
index 1caf6a398760bb1f156f5c088759f12e6039e589..75ce12a24dc2a6a6dfdb756fce5ae6c148de20f6 100644 (file)
@@ -159,7 +159,7 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
 }
 
 /**
- * ccw_device_start_key() - start a s390 channel program with key
+ * ccw_device_start_timeout_key() - start a s390 channel program with timeout and key
  * @cdev: target ccw device
  * @cpa: logical start address of channel program
  * @intparm: user specific interruption parameter; will be presented back to
@@ -170,10 +170,15 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
  * @key: storage key to be used for the I/O
  * @flags: additional flags; defines the action to be performed for I/O
  *        processing.
+ * @expires: timeout value in jiffies
  *
  * Start a S/390 channel program. When the interrupt arrives, the
  * IRQ handler is called, either immediately, delayed (dev-end missing,
  * or sense required) or never (no IRQ handler registered).
+ * This function notifies the device driver if the channel program has not
+ * completed during the time specified by @expires. If a timeout occurs, the
+ * channel program is terminated via xsch, hsch or csch, and the device's
+ * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
  * Returns:
  *  %0, if the operation was successful;
  *  -%EBUSY, if the device is busy, or status pending;
@@ -182,9 +187,9 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
  * Context:
  *  Interrupts disabled, ccw device lock held
  */
-int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
-                        unsigned long intparm, __u8 lpm, __u8 key,
-                        unsigned long flags)
+int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
+                                unsigned long intparm, __u8 lpm, __u8 key,
+                                unsigned long flags, int expires)
 {
        struct subchannel *sch;
        int ret;
@@ -224,6 +229,8 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
        switch (ret) {
        case 0:
                cdev->private->intparm = intparm;
+               if (expires)
+                       ccw_device_set_timeout(cdev, expires);
                break;
        case -EACCES:
        case -ENODEV:
@@ -234,7 +241,7 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
 }
 
 /**
- * ccw_device_start_timeout_key() - start a s390 channel program with timeout and key
+ * ccw_device_start_key() - start a s390 channel program with key
  * @cdev: target ccw device
  * @cpa: logical start address of channel program
  * @intparm: user specific interruption parameter; will be presented back to
@@ -245,15 +252,10 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
  * @key: storage key to be used for the I/O
  * @flags: additional flags; defines the action to be performed for I/O
  *        processing.
- * @expires: timeout value in jiffies
  *
  * Start a S/390 channel program. When the interrupt arrives, the
  * IRQ handler is called, either immediately, delayed (dev-end missing,
  * or sense required) or never (no IRQ handler registered).
- * This function notifies the device driver if the channel program has not
- * completed during the time specified by @expires. If a timeout occurs, the
- * channel program is terminated via xsch, hsch or csch, and the device's
- * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
  * Returns:
  *  %0, if the operation was successful;
  *  -%EBUSY, if the device is busy, or status pending;
@@ -262,19 +264,12 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
  * Context:
  *  Interrupts disabled, ccw device lock held
  */
-int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
-                                unsigned long intparm, __u8 lpm, __u8 key,
-                                unsigned long flags, int expires)
+int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
+                        unsigned long intparm, __u8 lpm, __u8 key,
+                        unsigned long flags)
 {
-       int ret;
-
-       if (!cdev)
-               return -ENODEV;
-       ccw_device_set_timeout(cdev, expires);
-       ret = ccw_device_start_key(cdev, cpa, intparm, lpm, key, flags);
-       if (ret != 0)
-               ccw_device_set_timeout(cdev, 0);
-       return ret;
+       return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, key,
+                                           flags, 0);
 }
 
 /**
@@ -489,18 +484,20 @@ void ccw_device_get_id(struct ccw_device *cdev, struct ccw_dev_id *dev_id)
 EXPORT_SYMBOL(ccw_device_get_id);
 
 /**
- * ccw_device_tm_start_key() - perform start function
+ * ccw_device_tm_start_timeout_key() - perform start function
  * @cdev: ccw device on which to perform the start function
  * @tcw: transport-command word to be started
  * @intparm: user defined parameter to be passed to the interrupt handler
  * @lpm: mask of paths to use
  * @key: storage key to use for storage access
+ * @expires: time span in jiffies after which to abort request
  *
  * Start the tcw on the given ccw device. Return zero on success, non-zero
  * otherwise.
  */
-int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
-                           unsigned long intparm, u8 lpm, u8 key)
+int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
+                                   unsigned long intparm, u8 lpm, u8 key,
+                                   int expires)
 {
        struct subchannel *sch;
        int rc;
@@ -527,37 +524,32 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
                        return -EACCES;
        }
        rc = cio_tm_start_key(sch, tcw, lpm, key);
-       if (rc == 0)
+       if (rc == 0) {
                cdev->private->intparm = intparm;
+               if (expires)
+                       ccw_device_set_timeout(cdev, expires);
+       }
        return rc;
 }
-EXPORT_SYMBOL(ccw_device_tm_start_key);
+EXPORT_SYMBOL(ccw_device_tm_start_timeout_key);
 
 /**
- * ccw_device_tm_start_timeout_key() - perform start function
+ * ccw_device_tm_start_key() - perform start function
  * @cdev: ccw device on which to perform the start function
  * @tcw: transport-command word to be started
  * @intparm: user defined parameter to be passed to the interrupt handler
  * @lpm: mask of paths to use
  * @key: storage key to use for storage access
- * @expires: time span in jiffies after which to abort request
  *
  * Start the tcw on the given ccw device. Return zero on success, non-zero
  * otherwise.
  */
-int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
-                                   unsigned long intparm, u8 lpm, u8 key,
-                                   int expires)
+int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
+                           unsigned long intparm, u8 lpm, u8 key)
 {
-       int ret;
-
-       ccw_device_set_timeout(cdev, expires);
-       ret = ccw_device_tm_start_key(cdev, tcw, intparm, lpm, key);
-       if (ret != 0)
-               ccw_device_set_timeout(cdev, 0);
-       return ret;
+       return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm, key, 0);
 }
-EXPORT_SYMBOL(ccw_device_tm_start_timeout_key);
+EXPORT_SYMBOL(ccw_device_tm_start_key);
 
 /**
  * ccw_device_tm_start() - perform start function
index af571d8d6925e7a8bb4f35db7e0a7c8aff1bdbf8..90e4e3a7841be1b23e833809587096dc9290f16e 100644 (file)
@@ -157,6 +157,7 @@ struct ccw_device_private {
        unsigned long intparm;  /* user interruption parameter */
        struct qdio_irq *qdio_data;
        struct irb irb;         /* device status */
+       int async_kill_io_rc;
        struct senseid senseid; /* SenseID info */
        struct pgid pgid[8];    /* path group IDs per chpid*/
        struct ccw1 iccws[2];   /* ccws for SNID/SID/SPGID commands */
index ca72f3311004a3d020ed07266596ff63ce740b26..3653bea384705f1b1a27df45a94db33148194e1f 100644 (file)
@@ -527,8 +527,7 @@ static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue)
            queue == card->qdio.no_in_queues - 1;
 }
 
-
-static int qeth_issue_next_read(struct qeth_card *card)
+static int __qeth_issue_next_read(struct qeth_card *card)
 {
        int rc;
        struct qeth_cmd_buffer *iob;
@@ -559,6 +558,17 @@ static int qeth_issue_next_read(struct qeth_card *card)
        return rc;
 }
 
+static int qeth_issue_next_read(struct qeth_card *card)
+{
+       int ret;
+
+       spin_lock_irq(get_ccwdev_lock(CARD_RDEV(card)));
+       ret = __qeth_issue_next_read(card);
+       spin_unlock_irq(get_ccwdev_lock(CARD_RDEV(card)));
+
+       return ret;
+}
+
 static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
 {
        struct qeth_reply *reply;
@@ -960,7 +970,7 @@ void qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
        spin_lock_irqsave(&card->thread_mask_lock, flags);
        card->thread_running_mask &= ~thread;
        spin_unlock_irqrestore(&card->thread_mask_lock, flags);
-       wake_up(&card->wait_q);
+       wake_up_all(&card->wait_q);
 }
 EXPORT_SYMBOL_GPL(qeth_clear_thread_running_bit);
 
@@ -1164,6 +1174,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                }
                rc = qeth_get_problem(cdev, irb);
                if (rc) {
+                       card->read_or_write_problem = 1;
                        qeth_clear_ipacmd_list(card);
                        qeth_schedule_recovery(card);
                        goto out;
@@ -1182,7 +1193,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                return;
        if (channel == &card->read &&
            channel->state == CH_STATE_UP)
-               qeth_issue_next_read(card);
+               __qeth_issue_next_read(card);
 
        iob = channel->iob;
        index = channel->buf_no;
@@ -2134,24 +2145,25 @@ int qeth_send_control_data(struct qeth_card *card, int len,
        }
        reply->callback = reply_cb;
        reply->param = reply_param;
-       if (card->state == CARD_STATE_DOWN)
-               reply->seqno = QETH_IDX_COMMAND_SEQNO;
-       else
-               reply->seqno = card->seqno.ipa++;
+
        init_waitqueue_head(&reply->wait_q);
-       spin_lock_irqsave(&card->lock, flags);
-       list_add_tail(&reply->list, &card->cmd_waiter_list);
-       spin_unlock_irqrestore(&card->lock, flags);
 
        while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
-       qeth_prepare_control_data(card, len, iob);
 
        if (IS_IPA(iob->data)) {
                cmd = __ipa_cmd(iob);
+               cmd->hdr.seqno = card->seqno.ipa++;
+               reply->seqno = cmd->hdr.seqno;
                event_timeout = QETH_IPA_TIMEOUT;
        } else {
+               reply->seqno = QETH_IDX_COMMAND_SEQNO;
                event_timeout = QETH_TIMEOUT;
        }
+       qeth_prepare_control_data(card, len, iob);
+
+       spin_lock_irqsave(&card->lock, flags);
+       list_add_tail(&reply->list, &card->cmd_waiter_list);
+       spin_unlock_irqrestore(&card->lock, flags);
 
        timeout = jiffies + event_timeout;
 
@@ -2933,7 +2945,7 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card,
        memset(cmd, 0, sizeof(struct qeth_ipa_cmd));
        cmd->hdr.command = command;
        cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
-       cmd->hdr.seqno = card->seqno.ipa;
+       /* cmd->hdr.seqno is set by qeth_send_control_data() */
        cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
        cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
        if (card->options.layer2)
@@ -3898,10 +3910,12 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
 int qeth_get_elements_no(struct qeth_card *card,
                     struct sk_buff *skb, int extra_elems, int data_offset)
 {
-       int elements = qeth_get_elements_for_range(
-                               (addr_t)skb->data + data_offset,
-                               (addr_t)skb->data + skb_headlen(skb)) +
-                       qeth_get_elements_for_frags(skb);
+       addr_t end = (addr_t)skb->data + skb_headlen(skb);
+       int elements = qeth_get_elements_for_frags(skb);
+       addr_t start = (addr_t)skb->data + data_offset;
+
+       if (start != end)
+               elements += qeth_get_elements_for_range(start, end);
 
        if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
                QETH_DBF_MESSAGE(2, "Invalid size of IP packet "
@@ -5084,8 +5098,6 @@ static void qeth_core_free_card(struct qeth_card *card)
        QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
        qeth_clean_channel(&card->read);
        qeth_clean_channel(&card->write);
-       if (card->dev)
-               free_netdev(card->dev);
        qeth_free_qdio_buffers(card);
        unregister_service_level(&card->qeth_service_level);
        kfree(card);
index 7f236440483f2ca6fdc82caf5d21b649f8434471..5ef4c978ad199fdb4e5f3209c06acdc8e2369b94 100644 (file)
@@ -915,8 +915,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
                qeth_l2_set_offline(cgdev);
 
        if (card->dev) {
-               netif_napi_del(&card->napi);
                unregister_netdev(card->dev);
+               free_netdev(card->dev);
                card->dev = NULL;
        }
        return;
index bdd45f4dcacecc11b9334c94c717e6cc08b6c84c..498fe9af2cdb90bd28dd9cdfb788e747e6cc0b53 100644 (file)
@@ -40,8 +40,40 @@ struct qeth_ipaddr {
                        unsigned int pfxlen;
                } a6;
        } u;
-
 };
+
+static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1,
+                                        struct qeth_ipaddr *a2)
+{
+       if (a1->proto != a2->proto)
+               return false;
+       if (a1->proto == QETH_PROT_IPV6)
+               return ipv6_addr_equal(&a1->u.a6.addr, &a2->u.a6.addr);
+       return a1->u.a4.addr == a2->u.a4.addr;
+}
+
+static inline bool qeth_l3_addr_match_all(struct qeth_ipaddr *a1,
+                                         struct qeth_ipaddr *a2)
+{
+       /* Assumes that the pair was obtained via qeth_l3_addr_find_by_ip(),
+        * so 'proto' and 'addr' match for sure.
+        *
+        * For ucast:
+        * -    'mac' is always 0.
+        * -    'mask'/'pfxlen' for RXIP/VIPA is always 0. For NORMAL, matching
+        *      values are required to avoid mixups in takeover eligibility.
+        *
+        * For mcast,
+        * -    'mac' is mapped from the IP, and thus always matches.
+        * -    'mask'/'pfxlen' is always 0.
+        */
+       if (a1->type != a2->type)
+               return false;
+       if (a1->proto == QETH_PROT_IPV6)
+               return a1->u.a6.pfxlen == a2->u.a6.pfxlen;
+       return a1->u.a4.mask == a2->u.a4.mask;
+}
+
 static inline  u64 qeth_l3_ipaddr_hash(struct qeth_ipaddr *addr)
 {
        u64  ret = 0;
index b0c888e86cd4a0980ff42e49f06d6022c93f4de7..b6b12220da7157d0b53a38d926f42313e2aade48 100644 (file)
@@ -67,6 +67,24 @@ void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
                qeth_l3_ipaddr6_to_string(addr, buf);
 }
 
+static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card,
+                                                  struct qeth_ipaddr *query)
+{
+       u64 key = qeth_l3_ipaddr_hash(query);
+       struct qeth_ipaddr *addr;
+
+       if (query->is_multicast) {
+               hash_for_each_possible(card->ip_mc_htable, addr, hnode, key)
+                       if (qeth_l3_addr_match_ip(addr, query))
+                               return addr;
+       } else {
+               hash_for_each_possible(card->ip_htable,  addr, hnode, key)
+                       if (qeth_l3_addr_match_ip(addr, query))
+                               return addr;
+       }
+       return NULL;
+}
+
 static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
 {
        int i, j;
@@ -120,34 +138,6 @@ static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
        return rc;
 }
 
-inline int
-qeth_l3_ipaddrs_is_equal(struct qeth_ipaddr *addr1, struct qeth_ipaddr *addr2)
-{
-       return addr1->proto == addr2->proto &&
-              !memcmp(&addr1->u, &addr2->u, sizeof(addr1->u)) &&
-              ether_addr_equal_64bits(addr1->mac, addr2->mac);
-}
-
-static struct qeth_ipaddr *
-qeth_l3_ip_from_hash(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
-{
-       struct qeth_ipaddr *addr;
-
-       if (tmp_addr->is_multicast) {
-               hash_for_each_possible(card->ip_mc_htable,  addr,
-                               hnode, qeth_l3_ipaddr_hash(tmp_addr))
-                       if (qeth_l3_ipaddrs_is_equal(tmp_addr, addr))
-                               return addr;
-       } else {
-               hash_for_each_possible(card->ip_htable,  addr,
-                               hnode, qeth_l3_ipaddr_hash(tmp_addr))
-                       if (qeth_l3_ipaddrs_is_equal(tmp_addr, addr))
-                               return addr;
-       }
-
-       return NULL;
-}
-
 int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
 {
        int rc = 0;
@@ -162,23 +152,18 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
                QETH_CARD_HEX(card, 4, ((char *)&tmp_addr->u.a6.addr) + 8, 8);
        }
 
-       addr = qeth_l3_ip_from_hash(card, tmp_addr);
-       if (!addr)
+       addr = qeth_l3_find_addr_by_ip(card, tmp_addr);
+       if (!addr || !qeth_l3_addr_match_all(addr, tmp_addr))
                return -ENOENT;
 
        addr->ref_counter--;
-       if (addr->ref_counter > 0 && (addr->type == QETH_IP_TYPE_NORMAL ||
-                                     addr->type == QETH_IP_TYPE_RXIP))
+       if (addr->type == QETH_IP_TYPE_NORMAL && addr->ref_counter > 0)
                return rc;
        if (addr->in_progress)
                return -EINPROGRESS;
 
-       if (!qeth_card_hw_is_reachable(card)) {
-               addr->disp_flag = QETH_DISP_ADDR_DELETE;
-               return 0;
-       }
-
-       rc = qeth_l3_deregister_addr_entry(card, addr);
+       if (qeth_card_hw_is_reachable(card))
+               rc = qeth_l3_deregister_addr_entry(card, addr);
 
        hash_del(&addr->hnode);
        kfree(addr);
@@ -190,6 +175,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
 {
        int rc = 0;
        struct qeth_ipaddr *addr;
+       char buf[40];
 
        QETH_CARD_TEXT(card, 4, "addip");
 
@@ -200,8 +186,20 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
                QETH_CARD_HEX(card, 4, ((char *)&tmp_addr->u.a6.addr) + 8, 8);
        }
 
-       addr = qeth_l3_ip_from_hash(card, tmp_addr);
-       if (!addr) {
+       addr = qeth_l3_find_addr_by_ip(card, tmp_addr);
+       if (addr) {
+               if (tmp_addr->type != QETH_IP_TYPE_NORMAL)
+                       return -EADDRINUSE;
+               if (qeth_l3_addr_match_all(addr, tmp_addr)) {
+                       addr->ref_counter++;
+                       return 0;
+               }
+               qeth_l3_ipaddr_to_string(tmp_addr->proto, (u8 *)&tmp_addr->u,
+                                        buf);
+               dev_warn(&card->gdev->dev,
+                        "Registering IP address %s failed\n", buf);
+               return -EADDRINUSE;
+       } else {
                addr = qeth_l3_get_addr_buffer(tmp_addr->proto);
                if (!addr)
                        return -ENOMEM;
@@ -241,19 +239,15 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
                                (rc == IPA_RC_LAN_OFFLINE)) {
                        addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
                        if (addr->ref_counter < 1) {
-                               qeth_l3_delete_ip(card, addr);
+                               qeth_l3_deregister_addr_entry(card, addr);
+                               hash_del(&addr->hnode);
                                kfree(addr);
                        }
                } else {
                        hash_del(&addr->hnode);
                        kfree(addr);
                }
-       } else {
-               if (addr->type == QETH_IP_TYPE_NORMAL ||
-                   addr->type == QETH_IP_TYPE_RXIP)
-                       addr->ref_counter++;
        }
-
        return rc;
 }
 
@@ -321,11 +315,7 @@ static void qeth_l3_recover_ip(struct qeth_card *card)
        spin_lock_bh(&card->ip_lock);
 
        hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) {
-               if (addr->disp_flag == QETH_DISP_ADDR_DELETE) {
-                       qeth_l3_deregister_addr_entry(card, addr);
-                       hash_del(&addr->hnode);
-                       kfree(addr);
-               } else if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
+               if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
                        if (addr->proto == QETH_PROT_IPV4) {
                                addr->in_progress = 1;
                                spin_unlock_bh(&card->ip_lock);
@@ -643,12 +633,7 @@ int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
                return -ENOMEM;
 
        spin_lock_bh(&card->ip_lock);
-
-       if (qeth_l3_ip_from_hash(card, ipaddr))
-               rc = -EEXIST;
-       else
-               rc = qeth_l3_add_ip(card, ipaddr);
-
+       rc = qeth_l3_add_ip(card, ipaddr);
        spin_unlock_bh(&card->ip_lock);
 
        kfree(ipaddr);
@@ -713,12 +698,7 @@ int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
                return -ENOMEM;
 
        spin_lock_bh(&card->ip_lock);
-
-       if (qeth_l3_ip_from_hash(card, ipaddr))
-               rc = -EEXIST;
-       else
-               rc = qeth_l3_add_ip(card, ipaddr);
-
+       rc = qeth_l3_add_ip(card, ipaddr);
        spin_unlock_bh(&card->ip_lock);
 
        kfree(ipaddr);
@@ -1239,8 +1219,9 @@ qeth_l3_add_mc_to_hash(struct qeth_card *card, struct in_device *in4_dev)
                tmp->u.a4.addr = be32_to_cpu(im4->multiaddr);
                tmp->is_multicast = 1;
 
-               ipm = qeth_l3_ip_from_hash(card, tmp);
+               ipm = qeth_l3_find_addr_by_ip(card, tmp);
                if (ipm) {
+                       /* for mcast, by-IP match means full match */
                        ipm->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
                } else {
                        ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
@@ -1319,8 +1300,9 @@ static void qeth_l3_add_mc6_to_hash(struct qeth_card *card,
                       sizeof(struct in6_addr));
                tmp->is_multicast = 1;
 
-               ipm = qeth_l3_ip_from_hash(card, tmp);
+               ipm = qeth_l3_find_addr_by_ip(card, tmp);
                if (ipm) {
+                       /* for mcast, by-IP match means full match */
                        ipm->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
                        continue;
                }
@@ -2450,11 +2432,12 @@ static void qeth_tso_fill_header(struct qeth_card *card,
 static int qeth_l3_get_elements_no_tso(struct qeth_card *card,
                        struct sk_buff *skb, int extra_elems)
 {
-       addr_t tcpdptr = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
-       int elements = qeth_get_elements_for_range(
-                               tcpdptr,
-                               (addr_t)skb->data + skb_headlen(skb)) +
-                               qeth_get_elements_for_frags(skb);
+       addr_t start = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
+       addr_t end = (addr_t)skb->data + skb_headlen(skb);
+       int elements = qeth_get_elements_for_frags(skb);
+
+       if (start != end)
+               elements += qeth_get_elements_for_range(start, end);
 
        if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
                QETH_DBF_MESSAGE(2,
@@ -2882,8 +2865,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
                qeth_l3_set_offline(cgdev);
 
        if (card->dev) {
-               netif_napi_del(&card->napi);
                unregister_netdev(card->dev);
+               free_netdev(card->dev);
                card->dev = NULL;
        }
 
index ba2e0856d22cdfb5396457366276e01bc9ac7851..8f5c1d7f751aee594b763100c2bf6265df9f3a7d 100644 (file)
@@ -1297,6 +1297,9 @@ static int virtio_ccw_cio_notify(struct ccw_device *cdev, int event)
                vcdev->device_lost = true;
                rc = NOTIFY_DONE;
                break;
+       case CIO_OPER:
+               rc = NOTIFY_OK;
+               break;
        default:
                rc = NOTIFY_DONE;
                break;
@@ -1309,6 +1312,27 @@ static struct ccw_device_id virtio_ids[] = {
        {},
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int virtio_ccw_freeze(struct ccw_device *cdev)
+{
+       struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
+
+       return virtio_device_freeze(&vcdev->vdev);
+}
+
+static int virtio_ccw_restore(struct ccw_device *cdev)
+{
+       struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
+       int ret;
+
+       ret = virtio_ccw_set_transport_rev(vcdev);
+       if (ret)
+               return ret;
+
+       return virtio_device_restore(&vcdev->vdev);
+}
+#endif
+
 static struct ccw_driver virtio_ccw_driver = {
        .driver = {
                .owner = THIS_MODULE,
@@ -1321,6 +1345,11 @@ static struct ccw_driver virtio_ccw_driver = {
        .set_online = virtio_ccw_online,
        .notify = virtio_ccw_cio_notify,
        .int_class = IRQIO_VIR,
+#ifdef CONFIG_PM_SLEEP
+       .freeze = virtio_ccw_freeze,
+       .thaw = virtio_ccw_restore,
+       .restore = virtio_ccw_restore,
+#endif
 };
 
 static int __init pure_hex(char **cp, unsigned int *val, int min_digit,
index fcfd28d2884c546de6b26f1daf1d8773518291de..de1b3fce936d5d7d3ee70c2dabc3957e911b438f 100644 (file)
@@ -185,7 +185,6 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
 CFLAGS_ncr53c8xx.o     := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m)
 zalon7xx-objs  := zalon.o ncr53c8xx.o
 NCR_Q720_mod-objs      := NCR_Q720.o ncr53c8xx.o
-oktagon_esp_mod-objs   := oktagon_esp.o oktagon_io.o
 
 # Files generated that shall be removed upon make clean
 clean-files := 53c700_d.h 53c700_u.h
index b3b931ab77ebdfc2190b113489bb1bcf81edd623..2664ea0df35fa1384db54c3e8f0ff270cba09148 100644 (file)
@@ -1693,8 +1693,10 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
         *      Map in the registers from the adapter.
         */
        aac->base_size = AAC_MIN_FOOTPRINT_SIZE;
-       if ((*aac_drivers[index].init)(aac))
+       if ((*aac_drivers[index].init)(aac)) {
+               error = -ENODEV;
                goto out_unmap;
+       }
 
        if (aac->sync_mode) {
                if (aac_sync_mode)
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c
deleted file mode 100644 (file)
index 828ae3d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Implementation of Utility functions for all SCSI device types.
- *
- * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
- * Copyright (c) 1997, 1998 Kenneth D. Merry.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification, immediately at the beginning of the file.
- * 2. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $
- * $Id$
- */
-
-#include "aiclib.h"
-
index 8e2f767147cb43de2acdcabeab820537fc3422d3..5a645b8b9af170d66a2abd510393c5f5c5725aa8 100644 (file)
@@ -1889,6 +1889,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
                /* we will not receive ABTS response for this IO */
                BNX2FC_IO_DBG(io_req, "Timer context finished processing "
                           "this scsi cmd\n");
+               return;
        }
 
        /* Cancel the timeout_work, as we received IO completion */
index be5ee2d37815510226627261955f75d842711fd6..7dbbbb81a1e7de64fc3f8ad3079b4a5879153f39 100644 (file)
@@ -114,7 +114,7 @@ static enum csio_ln_ev fwevt_to_lnevt[] = {
 static struct csio_lnode *
 csio_ln_lookup_by_portid(struct csio_hw *hw, uint8_t portid)
 {
-       struct csio_lnode *ln = hw->rln;
+       struct csio_lnode *ln;
        struct list_head *tmp;
 
        /* Match siblings lnode with portid */
index 022e421c218513055f0e4033611736523751cbb6..4b44325d1a82868b94909240347c3d6258c5a794 100644 (file)
@@ -876,6 +876,11 @@ static void alua_rtpg_work(struct work_struct *work)
 
 /**
  * alua_rtpg_queue() - cause RTPG to be submitted asynchronously
+ * @pg: ALUA port group associated with @sdev.
+ * @sdev: SCSI device for which to submit an RTPG.
+ * @qdata: Information about the callback to invoke after the RTPG.
+ * @force: Whether or not to submit an RTPG if a work item that will submit an
+ *         RTPG already has been scheduled.
  *
  * Returns true if and only if alua_rtpg_work() will be called asynchronously.
  * That function is responsible for calling @qdata->fn().
index 57bf43e34863ec09c9c15217f7f02fa97711a75f..dd9464920456fd550f8da9bab2e345ae843d1d15 100644 (file)
@@ -328,8 +328,6 @@ static void scsi_host_dev_release(struct device *dev)
        if (shost->work_q)
                destroy_workqueue(shost->work_q);
 
-       destroy_rcu_head(&shost->rcu);
-
        if (shost->shost_state == SHOST_CREATED) {
                /*
                 * Free the shost_dev device name here if scsi_host_alloc()
@@ -404,7 +402,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
        INIT_LIST_HEAD(&shost->starved_list);
        init_waitqueue_head(&shost->host_wait);
        mutex_init(&shost->scan_mutex);
-       init_rcu_head(&shost->rcu);
 
        index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
        if (index < 0)
index 9a0696f68f37153a5b7647c0e5c22ac69574f583..b81a53c4a9a8b1020a96a85fd5e84cde2adb9900 100644 (file)
@@ -367,7 +367,7 @@ enum ibmvfc_fcp_rsp_info_codes {
 };
 
 struct ibmvfc_fcp_rsp_info {
-       __be16 reserved;
+       u8 reserved[3];
        u8 rsp_code;
        u8 reserved2[4];
 }__attribute__((packed, aligned (2)));
index 6de9681ace82603370005590238e315b36df19b4..ceab5e5c41c277a25f879348885be5fa847c4cd8 100644 (file)
@@ -223,6 +223,7 @@ out_done:
 static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
 {
        struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
+       struct domain_device *dev = cmd_to_domain_dev(cmd);
        struct sas_task *task = TO_SAS_TASK(cmd);
 
        /* At this point, we only get called following an actual abort
@@ -231,6 +232,14 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
         */
        sas_end_task(cmd, task);
 
+       if (dev_is_sata(dev)) {
+               /* defer commands to libata so that libata EH can
+                * handle ata qcs correctly
+                */
+               list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q);
+               return;
+       }
+
        /* now finish the command and move it on to the error
         * handler done list, this also takes it off the
         * error handler pending list.
@@ -238,22 +247,6 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
        scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
 }
 
-static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
-{
-       struct domain_device *dev = cmd_to_domain_dev(cmd);
-       struct sas_ha_struct *ha = dev->port->ha;
-       struct sas_task *task = TO_SAS_TASK(cmd);
-
-       if (!dev_is_sata(dev)) {
-               sas_eh_finish_cmd(cmd);
-               return;
-       }
-
-       /* report the timeout to libata */
-       sas_end_task(cmd, task);
-       list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
-}
-
 static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
 {
        struct scsi_cmnd *cmd, *n;
@@ -261,7 +254,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd
        list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
                if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
                    cmd->device->lun == my_cmd->device->lun)
-                       sas_eh_defer_cmd(cmd);
+                       sas_eh_finish_cmd(cmd);
        }
 }
 
@@ -631,12 +624,12 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *
                case TASK_IS_DONE:
                        SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
                                    task);
-                       sas_eh_defer_cmd(cmd);
+                       sas_eh_finish_cmd(cmd);
                        continue;
                case TASK_IS_ABORTED:
                        SAS_DPRINTK("%s: task 0x%p is aborted\n",
                                    __func__, task);
-                       sas_eh_defer_cmd(cmd);
+                       sas_eh_finish_cmd(cmd);
                        continue;
                case TASK_IS_AT_LU:
                        SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
@@ -647,7 +640,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *
                                            "recovered\n",
                                            SAS_ADDR(task->dev),
                                            cmd->device->lun);
-                               sas_eh_defer_cmd(cmd);
+                               sas_eh_finish_cmd(cmd);
                                sas_scsi_clear_queue_lu(work_q, cmd);
                                goto Again;
                        }
index 073ced07e662bc11bd00cdfc9d6214ec3a6a0b8e..dc8e850fbfd2217d1a64ea1ff9522bc2eeca3a40 100644 (file)
@@ -216,36 +216,30 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
 /**
  * megasas_fire_cmd_fusion -   Sends command to the FW
  * @instance:                  Adapter soft state
- * @req_desc:                  32bit or 64bit Request descriptor
+ * @req_desc:                  64bit Request descriptor
  *
- * Perform PCI Write. Ventura supports 32 bit Descriptor.
- * Prior to Ventura (12G) MR controller supports 64 bit Descriptor.
+ * Perform PCI Write.
  */
 
 static void
 megasas_fire_cmd_fusion(struct megasas_instance *instance,
                union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc)
 {
-       if (instance->adapter_type == VENTURA_SERIES)
-               writel(le32_to_cpu(req_desc->u.low),
-                       &instance->reg_set->inbound_single_queue_port);
-       else {
 #if defined(writeq) && defined(CONFIG_64BIT)
-               u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
-                               le32_to_cpu(req_desc->u.low));
+       u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
+               le32_to_cpu(req_desc->u.low));
 
-               writeq(req_data, &instance->reg_set->inbound_low_queue_port);
+       writeq(req_data, &instance->reg_set->inbound_low_queue_port);
 #else
-               unsigned long flags;
-               spin_lock_irqsave(&instance->hba_lock, flags);
-               writel(le32_to_cpu(req_desc->u.low),
-                       &instance->reg_set->inbound_low_queue_port);
-               writel(le32_to_cpu(req_desc->u.high),
-                       &instance->reg_set->inbound_high_queue_port);
-               mmiowb();
-               spin_unlock_irqrestore(&instance->hba_lock, flags);
+       unsigned long flags;
+       spin_lock_irqsave(&instance->hba_lock, flags);
+       writel(le32_to_cpu(req_desc->u.low),
+               &instance->reg_set->inbound_low_queue_port);
+       writel(le32_to_cpu(req_desc->u.high),
+               &instance->reg_set->inbound_high_queue_port);
+       mmiowb();
+       spin_unlock_irqrestore(&instance->hba_lock, flags);
 #endif
-       }
 }
 
 /**
@@ -982,7 +976,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
        const char *sys_info;
        MFI_CAPABILITIES *drv_ops;
        u32 scratch_pad_2;
-       unsigned long flags;
        ktime_t time;
        bool cur_fw_64bit_dma_capable;
 
@@ -1121,14 +1114,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
                        break;
        }
 
-       /* For Ventura also IOC INIT required 64 bit Descriptor write. */
-       spin_lock_irqsave(&instance->hba_lock, flags);
-       writel(le32_to_cpu(req_desc.u.low),
-              &instance->reg_set->inbound_low_queue_port);
-       writel(le32_to_cpu(req_desc.u.high),
-              &instance->reg_set->inbound_high_queue_port);
-       mmiowb();
-       spin_unlock_irqrestore(&instance->hba_lock, flags);
+       megasas_fire_cmd_fusion(instance, &req_desc);
 
        wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS);
 
index 13d6e4ec3022cc6c38e5b36496556f5bad998afa..0aafbfd1b7465c3a566c89392e73bfab1e037173 100644 (file)
@@ -2410,8 +2410,11 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
                                continue;
                        }
 
-                       for_each_cpu(cpu, mask)
+                       for_each_cpu_and(cpu, mask, cpu_online_mask) {
+                               if (cpu >= ioc->cpu_msix_table_sz)
+                                       break;
                                ioc->cpu_msix_table[cpu] = reply_q->msix_index;
+                       }
                }
                return;
        }
@@ -6294,14 +6297,14 @@ _base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
 }
 
 /**
- * _wait_for_commands_to_complete - reset controller
+ * mpt3sas_wait_for_commands_to_complete - reset controller
  * @ioc: Pointer to MPT_ADAPTER structure
  *
  * This function is waiting 10s for all pending commands to complete
  * prior to putting controller in reset.
  */
-static void
-_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
+void
+mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
 {
        u32 ioc_state;
 
@@ -6374,7 +6377,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
                        is_fault = 1;
        }
        _base_reset_handler(ioc, MPT3_IOC_PRE_RESET);
-       _wait_for_commands_to_complete(ioc);
+       mpt3sas_wait_for_commands_to_complete(ioc);
        _base_mask_interrupts(ioc);
        r = _base_make_ioc_ready(ioc, type);
        if (r)
index 789bc421424bcf5ba7de5904e9fef073843e312d..99ccf83b8c518c91b794a0311ce79d4cd41de795 100644 (file)
@@ -1433,6 +1433,9 @@ void mpt3sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc,
 
 int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
 
+void
+mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
+
 
 /* scsih shared API */
 struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc,
index 74fca184dba9830acd9b812b7b27f71cd32bf724..a1cb0236c550330a5de690462f5ac48c4a3e8bad 100644 (file)
@@ -2835,7 +2835,8 @@ scsih_abort(struct scsi_cmnd *scmd)
        _scsih_tm_display_info(ioc, scmd);
 
        sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
+       if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
+           ioc->remove_host) {
                sdev_printk(KERN_INFO, scmd->device,
                        "device been deleted! scmd(%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
@@ -2898,7 +2899,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
        _scsih_tm_display_info(ioc, scmd);
 
        sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
+       if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
+           ioc->remove_host) {
                sdev_printk(KERN_INFO, scmd->device,
                        "device been deleted! scmd(%p)\n", scmd);
                scmd->result = DID_NO_CONNECT << 16;
@@ -2961,7 +2963,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
        _scsih_tm_display_info(ioc, scmd);
 
        sas_device_priv_data = scmd->device->hostdata;
-       if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
+       if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
+           ioc->remove_host) {
                starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n",
                        scmd);
                scmd->result = DID_NO_CONNECT << 16;
@@ -3019,7 +3022,7 @@ scsih_host_reset(struct scsi_cmnd *scmd)
            ioc->name, scmd);
        scsi_print_command(scmd);
 
-       if (ioc->is_driver_loading) {
+       if (ioc->is_driver_loading || ioc->remove_host) {
                pr_info(MPT3SAS_FMT "Blocking the host reset\n",
                    ioc->name);
                r = FAILED;
@@ -4453,7 +4456,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
                st = scsi_cmd_priv(scmd);
                mpt3sas_base_clear_st(ioc, st);
                scsi_dma_unmap(scmd);
-               if (ioc->pci_error_recovery)
+               if (ioc->pci_error_recovery || ioc->remove_host)
                        scmd->result = DID_NO_CONNECT << 16;
                else
                        scmd->result = DID_RESET << 16;
@@ -9739,6 +9742,10 @@ static void scsih_remove(struct pci_dev *pdev)
        unsigned long flags;
 
        ioc->remove_host = 1;
+
+       mpt3sas_wait_for_commands_to_complete(ioc);
+       _scsih_flush_running_cmds(ioc);
+
        _scsih_fw_event_cleanup_queue(ioc);
 
        spin_lock_irqsave(&ioc->fw_event_lock, flags);
@@ -9815,6 +9822,10 @@ scsih_shutdown(struct pci_dev *pdev)
        unsigned long flags;
 
        ioc->remove_host = 1;
+
+       mpt3sas_wait_for_commands_to_complete(ioc);
+       _scsih_flush_running_cmds(ioc);
+
        _scsih_fw_event_cleanup_queue(ioc);
 
        spin_lock_irqsave(&ioc->fw_event_lock, flags);
@@ -10547,7 +10558,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
            "fw_event_%s%d", ioc->driver_name, ioc->id);
        ioc->firmware_event_thread = alloc_ordered_workqueue(
-           ioc->firmware_event_name, WQ_MEM_RECLAIM);
+           ioc->firmware_event_name, 0);
        if (!ioc->firmware_event_thread) {
                pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
                    ioc->name, __FILE__, __LINE__, __func__);
index 667d7697ba01d6a63da5b28ce6953d7cb9465e09..d09afe1b567d9dd2cbfd383fb771071e61d61609 100644 (file)
@@ -762,6 +762,11 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi,
 
        iscsi_cid = cqe->conn_id;
        qedi_conn = qedi->cid_que.conn_cid_tbl[iscsi_cid];
+       if (!qedi_conn) {
+               QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+                         "icid not found 0x%x\n", cqe->conn_id);
+               return;
+       }
 
        /* Based on this itt get the corresponding qedi_cmd */
        spin_lock_bh(&qedi_conn->tmf_work_lock);
index 029e2e69b29f8dedd43b937212a23b81a7aca3e7..f57a94b4f0d91636590a5ea1994e2730f8d00512 100644 (file)
@@ -1724,7 +1724,6 @@ static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf)
 {
        struct qedi_ctx *qedi = data;
        struct nvm_iscsi_initiator *initiator;
-       char *str = buf;
        int rc = 1;
        u32 ipv6_en, dhcp_en, ip_len;
        struct nvm_iscsi_block *block;
@@ -1758,32 +1757,32 @@ static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf)
 
        switch (type) {
        case ISCSI_BOOT_ETH_IP_ADDR:
-               rc = snprintf(str, ip_len, fmt, ip);
+               rc = snprintf(buf, ip_len, fmt, ip);
                break;
        case ISCSI_BOOT_ETH_SUBNET_MASK:
-               rc = snprintf(str, ip_len, fmt, sub);
+               rc = snprintf(buf, ip_len, fmt, sub);
                break;
        case ISCSI_BOOT_ETH_GATEWAY:
-               rc = snprintf(str, ip_len, fmt, gw);
+               rc = snprintf(buf, ip_len, fmt, gw);
                break;
        case ISCSI_BOOT_ETH_FLAGS:
-               rc = snprintf(str, 3, "%hhd\n",
+               rc = snprintf(buf, 3, "%hhd\n",
                              SYSFS_FLAG_FW_SEL_BOOT);
                break;
        case ISCSI_BOOT_ETH_INDEX:
-               rc = snprintf(str, 3, "0\n");
+               rc = snprintf(buf, 3, "0\n");
                break;
        case ISCSI_BOOT_ETH_MAC:
-               rc = sysfs_format_mac(str, qedi->mac, ETH_ALEN);
+               rc = sysfs_format_mac(buf, qedi->mac, ETH_ALEN);
                break;
        case ISCSI_BOOT_ETH_VLAN:
-               rc = snprintf(str, 12, "%d\n",
+               rc = snprintf(buf, 12, "%d\n",
                              GET_FIELD2(initiator->generic_cont0,
                                         NVM_ISCSI_CFG_INITIATOR_VLAN));
                break;
        case ISCSI_BOOT_ETH_ORIGIN:
                if (dhcp_en)
-                       rc = snprintf(str, 3, "3\n");
+                       rc = snprintf(buf, 3, "3\n");
                break;
        default:
                rc = 0;
@@ -1819,7 +1818,6 @@ static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf)
 {
        struct qedi_ctx *qedi = data;
        struct nvm_iscsi_initiator *initiator;
-       char *str = buf;
        int rc;
        struct nvm_iscsi_block *block;
 
@@ -1831,8 +1829,8 @@ static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf)
 
        switch (type) {
        case ISCSI_BOOT_INI_INITIATOR_NAME:
-               rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
-                             initiator->initiator_name.byte);
+               rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN,
+                            initiator->initiator_name.byte);
                break;
        default:
                rc = 0;
@@ -1860,7 +1858,6 @@ static ssize_t
 qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type,
                        char *buf, enum qedi_nvm_tgts idx)
 {
-       char *str = buf;
        int rc = 1;
        u32 ctrl_flags, ipv6_en, chap_en, mchap_en, ip_len;
        struct nvm_iscsi_block *block;
@@ -1899,48 +1896,48 @@ qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type,
 
        switch (type) {
        case ISCSI_BOOT_TGT_NAME:
-               rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
-                             block->target[idx].target_name.byte);
+               rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN,
+                            block->target[idx].target_name.byte);
                break;
        case ISCSI_BOOT_TGT_IP_ADDR:
                if (ipv6_en)
-                       rc = snprintf(str, ip_len, "%pI6\n",
+                       rc = snprintf(buf, ip_len, "%pI6\n",
                                      block->target[idx].ipv6_addr.byte);
                else
-                       rc = snprintf(str, ip_len, "%pI4\n",
+                       rc = snprintf(buf, ip_len, "%pI4\n",
                                      block->target[idx].ipv4_addr.byte);
                break;
        case ISCSI_BOOT_TGT_PORT:
-               rc = snprintf(str, 12, "%d\n",
+               rc = snprintf(buf, 12, "%d\n",
                              GET_FIELD2(block->target[idx].generic_cont0,
                                         NVM_ISCSI_CFG_TARGET_TCP_PORT));
                break;
        case ISCSI_BOOT_TGT_LUN:
-               rc = snprintf(str, 22, "%.*d\n",
+               rc = snprintf(buf, 22, "%.*d\n",
                              block->target[idx].lun.value[1],
                              block->target[idx].lun.value[0]);
                break;
        case ISCSI_BOOT_TGT_CHAP_NAME:
-               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n",
-                             chap_name);
+               rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN,
+                            chap_name);
                break;
        case ISCSI_BOOT_TGT_CHAP_SECRET:
-               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n",
-                             chap_secret);
+               rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN,
+                            chap_secret);
                break;
        case ISCSI_BOOT_TGT_REV_CHAP_NAME:
-               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n",
-                             mchap_name);
+               rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN,
+                            mchap_name);
                break;
        case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
-               rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n",
-                             mchap_secret);
+               rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN,
+                            mchap_secret);
                break;
        case ISCSI_BOOT_TGT_FLAGS:
-               rc = snprintf(str, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT);
+               rc = snprintf(buf, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT);
                break;
        case ISCSI_BOOT_TGT_NIC_ASSOC:
-               rc = snprintf(str, 3, "0\n");
+               rc = snprintf(buf, 3, "0\n");
                break;
        default:
                rc = 0;
index be7d6824581ac059015d0a8c74d7449074d09962..c9689f97c307ac34c0baeed35bfd60b13c2e96e2 100644 (file)
 struct name_list_extended {
        struct get_name_list_extended *l;
        dma_addr_t              ldma;
-       struct list_head        fcports;        /* protect by sess_list */
+       struct list_head        fcports;
+       spinlock_t              fcports_lock;
        u32                     size;
-       u8                      sent;
 };
 /*
  * Timeout timer counts in seconds
@@ -2217,6 +2217,7 @@ typedef struct {
 
 /* FCP-4 types */
 #define FC4_TYPE_FCP_SCSI      0x08
+#define FC4_TYPE_NVME          0x28
 #define FC4_TYPE_OTHER         0x0
 #define FC4_TYPE_UNKNOWN       0xff
 
index 5bf9a59432f6a10a23360e4f0ea9950ee285956c..403fa096f8c807bbc1510cad0bc7ee1230dddb6c 100644 (file)
@@ -3179,6 +3179,7 @@ done_free_sp:
        sp->free(sp);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
        return rval;
 }
 
@@ -3370,6 +3371,7 @@ done_free_sp:
        sp->free(sp);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
        return rval;
 }
 
@@ -3971,6 +3973,9 @@ out:
        spin_lock_irqsave(&vha->work_lock, flags);
        vha->scan.scan_flags &= ~SF_SCANNING;
        spin_unlock_irqrestore(&vha->work_lock, flags);
+
+       if ((fc4type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled)
+               qla24xx_async_gpnft(vha, FC4_TYPE_NVME);
 }
 
 static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
index aececf664654df95c04ff005dcd90f69a5fe5622..8d7fab3cd01d28e393a17263b13dab44fe855f8a 100644 (file)
@@ -59,8 +59,6 @@ qla2x00_sp_timeout(struct timer_list *t)
        req->outstanding_cmds[sp->handle] = NULL;
        iocb = &sp->u.iocb_cmd;
        iocb->timeout(sp);
-       if (sp->type != SRB_ELS_DCMD)
-               sp->free(sp);
        spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
 }
 
@@ -102,7 +100,6 @@ qla2x00_async_iocb_timeout(void *data)
        srb_t *sp = data;
        fc_port_t *fcport = sp->fcport;
        struct srb_iocb *lio = &sp->u.iocb_cmd;
-       struct event_arg ea;
 
        if (fcport) {
                ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
@@ -117,25 +114,13 @@ qla2x00_async_iocb_timeout(void *data)
 
        switch (sp->type) {
        case SRB_LOGIN_CMD:
-               if (!fcport)
-                       break;
                /* Retry as needed. */
                lio->u.logio.data[0] = MBS_COMMAND_ERROR;
                lio->u.logio.data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
                        QLA_LOGIO_LOGIN_RETRIED : 0;
-               memset(&ea, 0, sizeof(ea));
-               ea.event = FCME_PLOGI_DONE;
-               ea.fcport = sp->fcport;
-               ea.data[0] = lio->u.logio.data[0];
-               ea.data[1] = lio->u.logio.data[1];
-               ea.sp = sp;
-               qla24xx_handle_plogi_done_event(fcport->vha, &ea);
+               sp->done(sp, QLA_FUNCTION_TIMEOUT);
                break;
        case SRB_LOGOUT_CMD:
-               if (!fcport)
-                       break;
-               qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
-               break;
        case SRB_CT_PTHRU_CMD:
        case SRB_MB_IOCB:
        case SRB_NACK_PLOGI:
@@ -228,6 +213,7 @@ done_free_sp:
        sp->free(sp);
        fcport->flags &= ~FCF_ASYNC_SENT;
 done:
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
        return rval;
 }
 
@@ -235,12 +221,10 @@ static void
 qla2x00_async_logout_sp_done(void *ptr, int res)
 {
        srb_t *sp = ptr;
-       struct srb_iocb *lio = &sp->u.iocb_cmd;
 
        sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
-       if (!test_bit(UNLOADING, &sp->vha->dpc_flags))
-               qla2x00_post_async_logout_done_work(sp->vha, sp->fcport,
-                   lio->u.logio.data);
+       sp->fcport->login_gen++;
+       qlt_logo_completion_handler(sp->fcport, res);
        sp->free(sp);
 }
 
@@ -280,7 +264,7 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
 done_free_sp:
        sp->free(sp);
 done:
-       fcport->flags &= ~FCF_ASYNC_SENT;
+       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        return rval;
 }
 
@@ -288,6 +272,7 @@ void
 qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport,
     uint16_t *data)
 {
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
        /* Don't re-login in target mode */
        if (!fcport->tgt_session)
                qla2x00_mark_device_lost(vha, fcport, 1, 0);
@@ -301,6 +286,7 @@ qla2x00_async_prlo_sp_done(void *s, int res)
        struct srb_iocb *lio = &sp->u.iocb_cmd;
        struct scsi_qla_host *vha = sp->vha;
 
+       sp->fcport->flags &= ~FCF_ASYNC_ACTIVE;
        if (!test_bit(UNLOADING, &vha->dpc_flags))
                qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport,
                    lio->u.logio.data);
@@ -339,6 +325,7 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport)
 done_free_sp:
        sp->free(sp);
 done:
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
        return rval;
 }
 
@@ -392,6 +379,8 @@ qla2x00_async_adisc_sp_done(void *ptr, int res)
            "Async done-%s res %x %8phC\n",
            sp->name, res, sp->fcport->port_name);
 
+       sp->fcport->flags &= ~FCF_ASYNC_SENT;
+
        memset(&ea, 0, sizeof(ea));
        ea.event = FCME_ADISC_DONE;
        ea.rc = res;
@@ -442,7 +431,7 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
 done_free_sp:
        sp->free(sp);
 done:
-       fcport->flags &= ~FCF_ASYNC_SENT;
+       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        qla2x00_post_async_adisc_work(vha, fcport, data);
        return rval;
 }
@@ -660,8 +649,7 @@ qla24xx_async_gnl_sp_done(void *s, int res)
                    (loop_id & 0x7fff));
        }
 
-       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
-       vha->gnl.sent = 0;
+       spin_lock_irqsave(&vha->gnl.fcports_lock, flags);
 
        INIT_LIST_HEAD(&h);
        fcport = tf = NULL;
@@ -670,12 +658,16 @@ qla24xx_async_gnl_sp_done(void *s, int res)
 
        list_for_each_entry_safe(fcport, tf, &h, gnl_entry) {
                list_del_init(&fcport->gnl_entry);
+               spin_lock(&vha->hw->tgt.sess_lock);
                fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+               spin_unlock(&vha->hw->tgt.sess_lock);
                ea.fcport = fcport;
 
                qla2x00_fcport_event_handler(vha, &ea);
        }
+       spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags);
 
+       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
        /* create new fcport if fw has knowledge of new sessions */
        for (i = 0; i < n; i++) {
                port_id_t id;
@@ -727,18 +719,21 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
        ql_dbg(ql_dbg_disc, vha, 0x20d9,
            "Async-gnlist WWPN %8phC \n", fcport->port_name);
 
-       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+       spin_lock_irqsave(&vha->gnl.fcports_lock, flags);
+       if (!list_empty(&fcport->gnl_entry)) {
+               spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags);
+               rval = QLA_SUCCESS;
+               goto done;
+       }
+
+       spin_lock(&vha->hw->tgt.sess_lock);
        fcport->disc_state = DSC_GNL;
        fcport->last_rscn_gen = fcport->rscn_gen;
        fcport->last_login_gen = fcport->login_gen;
+       spin_unlock(&vha->hw->tgt.sess_lock);
 
        list_add_tail(&fcport->gnl_entry, &vha->gnl.fcports);
-       if (vha->gnl.sent) {
-               spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
-               return QLA_SUCCESS;
-       }
-       vha->gnl.sent = 1;
-       spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+       spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags);
 
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
@@ -1066,6 +1061,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
        fc_port_t *fcport = ea->fcport;
        struct port_database_24xx *pd;
        struct srb *sp = ea->sp;
+       uint8_t ls;
 
        pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in;
 
@@ -1078,7 +1074,12 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
        if (fcport->disc_state == DSC_DELETE_PEND)
                return;
 
-       switch (pd->current_login_state) {
+       if (fcport->fc4f_nvme)
+               ls = pd->current_login_state >> 4;
+       else
+               ls = pd->current_login_state & 0xf;
+
+       switch (ls) {
        case PDS_PRLI_COMPLETE:
                __qla24xx_parse_gpdb(vha, fcport, pd);
                break;
@@ -1168,8 +1169,9 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
        if (fcport->scan_state != QLA_FCPORT_FOUND)
                return 0;
 
-       if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
-           (fcport->fw_login_state == DSC_LS_PRLI_PEND))
+       if ((fcport->loop_id != FC_NO_LOOP_ID) &&
+           ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
+            (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
                return 0;
 
        if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
@@ -1544,6 +1546,7 @@ qla24xx_abort_sp_done(void *ptr, int res)
        srb_t *sp = ptr;
        struct srb_iocb *abt = &sp->u.iocb_cmd;
 
+       del_timer(&sp->u.iocb_cmd.timer);
        complete(&abt->u.abt.comp);
 }
 
@@ -1716,7 +1719,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
 
                        set_bit(ea->fcport->loop_id, vha->hw->loop_id_map);
                        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
-                       ea->fcport->loop_id = FC_NO_LOOP_ID;
                        ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
                        ea->fcport->logout_on_delete = 1;
                        ea->fcport->send_els_logo = 0;
@@ -1808,6 +1810,7 @@ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
        qla2x00_mark_device_lost(vha, fcport, 1, 0);
        qlt_logo_completion_handler(fcport, data[0]);
        fcport->login_gen++;
+       fcport->flags &= ~FCF_ASYNC_ACTIVE;
        return;
 }
 
@@ -1815,6 +1818,7 @@ void
 qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
     uint16_t *data)
 {
+       fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
        if (data[0] == MBS_COMMAND_COMPLETE) {
                qla2x00_update_fcport(vha, fcport);
 
@@ -1822,7 +1826,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
        }
 
        /* Retry login. */
-       fcport->flags &= ~FCF_ASYNC_SENT;
        if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
                set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
        else
index 1b62e943ec49c15dabf3054946619a944980cba5..8d00d559bd2659b13bb2362034dffd855a370d44 100644 (file)
@@ -3275,12 +3275,11 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
        memset(abt_iocb, 0, sizeof(struct abort_entry_24xx));
        abt_iocb->entry_type = ABORT_IOCB_TYPE;
        abt_iocb->entry_count = 1;
-       abt_iocb->handle =
-            cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no,
-                aio->u.abt.cmd_hndl));
+       abt_iocb->handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
        abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
        abt_iocb->handle_to_abort =
-           cpu_to_le32(MAKE_HANDLE(req->id, aio->u.abt.cmd_hndl));
+           cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no,
+                                   aio->u.abt.cmd_hndl));
        abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
        abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
        abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
index 14109d86c3f6a786313bbf83d4c973e60553e33e..89f93ebd819d7590a5ece0dd689f6bd350be7393 100644 (file)
@@ -272,7 +272,8 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
        /* Read all mbox registers? */
-       mboxes = (1 << ha->mbx_count) - 1;
+       WARN_ON_ONCE(ha->mbx_count > 32);
+       mboxes = (1ULL << ha->mbx_count) - 1;
        if (!ha->mcp)
                ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERROR.\n");
        else
@@ -2880,7 +2881,8 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
        /* Read all mbox registers? */
-       mboxes = (1 << ha->mbx_count) - 1;
+       WARN_ON_ONCE(ha->mbx_count > 32);
+       mboxes = (1ULL << ha->mbx_count) - 1;
        if (!ha->mcp)
                ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERROR.\n");
        else
index 12ee6e02d146d169940ead69af93d42d79d6508b..5c5dcca4d1da4aee502f2ac33b3dd13a8375812c 100644 (file)
@@ -454,7 +454,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
        ha->req_q_map[0] = req;
        set_bit(0, ha->rsp_qid_map);
        set_bit(0, ha->req_qid_map);
-       return 1;
+       return 0;
 
 fail_qpair_map:
        kfree(ha->base_qpair);
@@ -471,6 +471,9 @@ fail_req_map:
 
 static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
 {
+       if (!ha->req_q_map)
+               return;
+
        if (IS_QLAFX00(ha)) {
                if (req && req->ring_fx00)
                        dma_free_coherent(&ha->pdev->dev,
@@ -481,14 +484,17 @@ static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
                (req->length + 1) * sizeof(request_t),
                req->ring, req->dma);
 
-       if (req)
+       if (req) {
                kfree(req->outstanding_cmds);
-
-       kfree(req);
+               kfree(req);
+       }
 }
 
 static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
 {
+       if (!ha->rsp_q_map)
+               return;
+
        if (IS_QLAFX00(ha)) {
                if (rsp && rsp->ring)
                        dma_free_coherent(&ha->pdev->dev,
@@ -499,7 +505,8 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
                (rsp->length + 1) * sizeof(response_t),
                rsp->ring, rsp->dma);
        }
-       kfree(rsp);
+       if (rsp)
+               kfree(rsp);
 }
 
 static void qla2x00_free_queues(struct qla_hw_data *ha)
@@ -1723,6 +1730,8 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
        struct qla_tgt_cmd *cmd;
        uint8_t trace = 0;
 
+       if (!ha->req_q_map)
+               return;
        spin_lock_irqsave(qp->qp_lock_ptr, flags);
        req = qp->req;
        for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
@@ -3095,14 +3104,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        /* Set up the irqs */
        ret = qla2x00_request_irqs(ha, rsp);
        if (ret)
-               goto probe_hw_failed;
+               goto probe_failed;
 
        /* Alloc arrays of request and response ring ptrs */
-       if (!qla2x00_alloc_queues(ha, req, rsp)) {
+       if (qla2x00_alloc_queues(ha, req, rsp)) {
                ql_log(ql_log_fatal, base_vha, 0x003d,
                    "Failed to allocate memory for queue pointers..."
                    "aborting.\n");
-               goto probe_init_failed;
+               goto probe_failed;
        }
 
        if (ha->mqenable && shost_use_blk_mq(host)) {
@@ -3387,15 +3396,6 @@ skip_dpc:
 
        return 0;
 
-probe_init_failed:
-       qla2x00_free_req_que(ha, req);
-       ha->req_q_map[0] = NULL;
-       clear_bit(0, ha->req_qid_map);
-       qla2x00_free_rsp_que(ha, rsp);
-       ha->rsp_q_map[0] = NULL;
-       clear_bit(0, ha->rsp_qid_map);
-       ha->max_req_queues = ha->max_rsp_queues = 0;
-
 probe_failed:
        if (base_vha->timer_active)
                qla2x00_stop_timer(base_vha);
@@ -3625,6 +3625,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
        }
        qla2x00_wait_for_hba_ready(base_vha);
 
+       qla2x00_wait_for_sess_deletion(base_vha);
+
        /*
         * if UNLOAD flag is already set, then continue unload,
         * where it was set first.
@@ -4506,11 +4508,17 @@ qla2x00_mem_free(struct qla_hw_data *ha)
        if (ha->init_cb)
                dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
                        ha->init_cb, ha->init_cb_dma);
-       vfree(ha->optrom_buffer);
-       kfree(ha->nvram);
-       kfree(ha->npiv_info);
-       kfree(ha->swl);
-       kfree(ha->loop_id_map);
+
+       if (ha->optrom_buffer)
+               vfree(ha->optrom_buffer);
+       if (ha->nvram)
+               kfree(ha->nvram);
+       if (ha->npiv_info)
+               kfree(ha->npiv_info);
+       if (ha->swl)
+               kfree(ha->swl);
+       if (ha->loop_id_map)
+               kfree(ha->loop_id_map);
 
        ha->srb_mempool = NULL;
        ha->ctx_mempool = NULL;
@@ -4526,6 +4534,15 @@ qla2x00_mem_free(struct qla_hw_data *ha)
        ha->ex_init_cb_dma = 0;
        ha->async_pd = NULL;
        ha->async_pd_dma = 0;
+       ha->loop_id_map = NULL;
+       ha->npiv_info = NULL;
+       ha->optrom_buffer = NULL;
+       ha->swl = NULL;
+       ha->nvram = NULL;
+       ha->mctp_dump = NULL;
+       ha->dcbx_tlv = NULL;
+       ha->xgmac_data = NULL;
+       ha->sfp_data = NULL;
 
        ha->s_dma_pool = NULL;
        ha->dl_dma_pool = NULL;
@@ -4575,6 +4592,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
 
        spin_lock_init(&vha->work_lock);
        spin_lock_init(&vha->cmd_list_lock);
+       spin_lock_init(&vha->gnl.fcports_lock);
        init_waitqueue_head(&vha->fcport_waitQ);
        init_waitqueue_head(&vha->vref_waitq);
 
@@ -4804,9 +4822,12 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                        fcport->d_id = e->u.new_sess.id;
                        fcport->flags |= FCF_FABRIC_DEVICE;
                        fcport->fw_login_state = DSC_LS_PLOGI_PEND;
-                       if (e->u.new_sess.fc4_type == FC4_TYPE_FCP_SCSI)
+                       if (e->u.new_sess.fc4_type == FC4_TYPE_FCP_SCSI) {
                                fcport->fc4_type = FC4_TYPE_FCP_SCSI;
-
+                       } else if (e->u.new_sess.fc4_type == FC4_TYPE_NVME) {
+                               fcport->fc4_type = FC4_TYPE_OTHER;
+                               fcport->fc4f_nvme = FC4_TYPE_NVME;
+                       }
                        memcpy(fcport->port_name, e->u.new_sess.port_name,
                            WWN_SIZE);
                } else {
@@ -4875,6 +4896,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                        }
                        qlt_plogi_ack_unref(vha, pla);
                } else {
+                       fc_port_t *dfcp = NULL;
+
                        spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
                        tfcp = qla2x00_find_fcport_by_nportid(vha,
                            &e->u.new_sess.id, 1);
@@ -4897,11 +4920,13 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                                default:
                                        fcport->login_pause = 1;
                                        tfcp->conflict = fcport;
-                                       qlt_schedule_sess_for_deletion(tfcp);
+                                       dfcp = tfcp;
                                        break;
                                }
                        }
                        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+                       if (dfcp)
+                               qlt_schedule_sess_for_deletion(tfcp);
 
                        wwn = wwn_to_u64(fcport->node_name);
 
index fc89af8fe2569a65d8b2751e72b74699977f9504..b49ac85f3de2254694e728f75d4cf2fa7e260662 100644 (file)
@@ -1224,10 +1224,10 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess)
        }
 }
 
-/* ha->tgt.sess_lock supposed to be held on entry */
 void qlt_schedule_sess_for_deletion(struct fc_port *sess)
 {
        struct qla_tgt *tgt = sess->tgt;
+       struct qla_hw_data *ha = sess->vha->hw;
        unsigned long flags;
 
        if (sess->disc_state == DSC_DELETE_PEND)
@@ -1244,16 +1244,16 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
                        return;
        }
 
+       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        if (sess->deleted == QLA_SESS_DELETED)
                sess->logout_on_delete = 0;
 
-       spin_lock_irqsave(&sess->vha->work_lock, flags);
        if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
-               spin_unlock_irqrestore(&sess->vha->work_lock, flags);
+               spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
                return;
        }
        sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
-       spin_unlock_irqrestore(&sess->vha->work_lock, flags);
+       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
 
        sess->disc_state = DSC_DELETE_PEND;
 
@@ -1262,13 +1262,10 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
        ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
            "Scheduling sess %p for deletion\n", sess);
 
-       /* use cancel to push work element through before re-queue */
-       cancel_work_sync(&sess->del_work);
        INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn);
-       queue_work(sess->vha->hw->wq, &sess->del_work);
+       WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work));
 }
 
-/* ha->tgt.sess_lock supposed to be held on entry */
 static void qlt_clear_tgt_db(struct qla_tgt *tgt)
 {
        struct fc_port *sess;
@@ -1451,8 +1448,8 @@ qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen)
        ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess);
 
        sess->local = 1;
-       qlt_schedule_sess_for_deletion(sess);
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+       qlt_schedule_sess_for_deletion(sess);
 }
 
 static inline int test_tgt_sess_count(struct qla_tgt *tgt)
@@ -1512,10 +1509,8 @@ int qlt_stop_phase1(struct qla_tgt *tgt)
         * Lock is needed, because we still can get an incoming packet.
         */
        mutex_lock(&vha->vha_tgt.tgt_mutex);
-       spin_lock_irqsave(&ha->tgt.sess_lock, flags);
        tgt->tgt_stop = 1;
        qlt_clear_tgt_db(tgt);
-       spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
        mutex_unlock(&vha->vha_tgt.tgt_mutex);
        mutex_unlock(&qla_tgt_mutex);
 
@@ -4871,8 +4866,6 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
                                    sess);
                                qlt_send_term_imm_notif(vha, iocb, 1);
                                res = 0;
-                               spin_lock_irqsave(&tgt->ha->tgt.sess_lock,
-                                   flags);
                                break;
                        }
 
index fc233717355fe22687678c805069478eddd99113..817f312023a999a3561794472c65c31c1ba18605 100644 (file)
 #define DEV_DB_NON_PERSISTENT  0
 #define DEV_DB_PERSISTENT      1
 
+#define QL4_ISP_REG_DISCONNECT 0xffffffffU
+
 #define COPY_ISID(dst_isid, src_isid) {                        \
        int i, j;                                       \
        for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;)  \
index 82e889bbe0ed8f1959de20fce2d4af88e493508e..fc2c97d9a0d60de85b6fbf97a2202b3fd0267928 100644 (file)
@@ -262,6 +262,24 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
 
 static struct scsi_transport_template *qla4xxx_scsi_transport;
 
+static int qla4xxx_isp_check_reg(struct scsi_qla_host *ha)
+{
+       u32 reg_val = 0;
+       int rval = QLA_SUCCESS;
+
+       if (is_qla8022(ha))
+               reg_val = readl(&ha->qla4_82xx_reg->host_status);
+       else if (is_qla8032(ha) || is_qla8042(ha))
+               reg_val = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
+       else
+               reg_val = readw(&ha->reg->ctrl_status);
+
+       if (reg_val == QL4_ISP_REG_DISCONNECT)
+               rval = QLA_ERROR;
+
+       return rval;
+}
+
 static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
                             uint32_t iface_type, uint32_t payload_size,
                             uint32_t pid, struct sockaddr *dst_addr)
@@ -9186,10 +9204,17 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
        struct srb *srb = NULL;
        int ret = SUCCESS;
        int wait = 0;
+       int rval;
 
        ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n",
                   ha->host_no, id, lun, cmd, cmd->cmnd[0]);
 
+       rval = qla4xxx_isp_check_reg(ha);
+       if (rval != QLA_SUCCESS) {
+               ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
+
        spin_lock_irqsave(&ha->hardware_lock, flags);
        srb = (struct srb *) CMD_SP(cmd);
        if (!srb) {
@@ -9241,6 +9266,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
        struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
        struct ddb_entry *ddb_entry = cmd->device->hostdata;
        int ret = FAILED, stat;
+       int rval;
 
        if (!ddb_entry)
                return ret;
@@ -9260,6 +9286,12 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
                      cmd, jiffies, cmd->request->timeout / HZ,
                      ha->dpc_flags, cmd->result, cmd->allowed));
 
+       rval = qla4xxx_isp_check_reg(ha);
+       if (rval != QLA_SUCCESS) {
+               ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
+
        /* FIXME: wait for hba to go online */
        stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun);
        if (stat != QLA_SUCCESS) {
@@ -9303,6 +9335,7 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
        struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
        struct ddb_entry *ddb_entry = cmd->device->hostdata;
        int stat, ret;
+       int rval;
 
        if (!ddb_entry)
                return FAILED;
@@ -9320,6 +9353,12 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
                      ha->host_no, cmd, jiffies, cmd->request->timeout / HZ,
                      ha->dpc_flags, cmd->result, cmd->allowed));
 
+       rval = qla4xxx_isp_check_reg(ha);
+       if (rval != QLA_SUCCESS) {
+               ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
+
        stat = qla4xxx_reset_target(ha, ddb_entry);
        if (stat != QLA_SUCCESS) {
                starget_printk(KERN_INFO, scsi_target(cmd->device),
@@ -9374,9 +9413,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
 {
        int return_status = FAILED;
        struct scsi_qla_host *ha;
+       int rval;
 
        ha = to_qla_host(cmd->device->host);
 
+       rval = qla4xxx_isp_check_reg(ha);
+       if (rval != QLA_SUCCESS) {
+               ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
+               return FAILED;
+       }
+
        if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba)
                qla4_83xx_set_idc_dontreset(ha);
 
index d042915ce895517b472c52a75dbf8927bf9eed86..ca53a5f785ee239cee9b7de7c10edf75b01ff2d8 100644 (file)
@@ -223,7 +223,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd)
 
 static void scsi_eh_inc_host_failed(struct rcu_head *head)
 {
-       struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu);
+       struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
+       struct Scsi_Host *shost = scmd->device->host;
        unsigned long flags;
 
        spin_lock_irqsave(shost->host_lock, flags);
@@ -259,7 +260,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd)
         * Ensure that all tasks observe the host state change before the
         * host_failed change.
         */
-       call_rcu(&shost->rcu, scsi_eh_inc_host_failed);
+       call_rcu(&scmd->rcu, scsi_eh_inc_host_failed);
 }
 
 /**
index a86df9ca7d1c88aceb1d1e2298f48fbdb8bb3c49..c84f931388f226cdab2071245f7308d2c0b035b3 100644 (file)
@@ -671,6 +671,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
        if (!blk_rq_is_scsi(req)) {
                WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
                cmd->flags &= ~SCMD_INITIALIZED;
+               destroy_rcu_head(&cmd->rcu);
        }
 
        if (req->mq_ctx) {
@@ -720,6 +721,8 @@ static blk_status_t __scsi_error_from_host_byte(struct scsi_cmnd *cmd,
                int result)
 {
        switch (host_byte(result)) {
+       case DID_OK:
+               return BLK_STS_OK;
        case DID_TRANSPORT_FAILFAST:
                return BLK_STS_TRANSPORT;
        case DID_TARGET_FAILURE:
@@ -1151,6 +1154,7 @@ static void scsi_initialize_rq(struct request *rq)
        struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
 
        scsi_req_init(&cmd->req);
+       init_rcu_head(&cmd->rcu);
        cmd->jiffies_at_alloc = jiffies;
        cmd->retries = 0;
 }
index bff21e636dddefba176ff6a435cd23863335c3f8..3541caf3fceb4441b220d50b4fac1dc8b98b751d 100644 (file)
@@ -2595,6 +2595,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
        int res;
        struct scsi_device *sdp = sdkp->device;
        struct scsi_mode_data data;
+       int disk_ro = get_disk_ro(sdkp->disk);
        int old_wp = sdkp->write_prot;
 
        set_disk_ro(sdkp->disk, 0);
@@ -2635,7 +2636,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
                          "Test WP failed, assume Write Enabled\n");
        } else {
                sdkp->write_prot = ((data.device_specific & 0x80) != 0);
-               set_disk_ro(sdkp->disk, sdkp->write_prot);
+               set_disk_ro(sdkp->disk, sdkp->write_prot || disk_ro);
                if (sdkp->first_scan || old_wp != sdkp->write_prot) {
                        sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n",
                                  sdkp->write_prot ? "on" : "off");
index 6c348a211ebb1e73d5803be0957aacc4c179a18a..89cf4498f5358e17c5473783a58603ca0a38c9a5 100644 (file)
@@ -403,7 +403,7 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf)
  */
 static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
 {
-       u64 zone_blocks;
+       u64 zone_blocks = 0;
        sector_t block = 0;
        unsigned char *buf;
        unsigned char *rec;
@@ -421,10 +421,8 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
 
        /* Do a report zone to get the same field */
        ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0);
-       if (ret) {
-               zone_blocks = 0;
-               goto out;
-       }
+       if (ret)
+               goto out_free;
 
        same = buf[4] & 0x0f;
        if (same > 0) {
@@ -464,7 +462,7 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
                        ret = sd_zbc_report_zones(sdkp, buf,
                                                  SD_ZBC_BUF_SIZE, block);
                        if (ret)
-                               return ret;
+                               goto out_free;
                }
 
        } while (block < sdkp->capacity);
@@ -472,35 +470,32 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp)
        zone_blocks = sdkp->zone_blocks;
 
 out:
-       kfree(buf);
-
        if (!zone_blocks) {
                if (sdkp->first_scan)
                        sd_printk(KERN_NOTICE, sdkp,
                                  "Devices with non constant zone "
                                  "size are not supported\n");
-               return -ENODEV;
-       }
-
-       if (!is_power_of_2(zone_blocks)) {
+               ret = -ENODEV;
+       } else if (!is_power_of_2(zone_blocks)) {
                if (sdkp->first_scan)
                        sd_printk(KERN_NOTICE, sdkp,
                                  "Devices with non power of 2 zone "
                                  "size are not supported\n");
-               return -ENODEV;
-       }
-
-       if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
+               ret = -ENODEV;
+       } else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) {
                if (sdkp->first_scan)
                        sd_printk(KERN_NOTICE, sdkp,
                                  "Zone size too large\n");
-               return -ENODEV;
+               ret = -ENODEV;
+       } else {
+               sdkp->zone_blocks = zone_blocks;
+               sdkp->zone_shift = ilog2(zone_blocks);
        }
 
-       sdkp->zone_blocks = zone_blocks;
-       sdkp->zone_shift = ilog2(zone_blocks);
+out_free:
+       kfree(buf);
 
-       return 0;
+       return ret;
 }
 
 /**
index 40fc7a590e81b6f9a6749dd4945a7f134e69364d..8c51d628b52edfd7e891182919fab16b469b0f3c 100644 (file)
@@ -1311,7 +1311,8 @@ static int storvsc_do_io(struct hv_device *device,
                         */
                        cpumask_and(&alloced_mask, &stor_device->alloced_cpus,
                                    cpumask_of_node(cpu_to_node(q_num)));
-                       for_each_cpu(tgt_cpu, &alloced_mask) {
+                       for_each_cpu_wrap(tgt_cpu, &alloced_mask,
+                                       outgoing_channel->target_cpu + 1) {
                                if (tgt_cpu != outgoing_channel->target_cpu) {
                                        outgoing_channel =
                                        stor_device->stor_chns[tgt_cpu];
@@ -1657,7 +1658,7 @@ static struct scsi_host_template scsi_driver = {
        .eh_timed_out =         storvsc_eh_timed_out,
        .slave_alloc =          storvsc_device_alloc,
        .slave_configure =      storvsc_device_configure,
-       .cmd_per_lun =          255,
+       .cmd_per_lun =          2048,
        .this_id =              -1,
        .use_clustering =       ENABLE_CLUSTERING,
        /* Make sure we dont get a sg segment crosses a page boundary */
index ca360daa6a253c7a9a0f4f29eaeaf5a49a1a8c98..378af306fda1748d8f587f466bb83fa34dbc9b5c 100644 (file)
@@ -536,7 +536,7 @@ sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fa
         *  Look for the greatest clock divisor that allows an 
         *  input speed faster than the period.
         */
-       while (div-- > 0)
+       while (--div > 0)
                if (kpc >= (div_10M[div] << 2)) break;
 
        /*
index a355d989b414f9059abe8e04bad9bbf6d2459c34..c7da2c185990615f906e847def5b6513a1338801 100644 (file)
@@ -4352,6 +4352,8 @@ static int ufshcd_slave_alloc(struct scsi_device *sdev)
        /* REPORT SUPPORTED OPERATION CODES is not supported */
        sdev->no_report_opcodes = 1;
 
+       /* WRITE_SAME command is not supported */
+       sdev->no_write_same = 1;
 
        ufshcd_set_queue_depth(sdev);
 
index e4f5bb056fd275b84d18a80ae1917e86baf1e319..ba3cfa8e279b508fc632147da0aab110e81724ca 100644 (file)
@@ -2443,39 +2443,21 @@ struct cgr_comp {
        struct completion completion;
 };
 
-static int qman_delete_cgr_thread(void *p)
+static void qman_delete_cgr_smp_call(void *p)
 {
-       struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
-       int ret;
-
-       ret = qman_delete_cgr(cgr_comp->cgr);
-       complete(&cgr_comp->completion);
-
-       return ret;
+       qman_delete_cgr((struct qman_cgr *)p);
 }
 
 void qman_delete_cgr_safe(struct qman_cgr *cgr)
 {
-       struct task_struct *thread;
-       struct cgr_comp cgr_comp;
-
        preempt_disable();
        if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
-               init_completion(&cgr_comp.completion);
-               cgr_comp.cgr = cgr;
-               thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
-                                       "cgr_del");
-
-               if (IS_ERR(thread))
-                       goto out;
-
-               kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
-               wake_up_process(thread);
-               wait_for_completion(&cgr_comp.completion);
+               smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
+                                        qman_delete_cgr_smp_call, cgr, true);
                preempt_enable();
                return;
        }
-out:
+
        qman_delete_cgr(cgr);
        preempt_enable();
 }
index 53f7275d6cbdb513001582555f898adb35e1cc5b..750f931974119804734945a501e0786ca003977d 100644 (file)
@@ -348,7 +348,7 @@ static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap,
                if (i == 1) {
                        domain->supply = devm_regulator_get(dev, "pu");
                        if (IS_ERR(domain->supply))
-                               return PTR_ERR(domain->supply);;
+                               return PTR_ERR(domain->supply);
 
                        ret = imx_pgc_get_clocks(dev, domain);
                        if (ret)
@@ -470,13 +470,21 @@ static int imx_gpc_probe(struct platform_device *pdev)
 
 static int imx_gpc_remove(struct platform_device *pdev)
 {
+       struct device_node *pgc_node;
        int ret;
 
+       pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc");
+
+       /* bail out if DT too old and doesn't provide the necessary info */
+       if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") &&
+           !pgc_node)
+               return 0;
+
        /*
         * If the old DT binding is used the toplevel driver needs to
         * de-register the power domains
         */
-       if (!of_get_child_by_name(pdev->dev.of_node, "pgc")) {
+       if (!pgc_node) {
                of_genpd_del_provider(pdev->dev.of_node);
 
                ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_PU].base);
index bbdc53b686dd19503796ed8fdfd97fd01596195f..86580b6df33d05c44b50b2dfda758d95c34b4386 100644 (file)
@@ -326,24 +326,23 @@ static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin)
        mutex_lock(&ashmem_mutex);
 
        if (asma->size == 0) {
-               ret = -EINVAL;
-               goto out;
+               mutex_unlock(&ashmem_mutex);
+               return -EINVAL;
        }
 
        if (!asma->file) {
-               ret = -EBADF;
-               goto out;
+               mutex_unlock(&ashmem_mutex);
+               return -EBADF;
        }
 
+       mutex_unlock(&ashmem_mutex);
+
        ret = vfs_llseek(asma->file, offset, origin);
        if (ret < 0)
-               goto out;
+               return ret;
 
        /** Copy f_pos from backing file, since f_ops->llseek() sets it */
        file->f_pos = asma->file->f_pos;
-
-out:
-       mutex_unlock(&ashmem_mutex);
        return ret;
 }
 
@@ -702,30 +701,30 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd,
        size_t pgstart, pgend;
        int ret = -EINVAL;
 
-       if (unlikely(!asma->file))
-               return -EINVAL;
-
        if (unlikely(copy_from_user(&pin, p, sizeof(pin))))
                return -EFAULT;
 
+       mutex_lock(&ashmem_mutex);
+
+       if (unlikely(!asma->file))
+               goto out_unlock;
+
        /* per custom, you can pass zero for len to mean "everything onward" */
        if (!pin.len)
                pin.len = PAGE_ALIGN(asma->size) - pin.offset;
 
        if (unlikely((pin.offset | pin.len) & ~PAGE_MASK))
-               return -EINVAL;
+               goto out_unlock;
 
        if (unlikely(((__u32)-1) - pin.offset < pin.len))
-               return -EINVAL;
+               goto out_unlock;
 
        if (unlikely(PAGE_ALIGN(asma->size) < pin.offset + pin.len))
-               return -EINVAL;
+               goto out_unlock;
 
        pgstart = pin.offset / PAGE_SIZE;
        pgend = pgstart + (pin.len / PAGE_SIZE) - 1;
 
-       mutex_lock(&ashmem_mutex);
-
        switch (cmd) {
        case ASHMEM_PIN:
                ret = ashmem_pin(asma, pgstart, pgend);
@@ -738,6 +737,7 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd,
                break;
        }
 
+out_unlock:
        mutex_unlock(&ashmem_mutex);
 
        return ret;
index 94e06925c712b5e52bb06d240ee33057077f8b0a..49718c96bf9ee3de6734ec9acfde9aa8fbc738d8 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/cma.h>
 #include <linux/scatterlist.h>
+#include <linux/highmem.h>
 
 #include "ion.h"
 
@@ -42,6 +43,22 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
        if (!pages)
                return -ENOMEM;
 
+       if (PageHighMem(pages)) {
+               unsigned long nr_clear_pages = nr_pages;
+               struct page *page = pages;
+
+               while (nr_clear_pages > 0) {
+                       void *vaddr = kmap_atomic(page);
+
+                       memset(vaddr, 0, PAGE_SIZE);
+                       kunmap_atomic(vaddr);
+                       page++;
+                       nr_clear_pages--;
+               }
+       } else {
+               memset(page_address(pages), 0, size);
+       }
+
        table = kmalloc(sizeof(*table), GFP_KERNEL);
        if (!table)
                goto err;
index e618a87521a35606cb97cae84d50fbcdfe13f688..9d733471ca2ede9c997e7a41262f7c1a3ca6635a 100644 (file)
@@ -475,8 +475,7 @@ unsigned int comedi_nsamples_left(struct comedi_subdevice *s,
        struct comedi_cmd *cmd = &async->cmd;
 
        if (cmd->stop_src == TRIG_COUNT) {
-               unsigned int nscans = nsamples / cmd->scan_end_arg;
-               unsigned int scans_left = __comedi_nscans_left(s, nscans);
+               unsigned int scans_left = __comedi_nscans_left(s, cmd->stop_arg);
                unsigned int scan_pos =
                    comedi_bytes_to_samples(s, async->scan_progress);
                unsigned long long samples_left = 0;
index 1f91000491767a9c049a27b3f27edf4c3c39b4fe..b35ef7ee690146fe257bcd81516b4a5e9aa264ab 100644 (file)
@@ -7,7 +7,7 @@
 
 config FSL_MC_BUS
        bool "QorIQ DPAA2 fsl-mc bus driver"
-       depends on OF && (ARCH_LAYERSCAPE || (COMPILE_TEST && (ARM || ARM64 || X86 || PPC)))
+       depends on OF && (ARCH_LAYERSCAPE || (COMPILE_TEST && (ARM || ARM64 || X86_LOCAL_APIC || PPC)))
        select GENERIC_MSI_IRQ_DOMAIN
        help
          Driver to enable the bus infrastructure for the QorIQ DPAA2
index 5064d5ddf581c2282eba49ab87a668da83a5aeee..fc2013aade51b6be6d281a1e14525cc24fa4f0ca 100644 (file)
@@ -73,6 +73,8 @@ static int __init its_fsl_mc_msi_init(void)
 
        for (np = of_find_matching_node(NULL, its_device_id); np;
             np = of_find_matching_node(np, its_device_id)) {
+               if (!of_device_is_available(np))
+                       continue;
                if (!of_property_read_bool(np, "msi-controller"))
                        continue;
 
index f01595593ce2d25558a51d47ec2eece33767f002..425e8b82533bb3e637e52ef3c1f48a24f3cc3afa 100644 (file)
 #define AD7192_GPOCON_P1DAT    BIT(1) /* P1 state */
 #define AD7192_GPOCON_P0DAT    BIT(0) /* P0 state */
 
+#define AD7192_EXT_FREQ_MHZ_MIN        2457600
+#define AD7192_EXT_FREQ_MHZ_MAX        5120000
 #define AD7192_INT_FREQ_MHZ    4915200
 
 /* NOTE:
@@ -218,6 +220,12 @@ static int ad7192_calibrate_all(struct ad7192_state *st)
                                ARRAY_SIZE(ad7192_calib_arr));
 }
 
+static inline bool ad7192_valid_external_frequency(u32 freq)
+{
+       return (freq >= AD7192_EXT_FREQ_MHZ_MIN &&
+               freq <= AD7192_EXT_FREQ_MHZ_MAX);
+}
+
 static int ad7192_setup(struct ad7192_state *st,
                        const struct ad7192_platform_data *pdata)
 {
@@ -243,17 +251,20 @@ static int ad7192_setup(struct ad7192_state *st,
                         id);
 
        switch (pdata->clock_source_sel) {
-       case AD7192_CLK_EXT_MCLK1_2:
-       case AD7192_CLK_EXT_MCLK2:
-               st->mclk = AD7192_INT_FREQ_MHZ;
-               break;
        case AD7192_CLK_INT:
        case AD7192_CLK_INT_CO:
-               if (pdata->ext_clk_hz)
-                       st->mclk = pdata->ext_clk_hz;
-               else
-                       st->mclk = AD7192_INT_FREQ_MHZ;
+               st->mclk = AD7192_INT_FREQ_MHZ;
                break;
+       case AD7192_CLK_EXT_MCLK1_2:
+       case AD7192_CLK_EXT_MCLK2:
+               if (ad7192_valid_external_frequency(pdata->ext_clk_hz)) {
+                       st->mclk = pdata->ext_clk_hz;
+                       break;
+               }
+               dev_err(&st->sd.spi->dev, "Invalid frequency setting %u\n",
+                       pdata->ext_clk_hz);
+               ret = -EINVAL;
+               goto out;
        default:
                ret = -EINVAL;
                goto out;
index 2b28fb9c0048e6c56e4b2c80c67f7e51c997c07b..3bcf494663617b73883241d73613f46324749e4b 100644 (file)
@@ -648,8 +648,6 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
        /* Ring buffer functions - here trigger setup related */
        indio_dev->setup_ops = &ad5933_ring_setup_ops;
 
-       indio_dev->modes |= INDIO_BUFFER_HARDWARE;
-
        return 0;
 }
 
@@ -762,7 +760,7 @@ static int ad5933_probe(struct i2c_client *client,
        indio_dev->dev.parent = &client->dev;
        indio_dev->info = &ad5933_info;
        indio_dev->name = id->name;
-       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE);
        indio_dev->channels = ad5933_channels;
        indio_dev->num_channels = ARRAY_SIZE(ad5933_channels);
 
index 804adfebba2f7e4631caa5c1205a5481e915cfb9..3e047eb4cc7c755f6863a3cf739c1a663d52adda 100644 (file)
@@ -981,6 +981,10 @@ ncp_read_kernel(struct ncp_server *server, const char *file_id,
                goto out;
        }
        *bytes_read = ncp_reply_be16(server, 0);
+       if (*bytes_read > to_read) {
+               result = -EINVAL;
+               goto out;
+       }
        source = ncp_reply_data(server, 2 + (offset & 1));
 
        memcpy(target, source, *bytes_read);
index 5c0e59e8fe46b087b58b213d6ee04ecfc7f36e3a..cbe98bc2b998276fd95b2d8086a6fabcf2351bf7 100644 (file)
@@ -2180,6 +2180,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
                                }
                                if (tty_hung_up_p(file))
                                        break;
+                               /*
+                                * Abort readers for ttys which never actually
+                                * get hung up.  See __tty_hangup().
+                                */
+                               if (test_bit(TTY_HUPPING, &tty->flags))
+                                       break;
                                if (!timeout)
                                        break;
                                if (file->f_flags & O_NONBLOCK) {
index 54adf8d563501ab844cea41edf0427fdb83a1a8e..a93f77ab3da089d9db5874c81a631f6a2f090a19 100644 (file)
@@ -3387,11 +3387,9 @@ static int serial_pci_is_class_communication(struct pci_dev *dev)
        /*
         * If it is not a communications device or the programming
         * interface is greater than 6, give up.
-        *
-        * (Should we try to make guesses for multiport serial devices
-        * later?)
         */
        if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
+            ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MULTISERIAL) &&
             ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
            (dev->class & 0xff) > 6)
                return -ENODEV;
@@ -3428,6 +3426,12 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
 {
        int num_iomem, num_port, first_port = -1, i;
 
+       /*
+        * Should we try to make guesses for multiport serial devices later?
+        */
+       if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_MULTISERIAL)
+               return -ENODEV;
+
        num_iomem = num_port = 0;
        for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
                if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
@@ -4698,6 +4702,17 @@ static const struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,    /* 135a.0dc0 */
                pbn_b2_4_115200 },
+       /*
+        * BrainBoxes UC-260
+        */
+       {       PCI_VENDOR_ID_INTASHIELD, 0x0D21,
+               PCI_ANY_ID, PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
+               pbn_b2_4_115200 },
+       {       PCI_VENDOR_ID_INTASHIELD, 0x0E34,
+               PCI_ANY_ID, PCI_ANY_ID,
+                PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
+               pbn_b2_4_115200 },
        /*
         * Perle PCI-RAS cards
         */
index df46a9e88c34dd89eaa766603fd5738c6d99ac9a..e287fe8f10fc035072f0f7ced35c0860616fe100 100644 (file)
@@ -1734,6 +1734,7 @@ static void atmel_get_ip_name(struct uart_port *port)
                switch (version) {
                case 0x302:
                case 0x10213:
+               case 0x10302:
                        dev_dbg(port->dev, "This version is usart\n");
                        atmel_port->has_frac_baudrate = true;
                        atmel_port->has_hw_timer = true;
index 870e84fb6e39ebb8fbfbc31f1a3608caddf6072d..a24278380fec2a6a67b2513514f08ecd6688dfe2 100644 (file)
@@ -245,11 +245,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match,
        }
        port->mapbase = addr;
        port->uartclk = BASE_BAUD * 16;
-       port->membase = earlycon_map(port->mapbase, SZ_4K);
 
        val = of_get_flat_dt_prop(node, "reg-offset", NULL);
        if (val)
                port->mapbase += be32_to_cpu(*val);
+       port->membase = earlycon_map(port->mapbase, SZ_4K);
+
        val = of_get_flat_dt_prop(node, "reg-shift", NULL);
        if (val)
                port->regshift = be32_to_cpu(*val);
index 1d7ca382bc12b2381eba26cf93eb67ec80853977..a33c685af99076953d99718ee05b0e2e97d4b803 100644 (file)
@@ -2093,7 +2093,7 @@ static int serial_imx_probe(struct platform_device *pdev)
        uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
 
        if (sport->port.rs485.flags & SER_RS485_ENABLED &&
-           (!sport->have_rtscts || !sport->have_rtsgpio))
+           (!sport->have_rtscts && !sport->have_rtsgpio))
                dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
 
        imx_rs485_config(&sport->port, &sport->port.rs485);
index c8dde56b532b2d88fdf15f29f7e81251c39be4ff..35b9201db3b4bb8bcb9219259ec04c98fbab6250 100644 (file)
@@ -1144,6 +1144,8 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state)
                uport->ops->config_port(uport, flags);
 
                ret = uart_startup(tty, state, 1);
+               if (ret == 0)
+                       tty_port_set_initialized(port, true);
                if (ret > 0)
                        ret = 0;
        }
index 7257c078e1554b198a29221b9ce142b5f98305ab..44adf9db38f8955b6cf730108abe5d72c87ef3e9 100644 (file)
@@ -885,6 +885,8 @@ static void sci_receive_chars(struct uart_port *port)
                /* Tell the rest of the system the news. New characters! */
                tty_flip_buffer_push(tport);
        } else {
+               /* TTY buffers full; read from RX reg to prevent lockup */
+               serial_port_in(port, SCxRDR);
                serial_port_in(port, SCxSR); /* dummy read */
                sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
        }
index eb9133b472f4849e831fd1a4a1c70cf6e917ba28..63114ea35ec1b8f3620ec888155b929ed1915200 100644 (file)
@@ -586,6 +586,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
                return;
        }
 
+       /*
+        * Some console devices aren't actually hung up for technical and
+        * historical reasons, which can lead to indefinite interruptible
+        * sleep in n_tty_read().  The following explicitly tells
+        * n_tty_read() to abort readers.
+        */
+       set_bit(TTY_HUPPING, &tty->flags);
+
        /* inuse_filps is protected by the single tty lock,
           this really needs to change if we want to flush the
           workqueue with the lock held */
@@ -640,6 +648,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
         * from the ldisc side, which is now guaranteed.
         */
        set_bit(TTY_HUPPED, &tty->flags);
+       clear_bit(TTY_HUPPING, &tty->flags);
        tty_unlock(tty);
 
        if (f)
index 88b902c525d7455e3e0398623d5c54dc65ad0ab9..b4e57c5a8bba6f30e4fe42c47baf591840f8da28 100644 (file)
@@ -1727,7 +1727,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
        default_attr(vc);
        update_attr(vc);
 
-       vc->vc_tab_stop[0]      = 0x01010100;
+       vc->vc_tab_stop[0]      =
        vc->vc_tab_stop[1]      =
        vc->vc_tab_stop[2]      =
        vc->vc_tab_stop[3]      =
@@ -1771,7 +1771,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                vc->vc_pos -= (vc->vc_x << 1);
                while (vc->vc_x < vc->vc_cols - 1) {
                        vc->vc_x++;
-                       if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
+                       if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31)))
                                break;
                }
                vc->vc_pos += (vc->vc_x << 1);
@@ -1831,7 +1831,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                        lf(vc);
                        return;
                case 'H':
-                       vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
+                       vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31));
                        return;
                case 'Z':
                        respond_ID(tty);
@@ -2024,7 +2024,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                        return;
                case 'g':
                        if (!vc->vc_par[0])
-                               vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
+                               vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31));
                        else if (vc->vc_par[0] == 3) {
                                vc->vc_tab_stop[0] =
                                        vc->vc_tab_stop[1] =
index f699abab17875ed26c6d56353c8eb87785664a54..148f3ee7028680b573bef22adebd9c908d75bd0b 100644 (file)
@@ -19,6 +19,12 @@ config USB_EHCI_BIG_ENDIAN_MMIO
 config USB_EHCI_BIG_ENDIAN_DESC
        bool
 
+config USB_UHCI_BIG_ENDIAN_MMIO
+       bool
+
+config USB_UHCI_BIG_ENDIAN_DESC
+       bool
+
 menuconfig USB_SUPPORT
        bool "USB support"
        depends on HAS_IOMEM
index 06b3b54a0e6804494c64c89a9f9181981a1f9c61..7b366a6c0b493f2eb8bec4959830d222223f3cb2 100644 (file)
@@ -174,6 +174,7 @@ static int acm_wb_alloc(struct acm *acm)
                wb = &acm->wb[wbn];
                if (!wb->use) {
                        wb->use = 1;
+                       wb->len = 0;
                        return wbn;
                }
                wbn = (wbn + 1) % ACM_NW;
@@ -805,16 +806,18 @@ static int acm_tty_write(struct tty_struct *tty,
 static void acm_tty_flush_chars(struct tty_struct *tty)
 {
        struct acm *acm = tty->driver_data;
-       struct acm_wb *cur = acm->putbuffer;
+       struct acm_wb *cur;
        int err;
        unsigned long flags;
 
+       spin_lock_irqsave(&acm->write_lock, flags);
+
+       cur = acm->putbuffer;
        if (!cur) /* nothing to do */
-               return;
+               goto out;
 
        acm->putbuffer = NULL;
        err = usb_autopm_get_interface_async(acm->control);
-       spin_lock_irqsave(&acm->write_lock, flags);
        if (err < 0) {
                cur->use = 0;
                acm->putbuffer = cur;
index c64cf6c4a83dde975fa90188f2b5f08cec91d688..0c11d40a12bcfa9a012edb8a4bf0d41d6a844365 100644 (file)
@@ -151,6 +151,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
 
        ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
 
+       /* Linger a bit, prior to the next control message. */
+       if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
+               msleep(200);
+
        kfree(dr);
 
        return ret;
index 4024926c1d68c93e97e40f822c4a690a4c113987..54b019e267c5d4b28613ccb99ab253749b016ffa 100644 (file)
@@ -226,8 +226,12 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
                        USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+       /* Corsair K70 RGB */
+       { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT },
+
        /* Corsair Strafe RGB */
-       { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
+       { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT |
+         USB_QUIRK_DELAY_CTRL_MSG },
 
        /* Corsair K70 LUX */
        { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
index e4c3ce0de5de11ba5532fb34c8b8d72e1fd98511..5bcad1d869b5070c628bf3b074ed078a5a9ed0c1 100644 (file)
@@ -1917,7 +1917,9 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
                /* Not specific buffer needed for ep0 ZLP */
                dma_addr_t dma = hs_ep->desc_list_dma;
 
-               dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);
+               if (!index)
+                       dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep);
+
                dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0);
        } else {
                dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
@@ -2974,9 +2976,13 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
        if (ints & DXEPINT_STSPHSERCVD) {
                dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__);
 
-               /* Move to STATUS IN for DDMA */
-               if (using_desc_dma(hsotg))
-                       dwc2_hsotg_ep0_zlp(hsotg, true);
+               /* Safety check EP0 state when STSPHSERCVD asserted */
+               if (hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
+                       /* Move to STATUS IN for DDMA */
+                       if (using_desc_dma(hsotg))
+                               dwc2_hsotg_ep0_zlp(hsotg, true);
+               }
+
        }
 
        if (ints & DXEPINT_BACK2BACKSETUP)
@@ -3375,12 +3381,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
        dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
               DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0);
 
-       dwc2_hsotg_enqueue_setup(hsotg);
-
-       dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-               dwc2_readl(hsotg->regs + DIEPCTL0),
-               dwc2_readl(hsotg->regs + DOEPCTL0));
-
        /* clear global NAKs */
        val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;
        if (!is_usb_reset)
@@ -3391,6 +3391,12 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
        mdelay(3);
 
        hsotg->lx_state = DWC2_L0;
+
+       dwc2_hsotg_enqueue_setup(hsotg);
+
+       dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
+               dwc2_readl(hsotg->regs + DIEPCTL0),
+               dwc2_readl(hsotg->regs + DOEPCTL0));
 }
 
 static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
index 03fd20f0b49613aaffba14aa117e48a7781391a5..c4a47496d2fb92a9ee7488a9e71446bfac0a488a 100644 (file)
@@ -137,7 +137,7 @@ static void dwc2_set_stm32f4x9_fsotg_params(struct dwc2_hsotg *hsotg)
        p->activate_stm_fs_transceiver = true;
 }
 
-static void dwc2_set_stm32f7xx_hsotg_params(struct dwc2_hsotg *hsotg)
+static void dwc2_set_stm32f7_hsotg_params(struct dwc2_hsotg *hsotg)
 {
        struct dwc2_core_params *p = &hsotg->params;
 
@@ -164,8 +164,8 @@ const struct of_device_id dwc2_of_match_table[] = {
        { .compatible = "st,stm32f4x9-fsotg",
          .data = dwc2_set_stm32f4x9_fsotg_params },
        { .compatible = "st,stm32f4x9-hsotg" },
-       { .compatible = "st,stm32f7xx-hsotg",
-         .data = dwc2_set_stm32f7xx_hsotg_params },
+       { .compatible = "st,stm32f7-hsotg",
+         .data = dwc2_set_stm32f7_hsotg_params },
        {},
 };
 MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
index ade2ab00d37ab1255a168b5f5e8d0911c1051a2f..e94bf91cc58a8821978418b6286fc0f8f2cd6e1d 100644 (file)
@@ -100,6 +100,8 @@ static void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
        reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
        reg |= DWC3_GCTL_PRTCAPDIR(mode);
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+
+       dwc->current_dr_role = mode;
 }
 
 static void __dwc3_set_mode(struct work_struct *work)
@@ -133,8 +135,6 @@ static void __dwc3_set_mode(struct work_struct *work)
 
        dwc3_set_prtcap(dwc, dwc->desired_dr_role);
 
-       dwc->current_dr_role = dwc->desired_dr_role;
-
        spin_unlock_irqrestore(&dwc->lock, flags);
 
        switch (dwc->desired_dr_role) {
@@ -175,7 +175,7 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
        dwc->desired_dr_role = mode;
        spin_unlock_irqrestore(&dwc->lock, flags);
 
-       queue_work(system_power_efficient_wq, &dwc->drd_work);
+       queue_work(system_freezable_wq, &dwc->drd_work);
 }
 
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
@@ -219,7 +219,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
         * XHCI driver will reset the host block. If dwc3 was configured for
         * host-only mode, then we can return early.
         */
-       if (dwc->dr_mode == USB_DR_MODE_HOST)
+       if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
                return 0;
 
        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -234,6 +234,9 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
                udelay(1);
        } while (--retries);
 
+       phy_exit(dwc->usb3_generic_phy);
+       phy_exit(dwc->usb2_generic_phy);
+
        return -ETIMEDOUT;
 }
 
@@ -483,6 +486,22 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
        parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
 }
 
+static int dwc3_core_ulpi_init(struct dwc3 *dwc)
+{
+       int intf;
+       int ret = 0;
+
+       intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);
+
+       if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
+           (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
+            dwc->hsphy_interface &&
+            !strncmp(dwc->hsphy_interface, "ulpi", 4)))
+               ret = dwc3_ulpi_init(dwc);
+
+       return ret;
+}
+
 /**
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -494,7 +513,6 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
 static int dwc3_phy_setup(struct dwc3 *dwc)
 {
        u32 reg;
-       int ret;
 
        reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
@@ -565,9 +583,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
                }
                /* FALLTHROUGH */
        case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
-               ret = dwc3_ulpi_init(dwc);
-               if (ret)
-                       return ret;
                /* FALLTHROUGH */
        default:
                break;
@@ -724,6 +739,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
 }
 
 static int dwc3_core_get_phy(struct dwc3 *dwc);
+static int dwc3_core_ulpi_init(struct dwc3 *dwc);
 
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
@@ -755,17 +771,27 @@ static int dwc3_core_init(struct dwc3 *dwc)
                        dwc->maximum_speed = USB_SPEED_HIGH;
        }
 
-       ret = dwc3_core_get_phy(dwc);
+       ret = dwc3_phy_setup(dwc);
        if (ret)
                goto err0;
 
-       ret = dwc3_core_soft_reset(dwc);
-       if (ret)
-               goto err0;
+       if (!dwc->ulpi_ready) {
+               ret = dwc3_core_ulpi_init(dwc);
+               if (ret)
+                       goto err0;
+               dwc->ulpi_ready = true;
+       }
 
-       ret = dwc3_phy_setup(dwc);
+       if (!dwc->phys_ready) {
+               ret = dwc3_core_get_phy(dwc);
+               if (ret)
+                       goto err0a;
+               dwc->phys_ready = true;
+       }
+
+       ret = dwc3_core_soft_reset(dwc);
        if (ret)
-               goto err0;
+               goto err0a;
 
        dwc3_core_setup_global_control(dwc);
        dwc3_core_num_eps(dwc);
@@ -838,6 +864,9 @@ err1:
        phy_exit(dwc->usb2_generic_phy);
        phy_exit(dwc->usb3_generic_phy);
 
+err0a:
+       dwc3_ulpi_exit(dwc);
+
 err0:
        return ret;
 }
@@ -916,7 +945,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
 
        switch (dwc->dr_mode) {
        case USB_DR_MODE_PERIPHERAL:
-               dwc->current_dr_role = DWC3_GCTL_PRTCAP_DEVICE;
                dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
 
                if (dwc->usb2_phy)
@@ -932,7 +960,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
                }
                break;
        case USB_DR_MODE_HOST:
-               dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST;
                dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
 
                if (dwc->usb2_phy)
@@ -1234,7 +1261,6 @@ err4:
 
 err3:
        dwc3_free_event_buffers(dwc);
-       dwc3_ulpi_exit(dwc);
 
 err2:
        pm_runtime_allow(&pdev->dev);
@@ -1284,7 +1310,7 @@ static int dwc3_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int dwc3_suspend_common(struct dwc3 *dwc)
+static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
 {
        unsigned long   flags;
 
@@ -1296,6 +1322,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
                dwc3_core_exit(dwc);
                break;
        case DWC3_GCTL_PRTCAP_HOST:
+               /* do nothing during host runtime_suspend */
+               if (!PMSG_IS_AUTO(msg))
+                       dwc3_core_exit(dwc);
+               break;
        default:
                /* do nothing */
                break;
@@ -1304,7 +1334,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
        return 0;
 }
 
-static int dwc3_resume_common(struct dwc3 *dwc)
+static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
 {
        unsigned long   flags;
        int             ret;
@@ -1320,6 +1350,13 @@ static int dwc3_resume_common(struct dwc3 *dwc)
                spin_unlock_irqrestore(&dwc->lock, flags);
                break;
        case DWC3_GCTL_PRTCAP_HOST:
+               /* nothing to do on host runtime_resume */
+               if (!PMSG_IS_AUTO(msg)) {
+                       ret = dwc3_core_init(dwc);
+                       if (ret)
+                               return ret;
+               }
+               break;
        default:
                /* do nothing */
                break;
@@ -1331,12 +1368,11 @@ static int dwc3_resume_common(struct dwc3 *dwc)
 static int dwc3_runtime_checks(struct dwc3 *dwc)
 {
        switch (dwc->current_dr_role) {
-       case USB_DR_MODE_PERIPHERAL:
-       case USB_DR_MODE_OTG:
+       case DWC3_GCTL_PRTCAP_DEVICE:
                if (dwc->connected)
                        return -EBUSY;
                break;
-       case USB_DR_MODE_HOST:
+       case DWC3_GCTL_PRTCAP_HOST:
        default:
                /* do nothing */
                break;
@@ -1353,7 +1389,7 @@ static int dwc3_runtime_suspend(struct device *dev)
        if (dwc3_runtime_checks(dwc))
                return -EBUSY;
 
-       ret = dwc3_suspend_common(dwc);
+       ret = dwc3_suspend_common(dwc, PMSG_AUTO_SUSPEND);
        if (ret)
                return ret;
 
@@ -1369,7 +1405,7 @@ static int dwc3_runtime_resume(struct device *dev)
 
        device_init_wakeup(dev, false);
 
-       ret = dwc3_resume_common(dwc);
+       ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME);
        if (ret)
                return ret;
 
@@ -1416,7 +1452,7 @@ static int dwc3_suspend(struct device *dev)
        struct dwc3     *dwc = dev_get_drvdata(dev);
        int             ret;
 
-       ret = dwc3_suspend_common(dwc);
+       ret = dwc3_suspend_common(dwc, PMSG_SUSPEND);
        if (ret)
                return ret;
 
@@ -1432,7 +1468,7 @@ static int dwc3_resume(struct device *dev)
 
        pinctrl_pm_select_default_state(dev);
 
-       ret = dwc3_resume_common(dwc);
+       ret = dwc3_resume_common(dwc, PMSG_RESUME);
        if (ret)
                return ret;
 
index 03c7aaaac9268dbc61fa7fdfc47a1b37dd7b7f9c..860d2bc184d1c4a29e0a17ea648152c014cb50fc 100644 (file)
 #define DWC3_GDBGFIFOSPACE_TYPE(n)     (((n) << 5) & 0x1e0)
 #define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff)
 
-#define DWC3_TXFIFOQ           1
-#define DWC3_RXFIFOQ           3
-#define DWC3_TXREQQ            5
-#define DWC3_RXREQQ            7
-#define DWC3_RXINFOQ           9
-#define DWC3_DESCFETCHQ                13
-#define DWC3_EVENTQ            15
+#define DWC3_TXFIFOQ           0
+#define DWC3_RXFIFOQ           1
+#define DWC3_TXREQQ            2
+#define DWC3_RXREQQ            3
+#define DWC3_RXINFOQ           4
+#define DWC3_PSTATQ            5
+#define DWC3_DESCFETCHQ                6
+#define DWC3_EVENTQ            7
+#define DWC3_AUXEVENTQ         8
 
 /* Global RX Threshold Configuration Register */
 #define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19)
@@ -795,7 +797,9 @@ struct dwc3_scratchpad_array {
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
  * @usb3_generic_phy: pointer to USB3 PHY
+ * @phys_ready: flag to indicate that PHYs are ready
  * @ulpi: pointer to ulpi interface
+ * @ulpi_ready: flag to indicate that ULPI is initialized
  * @u2sel: parameter from Set SEL request.
  * @u2pel: parameter from Set SEL request.
  * @u1sel: parameter from Set SEL request.
@@ -893,7 +897,10 @@ struct dwc3 {
        struct phy              *usb2_generic_phy;
        struct phy              *usb3_generic_phy;
 
+       bool                    phys_ready;
+
        struct ulpi             *ulpi;
+       bool                    ulpi_ready;
 
        void __iomem            *regs;
        size_t                  regs_size;
index 7ae0eefc7cc7daf0382c7aeaa56c14659f025ffb..e54c3622eb28a909aa5beb1d61ec09ec1324d082 100644 (file)
@@ -143,6 +143,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev)
                clk_disable_unprepare(simple->clks[i]);
                clk_put(simple->clks[i]);
        }
+       simple->num_clocks = 0;
 
        reset_control_assert(simple->resets);
        reset_control_put(simple->resets);
index a4719e853b85a96c185c6a011e10a353bc7d8d94..ed8b865176758fdeef0fc4d7c754793aad580ac0 100644 (file)
@@ -582,9 +582,25 @@ static int dwc3_omap_resume(struct device *dev)
        return 0;
 }
 
+static void dwc3_omap_complete(struct device *dev)
+{
+       struct dwc3_omap        *omap = dev_get_drvdata(dev);
+
+       if (extcon_get_state(omap->edev, EXTCON_USB))
+               dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
+       else
+               dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
+
+       if (extcon_get_state(omap->edev, EXTCON_USB_HOST))
+               dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
+       else
+               dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
+}
+
 static const struct dev_pm_ops dwc3_omap_dev_pm_ops = {
 
        SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
+       .complete = dwc3_omap_complete,
 };
 
 #define DEV_PM_OPS     (&dwc3_omap_dev_pm_ops)
index 9c2e4a17918e4c98fbd6d383a91d02388168e2b3..18be31d5743a1e64528c1567612f26be95106878 100644 (file)
@@ -854,7 +854,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
                trb++;
                trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
                trace_dwc3_complete_trb(ep0, trb);
-               ep0->trb_enqueue = 0;
+
+               if (r->direction)
+                       dwc->eps[1]->trb_enqueue = 0;
+               else
+                       dwc->eps[0]->trb_enqueue = 0;
+
                dwc->ep0_bounced = false;
        }
 
index 616ef49ccb49e106c6a454c1351806bb18b1a257..2bda4eb1e9ac175858189c498af875ed8315df80 100644 (file)
@@ -2745,6 +2745,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
                break;
        }
 
+       dwc->eps[1]->endpoint.maxpacket = dwc->gadget.ep0->maxpacket;
+
        /* Enable USB2 LPM Capability */
 
        if ((dwc->revision > DWC3_REVISION_194A) &&
index 8f2cf3baa19c10676915acbf4406a474e2e3e2a2..d2428a9e89003adcb5949c0636d3c0ffd940766d 100644 (file)
@@ -1538,7 +1538,6 @@ ffs_fs_kill_sb(struct super_block *sb)
        if (sb->s_fs_info) {
                ffs_release_dev(sb->s_fs_info);
                ffs_data_closed(sb->s_fs_info);
-               ffs_data_put(sb->s_fs_info);
        }
 }
 
@@ -1855,44 +1854,20 @@ static int ffs_func_eps_enable(struct ffs_function *func)
 
        spin_lock_irqsave(&func->ffs->eps_lock, flags);
        while(count--) {
-               struct usb_endpoint_descriptor *ds;
-               struct usb_ss_ep_comp_descriptor *comp_desc = NULL;
-               int needs_comp_desc = false;
-               int desc_idx;
-
-               if (ffs->gadget->speed == USB_SPEED_SUPER) {
-                       desc_idx = 2;
-                       needs_comp_desc = true;
-               } else if (ffs->gadget->speed == USB_SPEED_HIGH)
-                       desc_idx = 1;
-               else
-                       desc_idx = 0;
-
-               /* fall-back to lower speed if desc missing for current speed */
-               do {
-                       ds = ep->descs[desc_idx];
-               } while (!ds && --desc_idx >= 0);
-
-               if (!ds) {
-                       ret = -EINVAL;
-                       break;
-               }
-
                ep->ep->driver_data = ep;
-               ep->ep->desc = ds;
 
-               if (needs_comp_desc) {
-                       comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
-                                       USB_DT_ENDPOINT_SIZE);
-                       ep->ep->maxburst = comp_desc->bMaxBurst + 1;
-                       ep->ep->comp_desc = comp_desc;
+               ret = config_ep_by_speed(func->gadget, &func->function, ep->ep);
+               if (ret) {
+                       pr_err("%s: config_ep_by_speed(%s) returned %d\n",
+                                       __func__, ep->ep->name, ret);
+                       break;
                }
 
                ret = usb_ep_enable(ep->ep);
                if (likely(!ret)) {
                        epfile->ep = ep;
-                       epfile->in = usb_endpoint_dir_in(ds);
-                       epfile->isoc = usb_endpoint_xfer_isoc(ds);
+                       epfile->in = usb_endpoint_dir_in(ep->ep->desc);
+                       epfile->isoc = usb_endpoint_xfer_isoc(ep->ep->desc);
                } else {
                        break;
                }
@@ -2979,10 +2954,8 @@ static int _ffs_func_bind(struct usb_configuration *c,
        struct ffs_data *ffs = func->ffs;
 
        const int full = !!func->ffs->fs_descs_count;
-       const int high = gadget_is_dualspeed(func->gadget) &&
-               func->ffs->hs_descs_count;
-       const int super = gadget_is_superspeed(func->gadget) &&
-               func->ffs->ss_descs_count;
+       const int high = !!func->ffs->hs_descs_count;
+       const int super = !!func->ffs->ss_descs_count;
 
        int fs_len, hs_len, ss_len, ret, i;
        struct ffs_ep *eps_ptr;
index 11fe788b430879d3559b5a6fda7a4a563cd22c34..d2dc1f00180b7869201afc1dbd82dcd4b126ab16 100644 (file)
@@ -524,6 +524,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
                dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
                return ret;
        }
+       iad_desc.bFirstInterface = ret;
+
        std_ac_if_desc.bInterfaceNumber = ret;
        uac2->ac_intf = ret;
        uac2->ac_alt = 0;
index 1e9567091d86073f6e77f85021531de142c055a2..0875d38476ee9395fe33b1bb0d9b865e28322b24 100644 (file)
@@ -274,7 +274,6 @@ config USB_SNP_UDC_PLAT
        tristate "Synopsys USB 2.0 Device controller"
        depends on USB_GADGET && OF && HAS_DMA
        depends on EXTCON || EXTCON=n
-       select USB_GADGET_DUALSPEED
        select USB_SNP_CORE
        default ARCH_BCM_IPROC
        help
index 1e940f054cb8c41cb2150cd621eae1580f256bec..6dbc489513cdbbc5564598b0be10b2fce668c1e2 100644 (file)
@@ -77,6 +77,7 @@ static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
        if (ret) {
                dev_err(&pci->dev,
                        "couldn't add resources to bdc device\n");
+               platform_device_put(bdc);
                return ret;
        }
 
index 859d5b11ba4c45353ce4174b1e0436db67189b90..1f8b19d9cf97bdd2224102a3e2a1684460c6a46f 100644 (file)
@@ -180,8 +180,8 @@ EXPORT_SYMBOL_GPL(usb_ep_alloc_request);
 void usb_ep_free_request(struct usb_ep *ep,
                                       struct usb_request *req)
 {
-       ep->ops->free_request(ep, req);
        trace_usb_ep_free_request(ep, req, 0);
+       ep->ops->free_request(ep, req);
 }
 EXPORT_SYMBOL_GPL(usb_ep_free_request);
 
index e5b4ee96c4bf6817e8e84f2af81644732b008ff3..56b517a38865aace8b212a75044d8ab29bf575ec 100644 (file)
@@ -1305,7 +1305,7 @@ static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
 {
        struct fsl_ep *ep = get_ep_by_pipe(udc, pipe);
 
-       if (ep->name)
+       if (ep->ep.name)
                nuke(ep, -ESHUTDOWN);
 }
 
@@ -1693,7 +1693,7 @@ static void dtd_complete_irq(struct fsl_udc *udc)
                curr_ep = get_ep_by_pipe(udc, i);
 
                /* If the ep is configured */
-               if (curr_ep->name == NULL) {
+               if (!curr_ep->ep.name) {
                        WARNING("Invalid EP?");
                        continue;
                }
index 6e87af2483679aac59f23e942dde9367a30d35e4..409cde4e6a516495da098e6648d70069db3a738d 100644 (file)
@@ -2410,7 +2410,7 @@ static int renesas_usb3_remove(struct platform_device *pdev)
        __renesas_usb3_ep_free_request(usb3->ep0_req);
        if (usb3->phy)
                phy_put(usb3->phy);
-       pm_runtime_disable(usb3_to_dev(usb3));
+       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
index 6150bed7cfa80d19b7f04dc6ae89cef14ce1fb5b..4fcfb3084b3689102657641cfd674656fd1ca5c3 100644 (file)
@@ -633,14 +633,6 @@ config USB_UHCI_ASPEED
        bool
        default y if ARCH_ASPEED
 
-config USB_UHCI_BIG_ENDIAN_MMIO
-       bool
-       default y if SPARC_LEON
-
-config USB_UHCI_BIG_ENDIAN_DESC
-       bool
-       default y if SPARC_LEON
-
 config USB_FHCI_HCD
        tristate "Freescale QE USB Host Controller support"
        depends on OF_GPIO && QE_GPIO && QUICC_ENGINE
index facafdf8fb95dbc5104124b9d580f6c68e09b59a..d7641cbdee43d64e5bfcaff7c0628988f3c370fc 100644 (file)
@@ -774,12 +774,12 @@ static struct urb *request_single_step_set_feature_urb(
        atomic_inc(&urb->use_count);
        atomic_inc(&urb->dev->urbnum);
        urb->setup_dma = dma_map_single(
-                       hcd->self.controller,
+                       hcd->self.sysdev,
                        urb->setup_packet,
                        sizeof(struct usb_ctrlrequest),
                        DMA_TO_DEVICE);
        urb->transfer_dma = dma_map_single(
-                       hcd->self.controller,
+                       hcd->self.sysdev,
                        urb->transfer_buffer,
                        urb->transfer_buffer_length,
                        DMA_FROM_DEVICE);
index 88158324dcae24ce8e19a881639c86dd324101b2..3276304056952b5d377ffb55971e62140c414760 100644 (file)
@@ -1188,10 +1188,10 @@ static int submit_single_step_set_feature(
         * 15 secs after the setup
         */
        if (is_setup) {
-               /* SETUP pid */
+               /* SETUP pid, and interrupt after SETUP completion */
                qtd_fill(ehci, qtd, urb->setup_dma,
                                sizeof(struct usb_ctrlrequest),
-                               token | (2 /* "setup" */ << 8), 8);
+                               QTD_IOC | token | (2 /* "setup" */ << 8), 8);
 
                submit_async(ehci, urb, &qtd_list, GFP_ATOMIC);
                return 0; /*Return now; we shall come back after 15 seconds*/
@@ -1228,12 +1228,8 @@ static int submit_single_step_set_feature(
        qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
        list_add_tail(&qtd->qtd_list, head);
 
-       /* dont fill any data in such packets */
-       qtd_fill(ehci, qtd, 0, 0, token, 0);
-
-       /* by default, enable interrupt on urb completion */
-       if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
-               qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
+       /* Interrupt after STATUS completion */
+       qtd_fill(ehci, qtd, 0, 0, token | QTD_IOC, 0);
 
        submit_async(ehci, urb, &qtd_list, GFP_KERNEL);
 
index ee96763493332458da2397bc85a24e8dfa5b70e6..d088c340e4d06eb23bf500f2a5dca7a8610460f7 100644 (file)
@@ -74,6 +74,7 @@ static const char     hcd_name [] = "ohci_hcd";
 
 #define        STATECHANGE_DELAY       msecs_to_jiffies(300)
 #define        IO_WATCHDOG_DELAY       msecs_to_jiffies(275)
+#define        IO_WATCHDOG_OFF         0xffffff00
 
 #include "ohci.h"
 #include "pci-quirks.h"
@@ -231,7 +232,7 @@ static int ohci_urb_enqueue (
                }
 
                /* Start up the I/O watchdog timer, if it's not running */
-               if (!timer_pending(&ohci->io_watchdog) &&
+               if (ohci->prev_frame_no == IO_WATCHDOG_OFF &&
                                list_empty(&ohci->eds_in_use) &&
                                !(ohci->flags & OHCI_QUIRK_QEMU)) {
                        ohci->prev_frame_no = ohci_frame_no(ohci);
@@ -446,7 +447,8 @@ static int ohci_init (struct ohci_hcd *ohci)
        struct usb_hcd *hcd = ohci_to_hcd(ohci);
 
        /* Accept arbitrarily long scatter-gather lists */
-       hcd->self.sg_tablesize = ~0;
+       if (!(hcd->driver->flags & HCD_LOCAL_MEM))
+               hcd->self.sg_tablesize = ~0;
 
        if (distrust_firmware)
                ohci->flags |= OHCI_QUIRK_HUB_POWER;
@@ -501,6 +503,7 @@ static int ohci_init (struct ohci_hcd *ohci)
                return 0;
 
        timer_setup(&ohci->io_watchdog, io_watchdog_func, 0);
+       ohci->prev_frame_no = IO_WATCHDOG_OFF;
 
        ohci->hcca = dma_alloc_coherent (hcd->self.controller,
                        sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL);
@@ -730,7 +733,7 @@ static void io_watchdog_func(struct timer_list *t)
        u32             head;
        struct ed       *ed;
        struct td       *td, *td_start, *td_next;
-       unsigned        frame_no;
+       unsigned        frame_no, prev_frame_no = IO_WATCHDOG_OFF;
        unsigned long   flags;
 
        spin_lock_irqsave(&ohci->lock, flags);
@@ -835,7 +838,7 @@ static void io_watchdog_func(struct timer_list *t)
                        }
                }
                if (!list_empty(&ohci->eds_in_use)) {
-                       ohci->prev_frame_no = frame_no;
+                       prev_frame_no = frame_no;
                        ohci->prev_wdh_cnt = ohci->wdh_cnt;
                        ohci->prev_donehead = ohci_readl(ohci,
                                        &ohci->regs->donehead);
@@ -845,6 +848,7 @@ static void io_watchdog_func(struct timer_list *t)
        }
 
  done:
+       ohci->prev_frame_no = prev_frame_no;
        spin_unlock_irqrestore(&ohci->lock, flags);
 }
 
@@ -973,6 +977,7 @@ static void ohci_stop (struct usb_hcd *hcd)
        if (quirk_nec(ohci))
                flush_work(&ohci->nec_work);
        del_timer_sync(&ohci->io_watchdog);
+       ohci->prev_frame_no = IO_WATCHDOG_OFF;
 
        ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
        ohci_usb_reset(ohci);
index fb7aaa3b9d067956b7bd6089217af6b5e2180cb8..634f3c7bf7748085758635ffe86108c948e0d08e 100644 (file)
@@ -311,8 +311,10 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
                rc = ohci_rh_suspend (ohci, 0);
        spin_unlock_irq (&ohci->lock);
 
-       if (rc == 0)
+       if (rc == 0) {
                del_timer_sync(&ohci->io_watchdog);
+               ohci->prev_frame_no = IO_WATCHDOG_OFF;
+       }
        return rc;
 }
 
index b2ec8c399363b12fd430f10667303c88ecf5bc1a..4ccb85a67bb3c65bcf3d12e393e0838d4e30ada1 100644 (file)
@@ -1019,6 +1019,8 @@ skip_ed:
                 * have modified this list.  normally it's just prepending
                 * entries (which we'd ignore), but paranoia won't hurt.
                 */
+               *last = ed->ed_next;
+               ed->ed_next = NULL;
                modified = 0;
 
                /* unlink urbs as requested, but rescan the list after
@@ -1077,21 +1079,22 @@ rescan_this:
                        goto rescan_this;
 
                /*
-                * If no TDs are queued, take ED off the ed_rm_list.
+                * If no TDs are queued, ED is now idle.
                 * Otherwise, if the HC is running, reschedule.
-                * If not, leave it on the list for further dequeues.
+                * If the HC isn't running, add ED back to the
+                * start of the list for later processing.
                 */
                if (list_empty(&ed->td_list)) {
-                       *last = ed->ed_next;
-                       ed->ed_next = NULL;
                        ed->state = ED_IDLE;
                        list_del(&ed->in_use_list);
                } else if (ohci->rh_state == OHCI_RH_RUNNING) {
-                       *last = ed->ed_next;
-                       ed->ed_next = NULL;
                        ed_schedule(ohci, ed);
                } else {
-                       last = &ed->ed_next;
+                       ed->ed_next = ohci->ed_rm_list;
+                       ohci->ed_rm_list = ed;
+                       /* Don't loop on the same ED */
+                       if (last == &ohci->ed_rm_list)
+                               last = &ed->ed_next;
                }
 
                if (modified)
index 1615367170251a2c33b3db8bef9d9cf9ab4d80f7..67ad4bb6919a22b107630bf976fc4c5c66b148e1 100644 (file)
 #define        AX_INDXC                0x30
 #define        AX_DATAC                0x34
 
+#define PT_ADDR_INDX           0xE8
+#define PT_READ_INDX           0xE4
+#define PT_SIG_1_ADDR          0xA520
+#define PT_SIG_2_ADDR          0xA521
+#define PT_SIG_3_ADDR          0xA522
+#define PT_SIG_4_ADDR          0xA523
+#define PT_SIG_1_DATA          0x78
+#define PT_SIG_2_DATA          0x56
+#define PT_SIG_3_DATA          0x34
+#define PT_SIG_4_DATA          0x12
+#define PT4_P1_REG             0xB521
+#define PT4_P2_REG             0xB522
+#define PT2_P1_REG             0xD520
+#define PT2_P2_REG             0xD521
+#define PT1_P1_REG             0xD522
+#define PT1_P2_REG             0xD523
+
 #define        NB_PCIE_INDX_ADDR       0xe0
 #define        NB_PCIE_INDX_DATA       0xe4
 #define        PCIE_P_CNTL             0x10040
@@ -512,6 +529,98 @@ void usb_amd_dev_put(void)
 }
 EXPORT_SYMBOL_GPL(usb_amd_dev_put);
 
+/*
+ * Check if port is disabled in BIOS on AMD Promontory host.
+ * BIOS Disabled ports may wake on connect/disconnect and need
+ * driver workaround to keep them disabled.
+ * Returns true if port is marked disabled.
+ */
+bool usb_amd_pt_check_port(struct device *device, int port)
+{
+       unsigned char value, port_shift;
+       struct pci_dev *pdev;
+       u16 reg;
+
+       pdev = to_pci_dev(device);
+       pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_1_ADDR);
+
+       pci_read_config_byte(pdev, PT_READ_INDX, &value);
+       if (value != PT_SIG_1_DATA)
+               return false;
+
+       pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_2_ADDR);
+
+       pci_read_config_byte(pdev, PT_READ_INDX, &value);
+       if (value != PT_SIG_2_DATA)
+               return false;
+
+       pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_3_ADDR);
+
+       pci_read_config_byte(pdev, PT_READ_INDX, &value);
+       if (value != PT_SIG_3_DATA)
+               return false;
+
+       pci_write_config_word(pdev, PT_ADDR_INDX, PT_SIG_4_ADDR);
+
+       pci_read_config_byte(pdev, PT_READ_INDX, &value);
+       if (value != PT_SIG_4_DATA)
+               return false;
+
+       /* Check disabled port setting, if bit is set port is enabled */
+       switch (pdev->device) {
+       case 0x43b9:
+       case 0x43ba:
+       /*
+        * device is AMD_PROMONTORYA_4(0x43b9) or PROMONTORYA_3(0x43ba)
+        * PT4_P1_REG bits[7..1] represents USB2.0 ports 6 to 0
+        * PT4_P2_REG bits[6..0] represents ports 13 to 7
+        */
+               if (port > 6) {
+                       reg = PT4_P2_REG;
+                       port_shift = port - 7;
+               } else {
+                       reg = PT4_P1_REG;
+                       port_shift = port + 1;
+               }
+               break;
+       case 0x43bb:
+       /*
+        * device is AMD_PROMONTORYA_2(0x43bb)
+        * PT2_P1_REG bits[7..5] represents USB2.0 ports 2 to 0
+        * PT2_P2_REG bits[5..0] represents ports 9 to 3
+        */
+               if (port > 2) {
+                       reg = PT2_P2_REG;
+                       port_shift = port - 3;
+               } else {
+                       reg = PT2_P1_REG;
+                       port_shift = port + 5;
+               }
+               break;
+       case 0x43bc:
+       /*
+        * device is AMD_PROMONTORYA_1(0x43bc)
+        * PT1_P1_REG[7..4] represents USB2.0 ports 3 to 0
+        * PT1_P2_REG[5..0] represents ports 9 to 4
+        */
+               if (port > 3) {
+                       reg = PT1_P2_REG;
+                       port_shift = port - 4;
+               } else {
+                       reg = PT1_P1_REG;
+                       port_shift = port + 4;
+               }
+               break;
+       default:
+               return false;
+       }
+       pci_write_config_word(pdev, PT_ADDR_INDX, reg);
+       pci_read_config_byte(pdev, PT_READ_INDX, &value);
+
+       return !(value & BIT(port_shift));
+}
+EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
+
 /*
  * Make sure the controller is completely inactive, unable to
  * generate interrupts or do DMA.
index b68dcb5dd0fdb0d69b2e2e48cc9f984e58bff56d..4ca0d9b7e463c54766e7881d239f8e6319d89c13 100644 (file)
@@ -17,6 +17,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
 void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
 void sb800_prefetch(struct device *dev, int on);
 bool usb_xhci_needs_pci_reset(struct pci_dev *pdev);
+bool usb_amd_pt_check_port(struct device *device, int port);
 #else
 struct pci_dev;
 static inline void usb_amd_quirk_pll_disable(void) {}
@@ -25,6 +26,10 @@ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
 static inline void usb_amd_dev_put(void) {}
 static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
 static inline void sb800_prefetch(struct device *dev, int on) {}
+static inline bool usb_amd_pt_check_port(struct device *device, int port)
+{
+       return false;
+}
 #endif  /* CONFIG_USB_PCI */
 
 #endif  /*  __LINUX_USB_PCI_QUIRKS_H  */
index a1ab8acf39ba5b420dc6932d860a57d150c0ba05..c359bae7b7542cda0d6fbf7d3867b62ab234ff66 100644 (file)
@@ -328,13 +328,14 @@ dbc_ep_do_queue(struct dbc_ep *dep, struct dbc_request *req)
 int dbc_ep_queue(struct dbc_ep *dep, struct dbc_request *req,
                 gfp_t gfp_flags)
 {
+       unsigned long           flags;
        struct xhci_dbc         *dbc = dep->dbc;
        int                     ret = -ESHUTDOWN;
 
-       spin_lock(&dbc->lock);
+       spin_lock_irqsave(&dbc->lock, flags);
        if (dbc->state == DS_CONFIGURED)
                ret = dbc_ep_do_queue(dep, req);
-       spin_unlock(&dbc->lock);
+       spin_unlock_irqrestore(&dbc->lock, flags);
 
        mod_delayed_work(system_wq, &dbc->event_work, 0);
 
@@ -521,15 +522,16 @@ static void xhci_do_dbc_stop(struct xhci_hcd *xhci)
 static int xhci_dbc_start(struct xhci_hcd *xhci)
 {
        int                     ret;
+       unsigned long           flags;
        struct xhci_dbc         *dbc = xhci->dbc;
 
        WARN_ON(!dbc);
 
        pm_runtime_get_sync(xhci_to_hcd(xhci)->self.controller);
 
-       spin_lock(&dbc->lock);
+       spin_lock_irqsave(&dbc->lock, flags);
        ret = xhci_do_dbc_start(xhci);
-       spin_unlock(&dbc->lock);
+       spin_unlock_irqrestore(&dbc->lock, flags);
 
        if (ret) {
                pm_runtime_put(xhci_to_hcd(xhci)->self.controller);
@@ -541,6 +543,7 @@ static int xhci_dbc_start(struct xhci_hcd *xhci)
 
 static void xhci_dbc_stop(struct xhci_hcd *xhci)
 {
+       unsigned long           flags;
        struct xhci_dbc         *dbc = xhci->dbc;
        struct dbc_port         *port = &dbc->port;
 
@@ -551,9 +554,9 @@ static void xhci_dbc_stop(struct xhci_hcd *xhci)
        if (port->registered)
                xhci_dbc_tty_unregister_device(xhci);
 
-       spin_lock(&dbc->lock);
+       spin_lock_irqsave(&dbc->lock, flags);
        xhci_do_dbc_stop(xhci);
-       spin_unlock(&dbc->lock);
+       spin_unlock_irqrestore(&dbc->lock, flags);
 
        pm_runtime_put_sync(xhci_to_hcd(xhci)->self.controller);
 }
@@ -779,14 +782,15 @@ static void xhci_dbc_handle_events(struct work_struct *work)
        int                     ret;
        enum evtreturn          evtr;
        struct xhci_dbc         *dbc;
+       unsigned long           flags;
        struct xhci_hcd         *xhci;
 
        dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work);
        xhci = dbc->xhci;
 
-       spin_lock(&dbc->lock);
+       spin_lock_irqsave(&dbc->lock, flags);
        evtr = xhci_dbc_do_handle_events(dbc);
-       spin_unlock(&dbc->lock);
+       spin_unlock_irqrestore(&dbc->lock, flags);
 
        switch (evtr) {
        case EVT_GSER:
index 8d47b6fbf973567620cb531c748f9ba32c9c1a2a..75f0b92694ba141beda621b712419031e80b1445 100644 (file)
@@ -92,21 +92,23 @@ static void dbc_start_rx(struct dbc_port *port)
 static void
 dbc_read_complete(struct xhci_hcd *xhci, struct dbc_request *req)
 {
+       unsigned long           flags;
        struct xhci_dbc         *dbc = xhci->dbc;
        struct dbc_port         *port = &dbc->port;
 
-       spin_lock(&port->port_lock);
+       spin_lock_irqsave(&port->port_lock, flags);
        list_add_tail(&req->list_pool, &port->read_queue);
        tasklet_schedule(&port->push);
-       spin_unlock(&port->port_lock);
+       spin_unlock_irqrestore(&port->port_lock, flags);
 }
 
 static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req)
 {
+       unsigned long           flags;
        struct xhci_dbc         *dbc = xhci->dbc;
        struct dbc_port         *port = &dbc->port;
 
-       spin_lock(&port->port_lock);
+       spin_lock_irqsave(&port->port_lock, flags);
        list_add(&req->list_pool, &port->write_pool);
        switch (req->status) {
        case 0:
@@ -119,7 +121,7 @@ static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req)
                          req->status);
                break;
        }
-       spin_unlock(&port->port_lock);
+       spin_unlock_irqrestore(&port->port_lock, flags);
 }
 
 static void xhci_dbc_free_req(struct dbc_ep *dep, struct dbc_request *req)
@@ -327,12 +329,13 @@ static void dbc_rx_push(unsigned long _port)
 {
        struct dbc_request      *req;
        struct tty_struct       *tty;
+       unsigned long           flags;
        bool                    do_push = false;
        bool                    disconnect = false;
        struct dbc_port         *port = (void *)_port;
        struct list_head        *queue = &port->read_queue;
 
-       spin_lock_irq(&port->port_lock);
+       spin_lock_irqsave(&port->port_lock, flags);
        tty = port->port.tty;
        while (!list_empty(queue)) {
                req = list_first_entry(queue, struct dbc_request, list_pool);
@@ -392,16 +395,17 @@ static void dbc_rx_push(unsigned long _port)
        if (!disconnect)
                dbc_start_rx(port);
 
-       spin_unlock_irq(&port->port_lock);
+       spin_unlock_irqrestore(&port->port_lock, flags);
 }
 
 static int dbc_port_activate(struct tty_port *_port, struct tty_struct *tty)
 {
+       unsigned long   flags;
        struct dbc_port *port = container_of(_port, struct dbc_port, port);
 
-       spin_lock_irq(&port->port_lock);
+       spin_lock_irqsave(&port->port_lock, flags);
        dbc_start_rx(port);
-       spin_unlock_irq(&port->port_lock);
+       spin_unlock_irqrestore(&port->port_lock, flags);
 
        return 0;
 }
index e26e685d8a578fddffaa7ff220a0c4442ba4f5ce..5851052d4668a64f9ab816de84f1381100650ea6 100644 (file)
@@ -211,7 +211,7 @@ static void xhci_ring_dump_segment(struct seq_file *s,
 static int xhci_ring_trb_show(struct seq_file *s, void *unused)
 {
        int                     i;
-       struct xhci_ring        *ring = s->private;
+       struct xhci_ring        *ring = *(struct xhci_ring **)s->private;
        struct xhci_segment     *seg = ring->first_seg;
 
        for (i = 0; i < ring->num_segs; i++) {
@@ -387,7 +387,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci,
 
        snprintf(epriv->name, sizeof(epriv->name), "ep%02d", ep_index);
        epriv->root = xhci_debugfs_create_ring_dir(xhci,
-                                                  &dev->eps[ep_index].new_ring,
+                                                  &dev->eps[ep_index].ring,
                                                   epriv->name,
                                                   spriv->root);
        spriv->eps[ep_index] = epriv;
index 46d5e08f05f154361a0adef325d56cc732f4c172..72ebbc908e19f7ea9701ca0e831ee703874d1908 100644 (file)
@@ -1224,17 +1224,17 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                temp = readl(port_array[wIndex]);
                                break;
                        }
-
-                       /* Software should not attempt to set
-                        * port link state above '3' (U3) and the port
-                        * must be enabled.
-                        */
-                       if ((temp & PORT_PE) == 0 ||
-                               (link_state > USB_SS_PORT_LS_U3)) {
-                               xhci_warn(xhci, "Cannot set link state.\n");
+                       /* Port must be enabled */
+                       if (!(temp & PORT_PE)) {
+                               retval = -ENODEV;
+                               break;
+                       }
+                       /* Can't set port link state above '3' (U3) */
+                       if (link_state > USB_SS_PORT_LS_U3) {
+                               xhci_warn(xhci, "Cannot set port %d link state %d\n",
+                                        wIndex, link_state);
                                goto error;
                        }
-
                        if (link_state == USB_SS_PORT_LS_U3) {
                                slot_id = xhci_find_slot_id_by_port(hcd, xhci,
                                                wIndex + 1);
@@ -1522,6 +1522,13 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
                                t2 |= PORT_WKOC_E | PORT_WKCONN_E;
                                t2 &= ~PORT_WKDISC_E;
                        }
+
+                       if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) &&
+                           (hcd->speed < HCD_USB3)) {
+                               if (usb_amd_pt_check_port(hcd->self.controller,
+                                                         port_index))
+                                       t2 &= ~PORT_WAKE_BITS;
+                       }
                } else
                        t2 &= ~PORT_WAKE_BITS;
 
index 6c79037876db0523ed24c47561fbe1c7e2e2a1ba..d9f831b67e579d037f8cca4c7f5a93afbbb85f65 100644 (file)
 #define PCI_DEVICE_ID_INTEL_APL_XHCI                   0x5aa8
 #define PCI_DEVICE_ID_INTEL_DNV_XHCI                   0x19d0
 
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_4                        0x43b9
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_3                        0x43ba
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_2                        0x43bb
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_1                        0x43bc
 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI               0x1142
 
 static const char hcd_name[] = "xhci_hcd";
@@ -122,9 +126,19 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
                xhci->quirks |= XHCI_AMD_PLL_FIX;
 
+       if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43bb)
+               xhci->quirks |= XHCI_SUSPEND_DELAY;
+
        if (pdev->vendor == PCI_VENDOR_ID_AMD)
                xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 
+       if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
+               ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
+               (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) ||
+               (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) ||
+               (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
+               xhci->quirks |= XHCI_U2_DISABLE_WAKE;
+
        if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
                xhci->quirks |= XHCI_LPM_SUPPORT;
                xhci->quirks |= XHCI_INTEL_HOST;
index 6f038306c14d6c244dc9a7305adce185ee3aaecc..6652e2d5bd2e4bc3f9d95f04f36c58a6850c7545 100644 (file)
@@ -360,7 +360,6 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev)
 {
        struct usb_hcd  *hcd = dev_get_drvdata(dev);
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-       int ret;
 
        /*
         * xhci_suspend() needs `do_wakeup` to know whether host is allowed
@@ -370,12 +369,7 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev)
         * reconsider this when xhci_plat_suspend enlarges its scope, e.g.,
         * also applies to runtime suspend.
         */
-       ret = xhci_suspend(xhci, device_may_wakeup(dev));
-
-       if (!device_may_wakeup(dev) && !IS_ERR(xhci->clk))
-               clk_disable_unprepare(xhci->clk);
-
-       return ret;
+       return xhci_suspend(xhci, device_may_wakeup(dev));
 }
 
 static int __maybe_unused xhci_plat_resume(struct device *dev)
@@ -384,9 +378,6 @@ static int __maybe_unused xhci_plat_resume(struct device *dev)
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        int ret;
 
-       if (!device_may_wakeup(dev) && !IS_ERR(xhci->clk))
-               clk_prepare_enable(xhci->clk);
-
        ret = xhci_priv_resume_quirk(hcd);
        if (ret)
                return ret;
index f0b559660007f03c0fe60c0f1bb162a40ca90dad..f33ffc2bc4ed67015e2493374ebf284f7d03b48a 100644 (file)
@@ -83,6 +83,10 @@ static const struct soc_device_attribute rcar_quirks_match[]  = {
                .soc_id = "r8a7796",
                .data = (void *)RCAR_XHCI_FIRMWARE_V3,
        },
+       {
+               .soc_id = "r8a77965",
+               .data = (void *)RCAR_XHCI_FIRMWARE_V3,
+       },
        { /* sentinel */ },
 };
 
index 1eeb3396300f245fd1741f319cc62a5482487ed9..5d37700ae4b009f0a87e5fa5e3c0cb1e64f39c02 100644 (file)
@@ -646,8 +646,6 @@ static void xhci_stop(struct usb_hcd *hcd)
                return;
        }
 
-       xhci_debugfs_exit(xhci);
-
        xhci_dbc_exit(xhci);
 
        spin_lock_irq(&xhci->lock);
@@ -680,6 +678,7 @@ static void xhci_stop(struct usb_hcd *hcd)
 
        xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory");
        xhci_mem_cleanup(xhci);
+       xhci_debugfs_exit(xhci);
        xhci_dbg_trace(xhci, trace_xhci_dbg_init,
                        "xhci_stop completed - status = %x",
                        readl(&xhci->op_regs->status));
@@ -878,6 +877,9 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
        clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
        del_timer_sync(&xhci->shared_hcd->rh_timer);
 
+       if (xhci->quirks & XHCI_SUSPEND_DELAY)
+               usleep_range(1000, 1500);
+
        spin_lock_irq(&xhci->lock);
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
@@ -1014,6 +1016,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
 
                xhci_dbg(xhci, "cleaning up memory\n");
                xhci_mem_cleanup(xhci);
+               xhci_debugfs_exit(xhci);
                xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
                            readl(&xhci->op_regs->status));
 
@@ -3544,12 +3547,10 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
                virt_dev->eps[i].ep_state &= ~EP_STOP_CMD_PENDING;
                del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);
        }
-
+       xhci_debugfs_remove_slot(xhci, udev->slot_id);
        ret = xhci_disable_slot(xhci, udev->slot_id);
-       if (ret) {
-               xhci_debugfs_remove_slot(xhci, udev->slot_id);
+       if (ret)
                xhci_free_virt_device(xhci, udev->slot_id);
-       }
 }
 
 int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
index 96099a245c69eecdd84feae2c3924ac7e9ca0a84..866e141d4972b5d743d5cb61be2f045a102a6574 100644 (file)
@@ -718,11 +718,12 @@ struct xhci_ep_ctx {
 /* bits 10:14 are Max Primary Streams */
 /* bit 15 is Linear Stream Array */
 /* Interval - period between requests to an endpoint - 125u increments. */
-#define EP_INTERVAL(p)         (((p) & 0xff) << 16)
-#define EP_INTERVAL_TO_UFRAMES(p)              (1 << (((p) >> 16) & 0xff))
-#define CTX_TO_EP_INTERVAL(p)  (((p) >> 16) & 0xff)
-#define EP_MAXPSTREAMS_MASK    (0x1f << 10)
-#define EP_MAXPSTREAMS(p)      (((p) << 10) & EP_MAXPSTREAMS_MASK)
+#define EP_INTERVAL(p)                 (((p) & 0xff) << 16)
+#define EP_INTERVAL_TO_UFRAMES(p)      (1 << (((p) >> 16) & 0xff))
+#define CTX_TO_EP_INTERVAL(p)          (((p) >> 16) & 0xff)
+#define EP_MAXPSTREAMS_MASK            (0x1f << 10)
+#define EP_MAXPSTREAMS(p)              (((p) << 10) & EP_MAXPSTREAMS_MASK)
+#define CTX_TO_EP_MAXPSTREAMS(p)       (((p) & EP_MAXPSTREAMS_MASK) >> 10)
 /* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */
 #define        EP_HAS_LSA              (1 << 15)
 /* hosts with LEC=1 use bits 31:24 as ESIT high bits. */
@@ -1822,9 +1823,10 @@ struct xhci_hcd {
 /* For controller with a broken Port Disable implementation */
 #define XHCI_BROKEN_PORT_PED   (1 << 25)
 #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
-/* Reserved. It was XHCI_U2_DISABLE_WAKE */
+#define XHCI_U2_DISABLE_WAKE   (1 << 27)
 #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL        (1 << 28)
 #define XHCI_HW_LPM_DISABLE    (1 << 29)
+#define XHCI_SUSPEND_DELAY     (1 << 30)
 
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
@@ -2549,21 +2551,22 @@ static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq,
        u8 burst;
        u8 cerr;
        u8 mult;
-       u8 lsa;
-       u8 hid;
+
+       bool lsa;
+       bool hid;
 
        esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 |
                CTX_TO_MAX_ESIT_PAYLOAD(tx_info);
 
        ep_state = info & EP_STATE_MASK;
-       max_pstr = info & EP_MAXPSTREAMS_MASK;
+       max_pstr = CTX_TO_EP_MAXPSTREAMS(info);
        interval = CTX_TO_EP_INTERVAL(info);
        mult = CTX_TO_EP_MULT(info) + 1;
-       lsa = info & EP_HAS_LSA;
+       lsa = !!(info & EP_HAS_LSA);
 
        cerr = (info2 & (3 << 1)) >> 1;
        ep_type = CTX_TO_EP_TYPE(info2);
-       hid = info2 & (1 << 7);
+       hid = !!(info2 & (1 << 7));
        burst = CTX_TO_MAX_BURST(info2);
        maxp = MAX_PACKET_DECODED(info2);
 
index 63b9e85dc0e9365254bc8752a833fd6fd1ba24dd..236a60f53099e042faa9d804f4c470b1d5b90ef1 100644 (file)
@@ -42,6 +42,9 @@
 #define USB_DEVICE_ID_LD_MICROCASSYTIME                0x1033  /* USB Product ID of Micro-CASSY Time (reserved) */
 #define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035  /* USB Product ID of Micro-CASSY Temperature */
 #define USB_DEVICE_ID_LD_MICROCASSYPH          0x1038  /* USB Product ID of Micro-CASSY pH */
+#define USB_DEVICE_ID_LD_POWERANALYSERCASSY    0x1040  /* USB Product ID of Power Analyser CASSY */
+#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY      0x1042  /* USB Product ID of Converter Controller CASSY */
+#define USB_DEVICE_ID_LD_MACHINETESTCASSY      0x1043  /* USB Product ID of Machine Test CASSY */
 #define USB_DEVICE_ID_LD_JWM           0x1080  /* USB Product ID of Joule and Wattmeter */
 #define USB_DEVICE_ID_LD_DMMP          0x1081  /* USB Product ID of Digital Multimeter P (reserved) */
 #define USB_DEVICE_ID_LD_UMIP          0x1090  /* USB Product ID of UMI P */
@@ -84,6 +87,9 @@ static const struct usb_device_id ld_usb_table[] = {
        { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
        { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
        { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
+       { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) },
+       { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) },
+       { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) },
        { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
        { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
        { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
index f5e1bb5e521777f1e5b6b29c61f4c4f9f19f9662..984f7e12a6a5b431d0281fd6715f9e990ff775b6 100644 (file)
@@ -85,6 +85,8 @@ struct mon_reader_text {
 
        wait_queue_head_t wait;
        int printf_size;
+       size_t printf_offset;
+       size_t printf_togo;
        char *printf_buf;
        struct mutex printf_lock;
 
@@ -376,75 +378,103 @@ err_alloc:
        return rc;
 }
 
-/*
- * For simplicity, we read one record in one system call and throw out
- * what does not fit. This means that the following does not work:
- *   dd if=/dbg/usbmon/0t bs=10
- * Also, we do not allow seeks and do not bother advancing the offset.
- */
+static ssize_t mon_text_copy_to_user(struct mon_reader_text *rp,
+    char __user * const buf, const size_t nbytes)
+{
+       const size_t togo = min(nbytes, rp->printf_togo);
+
+       if (copy_to_user(buf, &rp->printf_buf[rp->printf_offset], togo))
+               return -EFAULT;
+       rp->printf_togo -= togo;
+       rp->printf_offset += togo;
+       return togo;
+}
+
+/* ppos is not advanced since the llseek operation is not permitted. */
 static ssize_t mon_text_read_t(struct file *file, char __user *buf,
-                               size_t nbytes, loff_t *ppos)
+    size_t nbytes, loff_t *ppos)
 {
        struct mon_reader_text *rp = file->private_data;
        struct mon_event_text *ep;
        struct mon_text_ptr ptr;
+       ssize_t ret;
 
-       ep = mon_text_read_wait(rp, file);
-       if (IS_ERR(ep))
-               return PTR_ERR(ep);
        mutex_lock(&rp->printf_lock);
-       ptr.cnt = 0;
-       ptr.pbuf = rp->printf_buf;
-       ptr.limit = rp->printf_size;
-
-       mon_text_read_head_t(rp, &ptr, ep);
-       mon_text_read_statset(rp, &ptr, ep);
-       ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
-           " %d", ep->length);
-       mon_text_read_data(rp, &ptr, ep);
-
-       if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
-               ptr.cnt = -EFAULT;
+
+       if (rp->printf_togo == 0) {
+
+               ep = mon_text_read_wait(rp, file);
+               if (IS_ERR(ep)) {
+                       mutex_unlock(&rp->printf_lock);
+                       return PTR_ERR(ep);
+               }
+               ptr.cnt = 0;
+               ptr.pbuf = rp->printf_buf;
+               ptr.limit = rp->printf_size;
+
+               mon_text_read_head_t(rp, &ptr, ep);
+               mon_text_read_statset(rp, &ptr, ep);
+               ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
+                   " %d", ep->length);
+               mon_text_read_data(rp, &ptr, ep);
+
+               rp->printf_togo = ptr.cnt;
+               rp->printf_offset = 0;
+
+               kmem_cache_free(rp->e_slab, ep);
+       }
+
+       ret = mon_text_copy_to_user(rp, buf, nbytes);
        mutex_unlock(&rp->printf_lock);
-       kmem_cache_free(rp->e_slab, ep);
-       return ptr.cnt;
+       return ret;
 }
 
+/* ppos is not advanced since the llseek operation is not permitted. */
 static ssize_t mon_text_read_u(struct file *file, char __user *buf,
-                               size_t nbytes, loff_t *ppos)
+    size_t nbytes, loff_t *ppos)
 {
        struct mon_reader_text *rp = file->private_data;
        struct mon_event_text *ep;
        struct mon_text_ptr ptr;
+       ssize_t ret;
 
-       ep = mon_text_read_wait(rp, file);
-       if (IS_ERR(ep))
-               return PTR_ERR(ep);
        mutex_lock(&rp->printf_lock);
-       ptr.cnt = 0;
-       ptr.pbuf = rp->printf_buf;
-       ptr.limit = rp->printf_size;
 
-       mon_text_read_head_u(rp, &ptr, ep);
-       if (ep->type == 'E') {
-               mon_text_read_statset(rp, &ptr, ep);
-       } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
-               mon_text_read_isostat(rp, &ptr, ep);
-               mon_text_read_isodesc(rp, &ptr, ep);
-       } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
-               mon_text_read_intstat(rp, &ptr, ep);
-       } else {
-               mon_text_read_statset(rp, &ptr, ep);
+       if (rp->printf_togo == 0) {
+
+               ep = mon_text_read_wait(rp, file);
+               if (IS_ERR(ep)) {
+                       mutex_unlock(&rp->printf_lock);
+                       return PTR_ERR(ep);
+               }
+               ptr.cnt = 0;
+               ptr.pbuf = rp->printf_buf;
+               ptr.limit = rp->printf_size;
+
+               mon_text_read_head_u(rp, &ptr, ep);
+               if (ep->type == 'E') {
+                       mon_text_read_statset(rp, &ptr, ep);
+               } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
+                       mon_text_read_isostat(rp, &ptr, ep);
+                       mon_text_read_isodesc(rp, &ptr, ep);
+               } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
+                       mon_text_read_intstat(rp, &ptr, ep);
+               } else {
+                       mon_text_read_statset(rp, &ptr, ep);
+               }
+               ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
+                   " %d", ep->length);
+               mon_text_read_data(rp, &ptr, ep);
+
+               rp->printf_togo = ptr.cnt;
+               rp->printf_offset = 0;
+
+               kmem_cache_free(rp->e_slab, ep);
        }
-       ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
-           " %d", ep->length);
-       mon_text_read_data(rp, &ptr, ep);
 
-       if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
-               ptr.cnt = -EFAULT;
+       ret = mon_text_copy_to_user(rp, buf, nbytes);
        mutex_unlock(&rp->printf_lock);
-       kmem_cache_free(rp->e_slab, ep);
-       return ptr.cnt;
+       return ret;
 }
 
 static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
index 968bf1e8b0fed683f76563eddbe8d841a920e395..4d723077be2b990e109e6896d3e8e68cdcd08639 100644 (file)
@@ -1756,6 +1756,7 @@ vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
        int             vbus;
        u8              devctl;
 
+       pm_runtime_get_sync(dev);
        spin_lock_irqsave(&musb->lock, flags);
        val = musb->a_wait_bcon;
        vbus = musb_platform_get_vbus_status(musb);
@@ -1769,6 +1770,7 @@ vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
                        vbus = 0;
        }
        spin_unlock_irqrestore(&musb->lock, flags);
+       pm_runtime_put_sync(dev);
 
        return sprintf(buf, "Vbus %s, timeout %lu msec\n",
                        vbus ? "on" : "off", val);
@@ -2471,11 +2473,11 @@ static int musb_remove(struct platform_device *pdev)
        musb_disable_interrupts(musb);
        musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
        spin_unlock_irqrestore(&musb->lock, flags);
+       musb_platform_exit(musb);
 
        pm_runtime_dont_use_autosuspend(musb->controller);
        pm_runtime_put_sync(musb->controller);
        pm_runtime_disable(musb->controller);
-       musb_platform_exit(musb);
        musb_phy_callback = NULL;
        if (musb->dma_controller)
                musb_dma_controller_destroy(musb->dma_controller);
@@ -2708,7 +2710,8 @@ static int musb_resume(struct device *dev)
        if ((devctl & mask) != (musb->context.devctl & mask))
                musb->port1_status = 0;
 
-       musb_start(musb);
+       musb_enable_interrupts(musb);
+       musb_platform_enable(musb);
 
        spin_lock_irqsave(&musb->lock, flags);
        error = musb_run_resume_work(musb);
index 394b4ac8616173ba0f2a60a870ae70ff98dd40d0..45ed32c2cba949dd7babb4b9e4879a89aa251027 100644 (file)
@@ -391,13 +391,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
                }
        }
 
-       /*
-        * The pipe must be broken if current urb->status is set, so don't
-        * start next urb.
-        * TODO: to minimize the risk of regression, only check urb->status
-        * for RX, until we have a test case to understand the behavior of TX.
-        */
-       if ((!status || !is_in) && qh && qh->is_ready) {
+       if (qh != NULL && qh->is_ready) {
                musb_dbg(musb, "... next ep%d %cX urb %p",
                    hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh));
                musb_start_urb(musb, is_in, qh);
index da031c45395abd2576e144b409b4231972001a37..fbec863350f67cb914aef30a8036de2cf5819f25 100644 (file)
@@ -602,6 +602,9 @@ static enum usb_charger_type mxs_phy_charger_detect(struct usb_phy *phy)
        void __iomem *base = phy->io_priv;
        enum usb_charger_type chgr_type = UNKNOWN_TYPE;
 
+       if (!regmap)
+               return UNKNOWN_TYPE;
+
        if (mxs_charger_data_contact_detect(mxs_phy))
                return chgr_type;
 
index 5925d111bd4743e2378b2d91e0489d111738767d..39fa2fc1b8b767e10d37b6bde54a696d00de9f0c 100644 (file)
@@ -982,6 +982,10 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt,
        if ((uintptr_t)pkt->buf & (USBHS_USB_DMAC_XFER_SIZE - 1))
                goto usbhsf_pio_prepare_pop;
 
+       /* return at this time if the pipe is running */
+       if (usbhs_pipe_is_running(pipe))
+               return 0;
+
        usbhs_pipe_config_change_bfre(pipe, 1);
 
        ret = usbhsf_fifo_select(pipe, fifo, 0);
@@ -1172,6 +1176,7 @@ static int usbhsf_dma_pop_done_with_usb_dmac(struct usbhs_pkt *pkt,
        usbhsf_fifo_clear(pipe, fifo);
        pkt->actual = usbhs_dma_calc_received_size(pkt, chan, rcv_len);
 
+       usbhs_pipe_running(pipe, 0);
        usbhsf_dma_stop(pipe, fifo);
        usbhsf_dma_unmap(pkt);
        usbhsf_fifo_unselect(pipe, pipe->fifo);
index 5db8ed517e0e137de511192bb9c79e63618afe0b..2d8d9150da0cc70abd4cc440fad2618f38b558fb 100644 (file)
@@ -241,6 +241,7 @@ static void option_instat_callback(struct urb *urb);
 #define QUECTEL_PRODUCT_EC21                   0x0121
 #define QUECTEL_PRODUCT_EC25                   0x0125
 #define QUECTEL_PRODUCT_BG96                   0x0296
+#define QUECTEL_PRODUCT_EP06                   0x0306
 
 #define CMOTECH_VENDOR_ID                      0x16d8
 #define CMOTECH_PRODUCT_6001                   0x6001
@@ -689,6 +690,10 @@ static const struct option_blacklist_info yuga_clm920_nc5_blacklist = {
        .reserved = BIT(1) | BIT(4),
 };
 
+static const struct option_blacklist_info quectel_ep06_blacklist = {
+       .reserved = BIT(4) | BIT(5),
+};
+
 static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -1203,6 +1208,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
          .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06),
+         .driver_info = (kernel_ulong_t)&quectel_ep06_blacklist },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
index 3b1b9695177a4c9c0875fd764d1930cdffe5273b..6034c39b67d14ab43376b87eabbbc8e5bf87e0b1 100644 (file)
@@ -1076,7 +1076,7 @@ static int uas_post_reset(struct usb_interface *intf)
                return 0;
 
        err = uas_configure_endpoints(devinfo);
-       if (err && err != ENODEV)
+       if (err && err != -ENODEV)
                shost_printk(KERN_ERR, shost,
                             "%s: alloc streams error %d after reset",
                             __func__, err);
index 264af199aec855babdd43331893d523318cd47a0..747d3a9596d947e11b245b795da66d63f226de3f 100644 (file)
@@ -2118,6 +2118,13 @@ UNUSUAL_DEV(  0x152d, 0x2566, 0x0114, 0x0114,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_BROKEN_FUA ),
 
+/* Reported by Teijo Kinnunen <teijo.kinnunen@code-q.fi> */
+UNUSUAL_DEV(  0x152d, 0x2567, 0x0117, 0x0117,
+               "JMicron",
+               "USB to ATA/ATAPI Bridge",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BROKEN_FUA ),
+
 /* Reported-by George Cherian <george.cherian@cavium.com> */
 UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999,
                "JMicron",
index 9ce4756adad6e5fa20017ae4f27603eb87127312..dcd8ef085b30151e76e5cf5921040f15214a17e9 100644 (file)
@@ -1857,7 +1857,8 @@ static int fusb302_probe(struct i2c_client *client,
        chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev);
        if (IS_ERR(chip->tcpm_port)) {
                ret = PTR_ERR(chip->tcpm_port);
-               dev_err(dev, "cannot register tcpm port, ret=%d", ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "cannot register tcpm port, ret=%d", ret);
                goto destroy_workqueue;
        }
 
index f4d563ee769046236daeedb1956907752a1c3c3f..8b637a4b474b08b40690289c33ddc1306811e932 100644 (file)
@@ -252,9 +252,6 @@ struct tcpm_port {
        unsigned int nr_src_pdo;
        u32 snk_pdo[PDO_MAX_OBJECTS];
        unsigned int nr_snk_pdo;
-       unsigned int nr_fixed; /* number of fixed sink PDOs */
-       unsigned int nr_var; /* number of variable sink PDOs */
-       unsigned int nr_batt; /* number of battery sink PDOs */
        u32 snk_vdo[VDO_MAX_OBJECTS];
        unsigned int nr_snk_vdo;
 
@@ -1770,90 +1767,39 @@ static int tcpm_pd_check_request(struct tcpm_port *port)
        return 0;
 }
 
-#define min_power(x, y) min(pdo_max_power(x), pdo_max_power(y))
-#define min_current(x, y) min(pdo_max_current(x), pdo_max_current(y))
-
-static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo,
-                             int *src_pdo)
+static int tcpm_pd_select_pdo(struct tcpm_port *port)
 {
-       unsigned int i, j, max_mw = 0, max_mv = 0, mw = 0, mv = 0, ma = 0;
+       unsigned int i, max_mw = 0, max_mv = 0;
        int ret = -EINVAL;
 
        /*
-        * Select the source PDO providing the most power which has a
-        * matchig sink cap.
+        * Select the source PDO providing the most power while staying within
+        * the board's voltage limits. Prefer PDO providing exp
         */
        for (i = 0; i < port->nr_source_caps; i++) {
                u32 pdo = port->source_caps[i];
                enum pd_pdo_type type = pdo_type(pdo);
+               unsigned int mv, ma, mw;
 
-               if (type == PDO_TYPE_FIXED) {
-                       for (j = 0; j < port->nr_fixed; j++) {
-                               if (pdo_fixed_voltage(pdo) ==
-                                   pdo_fixed_voltage(port->snk_pdo[j])) {
-                                       ma = min_current(pdo, port->snk_pdo[j]);
-                                       mv = pdo_fixed_voltage(pdo);
-                                       mw = ma * mv / 1000;
-                                       if (mw > max_mw ||
-                                           (mw == max_mw && mv > max_mv)) {
-                                               ret = 0;
-                                               *src_pdo = i;
-                                               *sink_pdo = j;
-                                               max_mw = mw;
-                                               max_mv = mv;
-                                       }
-                                       /* There could only be one fixed pdo
-                                        * at a specific voltage level.
-                                        * So breaking here.
-                                        */
-                                       break;
-                               }
-                       }
-               } else if (type == PDO_TYPE_BATT) {
-                       for (j = port->nr_fixed;
-                            j < port->nr_fixed +
-                                port->nr_batt;
-                            j++) {
-                               if (pdo_min_voltage(pdo) >=
-                                    pdo_min_voltage(port->snk_pdo[j]) &&
-                                    pdo_max_voltage(pdo) <=
-                                    pdo_max_voltage(port->snk_pdo[j])) {
-                                       mw = min_power(pdo, port->snk_pdo[j]);
-                                       mv = pdo_min_voltage(pdo);
-                                       if (mw > max_mw ||
-                                           (mw == max_mw && mv > max_mv)) {
-                                               ret = 0;
-                                               *src_pdo = i;
-                                               *sink_pdo = j;
-                                               max_mw = mw;
-                                               max_mv = mv;
-                                       }
-                               }
-                       }
-               } else if (type == PDO_TYPE_VAR) {
-                       for (j = port->nr_fixed +
-                                port->nr_batt;
-                            j < port->nr_fixed +
-                                port->nr_batt +
-                                port->nr_var;
-                            j++) {
-                               if (pdo_min_voltage(pdo) >=
-                                    pdo_min_voltage(port->snk_pdo[j]) &&
-                                    pdo_max_voltage(pdo) <=
-                                    pdo_max_voltage(port->snk_pdo[j])) {
-                                       ma = min_current(pdo, port->snk_pdo[j]);
-                                       mv = pdo_min_voltage(pdo);
-                                       mw = ma * mv / 1000;
-                                       if (mw > max_mw ||
-                                           (mw == max_mw && mv > max_mv)) {
-                                               ret = 0;
-                                               *src_pdo = i;
-                                               *sink_pdo = j;
-                                               max_mw = mw;
-                                               max_mv = mv;
-                                       }
-                               }
-                       }
+               if (type == PDO_TYPE_FIXED)
+                       mv = pdo_fixed_voltage(pdo);
+               else
+                       mv = pdo_min_voltage(pdo);
+
+               if (type == PDO_TYPE_BATT) {
+                       mw = pdo_max_power(pdo);
+               } else {
+                       ma = min(pdo_max_current(pdo),
+                                port->max_snk_ma);
+                       mw = ma * mv / 1000;
+               }
+
+               /* Perfer higher voltages if available */
+               if ((mw > max_mw || (mw == max_mw && mv > max_mv)) &&
+                   mv <= port->max_snk_mv) {
+                       ret = i;
+                       max_mw = mw;
+                       max_mv = mv;
                }
        }
 
@@ -1865,14 +1811,13 @@ static int tcpm_pd_build_request(struct tcpm_port *port, u32 *rdo)
        unsigned int mv, ma, mw, flags;
        unsigned int max_ma, max_mw;
        enum pd_pdo_type type;
-       int src_pdo_index, snk_pdo_index;
-       u32 pdo, matching_snk_pdo;
+       int index;
+       u32 pdo;
 
-       if (tcpm_pd_select_pdo(port, &snk_pdo_index, &src_pdo_index) < 0)
+       index = tcpm_pd_select_pdo(port);
+       if (index < 0)
                return -EINVAL;
-
-       pdo = port->source_caps[src_pdo_index];
-       matching_snk_pdo = port->snk_pdo[snk_pdo_index];
+       pdo = port->source_caps[index];
        type = pdo_type(pdo);
 
        if (type == PDO_TYPE_FIXED)
@@ -1880,28 +1825,26 @@ static int tcpm_pd_build_request(struct tcpm_port *port, u32 *rdo)
        else
                mv = pdo_min_voltage(pdo);
 
-       /* Select maximum available current within the sink pdo's limit */
+       /* Select maximum available current within the board's power limit */
        if (type == PDO_TYPE_BATT) {
-               mw = min_power(pdo, matching_snk_pdo);
-               ma = 1000 * mw / mv;
+               mw = pdo_max_power(pdo);
+               ma = 1000 * min(mw, port->max_snk_mw) / mv;
        } else {
-               ma = min_current(pdo, matching_snk_pdo);
-               mw = ma * mv / 1000;
+               ma = min(pdo_max_current(pdo),
+                        1000 * port->max_snk_mw / mv);
        }
+       ma = min(ma, port->max_snk_ma);
 
        flags = RDO_USB_COMM | RDO_NO_SUSPEND;
 
        /* Set mismatch bit if offered power is less than operating power */
+       mw = ma * mv / 1000;
        max_ma = ma;
        max_mw = mw;
        if (mw < port->operating_snk_mw) {
                flags |= RDO_CAP_MISMATCH;
-               if (type == PDO_TYPE_BATT &&
-                   (pdo_max_power(matching_snk_pdo) > pdo_max_power(pdo)))
-                       max_mw = pdo_max_power(matching_snk_pdo);
-               else if (pdo_max_current(matching_snk_pdo) >
-                        pdo_max_current(pdo))
-                       max_ma = pdo_max_current(matching_snk_pdo);
+               max_mw = port->operating_snk_mw;
+               max_ma = max_mw * 1000 / mv;
        }
 
        tcpm_log(port, "cc=%d cc1=%d cc2=%d vbus=%d vconn=%s polarity=%d",
@@ -1910,16 +1853,16 @@ static int tcpm_pd_build_request(struct tcpm_port *port, u32 *rdo)
                 port->polarity);
 
        if (type == PDO_TYPE_BATT) {
-               *rdo = RDO_BATT(src_pdo_index + 1, mw, max_mw, flags);
+               *rdo = RDO_BATT(index + 1, mw, max_mw, flags);
 
                tcpm_log(port, "Requesting PDO %d: %u mV, %u mW%s",
-                        src_pdo_index, mv, mw,
+                        index, mv, mw,
                         flags & RDO_CAP_MISMATCH ? " [mismatch]" : "");
        } else {
-               *rdo = RDO_FIXED(src_pdo_index + 1, ma, max_ma, flags);
+               *rdo = RDO_FIXED(index + 1, ma, max_ma, flags);
 
                tcpm_log(port, "Requesting PDO %d: %u mV, %u mA%s",
-                        src_pdo_index, mv, ma,
+                        index, mv, ma,
                         flags & RDO_CAP_MISMATCH ? " [mismatch]" : "");
        }
 
@@ -3650,19 +3593,6 @@ int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo,
 }
 EXPORT_SYMBOL_GPL(tcpm_update_sink_capabilities);
 
-static int nr_type_pdos(const u32 *pdo, unsigned int nr_pdo,
-                       enum pd_pdo_type type)
-{
-       int count = 0;
-       int i;
-
-       for (i = 0; i < nr_pdo; i++) {
-               if (pdo_type(pdo[i]) == type)
-                       count++;
-       }
-       return count;
-}
-
 struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
 {
        struct tcpm_port *port;
@@ -3708,15 +3638,6 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
                                          tcpc->config->nr_src_pdo);
        port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, tcpc->config->snk_pdo,
                                          tcpc->config->nr_snk_pdo);
-       port->nr_fixed =  nr_type_pdos(port->snk_pdo,
-                                      port->nr_snk_pdo,
-                                      PDO_TYPE_FIXED);
-       port->nr_var = nr_type_pdos(port->snk_pdo,
-                                   port->nr_snk_pdo,
-                                   PDO_TYPE_VAR);
-       port->nr_batt = nr_type_pdos(port->snk_pdo,
-                                    port->nr_snk_pdo,
-                                    PDO_TYPE_BATT);
        port->nr_snk_vdo = tcpm_copy_vdos(port->snk_vdo, tcpc->config->snk_vdo,
                                          tcpc->config->nr_snk_vdo);
 
index 49e552472c3f32ac651287f3f6e620acb7690931..dd8ef36ab10ec7d612bdb2358017f142a43906d8 100644 (file)
@@ -73,6 +73,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a
                        goto err;
 
                sdev->ud.tcp_socket = socket;
+               sdev->ud.sockfd = sockfd;
 
                spin_unlock_irq(&sdev->ud.lock);
 
@@ -172,6 +173,7 @@ static void stub_shutdown_connection(struct usbip_device *ud)
        if (ud->tcp_socket) {
                sockfd_put(ud->tcp_socket);
                ud->tcp_socket = NULL;
+               ud->sockfd = -1;
        }
 
        /* 3. free used data */
@@ -266,6 +268,7 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev)
        sdev->ud.status         = SDEV_ST_AVAILABLE;
        spin_lock_init(&sdev->ud.lock);
        sdev->ud.tcp_socket     = NULL;
+       sdev->ud.sockfd         = -1;
 
        INIT_LIST_HEAD(&sdev->priv_init);
        INIT_LIST_HEAD(&sdev->priv_tx);
index c3e1008aa491ee45071adab6215f7440aa6dfa13..20e3d4609583848f8a14271d5c4bf3ffb8776123 100644 (file)
@@ -984,6 +984,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
        if (vdev->ud.tcp_socket) {
                sockfd_put(vdev->ud.tcp_socket);
                vdev->ud.tcp_socket = NULL;
+               vdev->ud.sockfd = -1;
        }
        pr_info("release socket\n");
 
@@ -1030,6 +1031,7 @@ static void vhci_device_reset(struct usbip_device *ud)
        if (ud->tcp_socket) {
                sockfd_put(ud->tcp_socket);
                ud->tcp_socket = NULL;
+               ud->sockfd = -1;
        }
        ud->status = VDEV_ST_NULL;
 
index d86f72bbbb91ddc24638ec0db5c1b96d8dcb82e1..6dcd3ff655c3367cde86919e024b9cc7d174ecec 100644 (file)
@@ -105,10 +105,14 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a
        if (rv != 0)
                return -EINVAL;
 
+       if (!udc) {
+               dev_err(dev, "no device");
+               return -ENODEV;
+       }
        spin_lock_irqsave(&udc->lock, flags);
        /* Don't export what we don't have */
-       if (!udc || !udc->driver || !udc->pullup) {
-               dev_err(dev, "no device or gadget not bound");
+       if (!udc->driver || !udc->pullup) {
+               dev_err(dev, "gadget not bound");
                ret = -ENODEV;
                goto unlock;
        }
index b0f759476900d1520565810a4ead4cc2cc3a1ac2..8a1508a8e48126e2cfdb84d30ad01432792b8ad4 100644 (file)
@@ -207,9 +207,6 @@ static bool vfio_pci_nointx(struct pci_dev *pdev)
                }
        }
 
-       if (!pdev->irq)
-               return true;
-
        return false;
 }
 
index e30e29ae4819f60cbb53c808558ee808079febe0..45657e2b1ff77b813b546239dd11ee97dfb2fcb4 100644 (file)
@@ -338,11 +338,12 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
 {
        struct page *page[1];
        struct vm_area_struct *vma;
+       struct vm_area_struct *vmas[1];
        int ret;
 
        if (mm == current->mm) {
-               ret = get_user_pages_fast(vaddr, 1, !!(prot & IOMMU_WRITE),
-                                         page);
+               ret = get_user_pages_longterm(vaddr, 1, !!(prot & IOMMU_WRITE),
+                                             page, vmas);
        } else {
                unsigned int flags = 0;
 
@@ -351,7 +352,18 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
 
                down_read(&mm->mmap_sem);
                ret = get_user_pages_remote(NULL, mm, vaddr, 1, flags, page,
-                                           NULL, NULL);
+                                           vmas, NULL);
+               /*
+                * The lifetime of a vaddr_get_pfn() page pin is
+                * userspace-controlled. In the fs-dax case this could
+                * lead to indefinite stalls in filesystem operations.
+                * Disallow attempts to pin fs-dax pages via this
+                * interface.
+                */
+               if (ret > 0 && vma_is_fsdax(vmas[0])) {
+                       ret = -EOPNOTSUPP;
+                       put_page(page[0]);
+               }
                up_read(&mm->mmap_sem);
        }
 
index 610cba276d4762a2b69d90a49dc0f846c6822835..8139bc70ad7dcf09b2d2311fc1eab9d450ab4814 100644 (file)
@@ -170,7 +170,7 @@ static void vhost_net_buf_unproduce(struct vhost_net_virtqueue *nvq)
        if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) {
                ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head,
                                   vhost_net_buf_get_size(rxq),
-                                  __skb_array_destroy_skb);
+                                  tun_ptr_free);
                rxq->head = rxq->tail = 0;
        }
 }
@@ -948,6 +948,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
                n->vqs[i].done_idx = 0;
                n->vqs[i].vhost_hlen = 0;
                n->vqs[i].sock_hlen = 0;
+               n->vqs[i].rx_ring = NULL;
                vhost_net_buf_init(&n->vqs[i].rxq);
        }
        vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX);
@@ -972,6 +973,7 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n,
        vhost_net_disable_vq(n, vq);
        vq->private_data = NULL;
        vhost_net_buf_unproduce(nvq);
+       nvq->rx_ring = NULL;
        mutex_unlock(&vq->mutex);
        return sock;
 }
@@ -1161,14 +1163,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
                vhost_net_disable_vq(n, vq);
                vq->private_data = sock;
                vhost_net_buf_unproduce(nvq);
-               if (index == VHOST_NET_VQ_RX)
-                       nvq->rx_ring = get_tap_ptr_ring(fd);
                r = vhost_vq_init_access(vq);
                if (r)
                        goto err_used;
                r = vhost_net_enable_vq(n, vq);
                if (r)
                        goto err_used;
+               if (index == VHOST_NET_VQ_RX)
+                       nvq->rx_ring = get_tap_ptr_ring(fd);
 
                oldubufs = nvq->ubufs;
                nvq->ubufs = ubufs;
index 6082f653c68a448e3e32ea08571f04af97f6acf5..67773e8bbb954b36bdfc7f005e026661c3ba79c9 100644 (file)
@@ -127,7 +127,7 @@ void gx_set_dclk_frequency(struct fb_info *info)
        int timeout = 1000;
 
        /* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */
-       if (cpu_data(0).x86_mask == 1) {
+       if (cpu_data(0).x86_stepping == 1) {
                pll_table = gx_pll_table_14MHz;
                pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz);
        } else {
index af6fc97f4ba4a5fac8cf2f100616f3cdf33a8aae..a436d44f1b7fbf4e2fe2447de21a6aa5a4903cde 100644 (file)
@@ -122,7 +122,7 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                unsigned char __user *ured;
                unsigned char __user *ugreen;
                unsigned char __user *ublue;
-               int index, count, i;
+               unsigned int index, count, i;
 
                if (get_user(index, &c->index) ||
                    __get_user(count, &c->count) ||
@@ -161,7 +161,7 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                unsigned char __user *ugreen;
                unsigned char __user *ublue;
                struct fb_cmap *cmap = &info->cmap;
-               int index, count, i;
+               unsigned int index, count, i;
                u8 red, green, blue;
 
                if (get_user(index, &c->index) ||
index eb30f3e09a4775b3f046ccc698f18a05210f17ad..71458f493cf864aa260e493c0ef5ddc4d6c78274 100644 (file)
@@ -428,8 +428,6 @@ unmap_release:
                i = virtio16_to_cpu(_vq->vdev, vq->vring.desc[i].next);
        }
 
-       vq->vq.num_free += total_sg;
-
        if (indirect)
                kfree(desc);
 
index aff773bcebdb59f14a88a3c92b779f5c03de3ba5..37460cd6cabb806ecdf536f5a44019ff845164b9 100644 (file)
@@ -226,6 +226,7 @@ config ZIIRAVE_WATCHDOG
 config RAVE_SP_WATCHDOG
        tristate "RAVE SP Watchdog timer"
        depends on RAVE_SP_CORE
+       depends on NVMEM || !NVMEM
        select WATCHDOG_CORE
        help
          Support for the watchdog on RAVE SP device.
@@ -903,6 +904,7 @@ config F71808E_WDT
 config SP5100_TCO
        tristate "AMD/ATI SP5100 TCO Timer/Watchdog"
        depends on X86 && PCI
+       select WATCHDOG_CORE
        ---help---
          Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO
          (Total Cost of Ownership) timer is a watchdog timer that will reboot
@@ -1008,6 +1010,7 @@ config WAFER_WDT
 config I6300ESB_WDT
        tristate "Intel 6300ESB Timer/Watchdog"
        depends on PCI
+       select WATCHDOG_CORE
        ---help---
          Hardware driver for the watchdog timer built into the Intel
          6300ESB controller hub.
@@ -1837,6 +1840,7 @@ config WATCHDOG_SUN4V
 config XEN_WDT
        tristate "Xen Watchdog support"
        depends on XEN
+       select WATCHDOG_CORE
        help
          Say Y here to support the hypervisor watchdog capability provided
          by Xen 4.0 and newer.  The watchdog timeout period is normally one
index e0678c14480f2c96619562e6c3d0098a0541189d..3a33c5344bd5eaaad338dd77e138b5610c35dc27 100644 (file)
@@ -566,7 +566,8 @@ static ssize_t watchdog_write(struct file *file, const char __user *buf,
                                char c;
                                if (get_user(c, buf + i))
                                        return -EFAULT;
-                               expect_close = (c == 'V');
+                               if (c == 'V')
+                                       expect_close = true;
                        }
 
                        /* Properly order writes across fork()ed processes */
index f1f00dfc0e68ce3eb323d7e7bf63ecb4f7ba399a..b0a158073abd55b4dcb961ef7d241dcecfe225f7 100644 (file)
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/watchdog.h>
-#ifdef CONFIG_HPWDT_NMI_DECODING
-#include <linux/dmi.h>
-#include <linux/spinlock.h>
-#include <linux/nmi.h>
-#include <linux/kdebug.h>
-#include <linux/notifier.h>
-#include <asm/set_memory.h>
-#endif /* CONFIG_HPWDT_NMI_DECODING */
 #include <asm/nmi.h>
-#include <asm/frame.h>
 
 #define HPWDT_VERSION                  "1.4.0"
 #define SECS_TO_TICKS(secs)            ((secs) * 1000 / 128)
@@ -48,6 +39,9 @@
 static unsigned int soft_margin = DEFAULT_MARGIN;      /* in seconds */
 static unsigned int reload;                    /* the computed soft_margin */
 static bool nowayout = WATCHDOG_NOWAYOUT;
+#ifdef CONFIG_HPWDT_NMI_DECODING
+static unsigned int allow_kdump = 1;
+#endif
 static char expect_release;
 static unsigned long hpwdt_is_open;
 
@@ -63,373 +57,6 @@ static const struct pci_device_id hpwdt_devices[] = {
 };
 MODULE_DEVICE_TABLE(pci, hpwdt_devices);
 
-#ifdef CONFIG_HPWDT_NMI_DECODING
-#define PCI_BIOS32_SD_VALUE            0x5F32335F      /* "_32_" */
-#define CRU_BIOS_SIGNATURE_VALUE       0x55524324
-#define PCI_BIOS32_PARAGRAPH_LEN       16
-#define PCI_ROM_BASE1                  0x000F0000
-#define ROM_SIZE                       0x10000
-
-struct bios32_service_dir {
-       u32 signature;
-       u32 entry_point;
-       u8 revision;
-       u8 length;
-       u8 checksum;
-       u8 reserved[5];
-};
-
-/* type 212 */
-struct smbios_cru64_info {
-       u8 type;
-       u8 byte_length;
-       u16 handle;
-       u32 signature;
-       u64 physical_address;
-       u32 double_length;
-       u32 double_offset;
-};
-#define SMBIOS_CRU64_INFORMATION       212
-
-/* type 219 */
-struct smbios_proliant_info {
-       u8 type;
-       u8 byte_length;
-       u16 handle;
-       u32 power_features;
-       u32 omega_features;
-       u32 reserved;
-       u32 misc_features;
-};
-#define SMBIOS_ICRU_INFORMATION                219
-
-
-struct cmn_registers {
-       union {
-               struct {
-                       u8 ral;
-                       u8 rah;
-                       u16 rea2;
-               };
-               u32 reax;
-       } u1;
-       union {
-               struct {
-                       u8 rbl;
-                       u8 rbh;
-                       u8 reb2l;
-                       u8 reb2h;
-               };
-               u32 rebx;
-       } u2;
-       union {
-               struct {
-                       u8 rcl;
-                       u8 rch;
-                       u16 rec2;
-               };
-               u32 recx;
-       } u3;
-       union {
-               struct {
-                       u8 rdl;
-                       u8 rdh;
-                       u16 red2;
-               };
-               u32 redx;
-       } u4;
-
-       u32 resi;
-       u32 redi;
-       u16 rds;
-       u16 res;
-       u32 reflags;
-}  __attribute__((packed));
-
-static unsigned int hpwdt_nmi_decoding;
-static unsigned int allow_kdump = 1;
-static unsigned int is_icru;
-static unsigned int is_uefi;
-static DEFINE_SPINLOCK(rom_lock);
-static void *cru_rom_addr;
-static struct cmn_registers cmn_regs;
-
-extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
-                                               unsigned long *pRomEntry);
-
-#ifdef CONFIG_X86_32
-/* --32 Bit Bios------------------------------------------------------------ */
-
-#define HPWDT_ARCH     32
-
-asm(".text                          \n\t"
-    ".align 4                       \n\t"
-    ".globl asminline_call         \n"
-    "asminline_call:                \n\t"
-    "pushl       %ebp               \n\t"
-    "movl        %esp, %ebp         \n\t"
-    "pusha                          \n\t"
-    "pushf                          \n\t"
-    "push        %es                \n\t"
-    "push        %ds                \n\t"
-    "pop         %es                \n\t"
-    "movl        8(%ebp),%eax       \n\t"
-    "movl        4(%eax),%ebx       \n\t"
-    "movl        8(%eax),%ecx       \n\t"
-    "movl        12(%eax),%edx      \n\t"
-    "movl        16(%eax),%esi      \n\t"
-    "movl        20(%eax),%edi      \n\t"
-    "movl        (%eax),%eax        \n\t"
-    "push        %cs                \n\t"
-    "call        *12(%ebp)          \n\t"
-    "pushf                          \n\t"
-    "pushl       %eax               \n\t"
-    "movl        8(%ebp),%eax       \n\t"
-    "movl        %ebx,4(%eax)       \n\t"
-    "movl        %ecx,8(%eax)       \n\t"
-    "movl        %edx,12(%eax)      \n\t"
-    "movl        %esi,16(%eax)      \n\t"
-    "movl        %edi,20(%eax)      \n\t"
-    "movw        %ds,24(%eax)       \n\t"
-    "movw        %es,26(%eax)       \n\t"
-    "popl        %ebx               \n\t"
-    "movl        %ebx,(%eax)        \n\t"
-    "popl        %ebx               \n\t"
-    "movl        %ebx,28(%eax)      \n\t"
-    "pop         %es                \n\t"
-    "popf                           \n\t"
-    "popa                           \n\t"
-    "leave                          \n\t"
-    "ret                            \n\t"
-    ".previous");
-
-
-/*
- *     cru_detect
- *
- *     Routine Description:
- *     This function uses the 32-bit BIOS Service Directory record to
- *     search for a $CRU record.
- *
- *     Return Value:
- *     0        :  SUCCESS
- *     <0       :  FAILURE
- */
-static int cru_detect(unsigned long map_entry,
-       unsigned long map_offset)
-{
-       void *bios32_map;
-       unsigned long *bios32_entrypoint;
-       unsigned long cru_physical_address;
-       unsigned long cru_length;
-       unsigned long physical_bios_base = 0;
-       unsigned long physical_bios_offset = 0;
-       int retval = -ENODEV;
-
-       bios32_map = ioremap(map_entry, (2 * PAGE_SIZE));
-
-       if (bios32_map == NULL)
-               return -ENODEV;
-
-       bios32_entrypoint = bios32_map + map_offset;
-
-       cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
-
-       set_memory_x((unsigned long)bios32_map, 2);
-       asminline_call(&cmn_regs, bios32_entrypoint);
-
-       if (cmn_regs.u1.ral != 0) {
-               pr_warn("Call succeeded but with an error: 0x%x\n",
-                       cmn_regs.u1.ral);
-       } else {
-               physical_bios_base = cmn_regs.u2.rebx;
-               physical_bios_offset = cmn_regs.u4.redx;
-               cru_length = cmn_regs.u3.recx;
-               cru_physical_address =
-                       physical_bios_base + physical_bios_offset;
-
-               /* If the values look OK, then map it in. */
-               if ((physical_bios_base + physical_bios_offset)) {
-                       cru_rom_addr =
-                               ioremap(cru_physical_address, cru_length);
-                       if (cru_rom_addr) {
-                               set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
-                                       (cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT);
-                               retval = 0;
-                       }
-               }
-
-               pr_debug("CRU Base Address:   0x%lx\n", physical_bios_base);
-               pr_debug("CRU Offset Address: 0x%lx\n", physical_bios_offset);
-               pr_debug("CRU Length:         0x%lx\n", cru_length);
-               pr_debug("CRU Mapped Address: %p\n", &cru_rom_addr);
-       }
-       iounmap(bios32_map);
-       return retval;
-}
-
-/*
- *     bios_checksum
- */
-static int bios_checksum(const char __iomem *ptr, int len)
-{
-       char sum = 0;
-       int i;
-
-       /*
-        * calculate checksum of size bytes. This should add up
-        * to zero if we have a valid header.
-        */
-       for (i = 0; i < len; i++)
-               sum += ptr[i];
-
-       return ((sum == 0) && (len > 0));
-}
-
-/*
- *     bios32_present
- *
- *     Routine Description:
- *     This function finds the 32-bit BIOS Service Directory
- *
- *     Return Value:
- *     0        :  SUCCESS
- *     <0       :  FAILURE
- */
-static int bios32_present(const char __iomem *p)
-{
-       struct bios32_service_dir *bios_32_ptr;
-       int length;
-       unsigned long map_entry, map_offset;
-
-       bios_32_ptr = (struct bios32_service_dir *) p;
-
-       /*
-        * Search for signature by checking equal to the swizzled value
-        * instead of calling another routine to perform a strcmp.
-        */
-       if (bios_32_ptr->signature == PCI_BIOS32_SD_VALUE) {
-               length = bios_32_ptr->length * PCI_BIOS32_PARAGRAPH_LEN;
-               if (bios_checksum(p, length)) {
-                       /*
-                        * According to the spec, we're looking for the
-                        * first 4KB-aligned address below the entrypoint
-                        * listed in the header. The Service Directory code
-                        * is guaranteed to occupy no more than 2 4KB pages.
-                        */
-                       map_entry = bios_32_ptr->entry_point & ~(PAGE_SIZE - 1);
-                       map_offset = bios_32_ptr->entry_point - map_entry;
-
-                       return cru_detect(map_entry, map_offset);
-               }
-       }
-       return -ENODEV;
-}
-
-static int detect_cru_service(void)
-{
-       char __iomem *p, *q;
-       int rc = -1;
-
-       /*
-        * Search from 0x0f0000 through 0x0fffff, inclusive.
-        */
-       p = ioremap(PCI_ROM_BASE1, ROM_SIZE);
-       if (p == NULL)
-               return -ENOMEM;
-
-       for (q = p; q < p + ROM_SIZE; q += 16) {
-               rc = bios32_present(q);
-               if (!rc)
-                       break;
-       }
-       iounmap(p);
-       return rc;
-}
-/* ------------------------------------------------------------------------- */
-#endif /* CONFIG_X86_32 */
-#ifdef CONFIG_X86_64
-/* --64 Bit Bios------------------------------------------------------------ */
-
-#define HPWDT_ARCH     64
-
-asm(".text                      \n\t"
-    ".align 4                   \n\t"
-    ".globl asminline_call     \n\t"
-    ".type asminline_call, @function \n\t"
-    "asminline_call:            \n\t"
-    FRAME_BEGIN
-    "pushq      %rax            \n\t"
-    "pushq      %rbx            \n\t"
-    "pushq      %rdx            \n\t"
-    "pushq      %r12            \n\t"
-    "pushq      %r9             \n\t"
-    "movq       %rsi, %r12      \n\t"
-    "movq       %rdi, %r9       \n\t"
-    "movl       4(%r9),%ebx     \n\t"
-    "movl       8(%r9),%ecx     \n\t"
-    "movl       12(%r9),%edx    \n\t"
-    "movl       16(%r9),%esi    \n\t"
-    "movl       20(%r9),%edi    \n\t"
-    "movl       (%r9),%eax      \n\t"
-    "call       *%r12           \n\t"
-    "pushfq                     \n\t"
-    "popq        %r12           \n\t"
-    "movl       %eax, (%r9)     \n\t"
-    "movl       %ebx, 4(%r9)    \n\t"
-    "movl       %ecx, 8(%r9)    \n\t"
-    "movl       %edx, 12(%r9)   \n\t"
-    "movl       %esi, 16(%r9)   \n\t"
-    "movl       %edi, 20(%r9)   \n\t"
-    "movq       %r12, %rax      \n\t"
-    "movl       %eax, 28(%r9)   \n\t"
-    "popq       %r9             \n\t"
-    "popq       %r12            \n\t"
-    "popq       %rdx            \n\t"
-    "popq       %rbx            \n\t"
-    "popq       %rax            \n\t"
-    FRAME_END
-    "ret                        \n\t"
-    ".previous");
-
-/*
- *     dmi_find_cru
- *
- *     Routine Description:
- *     This function checks whether or not a SMBIOS/DMI record is
- *     the 64bit CRU info or not
- */
-static void dmi_find_cru(const struct dmi_header *dm, void *dummy)
-{
-       struct smbios_cru64_info *smbios_cru64_ptr;
-       unsigned long cru_physical_address;
-
-       if (dm->type == SMBIOS_CRU64_INFORMATION) {
-               smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
-               if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
-                       cru_physical_address =
-                               smbios_cru64_ptr->physical_address +
-                               smbios_cru64_ptr->double_offset;
-                       cru_rom_addr = ioremap(cru_physical_address,
-                               smbios_cru64_ptr->double_length);
-                       set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
-                               smbios_cru64_ptr->double_length >> PAGE_SHIFT);
-               }
-       }
-}
-
-static int detect_cru_service(void)
-{
-       cru_rom_addr = NULL;
-
-       dmi_walk(dmi_find_cru, NULL);
-
-       /* if cru_rom_addr has been set then we found a CRU service */
-       return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
-}
-/* ------------------------------------------------------------------------- */
-#endif /* CONFIG_X86_64 */
-#endif /* CONFIG_HPWDT_NMI_DECODING */
 
 /*
  *     Watchdog operations
@@ -486,30 +113,12 @@ static int hpwdt_my_nmi(void)
  */
 static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
 {
-       unsigned long rom_pl;
-       static int die_nmi_called;
-
-       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);
-       die_nmi_called = 1;
-       spin_unlock_irqrestore(&rom_lock, rom_pl);
-
        if (allow_kdump)
                hpwdt_stop();
 
-       if (!is_icru && !is_uefi) {
-               if (cmn_regs.u1.ral == 0) {
-                       nmi_panic(regs, "An NMI occurred, but unable to determine source.\n");
-                       return NMI_HANDLED;
-               }
-       }
        nmi_panic(regs, "An NMI occurred. Depending on your system the reason "
                "for the NMI is logged in any one of the following "
                "resources:\n"
@@ -675,84 +284,11 @@ static struct miscdevice hpwdt_miscdev = {
  *     Init & Exit
  */
 
-#ifdef CONFIG_HPWDT_NMI_DECODING
-#ifdef CONFIG_X86_LOCAL_APIC
-static void hpwdt_check_nmi_decoding(struct pci_dev *dev)
-{
-       /*
-        * If nmi_watchdog is turned off then we can turn on
-        * our nmi decoding capability.
-        */
-       hpwdt_nmi_decoding = 1;
-}
-#else
-static void hpwdt_check_nmi_decoding(struct pci_dev *dev)
-{
-       dev_warn(&dev->dev, "NMI decoding is disabled. "
-               "Your kernel does not support a NMI Watchdog.\n");
-}
-#endif /* CONFIG_X86_LOCAL_APIC */
-
-/*
- *     dmi_find_icru
- *
- *     Routine Description:
- *     This function checks whether or not we are on an iCRU-based server.
- *     This check is independent of architecture and needs to be made for
- *     any ProLiant system.
- */
-static void dmi_find_icru(const struct dmi_header *dm, void *dummy)
-{
-       struct smbios_proliant_info *smbios_proliant_ptr;
-
-       if (dm->type == SMBIOS_ICRU_INFORMATION) {
-               smbios_proliant_ptr = (struct smbios_proliant_info *) dm;
-               if (smbios_proliant_ptr->misc_features & 0x01)
-                       is_icru = 1;
-               if (smbios_proliant_ptr->misc_features & 0x1400)
-                       is_uefi = 1;
-       }
-}
 
 static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
 {
+#ifdef CONFIG_HPWDT_NMI_DECODING
        int retval;
-
-       /*
-        * On typical CRU-based systems we need to map that service in
-        * the BIOS. For 32 bit Operating Systems we need to go through
-        * the 32 Bit BIOS Service Directory. For 64 bit Operating
-        * Systems we get that service through SMBIOS.
-        *
-        * On systems that support the new iCRU service all we need to
-        * do is call dmi_walk to get the supported flag value and skip
-        * the old cru detect code.
-        */
-       dmi_walk(dmi_find_icru, NULL);
-       if (!is_icru && !is_uefi) {
-
-               /*
-               * We need to map the ROM to get the CRU service.
-               * For 32 bit Operating Systems we need to go through the 32 Bit
-               * BIOS Service Directory
-               * For 64 bit Operating Systems we get that service through SMBIOS.
-               */
-               retval = detect_cru_service();
-               if (retval < 0) {
-                       dev_warn(&dev->dev,
-                               "Unable to detect the %d Bit CRU Service.\n",
-                               HPWDT_ARCH);
-                       return retval;
-               }
-
-               /*
-               * We know this is the only CRU call we need to make so lets keep as
-               * few instructions as possible once the NMI comes in.
-               */
-               cmn_regs.u1.rah = 0x0D;
-               cmn_regs.u1.ral = 0x02;
-       }
-
        /*
         * Only one function can register for NMI_UNKNOWN
         */
@@ -780,44 +316,25 @@ error:
        dev_warn(&dev->dev,
                "Unable to register a die notifier (err=%d).\n",
                retval);
-       if (cru_rom_addr)
-               iounmap(cru_rom_addr);
        return retval;
+#endif /* CONFIG_HPWDT_NMI_DECODING */
+       return 0;
 }
 
 static void hpwdt_exit_nmi_decoding(void)
 {
+#ifdef CONFIG_HPWDT_NMI_DECODING
        unregister_nmi_handler(NMI_UNKNOWN, "hpwdt");
        unregister_nmi_handler(NMI_SERR, "hpwdt");
        unregister_nmi_handler(NMI_IO_CHECK, "hpwdt");
-       if (cru_rom_addr)
-               iounmap(cru_rom_addr);
-}
-#else /* !CONFIG_HPWDT_NMI_DECODING */
-static void hpwdt_check_nmi_decoding(struct pci_dev *dev)
-{
-}
-
-static int hpwdt_init_nmi_decoding(struct pci_dev *dev)
-{
-       return 0;
+#endif
 }
 
-static void hpwdt_exit_nmi_decoding(void)
-{
-}
-#endif /* CONFIG_HPWDT_NMI_DECODING */
-
 static int hpwdt_init_one(struct pci_dev *dev,
                                        const struct pci_device_id *ent)
 {
        int retval;
 
-       /*
-        * Check if we can do NMI decoding or not
-        */
-       hpwdt_check_nmi_decoding(dev);
-
        /*
         * First let's find out if we are on an iLO2+ server. We will
         * not run on a legacy ASM box.
@@ -922,6 +439,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 #ifdef CONFIG_HPWDT_NMI_DECODING
 module_param(allow_kdump, int, 0);
 MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
-#endif /* !CONFIG_HPWDT_NMI_DECODING */
+#endif /* CONFIG_HPWDT_NMI_DECODING */
 
 module_pci_driver(hpwdt_driver);
index 316c2eb122d23d335d738947a63fc2f9db2e4f1b..e8bd9887c56638aaf81659c45d7505c424266b55 100644 (file)
@@ -50,6 +50,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -159,7 +160,7 @@ static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
            !(readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0))
                timeleft += readl(gwdt->control_base + SBSA_GWDT_WOR);
 
-       timeleft += readq(gwdt->control_base + SBSA_GWDT_WCV) -
+       timeleft += lo_hi_readq(gwdt->control_base + SBSA_GWDT_WCV) -
                    arch_counter_get_cntvct();
 
        do_div(timeleft, gwdt->clk);
index 6d1fbda0f461ca2d2304eaeb43aef35adfd77cf4..0da9943d405f8ff89efc87a0cf6df5ff43df9d6f 100644 (file)
@@ -392,7 +392,7 @@ static int wdat_wdt_probe(struct platform_device *pdev)
 
                memset(&r, 0, sizeof(r));
                r.start = gas->address;
-               r.end = r.start + gas->access_width;
+               r.end = r.start + gas->access_width - 1;
                if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
                        r.flags = IORESOURCE_MEM;
                } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
index 1ab4bd11f5f3f01f34b1a0055f836c9a0ce755ba..762378f1811cc9069dc6171edb55aaa3610b82fa 100644 (file)
@@ -755,8 +755,8 @@ out:
        mutex_unlock(&irq_mapping_update_lock);
        return irq;
 error_irq:
-       for (; i >= 0; i--)
-               __unbind_from_irq(irq + i);
+       while (nvec--)
+               __unbind_from_irq(irq + nvec);
        mutex_unlock(&irq_mapping_update_lock);
        return ret;
 }
index 156e5aea36db964dfaac58784044ca1cd0cf57c7..b1092fbefa6309d2535b17b78979b6f3fa9b2b42 100644 (file)
@@ -416,7 +416,7 @@ static int pvcalls_back_connect(struct xenbus_device *dev,
                                        sock);
        if (!map) {
                ret = -EFAULT;
-               sock_release(map->sock);
+               sock_release(sock);
        }
 
 out:
index 753d9cb437d02597aa07452dabaac64263d35691..2f11ca72a281410122ef0b4f0dc4f173ef7c6697 100644 (file)
@@ -60,6 +60,7 @@ struct sock_mapping {
        bool active_socket;
        struct list_head list;
        struct socket *sock;
+       atomic_t refcount;
        union {
                struct {
                        int irq;
@@ -72,20 +73,25 @@ struct sock_mapping {
                        wait_queue_head_t inflight_conn_req;
                } active;
                struct {
-               /* Socket status */
+               /*
+                * Socket status, needs to be 64-bit aligned due to the
+                * test_and_* functions which have this requirement on arm64.
+                */
 #define PVCALLS_STATUS_UNINITALIZED  0
 #define PVCALLS_STATUS_BIND          1
 #define PVCALLS_STATUS_LISTEN        2
-                       uint8_t status;
+                       uint8_t status __attribute__((aligned(8)));
                /*
                 * Internal state-machine flags.
                 * Only one accept operation can be inflight for a socket.
                 * Only one poll operation can be inflight for a given socket.
+                * flags needs to be 64-bit aligned due to the test_and_*
+                * functions which have this requirement on arm64.
                 */
 #define PVCALLS_FLAG_ACCEPT_INFLIGHT 0
 #define PVCALLS_FLAG_POLL_INFLIGHT   1
 #define PVCALLS_FLAG_POLL_RET        2
-                       uint8_t flags;
+                       uint8_t flags __attribute__((aligned(8)));
                        uint32_t inflight_req_id;
                        struct sock_mapping *accept_map;
                        wait_queue_head_t inflight_accept_req;
@@ -93,6 +99,32 @@ struct sock_mapping {
        };
 };
 
+static inline struct sock_mapping *pvcalls_enter_sock(struct socket *sock)
+{
+       struct sock_mapping *map;
+
+       if (!pvcalls_front_dev ||
+               dev_get_drvdata(&pvcalls_front_dev->dev) == NULL)
+               return ERR_PTR(-ENOTCONN);
+
+       map = (struct sock_mapping *)sock->sk->sk_send_head;
+       if (map == NULL)
+               return ERR_PTR(-ENOTSOCK);
+
+       pvcalls_enter();
+       atomic_inc(&map->refcount);
+       return map;
+}
+
+static inline void pvcalls_exit_sock(struct socket *sock)
+{
+       struct sock_mapping *map;
+
+       map = (struct sock_mapping *)sock->sk->sk_send_head;
+       atomic_dec(&map->refcount);
+       pvcalls_exit();
+}
+
 static inline int get_request(struct pvcalls_bedata *bedata, int *req_id)
 {
        *req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1);
@@ -369,31 +401,23 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
        if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM)
                return -EOPNOTSUPP;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -ENOTCONN;
-       }
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
 
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *)sock->sk->sk_send_head;
-       if (!map) {
-               pvcalls_exit();
-               return -ENOTSOCK;
-       }
-
        spin_lock(&bedata->socket_lock);
        ret = get_request(bedata, &req_id);
        if (ret < 0) {
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
        ret = create_active(map, &evtchn);
        if (ret < 0) {
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
 
@@ -423,7 +447,7 @@ int pvcalls_front_connect(struct socket *sock, struct sockaddr *addr,
        smp_rmb();
        ret = bedata->rsp[req_id].ret;
        bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID;
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return ret;
 }
 
@@ -488,23 +512,15 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg,
        if (flags & (MSG_CONFIRM|MSG_DONTROUTE|MSG_EOR|MSG_OOB))
                return -EOPNOTSUPP;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -ENOTCONN;
-       }
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (!map) {
-               pvcalls_exit();
-               return -ENOTSOCK;
-       }
-
        mutex_lock(&map->active.out_mutex);
        if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) {
                mutex_unlock(&map->active.out_mutex);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -EAGAIN;
        }
        if (len > INT_MAX)
@@ -526,7 +542,7 @@ again:
                tot_sent = sent;
 
        mutex_unlock(&map->active.out_mutex);
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return tot_sent;
 }
 
@@ -591,19 +607,11 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        if (flags & (MSG_CMSG_CLOEXEC|MSG_ERRQUEUE|MSG_OOB|MSG_TRUNC))
                return -EOPNOTSUPP;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -ENOTCONN;
-       }
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (!map) {
-               pvcalls_exit();
-               return -ENOTSOCK;
-       }
-
        mutex_lock(&map->active.in_mutex);
        if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER))
                len = XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER);
@@ -623,7 +631,7 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
                ret = 0;
 
        mutex_unlock(&map->active.in_mutex);
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return ret;
 }
 
@@ -637,24 +645,16 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
        if (addr->sa_family != AF_INET || sock->type != SOCK_STREAM)
                return -EOPNOTSUPP;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -ENOTCONN;
-       }
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (map == NULL) {
-               pvcalls_exit();
-               return -ENOTSOCK;
-       }
-
        spin_lock(&bedata->socket_lock);
        ret = get_request(bedata, &req_id);
        if (ret < 0) {
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
        req = RING_GET_REQUEST(&bedata->ring, req_id);
@@ -684,7 +684,7 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
        bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID;
 
        map->passive.status = PVCALLS_STATUS_BIND;
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return 0;
 }
 
@@ -695,21 +695,13 @@ int pvcalls_front_listen(struct socket *sock, int backlog)
        struct xen_pvcalls_request *req;
        int notify, req_id, ret;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -ENOTCONN;
-       }
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (!map) {
-               pvcalls_exit();
-               return -ENOTSOCK;
-       }
-
        if (map->passive.status != PVCALLS_STATUS_BIND) {
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -EOPNOTSUPP;
        }
 
@@ -717,7 +709,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog)
        ret = get_request(bedata, &req_id);
        if (ret < 0) {
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
        req = RING_GET_REQUEST(&bedata->ring, req_id);
@@ -741,7 +733,7 @@ int pvcalls_front_listen(struct socket *sock, int backlog)
        bedata->rsp[req_id].req_id = PVCALLS_INVALID_ID;
 
        map->passive.status = PVCALLS_STATUS_LISTEN;
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return ret;
 }
 
@@ -753,21 +745,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags)
        struct xen_pvcalls_request *req;
        int notify, req_id, ret, evtchn, nonblock;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -ENOTCONN;
-       }
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
+               return PTR_ERR(map);
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (!map) {
-               pvcalls_exit();
-               return -ENOTSOCK;
-       }
-
        if (map->passive.status != PVCALLS_STATUS_LISTEN) {
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -EINVAL;
        }
 
@@ -785,13 +769,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags)
                        goto received;
                }
                if (nonblock) {
-                       pvcalls_exit();
+                       pvcalls_exit_sock(sock);
                        return -EAGAIN;
                }
                if (wait_event_interruptible(map->passive.inflight_accept_req,
                        !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
                                          (void *)&map->passive.flags))) {
-                       pvcalls_exit();
+                       pvcalls_exit_sock(sock);
                        return -EINTR;
                }
        }
@@ -802,7 +786,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags)
                clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
                          (void *)&map->passive.flags);
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
        map2 = kzalloc(sizeof(*map2), GFP_ATOMIC);
@@ -810,7 +794,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags)
                clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
                          (void *)&map->passive.flags);
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -ENOMEM;
        }
        ret = create_active(map2, &evtchn);
@@ -819,7 +803,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags)
                clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
                          (void *)&map->passive.flags);
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
        list_add_tail(&map2->list, &bedata->socket_mappings);
@@ -841,13 +825,13 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags)
        /* We could check if we have received a response before returning. */
        if (nonblock) {
                WRITE_ONCE(map->passive.inflight_req_id, req_id);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -EAGAIN;
        }
 
        if (wait_event_interruptible(bedata->inflight_req,
                READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) {
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -EINTR;
        }
        /* read req_id, then the content */
@@ -862,7 +846,7 @@ received:
                clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT,
                          (void *)&map->passive.flags);
                pvcalls_front_free_map(bedata, map2);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return -ENOMEM;
        }
        newsock->sk->sk_send_head = (void *)map2;
@@ -874,7 +858,7 @@ received:
        clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags);
        wake_up(&map->passive.inflight_accept_req);
 
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return ret;
 }
 
@@ -965,23 +949,16 @@ __poll_t pvcalls_front_poll(struct file *file, struct socket *sock,
        struct sock_mapping *map;
        __poll_t ret;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map))
                return EPOLLNVAL;
-       }
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (!map) {
-               pvcalls_exit();
-               return EPOLLNVAL;
-       }
        if (map->active_socket)
                ret = pvcalls_front_poll_active(file, bedata, map, wait);
        else
                ret = pvcalls_front_poll_passive(file, bedata, map, wait);
-       pvcalls_exit();
+       pvcalls_exit_sock(sock);
        return ret;
 }
 
@@ -995,25 +972,20 @@ int pvcalls_front_release(struct socket *sock)
        if (sock->sk == NULL)
                return 0;
 
-       pvcalls_enter();
-       if (!pvcalls_front_dev) {
-               pvcalls_exit();
-               return -EIO;
+       map = pvcalls_enter_sock(sock);
+       if (IS_ERR(map)) {
+               if (PTR_ERR(map) == -ENOTCONN)
+                       return -EIO;
+               else
+                       return 0;
        }
-
        bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
-       map = (struct sock_mapping *) sock->sk->sk_send_head;
-       if (map == NULL) {
-               pvcalls_exit();
-               return 0;
-       }
-
        spin_lock(&bedata->socket_lock);
        ret = get_request(bedata, &req_id);
        if (ret < 0) {
                spin_unlock(&bedata->socket_lock);
-               pvcalls_exit();
+               pvcalls_exit_sock(sock);
                return ret;
        }
        sock->sk->sk_send_head = NULL;
@@ -1043,14 +1015,20 @@ int pvcalls_front_release(struct socket *sock)
                /*
                 * We need to make sure that sendmsg/recvmsg on this socket have
                 * not started before we've cleared sk_send_head here. The
-                * easiest (though not optimal) way to guarantee this is to see
-                * that no pvcall (other than us) is in progress.
+                * easiest way to guarantee this is to see that no pvcalls
+                * (other than us) is in progress on this socket.
                 */
-               while (atomic_read(&pvcalls_refcount) > 1)
+               while (atomic_read(&map->refcount) > 1)
                        cpu_relax();
 
                pvcalls_front_free_map(bedata, map);
        } else {
+               wake_up(&bedata->inflight_req);
+               wake_up(&map->passive.inflight_accept_req);
+
+               while (atomic_read(&map->refcount) > 1)
+                       cpu_relax();
+
                spin_lock(&bedata->socket_lock);
                list_del(&map->list);
                spin_unlock(&bedata->socket_lock);
index bf13d1ec51f3bee0c92e9f9c968c21c13bd72173..04e7b3b29bac898ca66baac7aa96eadba2e3dc35 100644 (file)
@@ -284,6 +284,10 @@ static int tmem_frontswap_store(unsigned type, pgoff_t offset,
        int pool = tmem_frontswap_poolid;
        int ret;
 
+       /* THP isn't supported */
+       if (PageTransHuge(page))
+               return -1;
+
        if (pool < 0)
                return -1;
        if (ind64 != ind)
index 149c5e7efc89e75f0fd56a01b40f0f15b462af04..092981171df17ffe076dadd0582566902c03feda 100644 (file)
@@ -76,6 +76,7 @@ struct xb_req_data {
        struct list_head list;
        wait_queue_head_t wq;
        struct xsd_sockmsg msg;
+       uint32_t caller_req_id;
        enum xsd_sockmsg_type type;
        char *body;
        const struct kvec *vec;
index 5b081a01779de8001e48c1c0e2e0f9dea6697332..d239fc3c5e3ded66ad28194fcdc7d09a6df801da 100644 (file)
@@ -309,6 +309,7 @@ static int process_msg(void)
                        goto out;
 
                if (req->state == xb_req_state_wait_reply) {
+                       req->msg.req_id = req->caller_req_id;
                        req->msg.type = state.msg.type;
                        req->msg.len = state.msg.len;
                        req->body = state.body;
index 74888cacd0b0bdcd250135e6436e0c1e39fc330f..ec9eb4fba59c7e88f746f01aa9fe66c2ed590482 100644 (file)
@@ -466,8 +466,11 @@ int xenbus_probe_node(struct xen_bus_type *bus,
 
        /* Register with generic device framework. */
        err = device_register(&xendev->dev);
-       if (err)
+       if (err) {
+               put_device(&xendev->dev);
+               xendev = NULL;
                goto fail;
+       }
 
        return 0;
 fail:
index 3e59590c7254ddc8f1a08f4232262a74a29e3711..3f3b29398ab8e2b711ce724cf756ea8c241433cb 100644 (file)
@@ -227,6 +227,8 @@ static void xs_send(struct xb_req_data *req, struct xsd_sockmsg *msg)
        req->state = xb_req_state_queued;
        init_waitqueue_head(&req->wq);
 
+       /* Save the caller req_id and restore it later in the reply */
+       req->caller_req_id = req->msg.req_id;
        req->msg.req_id = xs_request_enter(req);
 
        mutex_lock(&xb_write_mutex);
@@ -310,6 +312,7 @@ static void *xs_talkv(struct xenbus_transaction t,
        req->num_vecs = num_vecs;
        req->cb = xs_wake_up;
 
+       msg.req_id = 0;
        msg.tx_id = t.id;
        msg.type = type;
        msg.len = 0;
index a062d75109cb380aeb819fe42d43644c8be33a91..6bcd3fb5265ad13fba958c2de06d0f54232a5eba 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -68,9 +68,9 @@ struct aio_ring {
 #define AIO_RING_PAGES 8
 
 struct kioctx_table {
-       struct rcu_head rcu;
-       unsigned        nr;
-       struct kioctx   *table[];
+       struct rcu_head         rcu;
+       unsigned                nr;
+       struct kioctx __rcu     *table[];
 };
 
 struct kioctx_cpu {
@@ -115,7 +115,8 @@ struct kioctx {
        struct page             **ring_pages;
        long                    nr_pages;
 
-       struct work_struct      free_work;
+       struct rcu_head         free_rcu;
+       struct work_struct      free_work;      /* see free_ioctx() */
 
        /*
         * signals when all in-flight requests are done
@@ -329,7 +330,7 @@ static int aio_ring_mremap(struct vm_area_struct *vma)
        for (i = 0; i < table->nr; i++) {
                struct kioctx *ctx;
 
-               ctx = table->table[i];
+               ctx = rcu_dereference(table->table[i]);
                if (ctx && ctx->aio_ring_file == file) {
                        if (!atomic_read(&ctx->dead)) {
                                ctx->user_id = ctx->mmap_base = vma->vm_start;
@@ -588,6 +589,12 @@ static int kiocb_cancel(struct aio_kiocb *kiocb)
        return cancel(&kiocb->common);
 }
 
+/*
+ * free_ioctx() should be RCU delayed to synchronize against the RCU
+ * protected lookup_ioctx() and also needs process context to call
+ * aio_free_ring(), so the double bouncing through kioctx->free_rcu and
+ * ->free_work.
+ */
 static void free_ioctx(struct work_struct *work)
 {
        struct kioctx *ctx = container_of(work, struct kioctx, free_work);
@@ -601,6 +608,14 @@ static void free_ioctx(struct work_struct *work)
        kmem_cache_free(kioctx_cachep, ctx);
 }
 
+static void free_ioctx_rcufn(struct rcu_head *head)
+{
+       struct kioctx *ctx = container_of(head, struct kioctx, free_rcu);
+
+       INIT_WORK(&ctx->free_work, free_ioctx);
+       schedule_work(&ctx->free_work);
+}
+
 static void free_ioctx_reqs(struct percpu_ref *ref)
 {
        struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
@@ -609,8 +624,8 @@ static void free_ioctx_reqs(struct percpu_ref *ref)
        if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count))
                complete(&ctx->rq_wait->comp);
 
-       INIT_WORK(&ctx->free_work, free_ioctx);
-       schedule_work(&ctx->free_work);
+       /* Synchronize against RCU protected table->table[] dereferences */
+       call_rcu(&ctx->free_rcu, free_ioctx_rcufn);
 }
 
 /*
@@ -651,9 +666,9 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
        while (1) {
                if (table)
                        for (i = 0; i < table->nr; i++)
-                               if (!table->table[i]) {
+                               if (!rcu_access_pointer(table->table[i])) {
                                        ctx->id = i;
-                                       table->table[i] = ctx;
+                                       rcu_assign_pointer(table->table[i], ctx);
                                        spin_unlock(&mm->ioctx_lock);
 
                                        /* While kioctx setup is in progress,
@@ -834,11 +849,11 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
        }
 
        table = rcu_dereference_raw(mm->ioctx_table);
-       WARN_ON(ctx != table->table[ctx->id]);
-       table->table[ctx->id] = NULL;
+       WARN_ON(ctx != rcu_access_pointer(table->table[ctx->id]));
+       RCU_INIT_POINTER(table->table[ctx->id], NULL);
        spin_unlock(&mm->ioctx_lock);
 
-       /* percpu_ref_kill() will do the necessary call_rcu() */
+       /* free_ioctx_reqs() will do the necessary RCU synchronization */
        wake_up_all(&ctx->wait);
 
        /*
@@ -880,7 +895,8 @@ void exit_aio(struct mm_struct *mm)
 
        skipped = 0;
        for (i = 0; i < table->nr; ++i) {
-               struct kioctx *ctx = table->table[i];
+               struct kioctx *ctx =
+                       rcu_dereference_protected(table->table[i], true);
 
                if (!ctx) {
                        skipped++;
@@ -1069,7 +1085,7 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)
        if (!table || id >= table->nr)
                goto out;
 
-       ctx = table->table[id];
+       ctx = rcu_dereference(table->table[id]);
        if (ctx && ctx->user_id == ctx_id) {
                percpu_ref_get(&ctx->users);
                ret = ctx;
index 4a181fcb51751dc2cbc8fda10930a47bc883380e..fe09ef9c21f349a55d31261b5dd416b1bde2a3aa 100644 (file)
@@ -1058,6 +1058,27 @@ retry:
        return 0;
 }
 
+static struct gendisk *bdev_get_gendisk(struct block_device *bdev, int *partno)
+{
+       struct gendisk *disk = get_gendisk(bdev->bd_dev, partno);
+
+       if (!disk)
+               return NULL;
+       /*
+        * Now that we hold gendisk reference we make sure bdev we looked up is
+        * not stale. If it is, it means device got removed and created before
+        * we looked up gendisk and we fail open in such case. Associating
+        * unhashed bdev with newly created gendisk could lead to two bdevs
+        * (and thus two independent caches) being associated with one device
+        * which is bad.
+        */
+       if (inode_unhashed(bdev->bd_inode)) {
+               put_disk_and_module(disk);
+               return NULL;
+       }
+       return disk;
+}
+
 /**
  * bd_start_claiming - start claiming a block device
  * @bdev: block device of interest
@@ -1094,7 +1115,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev,
         * @bdev might not have been initialized properly yet, look up
         * and grab the outer block device the hard way.
         */
-       disk = get_gendisk(bdev->bd_dev, &partno);
+       disk = bdev_get_gendisk(bdev, &partno);
        if (!disk)
                return ERR_PTR(-ENXIO);
 
@@ -1111,8 +1132,7 @@ static struct block_device *bd_start_claiming(struct block_device *bdev,
        else
                whole = bdgrab(bdev);
 
-       module_put(disk->fops->owner);
-       put_disk(disk);
+       put_disk_and_module(disk);
        if (!whole)
                return ERR_PTR(-ENOMEM);
 
@@ -1407,10 +1427,10 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part);
 static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
 {
        struct gendisk *disk;
-       struct module *owner;
        int ret;
        int partno;
        int perm = 0;
+       bool first_open = false;
 
        if (mode & FMODE_READ)
                perm |= MAY_READ;
@@ -1430,14 +1450,14 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
  restart:
 
        ret = -ENXIO;
-       disk = get_gendisk(bdev->bd_dev, &partno);
+       disk = bdev_get_gendisk(bdev, &partno);
        if (!disk)
                goto out;
-       owner = disk->fops->owner;
 
        disk_block_events(disk);
        mutex_lock_nested(&bdev->bd_mutex, for_part);
        if (!bdev->bd_openers) {
+               first_open = true;
                bdev->bd_disk = disk;
                bdev->bd_queue = disk->queue;
                bdev->bd_contains = bdev;
@@ -1463,8 +1483,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                                        bdev->bd_queue = NULL;
                                        mutex_unlock(&bdev->bd_mutex);
                                        disk_unblock_events(disk);
-                                       put_disk(disk);
-                                       module_put(owner);
+                                       put_disk_and_module(disk);
                                        goto restart;
                                }
                        }
@@ -1524,15 +1543,15 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                        if (ret)
                                goto out_unlock_bdev;
                }
-               /* only one opener holds refs to the module and disk */
-               put_disk(disk);
-               module_put(owner);
        }
        bdev->bd_openers++;
        if (for_part)
                bdev->bd_part_count++;
        mutex_unlock(&bdev->bd_mutex);
        disk_unblock_events(disk);
+       /* only one opener holds refs to the module and disk */
+       if (!first_open)
+               put_disk_and_module(disk);
        return 0;
 
  out_clear:
@@ -1546,8 +1565,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
  out_unlock_bdev:
        mutex_unlock(&bdev->bd_mutex);
        disk_unblock_events(disk);
-       put_disk(disk);
-       module_put(owner);
+       put_disk_and_module(disk);
  out:
        bdput(bdev);
 
@@ -1770,8 +1788,6 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
                        disk->fops->release(disk, mode);
        }
        if (!bdev->bd_openers) {
-               struct module *owner = disk->fops->owner;
-
                disk_put_part(bdev->bd_part);
                bdev->bd_part = NULL;
                bdev->bd_disk = NULL;
@@ -1779,8 +1795,7 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
                        victim = bdev->bd_contains;
                bdev->bd_contains = NULL;
 
-               put_disk(disk);
-               module_put(owner);
+               put_disk_and_module(disk);
        }
        mutex_unlock(&bdev->bd_mutex);
        bdput(bdev);
index e4054e533f6d4d26b783540657d2ea9b78bb97cc..26484648d0903298cbb68bff095232873e94673a 100644 (file)
@@ -1264,7 +1264,16 @@ again:
        while (node) {
                ref = rb_entry(node, struct prelim_ref, rbnode);
                node = rb_next(&ref->rbnode);
-               WARN_ON(ref->count < 0);
+               /*
+                * ref->count < 0 can happen here if there are delayed
+                * refs with a node->action of BTRFS_DROP_DELAYED_REF.
+                * prelim_ref_insert() relies on this when merging
+                * identical refs to keep the overall count correct.
+                * prelim_ref_insert() will merge only those refs
+                * which compare identically.  Any refs having
+                * e.g. different offsets would not be merged,
+                * and would retain their original ref->count < 0.
+                */
                if (roots && ref->count && ref->root_id && ref->parent == 0) {
                        if (sc && sc->root_objectid &&
                            ref->root_id != sc->root_objectid) {
@@ -1510,6 +1519,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr)
                if (!node)
                        break;
                bytenr = node->val;
+               shared.share_count = 0;
                cond_resched();
        }
 
index 1a462ab85c49888a3962b026a74ede8c47182fc1..da308774b8a4538c4bbea595a11b49a2a8c5ca5e 100644 (file)
@@ -2974,7 +2974,7 @@ static inline void free_fs_info(struct btrfs_fs_info *fs_info)
        kfree(fs_info->super_copy);
        kfree(fs_info->super_for_commit);
        security_free_mnt_opts(&fs_info->security_opts);
-       kfree(fs_info);
+       kvfree(fs_info);
 }
 
 /* tree mod log functions from ctree.c */
@@ -3095,7 +3095,10 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
                          u64 inode_objectid, u64 ref_objectid, int ins_len,
                          int cow);
 
-int btrfs_find_name_in_ext_backref(struct btrfs_path *path,
+int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
+                              const char *name,
+                              int name_len, struct btrfs_inode_ref **ref_ret);
+int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
                                   u64 ref_objectid, const char *name,
                                   int name_len,
                                   struct btrfs_inode_extref **extref_ret);
index a1a40cf382e39c1da97dcd3d8fd3a0a9eda537e2..7ab5e0128f0ce823101f5623a0664c01208f89a7 100644 (file)
@@ -821,7 +821,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        spin_unlock(&delayed_refs->lock);
 
        if (qrecord_inserted)
-               return btrfs_qgroup_trace_extent_post(fs_info, record);
+               btrfs_qgroup_trace_extent_post(fs_info, record);
+
        return 0;
 
 free_head_ref:
index 05751a677da4fb2fd9a2eee3f3d90ad0071c1ebd..c1618ab9fecfb06a50861f26e4d445fe9d63190e 100644 (file)
@@ -2147,6 +2147,10 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
                        u64 bytes;
                        struct request_queue *req_q;
 
+                       if (!stripe->dev->bdev) {
+                               ASSERT(btrfs_test_opt(fs_info, DEGRADED));
+                               continue;
+                       }
                        req_q = bdev_get_queue(stripe->dev->bdev);
                        if (!blk_queue_discard(req_q))
                                continue;
index 39c968f801572ec004223893d44525c64bb9ecc0..65e1a76bf7557441b22b16d4765a531b18b23562 100644 (file)
 #include "transaction.h"
 #include "print-tree.h"
 
-static int find_name_in_backref(struct btrfs_path *path, const char *name,
-                        int name_len, struct btrfs_inode_ref **ref_ret)
+int btrfs_find_name_in_backref(struct extent_buffer *leaf, int slot,
+                              const char *name,
+                              int name_len, struct btrfs_inode_ref **ref_ret)
 {
-       struct extent_buffer *leaf;
        struct btrfs_inode_ref *ref;
        unsigned long ptr;
        unsigned long name_ptr;
@@ -33,9 +33,8 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
        u32 cur_offset = 0;
        int len;
 
-       leaf = path->nodes[0];
-       item_size = btrfs_item_size_nr(leaf, path->slots[0]);
-       ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+       item_size = btrfs_item_size_nr(leaf, slot);
+       ptr = btrfs_item_ptr_offset(leaf, slot);
        while (cur_offset < item_size) {
                ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
                len = btrfs_inode_ref_name_len(leaf, ref);
@@ -44,18 +43,19 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
                if (len != name_len)
                        continue;
                if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) {
-                       *ref_ret = ref;
+                       if (ref_ret)
+                               *ref_ret = ref;
                        return 1;
                }
        }
        return 0;
 }
 
-int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
+int btrfs_find_name_in_ext_backref(struct extent_buffer *leaf, int slot,
+                                  u64 ref_objectid,
                                   const char *name, int name_len,
                                   struct btrfs_inode_extref **extref_ret)
 {
-       struct extent_buffer *leaf;
        struct btrfs_inode_extref *extref;
        unsigned long ptr;
        unsigned long name_ptr;
@@ -63,9 +63,8 @@ int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
        u32 cur_offset = 0;
        int ref_name_len;
 
-       leaf = path->nodes[0];
-       item_size = btrfs_item_size_nr(leaf, path->slots[0]);
-       ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+       item_size = btrfs_item_size_nr(leaf, slot);
+       ptr = btrfs_item_ptr_offset(leaf, slot);
 
        /*
         * Search all extended backrefs in this item. We're only
@@ -113,7 +112,9 @@ btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
                return ERR_PTR(ret);
        if (ret > 0)
                return NULL;
-       if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref))
+       if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
+                                           ref_objectid, name, name_len,
+                                           &extref))
                return NULL;
        return extref;
 }
@@ -155,7 +156,8 @@ static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
         * This should always succeed so error here will make the FS
         * readonly.
         */
-       if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
+       if (!btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
+                                           ref_objectid,
                                            name, name_len, &extref)) {
                btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
                ret = -EROFS;
@@ -225,7 +227,8 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
        } else if (ret < 0) {
                goto out;
        }
-       if (!find_name_in_backref(path, name, name_len, &ref)) {
+       if (!btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
+                                       name, name_len, &ref)) {
                ret = -ENOENT;
                search_ext_refs = 1;
                goto out;
@@ -293,7 +296,9 @@ static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
        ret = btrfs_insert_empty_item(trans, root, path, &key,
                                      ins_len);
        if (ret == -EEXIST) {
-               if (btrfs_find_name_in_ext_backref(path, ref_objectid,
+               if (btrfs_find_name_in_ext_backref(path->nodes[0],
+                                                  path->slots[0],
+                                                  ref_objectid,
                                                   name, name_len, NULL))
                        goto out;
 
@@ -351,7 +356,8 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
        if (ret == -EEXIST) {
                u32 old_size;
 
-               if (find_name_in_backref(path, name, name_len, &ref))
+               if (btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
+                                              name, name_len, &ref))
                        goto out;
 
                old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
@@ -365,7 +371,9 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
                ret = 0;
        } else if (ret < 0) {
                if (ret == -EOVERFLOW) {
-                       if (find_name_in_backref(path, name, name_len, &ref))
+                       if (btrfs_find_name_in_backref(path->nodes[0],
+                                                      path->slots[0],
+                                                      name, name_len, &ref))
                                ret = -EEXIST;
                        else
                                ret = -EMLINK;
index 53ca025655fca690b5f92ef93eb0d11047a1a0cc..f53470112670b2de73343e635e4304fd08816468 100644 (file)
@@ -1335,8 +1335,11 @@ next_slot:
                leaf = path->nodes[0];
                if (path->slots[0] >= btrfs_header_nritems(leaf)) {
                        ret = btrfs_next_leaf(root, path);
-                       if (ret < 0)
+                       if (ret < 0) {
+                               if (cow_start != (u64)-1)
+                                       cur_offset = cow_start;
                                goto error;
+                       }
                        if (ret > 0)
                                break;
                        leaf = path->nodes[0];
@@ -2040,12 +2043,15 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
                             struct inode *inode, struct list_head *list)
 {
        struct btrfs_ordered_sum *sum;
+       int ret;
 
        list_for_each_entry(sum, list, list) {
                trans->adding_csums = true;
-               btrfs_csum_file_blocks(trans,
+               ret = btrfs_csum_file_blocks(trans,
                       BTRFS_I(inode)->root->fs_info->csum_root, sum);
                trans->adding_csums = false;
+               if (ret)
+                       return ret;
        }
        return 0;
 }
@@ -3059,7 +3065,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                goto out;
        }
 
-       add_pending_csums(trans, inode, &ordered_extent->list);
+       ret = add_pending_csums(trans, inode, &ordered_extent->list);
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto out;
+       }
 
        btrfs_ordered_update_i_size(inode, 0, ordered_extent);
        ret = btrfs_update_inode_fallback(trans, root, inode);
@@ -3385,6 +3395,11 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
                ret = btrfs_orphan_reserve_metadata(trans, inode);
                ASSERT(!ret);
                if (ret) {
+                       /*
+                        * dec doesn't need spin_lock as ->orphan_block_rsv
+                        * would be released only if ->orphan_inodes is
+                        * zero.
+                        */
                        atomic_dec(&root->orphan_inodes);
                        clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                                  &inode->runtime_flags);
@@ -3399,12 +3414,17 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
        if (insert >= 1) {
                ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode));
                if (ret) {
-                       atomic_dec(&root->orphan_inodes);
                        if (reserve) {
                                clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                                          &inode->runtime_flags);
                                btrfs_orphan_release_metadata(inode);
                        }
+                       /*
+                        * btrfs_orphan_commit_root may race with us and set
+                        * ->orphan_block_rsv to zero, in order to avoid that,
+                        * decrease ->orphan_inodes after everything is done.
+                        */
+                       atomic_dec(&root->orphan_inodes);
                        if (ret != -EEXIST) {
                                clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
                                          &inode->runtime_flags);
@@ -3436,28 +3456,26 @@ static int btrfs_orphan_del(struct btrfs_trans_handle *trans,
 {
        struct btrfs_root *root = inode->root;
        int delete_item = 0;
-       int release_rsv = 0;
        int ret = 0;
 
-       spin_lock(&root->orphan_lock);
        if (test_and_clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
                               &inode->runtime_flags))
                delete_item = 1;
 
+       if (delete_item && trans)
+               ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode));
+
        if (test_and_clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                               &inode->runtime_flags))
-               release_rsv = 1;
-       spin_unlock(&root->orphan_lock);
+               btrfs_orphan_release_metadata(inode);
 
-       if (delete_item) {
+       /*
+        * btrfs_orphan_commit_root may race with us and set ->orphan_block_rsv
+        * to zero, in order to avoid that, decrease ->orphan_inodes after
+        * everything is done.
+        */
+       if (delete_item)
                atomic_dec(&root->orphan_inodes);
-               if (trans)
-                       ret = btrfs_del_orphan_item(trans, root,
-                                                   btrfs_ino(inode));
-       }
-
-       if (release_rsv)
-               btrfs_orphan_release_metadata(inode);
 
        return ret;
 }
@@ -5281,7 +5299,7 @@ void btrfs_evict_inode(struct inode *inode)
        trace_btrfs_inode_evict(inode);
 
        if (!root) {
-               kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
+               clear_inode(inode);
                return;
        }
 
index 9e61dd624f7b5b4e8dde13c47d6e24a8eb8138d5..aa259d6986e1c24049c8f500184b2393d99b0549 100644 (file)
@@ -1442,8 +1442,13 @@ int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info,
        int ret;
 
        ret = btrfs_find_all_roots(NULL, fs_info, bytenr, 0, &old_root, false);
-       if (ret < 0)
-               return ret;
+       if (ret < 0) {
+               fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+               btrfs_warn(fs_info,
+"error accounting new delayed refs extent (err code: %d), quota inconsistent",
+                       ret);
+               return 0;
+       }
 
        /*
         * Here we don't need to get the lock of
index dec0907dfb8a128fe368a951a76f25cc34563702..fcfc20de2df395bfd70aa5541ad34689e72f8deb 100644 (file)
@@ -1370,6 +1370,7 @@ static int find_bio_stripe(struct btrfs_raid_bio *rbio,
                stripe_start = stripe->physical;
                if (physical >= stripe_start &&
                    physical < stripe_start + rbio->stripe_len &&
+                   stripe->dev->bdev &&
                    bio->bi_disk == stripe->dev->bdev->bd_disk &&
                    bio->bi_partno == stripe->dev->bdev->bd_partno) {
                        return i;
index f0c3f00e97cbe76e1fa8484efc8933842856c8d5..cd2298d185dd121bd1412e571a07952c343b0ab5 100644 (file)
@@ -3268,8 +3268,22 @@ static int relocate_file_extent_cluster(struct inode *inode,
                        nr++;
                }
 
-               btrfs_set_extent_delalloc(inode, page_start, page_end, 0, NULL,
-                                         0);
+               ret = btrfs_set_extent_delalloc(inode, page_start, page_end, 0,
+                                               NULL, 0);
+               if (ret) {
+                       unlock_page(page);
+                       put_page(page);
+                       btrfs_delalloc_release_metadata(BTRFS_I(inode),
+                                                        PAGE_SIZE);
+                       btrfs_delalloc_release_extents(BTRFS_I(inode),
+                                                      PAGE_SIZE);
+
+                       clear_extent_bits(&BTRFS_I(inode)->io_tree,
+                                         page_start, page_end,
+                                         EXTENT_LOCKED | EXTENT_BOUNDARY);
+                       goto out;
+
+               }
                set_page_dirty(page);
 
                unlock_extent(&BTRFS_I(inode)->io_tree,
index f306c608dc2880f1811905e033c1219dd5e356cc..484e2af793de2a86fa206196661d47cda078f0c2 100644 (file)
@@ -5005,6 +5005,9 @@ static int send_hole(struct send_ctx *sctx, u64 end)
        u64 len;
        int ret = 0;
 
+       if (sctx->flags & BTRFS_SEND_FLAG_NO_FILE_DATA)
+               return send_update_extent(sctx, offset, end - offset);
+
        p = fs_path_alloc();
        if (!p)
                return -ENOMEM;
index 6e71a2a783630ac15d2d910fd0613347c4a260ac..4b817947e00f39e327a244f67bbde7ebf2d6b7e0 100644 (file)
@@ -1545,7 +1545,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
         * it for searching for existing supers, so this lets us do that and
         * then open_ctree will properly initialize everything later.
         */
-       fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
+       fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
        if (!fs_info) {
                error = -ENOMEM;
                goto error_sec_opts;
index afadaadab18e45f5901600be18405d7a74e1a1f6..434457794c279463872a593adf600783f82390cf 100644 (file)
@@ -29,6 +29,7 @@
 #include "hash.h"
 #include "compression.h"
 #include "qgroup.h"
+#include "inode-map.h"
 
 /* magic values for the inode_only field in btrfs_log_inode:
  *
@@ -966,7 +967,9 @@ static noinline int backref_in_log(struct btrfs_root *log,
        ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
 
        if (key->type == BTRFS_INODE_EXTREF_KEY) {
-               if (btrfs_find_name_in_ext_backref(path, ref_objectid,
+               if (btrfs_find_name_in_ext_backref(path->nodes[0],
+                                                  path->slots[0],
+                                                  ref_objectid,
                                                   name, namelen, NULL))
                        match = 1;
 
@@ -1190,7 +1193,8 @@ static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
        read_extent_buffer(eb, *name, (unsigned long)&extref->name,
                           *namelen);
 
-       *index = btrfs_inode_extref_index(eb, extref);
+       if (index)
+               *index = btrfs_inode_extref_index(eb, extref);
        if (parent_objectid)
                *parent_objectid = btrfs_inode_extref_parent(eb, extref);
 
@@ -1211,11 +1215,101 @@ static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
 
        read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen);
 
-       *index = btrfs_inode_ref_index(eb, ref);
+       if (index)
+               *index = btrfs_inode_ref_index(eb, ref);
 
        return 0;
 }
 
+/*
+ * Take an inode reference item from the log tree and iterate all names from the
+ * inode reference item in the subvolume tree with the same key (if it exists).
+ * For any name that is not in the inode reference item from the log tree, do a
+ * proper unlink of that name (that is, remove its entry from the inode
+ * reference item and both dir index keys).
+ */
+static int unlink_old_inode_refs(struct btrfs_trans_handle *trans,
+                                struct btrfs_root *root,
+                                struct btrfs_path *path,
+                                struct btrfs_inode *inode,
+                                struct extent_buffer *log_eb,
+                                int log_slot,
+                                struct btrfs_key *key)
+{
+       int ret;
+       unsigned long ref_ptr;
+       unsigned long ref_end;
+       struct extent_buffer *eb;
+
+again:
+       btrfs_release_path(path);
+       ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
+       if (ret > 0) {
+               ret = 0;
+               goto out;
+       }
+       if (ret < 0)
+               goto out;
+
+       eb = path->nodes[0];
+       ref_ptr = btrfs_item_ptr_offset(eb, path->slots[0]);
+       ref_end = ref_ptr + btrfs_item_size_nr(eb, path->slots[0]);
+       while (ref_ptr < ref_end) {
+               char *name = NULL;
+               int namelen;
+               u64 parent_id;
+
+               if (key->type == BTRFS_INODE_EXTREF_KEY) {
+                       ret = extref_get_fields(eb, ref_ptr, &namelen, &name,
+                                               NULL, &parent_id);
+               } else {
+                       parent_id = key->offset;
+                       ret = ref_get_fields(eb, ref_ptr, &namelen, &name,
+                                            NULL);
+               }
+               if (ret)
+                       goto out;
+
+               if (key->type == BTRFS_INODE_EXTREF_KEY)
+                       ret = btrfs_find_name_in_ext_backref(log_eb, log_slot,
+                                                            parent_id, name,
+                                                            namelen, NULL);
+               else
+                       ret = btrfs_find_name_in_backref(log_eb, log_slot, name,
+                                                        namelen, NULL);
+
+               if (!ret) {
+                       struct inode *dir;
+
+                       btrfs_release_path(path);
+                       dir = read_one_inode(root, parent_id);
+                       if (!dir) {
+                               ret = -ENOENT;
+                               kfree(name);
+                               goto out;
+                       }
+                       ret = btrfs_unlink_inode(trans, root, BTRFS_I(dir),
+                                                inode, name, namelen);
+                       kfree(name);
+                       iput(dir);
+                       if (ret)
+                               goto out;
+                       goto again;
+               }
+
+               kfree(name);
+               ref_ptr += namelen;
+               if (key->type == BTRFS_INODE_EXTREF_KEY)
+                       ref_ptr += sizeof(struct btrfs_inode_extref);
+               else
+                       ref_ptr += sizeof(struct btrfs_inode_ref);
+       }
+       ret = 0;
+ out:
+       btrfs_release_path(path);
+       return ret;
+}
+
 /*
  * replay one inode back reference item found in the log tree.
  * eb, slot and key refer to the buffer and key found in the log tree.
@@ -1344,6 +1438,19 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
                }
        }
 
+       /*
+        * Before we overwrite the inode reference item in the subvolume tree
+        * with the item from the log tree, we must unlink all names from the
+        * parent directory that are in the subvolume's tree inode reference
+        * item, otherwise we end up with an inconsistent subvolume tree where
+        * dir index entries exist for a name but there is no inode reference
+        * item with the same name.
+        */
+       ret = unlink_old_inode_refs(trans, root, path, BTRFS_I(inode), eb, slot,
+                                   key);
+       if (ret)
+               goto out;
+
        /* finally write the back reference in the inode */
        ret = overwrite_item(trans, root, path, eb, slot, key);
 out:
@@ -2472,6 +2579,9 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
                                        clean_tree_block(fs_info, next);
                                        btrfs_wait_tree_block_writeback(next);
                                        btrfs_tree_unlock(next);
+                               } else {
+                                       if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
+                                               clear_extent_buffer_dirty(next);
                                }
 
                                WARN_ON(root_owner !=
@@ -2552,6 +2662,9 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
                                        clean_tree_block(fs_info, next);
                                        btrfs_wait_tree_block_writeback(next);
                                        btrfs_tree_unlock(next);
+                               } else {
+                                       if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
+                                               clear_extent_buffer_dirty(next);
                                }
 
                                WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
@@ -2630,6 +2743,9 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
                                clean_tree_block(fs_info, next);
                                btrfs_wait_tree_block_writeback(next);
                                btrfs_tree_unlock(next);
+                       } else {
+                               if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
+                                       clear_extent_buffer_dirty(next);
                        }
 
                        WARN_ON(log->root_key.objectid !=
@@ -3018,13 +3134,14 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
 
        while (1) {
                ret = find_first_extent_bit(&log->dirty_log_pages,
-                               0, &start, &end, EXTENT_DIRTY | EXTENT_NEW,
+                               0, &start, &end,
+                               EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT,
                                NULL);
                if (ret)
                        break;
 
                clear_extent_bits(&log->dirty_log_pages, start, end,
-                                 EXTENT_DIRTY | EXTENT_NEW);
+                                 EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
        }
 
        /*
@@ -5677,6 +5794,23 @@ again:
                                                      path);
                }
 
+               if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
+                       struct btrfs_root *root = wc.replay_dest;
+
+                       btrfs_release_path(path);
+
+                       /*
+                        * We have just replayed everything, and the highest
+                        * objectid of fs roots probably has changed in case
+                        * some inode_item's got replayed.
+                        *
+                        * root->objectid_mutex is not acquired as log replay
+                        * could only happen during mount.
+                        */
+                       ret = btrfs_find_highest_objectid(root,
+                                                 &root->highest_objectid);
+               }
+
                key.offset = found_key.offset - 1;
                wc.replay_dest->log_root = NULL;
                free_extent_buffer(log->node);
@@ -5825,7 +5959,7 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
         * this will force the logging code to walk the dentry chain
         * up for the file
         */
-       if (S_ISREG(inode->vfs_inode.i_mode))
+       if (!S_ISDIR(inode->vfs_inode.i_mode))
                inode->last_unlink_trans = trans->transid;
 
        /*
index b5036bd69e6a6432bf014b5fb8fb9e0c5baf495e..b2d05c6b1c5672a638ba8752333c10508e366885 100644 (file)
@@ -645,6 +645,7 @@ static void btrfs_free_stale_devices(const char *path,
                                btrfs_sysfs_remove_fsid(fs_devs);
                                list_del(&fs_devs->list);
                                free_fs_devices(fs_devs);
+                               break;
                        } else {
                                fs_devs->num_devices--;
                                list_del(&dev->dev_list);
@@ -4828,10 +4829,13 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
        ndevs = min(ndevs, devs_max);
 
        /*
-        * the primary goal is to maximize the number of stripes, so use as many
-        * devices as possible, even if the stripes are not maximum sized.
+        * The primary goal is to maximize the number of stripes, so use as
+        * many devices as possible, even if the stripes are not maximum sized.
+        *
+        * The DUP profile stores more than one stripe per device, the
+        * max_avail is the total size so we have to adjust.
         */
-       stripe_size = devices_info[ndevs-1].max_avail;
+       stripe_size = div_u64(devices_info[ndevs - 1].max_avail, dev_stripes);
        num_stripes = ndevs * dev_stripes;
 
        /*
@@ -4866,8 +4870,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                        stripe_size = devices_info[ndevs-1].max_avail;
        }
 
-       stripe_size = div_u64(stripe_size, dev_stripes);
-
        /* align to BTRFS_STRIPE_LEN */
        stripe_size = round_down(stripe_size, BTRFS_STRIPE_LEN);
 
index 6582c4507e6c9d1fdf2876c13c424f0c5830495c..0e5bd3e3344e7983e6bdf38dba1adfba17500eba 100644 (file)
@@ -3964,6 +3964,32 @@ void ceph_put_fmode(struct ceph_inode_info *ci, int fmode)
                ceph_check_caps(ci, 0, NULL);
 }
 
+/*
+ * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it
+ * looks like the link count will hit 0, drop any other caps (other
+ * than PIN) we don't specifically want (due to the file still being
+ * open).
+ */
+int ceph_drop_caps_for_unlink(struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
+
+       spin_lock(&ci->i_ceph_lock);
+       if (inode->i_nlink == 1) {
+               drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
+
+               ci->i_ceph_flags |= CEPH_I_NODELAY;
+               if (__ceph_caps_dirty(ci)) {
+                       struct ceph_mds_client *mdsc =
+                               ceph_inode_to_client(inode)->mdsc;
+                       __cap_delay_requeue_front(mdsc, ci);
+               }
+       }
+       spin_unlock(&ci->i_ceph_lock);
+       return drop;
+}
+
 /*
  * Helpers for embedding cap and dentry lease releases into mds
  * requests.
index 0c4346806e17a6f9a70e35fdafab13440c426d65..f1d9c6cc0491d7f9f33e4073db9785afac669cc8 100644 (file)
@@ -1002,26 +1002,6 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
        return err;
 }
 
-/*
- * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps.  If it
- * looks like the link count will hit 0, drop any other caps (other
- * than PIN) we don't specifically want (due to the file still being
- * open).
- */
-static int drop_caps_for_unlink(struct inode *inode)
-{
-       struct ceph_inode_info *ci = ceph_inode(inode);
-       int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
-
-       spin_lock(&ci->i_ceph_lock);
-       if (inode->i_nlink == 1) {
-               drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN);
-               ci->i_ceph_flags |= CEPH_I_NODELAY;
-       }
-       spin_unlock(&ci->i_ceph_lock);
-       return drop;
-}
-
 /*
  * rmdir and unlink are differ only by the metadata op code
  */
@@ -1056,7 +1036,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
        set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
        req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
-       req->r_inode_drop = drop_caps_for_unlink(inode);
+       req->r_inode_drop = ceph_drop_caps_for_unlink(inode);
        err = ceph_mdsc_do_request(mdsc, dir, req);
        if (!err && !req->r_reply_info.head->is_dentry)
                d_delete(dentry);
@@ -1104,8 +1084,10 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
        req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
        /* release LINK_RDCACHE on source inode (mds will lock it) */
        req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
-       if (d_really_is_positive(new_dentry))
-               req->r_inode_drop = drop_caps_for_unlink(d_inode(new_dentry));
+       if (d_really_is_positive(new_dentry)) {
+               req->r_inode_drop =
+                       ceph_drop_caps_for_unlink(d_inode(new_dentry));
+       }
        err = ceph_mdsc_do_request(mdsc, old_dir, req);
        if (!err && !req->r_reply_info.head->is_dentry) {
                /*
index a62d2a9841dc2b0487181155373c03eac60f8a02..fb2bc9c15a2378ceb5712269ab93e677c360f5d0 100644 (file)
@@ -225,6 +225,7 @@ static int parse_fsopt_token(char *c, void *private)
                        return -ENOMEM;
                break;
        case Opt_mds_namespace:
+               kfree(fsopt->mds_namespace);
                fsopt->mds_namespace = kstrndup(argstr[0].from,
                                                argstr[0].to-argstr[0].from,
                                                GFP_KERNEL);
@@ -232,6 +233,7 @@ static int parse_fsopt_token(char *c, void *private)
                        return -ENOMEM;
                break;
        case Opt_fscache_uniq:
+               kfree(fsopt->fscache_uniq);
                fsopt->fscache_uniq = kstrndup(argstr[0].from,
                                               argstr[0].to-argstr[0].from,
                                               GFP_KERNEL);
@@ -711,14 +713,17 @@ static int __init init_caches(void)
                goto bad_dentry;
 
        ceph_file_cachep = KMEM_CACHE(ceph_file_info, SLAB_MEM_SPREAD);
-
        if (!ceph_file_cachep)
                goto bad_file;
 
-       if ((error = ceph_fscache_register()))
-               goto bad_file;
+       error = ceph_fscache_register();
+       if (error)
+               goto bad_fscache;
 
        return 0;
+
+bad_fscache:
+       kmem_cache_destroy(ceph_file_cachep);
 bad_file:
        kmem_cache_destroy(ceph_dentry_cachep);
 bad_dentry:
@@ -836,7 +841,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
        int err;
        unsigned long started = jiffies;  /* note the start time */
        struct dentry *root;
-       int first = 0;   /* first vfsmount for this super_block */
 
        dout("mount start %p\n", fsc);
        mutex_lock(&fsc->client->mount_mutex);
@@ -861,17 +865,17 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
                        path = fsc->mount_options->server_path + 1;
                        dout("mount opening path %s\n", path);
                }
+
+               err = ceph_fs_debugfs_init(fsc);
+               if (err < 0)
+                       goto out;
+
                root = open_root_dentry(fsc, path, started);
                if (IS_ERR(root)) {
                        err = PTR_ERR(root);
                        goto out;
                }
                fsc->sb->s_root = dget(root);
-               first = 1;
-
-               err = ceph_fs_debugfs_init(fsc);
-               if (err < 0)
-                       goto fail;
        } else {
                root = dget(fsc->sb->s_root);
        }
@@ -881,11 +885,6 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc)
        mutex_unlock(&fsc->client->mount_mutex);
        return root;
 
-fail:
-       if (first) {
-               dput(fsc->sb->s_root);
-               fsc->sb->s_root = NULL;
-       }
 out:
        mutex_unlock(&fsc->client->mount_mutex);
        return ERR_PTR(err);
index 21b2e5b004eb72ba10057df37c6907766aed5993..1c2086e0fec27a60577c7a676b00fac67fb11102 100644 (file)
@@ -987,7 +987,7 @@ extern void ceph_check_caps(struct ceph_inode_info *ci, int flags,
                            struct ceph_mds_session *session);
 extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc);
 extern void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc);
-
+extern int  ceph_drop_caps_for_unlink(struct inode *inode);
 extern int ceph_encode_inode_release(void **p, struct inode *inode,
                                     int mds, int drop, int unless, int force);
 extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
index 7c38f39958bc371d0324197968a732d68da927d8..8945e6cabd93f7ce42709f93b90db94dceb74273 100644 (file)
@@ -647,11 +647,16 @@ again:
                spin_unlock(&parent->d_lock);
                goto again;
        }
-       rcu_read_unlock();
-       if (parent != dentry)
+       if (parent != dentry) {
                spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
-       else
+               if (unlikely(dentry->d_lockref.count < 0)) {
+                       spin_unlock(&parent->d_lock);
+                       parent = NULL;
+               }
+       } else {
                parent = NULL;
+       }
+       rcu_read_unlock();
        return parent;
 }
 
@@ -2474,7 +2479,7 @@ struct dentry *d_alloc_parallel(struct dentry *parent,
 
 retry:
        rcu_read_lock();
-       seq = smp_load_acquire(&parent->d_inode->i_dir_seq) & ~1;
+       seq = smp_load_acquire(&parent->d_inode->i_dir_seq);
        r_seq = read_seqbegin(&rename_lock);
        dentry = __d_lookup_rcu(parent, name, &d_seq);
        if (unlikely(dentry)) {
@@ -2495,8 +2500,14 @@ retry:
                rcu_read_unlock();
                goto retry;
        }
+
+       if (unlikely(seq & 1)) {
+               rcu_read_unlock();
+               goto retry;
+       }
+
        hlist_bl_lock(b);
-       if (unlikely(parent->d_inode->i_dir_seq != seq)) {
+       if (unlikely(READ_ONCE(parent->d_inode->i_dir_seq) != seq)) {
                hlist_bl_unlock(b);
                rcu_read_unlock();
                goto retry;
index a0ca9e48e9937da671739e24d6d7dc2a4867d7ac..1357ef563893a1a8f0d2967eeb4b6e7b0ee6444a 100644 (file)
@@ -1274,8 +1274,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
         */
        if (dio->is_async && iov_iter_rw(iter) == WRITE) {
                retval = 0;
-               if ((iocb->ki_filp->f_flags & O_DSYNC) ||
-                   IS_SYNC(iocb->ki_filp->f_mapping->host))
+               if (iocb->ki_flags & IOCB_DSYNC)
                        retval = dio_set_defer_completion(dio);
                else if (!dio->inode->i_sb->s_dio_done_wq) {
                        /*
index 5f22e74bbadea0822e3f6f5378b732ab3c1e333d..8e568428c88be059299b5ada7eb48e7d289a04fe 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/efi.h>
+#include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/mount.h>
@@ -74,6 +75,11 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
        ssize_t size = 0;
        int err;
 
+       while (!__ratelimit(&file->f_cred->user->ratelimit)) {
+               if (!msleep_interruptible(50))
+                       return -EINTR;
+       }
+
        err = efivar_entry_size(var, &datasize);
 
        /*
index 86863792f36ae1cc60fea8221195824926712e13..51f940e76c5e329b5d3e43b07a84485e0f512c6c 100644 (file)
@@ -716,7 +716,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
        __be64 *ptr;
        sector_t lblock;
        sector_t lend;
-       int ret;
+       int ret = 0;
        int eob;
        unsigned int len;
        struct buffer_head *bh;
@@ -728,12 +728,14 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
                goto out;
        }
 
-       if ((flags & IOMAP_REPORT) && gfs2_is_stuffed(ip)) {
-               gfs2_stuffed_iomap(inode, iomap);
-               if (pos >= iomap->length)
-                       return -ENOENT;
-               ret = 0;
-               goto out;
+       if (gfs2_is_stuffed(ip)) {
+               if (flags & IOMAP_REPORT) {
+                       gfs2_stuffed_iomap(inode, iomap);
+                       if (pos >= iomap->length)
+                               ret = -ENOENT;
+                       goto out;
+               }
+               BUG_ON(!(flags & IOMAP_WRITE));
        }
 
        lblock = pos >> inode->i_blkbits;
@@ -744,7 +746,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
        iomap->type = IOMAP_HOLE;
        iomap->length = (u64)(lend - lblock) << inode->i_blkbits;
        iomap->flags = IOMAP_F_MERGED;
-       bmap_lock(ip, 0);
+       bmap_lock(ip, flags & IOMAP_WRITE);
 
        /*
         * Directory data blocks have a struct gfs2_meta_header header, so the
@@ -787,27 +789,25 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
                iomap->flags |= IOMAP_F_BOUNDARY;
        iomap->length = (u64)len << inode->i_blkbits;
 
-       ret = 0;
-
 out_release:
        release_metapath(&mp);
-       bmap_unlock(ip, 0);
+       bmap_unlock(ip, flags & IOMAP_WRITE);
 out:
        trace_gfs2_iomap_end(ip, iomap, ret);
        return ret;
 
 do_alloc:
-       if (!(flags & IOMAP_WRITE)) {
-               if (pos >= i_size_read(inode)) {
+       if (flags & IOMAP_WRITE) {
+               ret = gfs2_iomap_alloc(inode, iomap, flags, &mp);
+       } else if (flags & IOMAP_REPORT) {
+               loff_t size = i_size_read(inode);
+               if (pos >= size)
                        ret = -ENOENT;
-                       goto out_release;
-               }
-               ret = 0;
-               iomap->length = hole_size(inode, lblock, &mp);
-               goto out_release;
+               else if (height <= ip->i_height)
+                       iomap->length = hole_size(inode, lblock, &mp);
+               else
+                       iomap->length = size - pos;
        }
-
-       ret = gfs2_iomap_alloc(inode, iomap, flags, &mp);
        goto out_release;
 }
 
index 8fe1b0aa2896bc547955b8760bffea0ec326d7e8..b9a254dcc0e77e72873b9b49cf49787bd2154678 100644 (file)
@@ -108,6 +108,16 @@ static void huge_pagevec_release(struct pagevec *pvec)
        pagevec_reinit(pvec);
 }
 
+/*
+ * Mask used when checking the page offset value passed in via system
+ * calls.  This value will be converted to a loff_t which is signed.
+ * Therefore, we want to check the upper PAGE_SHIFT + 1 bits of the
+ * value.  The extra bit (- 1 in the shift value) is to take the sign
+ * bit into account.
+ */
+#define PGOFF_LOFFT_MAX \
+       (((1UL << (PAGE_SHIFT + 1)) - 1) <<  (BITS_PER_LONG - (PAGE_SHIFT + 1)))
+
 static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
        struct inode *inode = file_inode(file);
@@ -127,12 +137,13 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &hugetlb_vm_ops;
 
        /*
-        * Offset passed to mmap (before page shift) could have been
-        * negative when represented as a (l)off_t.
+        * page based offset in vm_pgoff could be sufficiently large to
+        * overflow a (l)off_t when converted to byte offset.
         */
-       if (((loff_t)vma->vm_pgoff << PAGE_SHIFT) < 0)
+       if (vma->vm_pgoff & PGOFF_LOFFT_MAX)
                return -EINVAL;
 
+       /* must be huge page aligned */
        if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
                return -EINVAL;
 
index 921ae32dbc8053813e70b2a6454bf7dc4f85306a..cafa365eeb70a55215806875685bd9ff047884cd 100644 (file)
@@ -559,9 +559,10 @@ static int __nd_alloc_stack(struct nameidata *nd)
 static bool path_connected(const struct path *path)
 {
        struct vfsmount *mnt = path->mnt;
+       struct super_block *sb = mnt->mnt_sb;
 
-       /* Only bind mounts can have disconnected paths */
-       if (mnt->mnt_root == mnt->mnt_sb->s_root)
+       /* Bind mounts and multi-root filesystems can have disconnected paths */
+       if (!(sb->s_iflags & SB_I_MULTIROOT) && (mnt->mnt_root == sb->s_root))
                return true;
 
        return is_subdir(path->dentry, mnt->mnt_root);
index 2435af56b87e4472a725f7ef1c6e3b252dd82ae9..a50d7813e3ea8dd03dd7c5e02b36574be815ad8b 100644 (file)
@@ -572,7 +572,7 @@ out:
 }
 
 static bool
-validate_bitmap_values(unsigned long mask)
+validate_bitmap_values(unsigned int mask)
 {
        return (mask & ~RCA4_TYPE_MASK_ALL) == 0;
 }
@@ -596,17 +596,15 @@ __be32 nfs4_callback_recallany(void *argp, void *resp,
                goto out;
 
        status = cpu_to_be32(NFS4_OK);
-       if (test_bit(RCA4_TYPE_MASK_RDATA_DLG, (const unsigned long *)
-                    &args->craa_type_mask))
+       if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_RDATA_DLG))
                flags = FMODE_READ;
-       if (test_bit(RCA4_TYPE_MASK_WDATA_DLG, (const unsigned long *)
-                    &args->craa_type_mask))
+       if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_WDATA_DLG))
                flags |= FMODE_WRITE;
-       if (test_bit(RCA4_TYPE_MASK_FILE_LAYOUT, (const unsigned long *)
-                    &args->craa_type_mask))
-               pnfs_recall_all_layouts(cps->clp);
        if (flags)
                nfs_expire_unused_delegation_types(cps->clp, flags);
+
+       if (args->craa_type_mask & BIT(RCA4_TYPE_MASK_FILE_LAYOUT))
+               pnfs_recall_all_layouts(cps->clp);
 out:
        dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
        return status;
index 8c10b0562e75d2fb0b3c92fe0628d3a79fede48b..621c517b325c664a81a609483ab7b9830f12e25a 100644 (file)
@@ -86,10 +86,10 @@ struct nfs_direct_req {
        struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX];
        int                     mirror_count;
 
+       loff_t                  io_start;       /* Start offset for I/O */
        ssize_t                 count,          /* bytes actually processed */
                                max_count,      /* max expected count */
                                bytes_left,     /* bytes left to be sent */
-                               io_start,       /* start of IO */
                                error;          /* any reported error */
        struct completion       completion;     /* wait for i/o completion */
 
index 49f848fd1f04779108d86a5eee618e21d11304e6..7327930ad970ab98338e8f21a4fb363559205522 100644 (file)
@@ -873,7 +873,7 @@ static void nfs3_nlm_release_call(void *data)
        }
 }
 
-const struct nlmclnt_operations nlmclnt_fl_close_lock_ops = {
+static const struct nlmclnt_operations nlmclnt_fl_close_lock_ops = {
        .nlmclnt_alloc_call = nfs3_nlm_alloc_call,
        .nlmclnt_unlock_prepare = nfs3_nlm_unlock_prepare,
        .nlmclnt_release_call = nfs3_nlm_release_call,
index 04612c24d39431b15ff58027a7ebfe7b5450d774..979631411a0e4ea5a7eedc3c668d36a57c20ced6 100644 (file)
@@ -868,8 +868,10 @@ static int nfs4_set_client(struct nfs_server *server,
        if (IS_ERR(clp))
                return PTR_ERR(clp);
 
-       if (server->nfs_client == clp)
+       if (server->nfs_client == clp) {
+               nfs_put_client(clp);
                return -ELOOP;
+       }
 
        /*
         * Query for the lease time on clientid setup or renewal
@@ -1244,11 +1246,11 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
                                clp->cl_proto, clnt->cl_timeout,
                                clp->cl_minorversion, net);
        clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
-       nfs_put_client(clp);
        if (error != 0) {
                nfs_server_insert_lists(server);
                return error;
        }
+       nfs_put_client(clp);
 
        if (server->nfs_client->cl_hostname == NULL)
                server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
index c13e826614b5798ccd7628398944c140ae07f983..ee723aa153a3300633bc434f52156f3cf443f3dd 100644 (file)
@@ -292,8 +292,11 @@ pnfs_detach_layout_hdr(struct pnfs_layout_hdr *lo)
 void
 pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
 {
-       struct inode *inode = lo->plh_inode;
+       struct inode *inode;
 
+       if (!lo)
+               return;
+       inode = lo->plh_inode;
        pnfs_layoutreturn_before_put_layout_hdr(lo);
 
        if (refcount_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) {
@@ -1241,10 +1244,12 @@ retry:
        spin_lock(&ino->i_lock);
        lo = nfsi->layout;
        if (!lo || !pnfs_layout_is_valid(lo) ||
-           test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags))
+           test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags)) {
+               lo = NULL;
                goto out_noroc;
+       }
+       pnfs_get_layout_hdr(lo);
        if (test_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) {
-               pnfs_get_layout_hdr(lo);
                spin_unlock(&ino->i_lock);
                wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN,
                                TASK_UNINTERRUPTIBLE);
@@ -1312,10 +1317,12 @@ out_noroc:
                struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
                if (ld->prepare_layoutreturn)
                        ld->prepare_layoutreturn(args);
+               pnfs_put_layout_hdr(lo);
                return true;
        }
        if (layoutreturn)
                pnfs_send_layoutreturn(lo, &stateid, iomode, true);
+       pnfs_put_layout_hdr(lo);
        return false;
 }
 
index 29bacdc56f6a9fcf83225844360088e180d32ad7..5e470e233c83d242856322bb27c86e50d206cfe8 100644 (file)
@@ -2631,6 +2631,8 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
                /* initial superblock/root creation */
                mount_info->fill_super(s, mount_info);
                nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned);
+               if (!(server->flags & NFS_MOUNT_UNSHARED))
+                       s->s_iflags |= SB_I_MULTIROOT;
        }
 
        mntroot = nfs_get_root(s, mount_info->mntfh, dev_name);
index 7428a669d7a77b5fd82a7b8da348308ac058d155..e7d8ceae8f26b4ad5f6b9c68df14f13d858ab308 100644 (file)
@@ -1876,40 +1876,43 @@ int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
        return status;
 }
 
-int nfs_commit_inode(struct inode *inode, int how)
+static int __nfs_commit_inode(struct inode *inode, int how,
+               struct writeback_control *wbc)
 {
        LIST_HEAD(head);
        struct nfs_commit_info cinfo;
        int may_wait = how & FLUSH_SYNC;
-       int error = 0;
-       int res;
+       int ret, nscan;
 
        nfs_init_cinfo_from_inode(&cinfo, inode);
        nfs_commit_begin(cinfo.mds);
-       res = nfs_scan_commit(inode, &head, &cinfo);
-       if (res)
-               error = nfs_generic_commit_list(inode, &head, how, &cinfo);
+       for (;;) {
+               ret = nscan = nfs_scan_commit(inode, &head, &cinfo);
+               if (ret <= 0)
+                       break;
+               ret = nfs_generic_commit_list(inode, &head, how, &cinfo);
+               if (ret < 0)
+                       break;
+               ret = 0;
+               if (wbc && wbc->sync_mode == WB_SYNC_NONE) {
+                       if (nscan < wbc->nr_to_write)
+                               wbc->nr_to_write -= nscan;
+                       else
+                               wbc->nr_to_write = 0;
+               }
+               if (nscan < INT_MAX)
+                       break;
+               cond_resched();
+       }
        nfs_commit_end(cinfo.mds);
-       if (res == 0)
-               return res;
-       if (error < 0)
-               goto out_error;
-       if (!may_wait)
-               goto out_mark_dirty;
-       error = wait_on_commit(cinfo.mds);
-       if (error < 0)
-               return error;
-       return res;
-out_error:
-       res = error;
-       /* Note: If we exit without ensuring that the commit is complete,
-        * we must mark the inode as dirty. Otherwise, future calls to
-        * sync_inode() with the WB_SYNC_ALL flag set will fail to ensure
-        * that the data is on the disk.
-        */
-out_mark_dirty:
-       __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
-       return res;
+       if (ret || !may_wait)
+               return ret;
+       return wait_on_commit(cinfo.mds);
+}
+
+int nfs_commit_inode(struct inode *inode, int how)
+{
+       return __nfs_commit_inode(inode, how, NULL);
 }
 EXPORT_SYMBOL_GPL(nfs_commit_inode);
 
@@ -1919,11 +1922,11 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
        int flags = FLUSH_SYNC;
        int ret = 0;
 
-       /* no commits means nothing needs to be done */
-       if (!atomic_long_read(&nfsi->commit_info.ncommit))
-               return ret;
-
        if (wbc->sync_mode == WB_SYNC_NONE) {
+               /* no commits means nothing needs to be done */
+               if (!atomic_long_read(&nfsi->commit_info.ncommit))
+                       goto check_requests_outstanding;
+
                /* Don't commit yet if this is a non-blocking flush and there
                 * are a lot of outstanding writes for this mapping.
                 */
@@ -1934,16 +1937,16 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
                flags = 0;
        }
 
-       ret = nfs_commit_inode(inode, flags);
-       if (ret >= 0) {
-               if (wbc->sync_mode == WB_SYNC_NONE) {
-                       if (ret < wbc->nr_to_write)
-                               wbc->nr_to_write -= ret;
-                       else
-                               wbc->nr_to_write = 0;
-               }
-               return 0;
-       }
+       ret = __nfs_commit_inode(inode, flags, wbc);
+       if (!ret) {
+               if (flags & FLUSH_SYNC)
+                       return 0;
+       } else if (atomic_long_read(&nfsi->commit_info.ncommit))
+               goto out_mark_dirty;
+
+check_requests_outstanding:
+       if (!atomic_read(&nfsi->commit_info.rpcs_out))
+               return ret;
 out_mark_dirty:
        __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
        return ret;
index 150521c9671b9f5d163cb18b7b6135709c112738..61b770e398093ae6fcc13150c8ec6736df2bee21 100644 (file)
@@ -268,6 +268,35 @@ free_blocked_lock(struct nfsd4_blocked_lock *nbl)
        kfree(nbl);
 }
 
+static void
+remove_blocked_locks(struct nfs4_lockowner *lo)
+{
+       struct nfs4_client *clp = lo->lo_owner.so_client;
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+       struct nfsd4_blocked_lock *nbl;
+       LIST_HEAD(reaplist);
+
+       /* Dequeue all blocked locks */
+       spin_lock(&nn->blocked_locks_lock);
+       while (!list_empty(&lo->lo_blocked)) {
+               nbl = list_first_entry(&lo->lo_blocked,
+                                       struct nfsd4_blocked_lock,
+                                       nbl_list);
+               list_del_init(&nbl->nbl_list);
+               list_move(&nbl->nbl_lru, &reaplist);
+       }
+       spin_unlock(&nn->blocked_locks_lock);
+
+       /* Now free them */
+       while (!list_empty(&reaplist)) {
+               nbl = list_first_entry(&reaplist, struct nfsd4_blocked_lock,
+                                       nbl_lru);
+               list_del_init(&nbl->nbl_lru);
+               posix_unblock_lock(&nbl->nbl_lock);
+               free_blocked_lock(nbl);
+       }
+}
+
 static int
 nfsd4_cb_notify_lock_done(struct nfsd4_callback *cb, struct rpc_task *task)
 {
@@ -1866,6 +1895,7 @@ static __be32 mark_client_expired_locked(struct nfs4_client *clp)
 static void
 __destroy_client(struct nfs4_client *clp)
 {
+       int i;
        struct nfs4_openowner *oo;
        struct nfs4_delegation *dp;
        struct list_head reaplist;
@@ -1895,6 +1925,16 @@ __destroy_client(struct nfs4_client *clp)
                nfs4_get_stateowner(&oo->oo_owner);
                release_openowner(oo);
        }
+       for (i = 0; i < OWNER_HASH_SIZE; i++) {
+               struct nfs4_stateowner *so, *tmp;
+
+               list_for_each_entry_safe(so, tmp, &clp->cl_ownerstr_hashtbl[i],
+                                        so_strhash) {
+                       /* Should be no openowners at this point */
+                       WARN_ON_ONCE(so->so_is_open_owner);
+                       remove_blocked_locks(lockowner(so));
+               }
+       }
        nfsd4_return_all_client_layouts(clp);
        nfsd4_shutdown_callback(clp);
        if (clp->cl_cb_conn.cb_xprt)
@@ -6355,6 +6395,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
        }
        spin_unlock(&clp->cl_lock);
        free_ol_stateid_reaplist(&reaplist);
+       remove_blocked_locks(lo);
        nfs4_put_stateowner(&lo->lo_owner);
 
        return status;
@@ -7140,6 +7181,8 @@ nfs4_state_destroy_net(struct net *net)
                }
        }
 
+       WARN_ON(!list_empty(&nn->blocked_locks_lru));
+
        for (i = 0; i < CLIENT_HASH_SIZE; i++) {
                while (!list_empty(&nn->unconf_id_hashtbl[i])) {
                        clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
@@ -7206,7 +7249,6 @@ nfs4_state_shutdown_net(struct net *net)
        struct nfs4_delegation *dp = NULL;
        struct list_head *pos, *next, reaplist;
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-       struct nfsd4_blocked_lock *nbl;
 
        cancel_delayed_work_sync(&nn->laundromat_work);
        locks_end_grace(&nn->nfsd4_manager);
@@ -7227,24 +7269,6 @@ nfs4_state_shutdown_net(struct net *net)
                nfs4_put_stid(&dp->dl_stid);
        }
 
-       BUG_ON(!list_empty(&reaplist));
-       spin_lock(&nn->blocked_locks_lock);
-       while (!list_empty(&nn->blocked_locks_lru)) {
-               nbl = list_first_entry(&nn->blocked_locks_lru,
-                                       struct nfsd4_blocked_lock, nbl_lru);
-               list_move(&nbl->nbl_lru, &reaplist);
-               list_del_init(&nbl->nbl_list);
-       }
-       spin_unlock(&nn->blocked_locks_lock);
-
-       while (!list_empty(&reaplist)) {
-               nbl = list_first_entry(&reaplist,
-                                       struct nfsd4_blocked_lock, nbl_lru);
-               list_del_init(&nbl->nbl_lru);
-               posix_unblock_lock(&nbl->nbl_lock);
-               free_blocked_lock(nbl);
-       }
-
        nfsd4_client_tracking_exit(net);
        nfs4_state_destroy_net(net);
 }
index 406e72de88f6f893a4e81189e6b8e1a9751573ae..ce6ff5a0a6e4e8b75d4f588981d9c710432bb52b 100644 (file)
@@ -24,6 +24,8 @@ config OVERLAY_FS_REDIRECT_DIR
          an overlay which has redirects on a kernel that doesn't support this
          feature will have unexpected results.
 
+         If unsure, say N.
+
 config OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
        bool "Overlayfs: follow redirects even if redirects are turned off"
        default y
@@ -32,8 +34,13 @@ config OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
          Disable this to get a possibly more secure configuration, but that
          might not be backward compatible with previous kernels.
 
+         If backward compatibility is not an issue, then it is safe and
+         recommended to say N here.
+
          For more information, see Documentation/filesystems/overlayfs.txt
 
+         If unsure, say Y.
+
 config OVERLAY_FS_INDEX
        bool "Overlayfs: turn on inodes index feature by default"
        depends on OVERLAY_FS
@@ -51,6 +58,8 @@ config OVERLAY_FS_INDEX
          That is, mounting an overlay which has an inodes index on a kernel
          that doesn't support this feature will have unexpected results.
 
+         If unsure, say N.
+
 config OVERLAY_FS_NFS_EXPORT
        bool "Overlayfs: turn on NFS export feature by default"
        depends on OVERLAY_FS
@@ -72,3 +81,8 @@ config OVERLAY_FS_NFS_EXPORT
          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.
+
+         Most users should say N here and enable this feature on a case-by-
+         case basis with the "nfs_export=on" mount option.
+
+         Say N unless you fully understand the consequences.
index bb94ce9da5c8723b9f35a9195f5e8926c9e83b91..87bd4148f4fb5811547fa2b44a7965af7f22e52a 100644 (file)
 #include <linux/ratelimit.h>
 #include "overlayfs.h"
 
+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) {
+               err = ovl_copy_up(dentry);
+               ovl_drop_write(dentry);
+       }
+
+       if (err) {
+               pr_warn_ratelimited("overlayfs: failed to copy up on encode (%pd2, err=%i)\n",
+                                   dentry, err);
+       }
+
+       return err;
+}
+
+/*
+ * Before encoding a non-upper directory file handle from real layer N, we need
+ * to check if it will be possible to reconnect an overlay dentry from the real
+ * lower decoded dentry. This is done by following the overlay ancestry up to a
+ * "layer N connected" ancestor and verifying that all parents along the way are
+ * "layer N connectable". If an ancestor that is NOT "layer N connectable" is
+ * found, we need to copy up an ancestor, which is "layer N connectable", thus
+ * making that ancestor "layer N connected". For example:
+ *
+ * layer 1: /a
+ * layer 2: /a/b/c
+ *
+ * The overlay dentry /a is NOT "layer 2 connectable", because if dir /a is
+ * copied up and renamed, upper dir /a will be indexed by lower dir /a from
+ * layer 1. The dir /a from layer 2 will never be indexed, so the algorithm (*)
+ * in ovl_lookup_real_ancestor() will not be able to lookup a connected overlay
+ * dentry from the connected lower dentry /a/b/c.
+ *
+ * To avoid this problem on decode time, we need to copy up an ancestor of
+ * /a/b/c, which is "layer 2 connectable", on encode time. That ancestor is
+ * /a/b. After copy up (and index) of /a/b, it will become "layer 2 connected"
+ * and when the time comes to decode the file handle from lower dentry /a/b/c,
+ * ovl_lookup_real_ancestor() will find the indexed ancestor /a/b and decoding
+ * a connected overlay dentry will be accomplished.
+ *
+ * (*) the algorithm in ovl_lookup_real_ancestor() can be improved to lookup an
+ * entry /a in the lower layers above layer N and find the indexed dir /a from
+ * layer 1. If that improvement is made, then the check for "layer N connected"
+ * will need to verify there are no redirects in lower layers above N. In the
+ * example above, /a will be "layer 2 connectable". However, if layer 2 dir /a
+ * is a target of a layer 1 redirect, then /a will NOT be "layer 2 connectable":
+ *
+ * layer 1: /A (redirect = /a)
+ * layer 2: /a/b/c
+ */
+
+/* Return the lowest layer for encoding a connectable file handle */
+static int ovl_connectable_layer(struct dentry *dentry)
+{
+       struct ovl_entry *oe = OVL_E(dentry);
+
+       /* We can get overlay root from root of any layer */
+       if (dentry == dentry->d_sb->s_root)
+               return oe->numlower;
+
+       /*
+        * If it's an unindexed merge dir, then it's not connectable with any
+        * lower layer
+        */
+       if (ovl_dentry_upper(dentry) &&
+           !ovl_test_flag(OVL_INDEX, d_inode(dentry)))
+               return 0;
+
+       /* We can get upper/overlay path from indexed/lower dentry */
+       return oe->lowerstack[0].layer->idx;
+}
+
+/*
+ * @dentry is "connected" if all ancestors up to root or a "connected" ancestor
+ * have the same uppermost lower layer as the origin's layer. We may need to
+ * copy up a "connectable" ancestor to make it "connected". A "connected" dentry
+ * cannot become non "connected", so cache positive result in dentry flags.
+ *
+ * Return the connected origin layer or < 0 on error.
+ */
+static int ovl_connect_layer(struct dentry *dentry)
+{
+       struct dentry *next, *parent = NULL;
+       int origin_layer;
+       int err = 0;
+
+       if (WARN_ON(dentry == dentry->d_sb->s_root) ||
+           WARN_ON(!ovl_dentry_lower(dentry)))
+               return -EIO;
+
+       origin_layer = OVL_E(dentry)->lowerstack[0].layer->idx;
+       if (ovl_dentry_test_flag(OVL_E_CONNECTED, dentry))
+               return origin_layer;
+
+       /* Find the topmost origin layer connectable ancestor of @dentry */
+       next = dget(dentry);
+       for (;;) {
+               parent = dget_parent(next);
+               if (WARN_ON(parent == next)) {
+                       err = -EIO;
+                       break;
+               }
+
+               /*
+                * If @parent is not origin layer connectable, then copy up
+                * @next which is origin layer connectable and we are done.
+                */
+               if (ovl_connectable_layer(parent) < origin_layer) {
+                       err = ovl_encode_maybe_copy_up(next);
+                       break;
+               }
+
+               /* If @parent is connected or indexed we are done */
+               if (ovl_dentry_test_flag(OVL_E_CONNECTED, parent) ||
+                   ovl_test_flag(OVL_INDEX, d_inode(parent)))
+                       break;
+
+               dput(next);
+               next = parent;
+       }
+
+       dput(parent);
+       dput(next);
+
+       if (!err)
+               ovl_dentry_set_flag(OVL_E_CONNECTED, dentry);
+
+       return err ?: origin_layer;
+}
+
 /*
  * 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
  * 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.
+ * possible when there are redirects in lower layers and non-indexed merge dirs.
+ * To mitigate those case, we may copy up the lower dir ancestor before encode
+ * a lower dir file handle.
+ *
+ * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
  */
-static bool ovl_should_encode_origin(struct dentry *dentry)
+static int ovl_check_encode_origin(struct dentry *dentry)
 {
        struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
 
+       /* Upper file handle for pure upper */
        if (!ovl_dentry_lower(dentry))
-               return false;
+               return 0;
 
        /*
-        * 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.
+        * Upper file handle for non-indexed upper.
         *
-        * TODO: copy up only the parent that is under redirected lower.
+        * Root is never indexed, so if there's an upper layer, encode upper for
+        * root.
         */
-       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);
+       /*
+        * Decoding a merge dir, whose origin's ancestor is under a redirected
+        * lower dir or under a non-indexed upper is not always possible.
+        * ovl_connect_layer() will try to make origin's layer "connected" by
+        * copying up a "connectable" ancestor.
+        */
+       if (d_is_dir(dentry) && ofs->upper_mnt)
+               return ovl_connect_layer(dentry);
 
-       ovl_drop_write(dentry);
-       return err;
+       /* Lower file handle for indexed and non-upper dir/non-dir */
+       return 1;
 }
 
 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;
+       int err, enc_lower;
 
        /*
-        * If we should not encode a lower dir file handle, copy up and encode
-        * an upper dir file handle.
+        * Check if we should encode a lower or upper file handle and maybe
+        * copy up an ancestor to make lower file handle connectable.
         */
-       if (!ovl_should_encode_origin(dentry)) {
-               err = ovl_encode_maybe_copy_up(dentry);
-               if (err)
-                       goto fail;
-
-               origin = NULL;
-       }
+       err = enc_lower = ovl_check_encode_origin(dentry);
+       if (enc_lower < 0)
+               goto fail;
 
-       /* Encode an upper or origin file handle */
-       fh = ovl_encode_fh(origin ?: ovl_dentry_upper(dentry), !origin);
+       /* Encode an upper or lower file handle */
+       fh = ovl_encode_fh(enc_lower ? ovl_dentry_lower(dentry) :
+                                      ovl_dentry_upper(dentry), !enc_lower);
        err = PTR_ERR(fh);
        if (IS_ERR(fh))
                goto fail;
@@ -355,8 +477,8 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
                dput(upper);
        }
 
-       if (!this)
-               return NULL;
+       if (IS_ERR_OR_NULL(this))
+               return this;
 
        if (WARN_ON(ovl_dentry_real_at(this, layer->idx) != real)) {
                dput(this);
@@ -498,7 +620,7 @@ static struct dentry *ovl_lookup_real(struct super_block *sb,
                        if (err == -ECHILD) {
                                this = ovl_lookup_real_ancestor(sb, real,
                                                                layer);
-                               err = IS_ERR(this) ? PTR_ERR(this) : 0;
+                               err = PTR_ERR_OR_ZERO(this);
                        }
                        if (!err) {
                                dput(connected);
index fcd97b783fa1ffa82dc7ec2eb4b82f03a0be50ef..3b1bd469accdfe767afc276def9f319f57ebde68 100644 (file)
@@ -669,38 +669,59 @@ struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
        return inode;
 }
 
+/*
+ * Does overlay inode need to be hashed by lower inode?
+ */
+static bool ovl_hash_bylower(struct super_block *sb, struct dentry *upper,
+                            struct dentry *lower, struct dentry *index)
+{
+       struct ovl_fs *ofs = sb->s_fs_info;
+
+       /* No, if pure upper */
+       if (!lower)
+               return false;
+
+       /* Yes, if already indexed */
+       if (index)
+               return true;
+
+       /* Yes, if won't be copied up */
+       if (!ofs->upper_mnt)
+               return true;
+
+       /* No, if lower hardlink is or will be broken on copy up */
+       if ((upper || !ovl_indexdir(sb)) &&
+           !d_is_dir(lower) && d_inode(lower)->i_nlink > 1)
+               return false;
+
+       /* No, if non-indexed upper with NFS export */
+       if (sb->s_export_op && upper)
+               return false;
+
+       /* Otherwise, hash by lower inode for fsnotify */
+       return true;
+}
+
 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(sb) && !upperdentry));
-       struct dentry *origin = indexed ? lowerdentry : NULL;
+       bool bylower = ovl_hash_bylower(sb, upperdentry, lowerdentry, index);
        bool is_dir;
 
-       if (WARN_ON(upperdentry && indexed && !lowerdentry))
-               return ERR_PTR(-EIO);
-
        if (!realinode)
                realinode = d_inode(lowerdentry);
 
        /*
-        * 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.
+        * Copy up origin (lower) may exist for non-indexed upper, but we must
+        * not use lower as hash key if this is a broken hardlink.
         */
        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);
+       if (upperdentry || bylower) {
+               struct inode *key = d_inode(bylower ? lowerdentry :
+                                                     upperdentry);
                unsigned int nlink = is_dir ? 1 : realinode->i_nlink;
 
                inode = iget5_locked(sb, (unsigned long) key,
@@ -728,6 +749,7 @@ struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
                        nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink);
                set_nlink(inode, nlink);
        } else {
+               /* Lower hardlink that will be broken on copy up */
                inode = new_inode(sb);
                if (!inode)
                        goto out_nomem;
index de3e6da1d5a51732f4e0ad3fbad3feb4b6664841..70fcfcc684cc0a07566aeacb7fe564f2156bc0d2 100644 (file)
@@ -913,9 +913,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                stack[ctr].layer = lower.layer;
                ctr++;
 
-               if (d.stop)
-                       break;
-
                /*
                 * Following redirects can have security consequences: it's like
                 * a symlink into the lower layer without the permission checks.
@@ -933,6 +930,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        goto out_put;
                }
 
+               if (d.stop)
+                       break;
+
                if (d.redirect && d.redirect[0] == '/' && poe != roe) {
                        poe = roe;
                        /* Find the current layer on the root dentry */
index 0df25a9c94bd777f41f83ad278586732e3104126..225ff11711474fe80d9d4151f6267aaab587f034 100644 (file)
@@ -40,6 +40,7 @@ enum ovl_inode_flag {
 enum ovl_entry_flag {
        OVL_E_UPPER_ALIAS,
        OVL_E_OPAQUE,
+       OVL_E_CONNECTED,
 };
 
 /*
index 9ee37c76091d685275dcc39945b29186900c2669..7c24619ae7fc5229a5d3af6c9298b51064498325 100644 (file)
@@ -1359,6 +1359,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
        /* Root is always merge -> can have whiteouts */
        ovl_set_flag(OVL_WHITEOUTS, d_inode(root_dentry));
+       ovl_dentry_set_flag(OVL_E_CONNECTED, root_dentry);
        ovl_inode_init(d_inode(root_dentry), upperpath.dentry,
                       ovl_dentry_lower(root_dentry));
 
index e8a93bc8285d85403db124f9acb3c80f2a122495..d1e82761de813abb95af0faac99194dba5821538 100644 (file)
@@ -510,6 +510,10 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                        /* we have to zero-fill user buffer even if no read */
                        if (copy_to_user(buffer, buf, tsz))
                                return -EFAULT;
+               } else if (m->type == KCORE_USER) {
+                       /* User page is handled prior to normal kernel page: */
+                       if (copy_to_user(buffer, (char *)start, tsz))
+                               return -EFAULT;
                } else {
                        if (kern_addr_valid(start)) {
                                /*
index 9990957264e3cc9460f287e7b1ef4f1dc94a1ea4..76bf9cc620742c1b7cd1622ff1f859fb7b606d51 100644 (file)
@@ -118,13 +118,22 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
                err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno);
 #endif
 #ifdef BUS_MCEERR_AO
-               /* 
+               /*
+                * Other callers might not initialize the si_lsb field,
+                * so check explicitly for the right codes here.
+                */
+               if (kinfo->si_signo == SIGBUS &&
+                    kinfo->si_code == BUS_MCEERR_AO)
+                       err |= __put_user((short) kinfo->si_addr_lsb,
+                                         &uinfo->ssi_addr_lsb);
+#endif
+#ifdef BUS_MCEERR_AR
+               /*
                 * Other callers might not initialize the si_lsb field,
                 * so check explicitly for the right codes here.
                 */
                if (kinfo->si_signo == SIGBUS &&
-                   (kinfo->si_code == BUS_MCEERR_AR ||
-                    kinfo->si_code == BUS_MCEERR_AO))
+                   kinfo->si_code == BUS_MCEERR_AR)
                        err |= __put_user((short) kinfo->si_addr_lsb,
                                          &uinfo->ssi_addr_lsb);
 #endif
index 8664db25a9a6f013922e889aa110927d4e3096fa..215c225b2ca17e462da85528026d07cdf8647ce2 100644 (file)
@@ -106,6 +106,7 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target,
 {
        return sysfs_do_create_link(kobj, target, name, 0);
 }
+EXPORT_SYMBOL_GPL(sysfs_create_link_nowarn);
 
 /**
  *     sysfs_delete_link - remove symlink in object's directory.
index fd975524f4603387e28078d13b175b5df2443021..05c66e05ae20f0bbe08c713de9feddf13c813982 100644 (file)
@@ -767,7 +767,7 @@ int
 xfs_scrub_agfl(
        struct xfs_scrub_context        *sc)
 {
-       struct xfs_scrub_agfl_info      sai = { 0 };
+       struct xfs_scrub_agfl_info      sai;
        struct xfs_agf                  *agf;
        xfs_agnumber_t                  agno;
        unsigned int                    agflcount;
@@ -795,6 +795,7 @@ xfs_scrub_agfl(
                xfs_scrub_block_set_corrupt(sc, sc->sa.agf_bp);
                goto out;
        }
+       memset(&sai, 0, sizeof(sai));
        sai.sz_entries = agflcount;
        sai.entries = kmem_zalloc(sizeof(xfs_agblock_t) * agflcount, KM_NOFS);
        if (!sai.entries) {
index 66e1edbfb2b2bcd7d278226a33f0531bb0043b97..046469fcc1b8a66075806080ca175277e2716dcd 100644 (file)
@@ -955,15 +955,29 @@ static inline bool imap_needs_alloc(struct inode *inode,
                (IS_DAX(inode) && imap->br_state == XFS_EXT_UNWRITTEN);
 }
 
+static inline bool needs_cow_for_zeroing(struct xfs_bmbt_irec *imap, int nimaps)
+{
+       return nimaps &&
+               imap->br_startblock != HOLESTARTBLOCK &&
+               imap->br_state != XFS_EXT_UNWRITTEN;
+}
+
 static inline bool need_excl_ilock(struct xfs_inode *ip, unsigned flags)
 {
        /*
-        * COW writes will allocate delalloc space, so we need to make sure
-        * to take the lock exclusively here.
+        * COW writes may allocate delalloc space or convert unwritten COW
+        * extents, so we need to make sure to take the lock exclusively here.
         */
        if (xfs_is_reflink_inode(ip) && (flags & (IOMAP_WRITE | IOMAP_ZERO)))
                return true;
-       if ((flags & IOMAP_DIRECT) && (flags & IOMAP_WRITE))
+
+       /*
+        * Extents not yet cached requires exclusive access, don't block.
+        * This is an opencoded xfs_ilock_data_map_shared() to cater for the
+        * non-blocking behaviour.
+        */
+       if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
+           !(ip->i_df.if_flags & XFS_IFEXTENTS))
                return true;
        return false;
 }
@@ -993,16 +1007,18 @@ xfs_file_iomap_begin(
                return xfs_file_iomap_begin_delay(inode, offset, length, iomap);
        }
 
-       if (need_excl_ilock(ip, flags)) {
+       if (need_excl_ilock(ip, flags))
                lockmode = XFS_ILOCK_EXCL;
-               xfs_ilock(ip, XFS_ILOCK_EXCL);
-       } else {
-               lockmode = xfs_ilock_data_map_shared(ip);
-       }
+       else
+               lockmode = XFS_ILOCK_SHARED;
 
-       if ((flags & IOMAP_NOWAIT) && !(ip->i_df.if_flags & XFS_IFEXTENTS)) {
-               error = -EAGAIN;
-               goto out_unlock;
+       if (flags & IOMAP_NOWAIT) {
+               if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
+                       return -EAGAIN;
+               if (!xfs_ilock_nowait(ip, lockmode))
+                       return -EAGAIN;
+       } else {
+               xfs_ilock(ip, lockmode);
        }
 
        ASSERT(offset <= mp->m_super->s_maxbytes);
@@ -1024,7 +1040,9 @@ xfs_file_iomap_begin(
                        goto out_unlock;
        }
 
-       if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && xfs_is_reflink_inode(ip)) {
+       if (xfs_is_reflink_inode(ip) &&
+           ((flags & IOMAP_WRITE) ||
+            ((flags & IOMAP_ZERO) && needs_cow_for_zeroing(&imap, nimaps)))) {
                if (flags & IOMAP_DIRECT) {
                        /*
                         * A reflinked inode will result in CoW alloc.
index 3a55d6fc271b1e6d50aa6ce96c9e84b7c5886e43..7a39f40645f7dddbd41740bce4404dbf36fd635b 100644 (file)
@@ -23,6 +23,7 @@
 #include "xfs_log_format.h"
 #include "xfs_trans_resv.h"
 #include "xfs_bit.h"
+#include "xfs_shared.h"
 #include "xfs_mount.h"
 #include "xfs_defer.h"
 #include "xfs_trans.h"
@@ -456,10 +457,12 @@ xfs_cui_recover(
         * transaction.  Normally, any work that needs to be deferred
         * gets attached to the same defer_ops that scheduled the
         * refcount update.  However, we're in log recovery here, so we
-        * we create our own defer_ops and use that to finish up any
-        * work that doesn't fit.
+        * we use the passed in defer_ops and to finish up any work that
+        * doesn't fit.  We need to reserve enough blocks to handle a
+        * full btree split on either end of the refcount range.
         */
-       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
+                       mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp);
        if (error)
                return error;
        cudp = xfs_trans_get_cud(tp, cuip);
index f3b139c9aa1674a3f652ec622286e9aba616d5c3..49d3124863a81f719efd1774b0b6ac7f651b0a26 100644 (file)
@@ -23,6 +23,7 @@
 #include "xfs_log_format.h"
 #include "xfs_trans_resv.h"
 #include "xfs_bit.h"
+#include "xfs_shared.h"
 #include "xfs_mount.h"
 #include "xfs_defer.h"
 #include "xfs_trans.h"
@@ -470,7 +471,8 @@ xfs_rui_recover(
                }
        }
 
-       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
+       error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
+                       mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp);
        if (error)
                return error;
        rudp = xfs_trans_get_rud(tp, ruip);
index 7aba628dc5279858a7608a78839b0e32753bbee6..93588ea3d3d2ca2d664edb4e1b853f5d0dad6a73 100644 (file)
@@ -250,6 +250,7 @@ xfs_parseargs(
                                return -EINVAL;
                        break;
                case Opt_logdev:
+                       kfree(mp->m_logname);
                        mp->m_logname = match_strdup(args);
                        if (!mp->m_logname)
                                return -ENOMEM;
@@ -258,6 +259,7 @@ xfs_parseargs(
                        xfs_warn(mp, "%s option not allowed on this system", p);
                        return -EINVAL;
                case Opt_rtdev:
+                       kfree(mp->m_rtname);
                        mp->m_rtname = match_strdup(args);
                        if (!mp->m_rtname)
                                return -ENOMEM;
index bc397573c43ad4f5d4a670f050818ff16ec313c0..67ab280ad13401088a2fb3426e9867f03bd51d26 100644 (file)
@@ -7,7 +7,8 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and provides acquire barrier semantics.
+ * This operation is atomic and provides acquire barrier semantics if
+ * the returned value is 0.
  * It can be used to implement bit locks.
  */
 #define test_and_set_bit_lock(nr, addr)        test_and_set_bit(nr, addr)
index 963b755d19b0329e9e15b238db5f62074d615c51..a7613e1b0c87a4a38635b6fe99333afde18238b6 100644 (file)
@@ -52,6 +52,7 @@ struct bug_entry {
 #ifndef HAVE_ARCH_BUG
 #define BUG() do { \
        printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
+       barrier_before_unreachable(); \
        panic("BUG!"); \
 } while (0)
 #endif
index 2cfa3075d148b60196c2d63ede83ea4e182ab1fe..bfbb44a5ad38965f00c82b19135b3d81ab20142d 100644 (file)
@@ -983,6 +983,8 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot);
 int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot);
 int pud_clear_huge(pud_t *pud);
 int pmd_clear_huge(pmd_t *pmd);
+int pud_free_pmd_page(pud_t *pud);
+int pmd_free_pte_page(pmd_t *pmd);
 #else  /* !CONFIG_HAVE_ARCH_HUGE_VMAP */
 static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot)
 {
@@ -1008,6 +1010,14 @@ static inline int pmd_clear_huge(pmd_t *pmd)
 {
        return 0;
 }
+static inline int pud_free_pmd_page(pud_t *pud)
+{
+       return 0;
+}
+static inline int pmd_free_pte_page(pmd_t *pmd)
+{
+       return 0;
+}
 #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
 
 #ifndef __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
index 1c27526c499eed6f50b46771aaea27282567deb9..cf13842a6dbd1fa8808f4e9c0d49a5f9b012c931 100644 (file)
@@ -134,6 +134,15 @@ struct drm_crtc_commit {
         * &drm_pending_vblank_event pointer to clean up private events.
         */
        struct drm_pending_vblank_event *event;
+
+       /**
+        * @abort_completion:
+        *
+        * A flag that's set after drm_atomic_helper_setup_commit takes a second
+        * reference for the completion of $drm_crtc_state.event. It's used by
+        * the free code to remove the second reference if commit fails.
+        */
+       bool abort_completion;
 };
 
 struct __drm_planes_state {
index 76e237bd989bef2f81142ef143960d9720651827..6914633037a5359f1355a15e94163dbde7d4ebe2 100644 (file)
@@ -77,5 +77,6 @@ void drm_kms_helper_hotplug_event(struct drm_device *dev);
 
 void drm_kms_helper_poll_disable(struct drm_device *dev);
 void drm_kms_helper_poll_enable(struct drm_device *dev);
+bool drm_kms_helper_is_poll_worker(void);
 
 #endif
index d32b688eb346c9252eb66d73be49fdd477e290de..d23dcdd1bd95a20ba98e4ae65b57d6f225cad7c3 100644 (file)
@@ -56,6 +56,7 @@ struct drm_printer;
 #define DRIVER_ATOMIC                  0x10000
 #define DRIVER_KMS_LEGACY_CONTEXT      0x20000
 #define DRIVER_SYNCOBJ                  0x40000
+#define DRIVER_PREFER_XBGR_30BPP        0x80000
 
 /**
  * struct drm_driver - DRM driver structure
diff --git a/include/dt-bindings/sound/rt5651.h b/include/dt-bindings/sound/rt5651.h
new file mode 100644 (file)
index 0000000..2f2dac9
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_RT5651_H
+#define __DT_RT5651_H
+
+#define RT5651_JD_NULL                 0
+#define RT5651_JD1_1                   1
+#define RT5651_JD1_2                   2
+#define RT5651_JD2                     3
+
+#define RT5651_OVCD_SF_0P5             0
+#define RT5651_OVCD_SF_0P75            1
+#define RT5651_OVCD_SF_1P0             2
+#define RT5651_OVCD_SF_1P5             3
+
+#endif /* __DT_RT5651_H */
index cdbd142ca7f2ea4513a7bcf44f877f9b3bbbebc3..02924ae2527e6580a553814d30fab930af071a19 100644 (file)
@@ -360,6 +360,7 @@ void kvm_vgic_put(struct kvm_vcpu *vcpu);
 bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
+void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid);
 
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 
index 64e10746f28288107131c2bef7e879c0aa5722f4..968173ec2726d64367d18d88558975833366bc5b 100644 (file)
@@ -587,7 +587,7 @@ extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
 const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
                                               const struct device *dev);
 
-void *acpi_get_match_data(const struct device *dev);
+const void *acpi_device_get_match_data(const struct device *dev);
 extern bool acpi_driver_match_device(struct device *dev,
                                     const struct device_driver *drv);
 int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
@@ -766,7 +766,7 @@ static inline const struct acpi_device_id *acpi_match_device(
        return NULL;
 }
 
-static inline void *acpi_get_match_data(const struct device *dev)
+static inline const void *acpi_device_get_match_data(const struct device *dev)
 {
        return NULL;
 }
index d0eb659fa733eb91b57a135932f45b1eea8d9975..ce547a25e8aed5d61efd5c0ce9b5c450af4fabcc 100644 (file)
@@ -511,6 +511,7 @@ void zero_fill_bio(struct bio *bio);
 extern struct bio_vec *bvec_alloc(gfp_t, int, unsigned long *, mempool_t *);
 extern void bvec_free(mempool_t *, struct bio_vec *, unsigned int);
 extern unsigned int bvec_nr_vecs(unsigned short idx);
+extern const char *bio_devname(struct bio *bio, char *buffer);
 
 #define bio_set_dev(bio, bdev)                         \
 do {                                           \
@@ -529,9 +530,6 @@ do {                                                \
 #define bio_dev(bio) \
        disk_devt((bio)->bi_disk)
 
-#define bio_devname(bio, buf) \
-       __bdevname(bio_dev(bio), (buf))
-
 #ifdef CONFIG_BLK_CGROUP
 int bio_associate_blkcg(struct bio *bio, struct cgroup_subsys_state *blkcg_css);
 void bio_disassociate_task(struct bio *bio);
index 4f3df807cf8f73076ca6e735b901b14360528aa6..ed63f3b69c12b6378feeb52dc91503753ec74284 100644 (file)
@@ -49,7 +49,7 @@ struct blk_stat_callback;
 #define BLKDEV_MIN_RQ  4
 #define BLKDEV_MAX_RQ  128     /* Default maximum */
 
-/* Must be consisitent with blk_mq_poll_stats_bkt() */
+/* Must be consistent with blk_mq_poll_stats_bkt() */
 #define BLK_MQ_POLL_STATS_BKTS 16
 
 /*
index 9f242b876fde2c29b1d3c023a3934ef01d04cfa9..f8e76d01a5ade411c231c926e55e59a71dde6cc5 100644 (file)
@@ -755,13 +755,13 @@ struct sock_cgroup_data {
  * updaters and return part of the previous pointer as the prioidx or
  * classid.  Such races are short-lived and the result isn't critical.
  */
-static inline u16 sock_cgroup_prioidx(struct sock_cgroup_data *skcd)
+static inline u16 sock_cgroup_prioidx(const struct sock_cgroup_data *skcd)
 {
        /* fallback to 1 which is always the ID of the root cgroup */
        return (skcd->is_data & 1) ? skcd->prioidx : 1;
 }
 
-static inline u32 sock_cgroup_classid(struct sock_cgroup_data *skcd)
+static inline u32 sock_cgroup_classid(const struct sock_cgroup_data *skcd)
 {
        /* fallback to 0 which is the unconfigured default classid */
        return (skcd->is_data & 1) ? skcd->classid : 0;
index 8a9643857c4a13be60726a18bfe51ccfb1557c46..16c3027074a22f6aea08e0157a5848f824e08afd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/if.h>
 #include <linux/fs.h>
 #include <linux/aio_abi.h>     /* for aio_context_t */
+#include <linux/uaccess.h>
 #include <linux/unistd.h>
 
 #include <asm/compat.h>
@@ -229,13 +230,13 @@ typedef struct compat_siginfo {
                                short int _addr_lsb;    /* Valid LSB of the reported address. */
                                /* used when si_code=SEGV_BNDERR */
                                struct {
-                                       short _dummy_bnd;
+                                       compat_uptr_t _dummy_bnd;
                                        compat_uptr_t _lower;
                                        compat_uptr_t _upper;
                                } _addr_bnd;
                                /* used when si_code=SEGV_PKUERR */
                                struct {
-                                       short _dummy_pkey;
+                                       compat_uptr_t _dummy_pkey;
                                        u32 _pkey;
                                } _addr_pkey;
                        };
@@ -550,8 +551,29 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
 extern int get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat);
-extern int put_compat_sigset(compat_sigset_t __user *compat,
-                            const sigset_t *set, unsigned int size);
+
+/*
+ * Defined inline such that size can be compile time constant, which avoids
+ * CONFIG_HARDENED_USERCOPY complaining about copies from task_struct
+ */
+static inline int
+put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
+                 unsigned int size)
+{
+       /* size <= sizeof(compat_sigset_t) <= sizeof(sigset_t) */
+#ifdef __BIG_ENDIAN
+       compat_sigset_t v;
+       switch (_NSIG_WORDS) {
+       case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
+       case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2];
+       case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1];
+       case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0];
+       }
+       return copy_to_user(compat, &v, size) ? -EFAULT : 0;
+#else
+       return copy_to_user(compat, set, size) ? -EFAULT : 0;
+#endif
+}
 
 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
                compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
index d02a4df3f4737a2ae98cce7928c3dcf4c4167164..d3f264a5b04d9c999a94273c18272416576b17c1 100644 (file)
@@ -27,3 +27,8 @@
 #if __has_feature(address_sanitizer)
 #define __SANITIZE_ADDRESS__
 #endif
+
+/* Clang doesn't have a way to turn it off per-function, yet. */
+#ifdef __noretpoline
+#undef __noretpoline
+#endif
index 631354acfa7204757a4ec29e74581dc2ee723a13..e2c7f4369effdbcf9cb46b1904c3cbe84debd2ca 100644 (file)
 #define __weak         __attribute__((weak))
 #define __alias(symbol)        __attribute__((alias(#symbol)))
 
+#ifdef RETPOLINE
+#define __noretpoline __attribute__((indirect_branch("keep")))
+#endif
+
 /*
  * it doesn't make sense on ARM (currently the only user of __naked)
  * to trace naked functions because then mcount is called without
 
 #if GCC_VERSION >= 40100
 # define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
-
-#define __nostackprotector     __attribute__((__optimize__("no-stack-protector")))
 #endif
 
 #if GCC_VERSION >= 40300
 #endif /* __CHECKER__ */
 #endif /* GCC_VERSION >= 40300 */
 
+#if GCC_VERSION >= 40400
+#define __optimize(level)      __attribute__((__optimize__(level)))
+#define __nostackprotector     __optimize("no-stack-protector")
+#endif /* GCC_VERSION >= 40400 */
+
 #if GCC_VERSION >= 40500
 
 #ifndef __CHECKER__
 #endif
 #endif
 
+/*
+ * calling noreturn functions, __builtin_unreachable() and __builtin_trap()
+ * confuse the stack allocation in gcc, leading to overly large stack
+ * frames, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
+ *
+ * Adding an empty inline assembly before it works around the problem
+ */
+#define barrier_before_unreachable() asm volatile("")
+
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
  * unreleased.  Really, we need to have autoconf for the kernel.
  */
 #define unreachable() \
-       do { annotate_unreachable(); __builtin_unreachable(); } while (0)
+       do {                                    \
+               annotate_unreachable();         \
+               barrier_before_unreachable();   \
+               __builtin_unreachable();        \
+       } while (0)
 
 /* Mark a function definition as prohibited from being cloned. */
 #define __noclone      __attribute__((__noclone__, __optimize__("no-tracer")))
index c2cc57a2f508f46dd815d79a9626119436486e51..ab4711c63601495347eee07382a692a4b1cee3ab 100644 (file)
@@ -86,6 +86,11 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 # define barrier_data(ptr) barrier()
 #endif
 
+/* workaround for GCC PR82365 if needed */
+#ifndef barrier_before_unreachable
+# define barrier_before_unreachable() do { } while (0)
+#endif
+
 /* Unreachable code */
 #ifdef CONFIG_STACK_VALIDATION
 /*
@@ -277,6 +282,10 @@ unsigned long read_word_at_a_time(const void *addr)
 
 #endif /* __ASSEMBLY__ */
 
+#ifndef __optimize
+# define __optimize(level)
+#endif
+
 /* Compile time object size, -1 for unknown */
 #ifndef __compiletime_object_size
 # define __compiletime_object_size(obj) -1
index 871f9e21810c8ebd22c3b1686777bc7c258cf8cf..0b3fc229086ca6cb98d24645c487ab097d6566e5 100644 (file)
@@ -225,7 +225,7 @@ static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev,
 }
 #endif
 
-#ifdef CONFIG_ARCH_HAS_CPU_RELAX
+#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_HAS_CPU_RELAX)
 void cpuidle_poll_state_init(struct cpuidle_driver *drv);
 #else
 static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {}
index d4a2a7dcd72d91f0b0a15f8561a27d5838bf041a..bf53d893ad02bbe460dd64ce03d8cfe10d709931 100644 (file)
@@ -170,6 +170,8 @@ static inline unsigned int cpumask_local_spread(unsigned int i, int node)
        for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
 #define for_each_cpu_not(cpu, mask)            \
        for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
+#define for_each_cpu_wrap(cpu, mask, start)    \
+       for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)(start))
 #define for_each_cpu_and(cpu, mask, and)       \
        for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and)
 #else
index 34fe8463d10ea3be5df5fb27d80c51d663b94136..eb9eab4ecd6d7a050115b54ac81cde94f15e6591 100644 (file)
@@ -578,7 +578,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 
 /*
  * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please
- * don't use this is new code.
+ * don't use this in new code.
  */
 #ifndef arch_dma_supported
 #define arch_dma_supported(dev, mask)  (1)
index 2a815560fda0e162c5c27da8249b9f3921328c21..c6baf767619ed3fdd819308031554a54bc60e630 100644 (file)
@@ -1317,6 +1317,7 @@ extern int send_sigurg(struct fown_struct *fown);
 #define SB_I_CGROUPWB  0x00000001      /* cgroup-aware writeback enabled */
 #define SB_I_NOEXEC    0x00000002      /* Ignore executables on this fs */
 #define SB_I_NODEV     0x00000004      /* Ignore devices on this fs */
+#define SB_I_MULTIROOT 0x00000008      /* Multiple roots to the dentry tree */
 
 /* sb->s_iflags to limit user namespace mounts */
 #define SB_I_USERNS_VISIBLE            0x00000010 /* fstype already mounted */
@@ -3198,7 +3199,7 @@ static inline bool vma_is_fsdax(struct vm_area_struct *vma)
        if (!vma_is_dax(vma))
                return false;
        inode = file_inode(vma->vm_file);
-       if (inode->i_mode == S_IFCHR)
+       if (S_ISCHR(inode->i_mode))
                return false; /* device-dax */
        return true;
 }
index c332f0a4560794225a538f2a45ed77f936472c46..3fdfede2f0f3e9d7f66cd498f2ac51d00a012d58 100644 (file)
@@ -734,11 +734,7 @@ struct fsl_ifc_nand {
        u32 res19[0x10];
        __be32 nand_fsr;
        u32 res20;
-       /* The V1 nand_eccstat is actually 4 words that overlaps the
-        * V2 nand_eccstat.
-        */
-       __be32 v1_nand_eccstat[2];
-       __be32 v2_nand_eccstat[6];
+       __be32 nand_eccstat[8];
        u32 res21[0x1c];
        __be32 nanndcr;
        u32 res22[0x2];
index 4fa1a489efe4cd6e15d88a269044fbd37dfe054d..4fe8f289b3f6f01d3b5ad94676e2239d208e5229 100644 (file)
@@ -73,8 +73,8 @@ struct fwnode_operations {
        struct fwnode_handle *(*get)(struct fwnode_handle *fwnode);
        void (*put)(struct fwnode_handle *fwnode);
        bool (*device_is_available)(const struct fwnode_handle *fwnode);
-       void *(*device_get_match_data)(const struct fwnode_handle *fwnode,
-                                      const struct device *dev);
+       const void *(*device_get_match_data)(const struct fwnode_handle *fwnode,
+                                            const struct device *dev);
        bool (*property_present)(const struct fwnode_handle *fwnode,
                                 const char *propname);
        int (*property_read_int_array)(const struct fwnode_handle *fwnode,
index 5e3531027b5113cc7a9fde0ec0ffc0cdf3389b97..c826b0b5232aff63877bb441fb62e43128b4e976 100644 (file)
@@ -198,6 +198,7 @@ struct gendisk {
        void *private_data;
 
        int flags;
+       struct rw_semaphore lookup_sem;
        struct kobject *slave_dir;
 
        struct timer_rand_state *random;
@@ -600,8 +601,9 @@ extern void delete_partition(struct gendisk *, int);
 extern void printk_all_partitions(void);
 
 extern struct gendisk *__alloc_disk_node(int minors, int node_id);
-extern struct kobject *get_disk(struct gendisk *disk);
+extern struct kobject *get_disk_and_module(struct gendisk *disk);
 extern void put_disk(struct gendisk *disk);
+extern void put_disk_and_module(struct gendisk *disk);
 extern void blk_register_region(dev_t devt, unsigned long range,
                        struct module *module,
                        struct kobject *(*probe)(dev_t, int *, void *),
index c5b0a75a78121935e3ab2874c03a1b9bc123f1cf..fd00170b494f7efee6f4a58ef19a4da10321564d 100644 (file)
@@ -25,6 +25,7 @@ struct ptr_ring *tun_get_tx_ring(struct file *file);
 bool tun_is_xdp_buff(void *ptr);
 void *tun_xdp_to_ptr(void *ptr);
 void *tun_ptr_to_xdp(void *ptr);
+void tun_ptr_free(void *ptr);
 #else
 #include <linux/err.h>
 #include <linux/errno.h>
@@ -50,5 +51,8 @@ static inline void *tun_ptr_to_xdp(void *ptr)
 {
        return NULL;
 }
+static inline void tun_ptr_free(void *ptr)
+{
+}
 #endif /* CONFIG_TUN */
 #endif /* __IF_TUN_H */
index 5e6a2d4dc366033772027940b5c4b742e17d0173..c4a1cff9c76861b3eef7b1eea97d8591532bf798 100644 (file)
@@ -300,30 +300,34 @@ static inline bool vlan_hw_offload_capable(netdev_features_t features,
 }
 
 /**
- * __vlan_insert_tag - regular VLAN tag inserting
+ * __vlan_insert_inner_tag - inner VLAN tag inserting
  * @skb: skbuff to tag
  * @vlan_proto: VLAN encapsulation protocol
  * @vlan_tci: VLAN TCI to insert
+ * @mac_len: MAC header length including outer vlan headers
  *
- * Inserts the VLAN tag into @skb as part of the payload
+ * Inserts the VLAN tag into @skb as part of the payload at offset mac_len
  * Returns error if skb_cow_head failes.
  *
  * Does not change skb->protocol so this function can be used during receive.
  */
-static inline int __vlan_insert_tag(struct sk_buff *skb,
-                                   __be16 vlan_proto, u16 vlan_tci)
+static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
+                                         __be16 vlan_proto, u16 vlan_tci,
+                                         unsigned int mac_len)
 {
        struct vlan_ethhdr *veth;
 
        if (skb_cow_head(skb, VLAN_HLEN) < 0)
                return -ENOMEM;
 
-       veth = skb_push(skb, VLAN_HLEN);
+       skb_push(skb, VLAN_HLEN);
 
-       /* Move the mac addresses to the beginning of the new header. */
-       memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
+       /* Move the mac header sans proto to the beginning of the new header. */
+       memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
        skb->mac_header -= VLAN_HLEN;
 
+       veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
+
        /* first, the ethernet type */
        veth->h_vlan_proto = vlan_proto;
 
@@ -334,12 +338,30 @@ static inline int __vlan_insert_tag(struct sk_buff *skb,
 }
 
 /**
- * vlan_insert_tag - regular VLAN tag inserting
+ * __vlan_insert_tag - regular VLAN tag inserting
  * @skb: skbuff to tag
  * @vlan_proto: VLAN encapsulation protocol
  * @vlan_tci: VLAN TCI to insert
  *
  * Inserts the VLAN tag into @skb as part of the payload
+ * Returns error if skb_cow_head failes.
+ *
+ * Does not change skb->protocol so this function can be used during receive.
+ */
+static inline int __vlan_insert_tag(struct sk_buff *skb,
+                                   __be16 vlan_proto, u16 vlan_tci)
+{
+       return __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN);
+}
+
+/**
+ * vlan_insert_inner_tag - inner VLAN tag inserting
+ * @skb: skbuff to tag
+ * @vlan_proto: VLAN encapsulation protocol
+ * @vlan_tci: VLAN TCI to insert
+ * @mac_len: MAC header length including outer vlan headers
+ *
+ * Inserts the VLAN tag into @skb as part of the payload at offset mac_len
  * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
  *
  * Following the skb_unshare() example, in case of error, the calling function
@@ -347,12 +369,14 @@ static inline int __vlan_insert_tag(struct sk_buff *skb,
  *
  * Does not change skb->protocol so this function can be used during receive.
  */
-static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
-                                             __be16 vlan_proto, u16 vlan_tci)
+static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb,
+                                                   __be16 vlan_proto,
+                                                   u16 vlan_tci,
+                                                   unsigned int mac_len)
 {
        int err;
 
-       err = __vlan_insert_tag(skb, vlan_proto, vlan_tci);
+       err = __vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, mac_len);
        if (err) {
                dev_kfree_skb_any(skb);
                return NULL;
@@ -360,6 +384,26 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
        return skb;
 }
 
+/**
+ * vlan_insert_tag - regular VLAN tag inserting
+ * @skb: skbuff to tag
+ * @vlan_proto: VLAN encapsulation protocol
+ * @vlan_tci: VLAN TCI to insert
+ *
+ * Inserts the VLAN tag into @skb as part of the payload
+ * Returns a VLAN tagged skb. If a new skb is created, @skb is freed.
+ *
+ * Following the skb_unshare() example, in case of error, the calling function
+ * doesn't have to worry about freeing the original skb.
+ *
+ * Does not change skb->protocol so this function can be used during receive.
+ */
+static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb,
+                                             __be16 vlan_proto, u16 vlan_tci)
+{
+       return vlan_insert_inner_tag(skb, vlan_proto, vlan_tci, ETH_HLEN);
+}
+
 /**
  * vlan_insert_tag_set_proto - regular VLAN tag inserting
  * @skb: skbuff to tag
index 506a9815113159651da4b98ec5d72700dbe6271f..bc27cf03c41ea5a4b19d87bb82da0f3d36e9390e 100644 (file)
@@ -6,10 +6,10 @@
 #include <linux/types.h>
 
 /* Built-in __init functions needn't be compiled with retpoline */
-#if defined(RETPOLINE) && !defined(MODULE)
-#define __noretpoline __attribute__((indirect_branch("keep")))
+#if defined(__noretpoline) && !defined(MODULE)
+#define __noinitretpoline __noretpoline
 #else
-#define __noretpoline
+#define __noinitretpoline
 #endif
 
 /* These macros are used to mark some functions or 
@@ -47,7 +47,7 @@
 
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
-#define __init         __section(.init.text) __cold  __latent_entropy __noretpoline
+#define __init         __section(.init.text) __cold  __latent_entropy __noinitretpoline
 #define __initdata     __section(.init.data)
 #define __initconst    __section(.init.rodata)
 #define __exitdata     __section(.exit.data)
index c00c4c33e432e0bd7e6a1ddf2775e5a45b24fa4f..b26eccc78fb1d708c7dc1ed1506770826a5214d0 100644 (file)
 
 #define ICH_HCR_EN                     (1 << 0)
 #define ICH_HCR_UIE                    (1 << 1)
+#define ICH_HCR_NPIE                   (1 << 3)
 #define ICH_HCR_TC                     (1 << 10)
 #define ICH_HCR_TALL0                  (1 << 11)
 #define ICH_HCR_TALL1                  (1 << 12)
index d3453ee072fc8aa859544e07598398884239d56f..68d8b1f73682be899af097adf1d95f6452c8a0c8 100644 (file)
@@ -84,6 +84,7 @@
 
 #define GICH_HCR_EN                    (1 << 0)
 #define GICH_HCR_UIE                   (1 << 1)
+#define GICH_HCR_NPIE                  (1 << 3)
 
 #define GICH_LR_VIRTUALID              (0x3ff << 0)
 #define GICH_LR_PHYSID_CPUID_SHIFT     (10)
index b6a29c126cc49285f62995b59dc517f17cdc3af6..b46b541c67c49f78dd5705cda9c8386f05a8a882 100644 (file)
@@ -151,6 +151,7 @@ extern struct jump_entry __start___jump_table[];
 extern struct jump_entry __stop___jump_table[];
 
 extern void jump_label_init(void);
+extern void jump_label_invalidate_initmem(void);
 extern void jump_label_lock(void);
 extern void jump_label_unlock(void);
 extern void arch_jump_label_transform(struct jump_entry *entry,
@@ -198,6 +199,8 @@ static __always_inline void jump_label_init(void)
        static_key_initialized = true;
 }
 
+static inline void jump_label_invalidate_initmem(void) {}
+
 static __always_inline bool static_key_false(struct static_key *key)
 {
        if (unlikely(static_key_count(key) > 0))
index fec5076eda91d2fd6e401b43463cb43855aa6c57..dcde9471897d5c5119145fd01dddd8e7f118f13c 100644 (file)
@@ -4,6 +4,12 @@
 
 #include <generated/autoconf.h>
 
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#else
+#define __LITTLE_ENDIAN 1234
+#endif
+
 #define __ARG_PLACEHOLDER_1 0,
 #define __take_second_arg(__ignored, val, ...) val
 
@@ -64,4 +70,7 @@
  */
 #define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option))
 
+/* Make sure we always have all types and struct attributes defined. */
+#include <linux/compiler_types.h>
+
 #endif /* __LINUX_KCONFIG_H */
index 7ff25a808feffd115e5af4faab56c2542c227c63..80db19d3a5054d5c064727644af49fdf31310111 100644 (file)
@@ -10,6 +10,7 @@ enum kcore_type {
        KCORE_VMALLOC,
        KCORE_RAM,
        KCORE_VMEMMAP,
+       KCORE_USER,
        KCORE_OTHER,
 };
 
index ce51455e2adf631229d21b43e6afb76b2496790c..3fd291503576f1407e633851bec2b785152e6576 100644 (file)
@@ -472,6 +472,7 @@ extern bool parse_option_str(const char *str, const char *option);
 extern char *next_arg(char *args, char **param, char **val);
 
 extern int core_kernel_text(unsigned long addr);
+extern int init_kernel_text(unsigned long addr);
 extern int core_kernel_data(unsigned long addr);
 extern int __kernel_text_address(unsigned long addr);
 extern int kernel_text_address(unsigned long addr);
index ac0062b74aed048923c9f08b4a9d74d176ff6c96..6930c63126c78a9ef665b5b5653a60a8773b4d4c 100644 (file)
@@ -1105,7 +1105,6 @@ static inline void kvm_irq_routing_update(struct kvm *kvm)
 {
 }
 #endif
-void kvm_arch_irq_routing_update(struct kvm *kvm);
 
 static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 {
@@ -1114,6 +1113,8 @@ static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 
 #endif /* CONFIG_HAVE_KVM_EVENTFD */
 
+void kvm_arch_irq_routing_update(struct kvm *kvm);
+
 static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)
 {
        /*
@@ -1272,4 +1273,7 @@ static inline long kvm_arch_vcpu_async_ioctl(struct file *filp,
 }
 #endif /* CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL */
 
+void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+               unsigned long start, unsigned long end);
+
 #endif
index 8be5077efb5fb246042d2f126348906b04e61c37..f92ea77836526666b1c410423a3c15a50e1eab85 100644 (file)
@@ -187,7 +187,6 @@ int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,
                            unsigned long  *end_pfn);
 void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
                          unsigned long *out_end_pfn, int *out_nid);
-unsigned long memblock_next_valid_pfn(unsigned long pfn, unsigned long max_pfn);
 
 /**
  * for_each_mem_pfn_range - early memory pfn range iterator
index 8820468635810a3d801a5dd52beca94a7a14b035..c46016bb25ebe2ba3919987876ae058dd0a7b01c 100644 (file)
@@ -523,9 +523,11 @@ static inline void __mod_memcg_state(struct mem_cgroup *memcg,
 static inline void mod_memcg_state(struct mem_cgroup *memcg,
                                   int idx, int val)
 {
-       preempt_disable();
+       unsigned long flags;
+
+       local_irq_save(flags);
        __mod_memcg_state(memcg, idx, val);
-       preempt_enable();
+       local_irq_restore(flags);
 }
 
 /**
@@ -606,9 +608,11 @@ static inline void __mod_lruvec_state(struct lruvec *lruvec,
 static inline void mod_lruvec_state(struct lruvec *lruvec,
                                    enum node_stat_item idx, int val)
 {
-       preempt_disable();
+       unsigned long flags;
+
+       local_irq_save(flags);
        __mod_lruvec_state(lruvec, idx, val);
-       preempt_enable();
+       local_irq_restore(flags);
 }
 
 static inline void __mod_lruvec_page_state(struct page *page,
@@ -630,9 +634,11 @@ static inline void __mod_lruvec_page_state(struct page *page,
 static inline void mod_lruvec_page_state(struct page *page,
                                         enum node_stat_item idx, int val)
 {
-       preempt_disable();
+       unsigned long flags;
+
+       local_irq_save(flags);
        __mod_lruvec_page_state(page, idx, val);
-       preempt_enable();
+       local_irq_restore(flags);
 }
 
 unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
@@ -659,9 +665,11 @@ static inline void __count_memcg_events(struct mem_cgroup *memcg,
 static inline void count_memcg_events(struct mem_cgroup *memcg,
                                      int idx, unsigned long count)
 {
-       preempt_disable();
+       unsigned long flags;
+
+       local_irq_save(flags);
        __count_memcg_events(memcg, idx, count);
-       preempt_enable();
+       local_irq_restore(flags);
 }
 
 /* idx can be of type enum memcg_event_item or vm_event_item */
index 6ed79a8a831889152504b64408b7758304e462ba..9d3a03364e6e2099938624eeca8cdf7995d4c60d 100644 (file)
@@ -453,8 +453,8 @@ struct mlx5_core_srq {
        struct mlx5_core_rsc_common     common; /* must be first */
        u32             srqn;
        int             max;
-       int             max_gs;
-       int             max_avail_gather;
+       size_t          max_gs;
+       size_t          max_avail_gather;
        int             wqe_shift;
        void (*event)   (struct mlx5_core_srq *, enum mlx5_event);
 
index c30b32e3c86248c2f39fa1b926124184fc45b205..10191c28fc04ce22c605d54a87257ee5ff427651 100644 (file)
@@ -127,10 +127,4 @@ static __always_inline enum lru_list page_lru(struct page *page)
 
 #define lru_to_page(head) (list_entry((head)->prev, struct page, lru))
 
-#ifdef arch_unmap_kpfn
-extern void arch_unmap_kpfn(unsigned long pfn);
-#else
-static __always_inline void arch_unmap_kpfn(unsigned long pfn) { }
-#endif
-
 #endif
index f25c13423bd4774d3d602d2ec7afb561a39614d5..cb3bbed4e6339cfd89586c15a1d65b1d7af61106 100644 (file)
@@ -66,6 +66,11 @@ struct mutex {
 #endif
 };
 
+/*
+ * Internal helper function; C doesn't allow us to hide it :/
+ *
+ * DO NOT USE (outside of mutex code).
+ */
 static inline struct task_struct *__mutex_owner(struct mutex *lock)
 {
        return (struct task_struct *)(atomic_long_read(&lock->owner) & ~0x07);
index 91216b16feb78e0a19b2129aa5c390fd0cd7eaff..2a0391eea05c3612b2ef560ed4852811fd16dfff 100644 (file)
@@ -222,6 +222,7 @@ enum {
 int sock_wake_async(struct socket_wq *sk_wq, int how, int band);
 int sock_register(const struct net_proto_family *fam);
 void sock_unregister(int family);
+bool sock_is_registered(int family);
 int __sock_create(struct net *net, int family, int type, int proto,
                  struct socket **res, int kern);
 int sock_create(int family, int type, int proto, struct socket **res);
index 1313b35c3ab7914a26c463aa9113756dd4e4ceae..14529511c4b8466ab81986ee9d874538bbe0e09a 100644 (file)
@@ -285,6 +285,8 @@ unsigned int *xt_alloc_entry_offsets(unsigned int size);
 bool xt_find_jump_offset(const unsigned int *offsets,
                         unsigned int target, unsigned int size);
 
+int xt_check_proc_name(const char *name, unsigned int size);
+
 int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
                   bool inv_proto);
 int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
index b99bced39ac2fa1b91cea50a8301336c3cbff133..e791ebc65c9c0776325cdc5e72de5d995038d7e0 100644 (file)
@@ -5,6 +5,7 @@
 
 #ifndef _LINUX_NOSPEC_H
 #define _LINUX_NOSPEC_H
+#include <asm/barrier.h>
 
 /**
  * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
 static inline unsigned long array_index_mask_nospec(unsigned long index,
                                                    unsigned long size)
 {
-       /*
-        * Warn developers about inappropriate array_index_nospec() usage.
-        *
-        * Even if the CPU speculates past the WARN_ONCE branch, the
-        * sign bit of @index is taken into account when generating the
-        * mask.
-        *
-        * This warning is compiled out when the compiler can infer that
-        * @index and @size are less than LONG_MAX.
-        */
-       if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX,
-                       "array_index_nospec() limited to range of [0, LONG_MAX]\n"))
-               return 0;
-
        /*
         * Always calculate and emit the mask even if the compiler
         * thinks the mask is not needed. The compiler does not take
@@ -66,7 +53,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
        BUILD_BUG_ON(sizeof(_i) > sizeof(long));                        \
        BUILD_BUG_ON(sizeof(_s) > sizeof(long));                        \
                                                                        \
-       _i &= _mask;                                                    \
-       _i;                                                             \
+       (typeof(_i)) (_i & _mask);                                      \
 })
 #endif /* _LINUX_NOSPEC_H */
index 88865e0ebf4dd551f8c41bd9fbc0f78d7899b552..091033a6b836fd78bd4a22dfdb622eb4b39c32b8 100644 (file)
@@ -13,7 +13,6 @@ struct device_node;
 struct device_node *of_pci_find_child_device(struct device_node *parent,
                                             unsigned int devfn);
 int of_pci_get_devfn(struct device_node *np);
-int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
 int of_pci_get_max_link_speed(struct device_node *node);
@@ -33,12 +32,6 @@ static inline int of_pci_get_devfn(struct device_node *np)
        return -EINVAL;
 }
 
-static inline int
-of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       return 0;
-}
-
 static inline int
 of_pci_parse_bus_range(struct device_node *node, struct resource *res)
 {
@@ -67,6 +60,16 @@ of_pci_get_max_link_speed(struct device_node *node)
 static inline void of_pci_check_probe_only(void) { }
 #endif
 
+#if IS_ENABLED(CONFIG_OF_IRQ)
+int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
+#else
+static inline int
+of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return 0;
+}
+#endif
+
 #if defined(CONFIG_OF_ADDRESS)
 int of_pci_get_host_bridge_resources(struct device_node *dev,
                        unsigned char busno, unsigned char bus_max,
index 864d167a10739e464ec534ad3b32a96757e316ac..009cdf3d65b63e0db3ddcf243d2ddfdff7be14fd 100644 (file)
  * calls io_destroy() or the process exits.
  *
  * In the aio code, kill_ioctx() is called when we wish to destroy a kioctx; it
- * calls percpu_ref_kill(), then hlist_del_rcu() and synchronize_rcu() to remove
- * the kioctx from the proccess's list of kioctxs - after that, there can't be
- * any new users of the kioctx (from lookup_ioctx()) and it's then safe to drop
- * the initial ref with percpu_ref_put().
+ * removes the kioctx from the proccess's table of kioctxs and kills percpu_ref.
+ * After that, there can't be any new users of the kioctx (from lookup_ioctx())
+ * and it's then safe to drop the initial ref with percpu_ref_put().
+ *
+ * Note that the free path, free_ioctx(), needs to go through explicit call_rcu()
+ * to synchronize with RCU protected lookup_ioctx().  percpu_ref operations don't
+ * imply RCU grace periods of any kind and if a user wants to combine percpu_ref
+ * with RCU protection, it must be done explicitly.
  *
  * Code that does a two stage shutdown like this often needs some kind of
  * explicit synchronization to ensure the initial refcount can only be dropped
@@ -113,8 +117,10 @@ void percpu_ref_reinit(struct percpu_ref *ref);
  * Must be used to drop the initial ref on a percpu refcount; must be called
  * precisely once before shutdown.
  *
- * Puts @ref in non percpu mode, then does a call_rcu() before gathering up the
- * percpu counters and dropping the initial ref.
+ * Switches @ref into atomic mode before gathering up the percpu counters
+ * and dropping the initial ref.
+ *
+ * There are no implied RCU grace periods between kill and release.
  */
 static inline void percpu_ref_kill(struct percpu_ref *ref)
 {
index af0f44effd44abc067d7f31e498c433fd061725e..40036a57d072f28dbdd9de54e7d1972d37072d64 100644 (file)
 
 #include <linux/interrupt.h>
 #include <linux/perf_event.h>
+#include <linux/platform_device.h>
 #include <linux/sysfs.h>
 #include <asm/cputype.h>
 
-/*
- * struct arm_pmu_platdata - ARM PMU platform data
- *
- * @handle_irq: an optional handler which will be called from the
- *     interrupt and passed the address of the low level handler,
- *     and can be used to implement any platform specific handling
- *     before or after calling it.
- *
- * @irq_flags: if non-zero, these flags will be passed to request_irq
- *             when requesting interrupts for this PMU device.
- */
-struct arm_pmu_platdata {
-       irqreturn_t (*handle_irq)(int irq, void *dev,
-                                 irq_handler_t pmu_handler);
-       unsigned long irq_flags;
-};
-
 #ifdef CONFIG_ARM_PMU
 
 /*
@@ -92,7 +76,6 @@ enum armpmu_attr_groups {
 
 struct arm_pmu {
        struct pmu      pmu;
-       cpumask_t       active_irqs;
        cpumask_t       supported_cpus;
        char            *name;
        irqreturn_t     (*handle_irq)(int irq_num, void *dev);
@@ -174,12 +157,11 @@ static inline int arm_pmu_acpi_probe(armpmu_init_fn init_fn) { return 0; }
 
 /* Internal functions only for core arm_pmu code */
 struct arm_pmu *armpmu_alloc(void);
+struct arm_pmu *armpmu_alloc_atomic(void);
 void armpmu_free(struct arm_pmu *pmu);
 int armpmu_register(struct arm_pmu *pmu);
-int armpmu_request_irqs(struct arm_pmu *armpmu);
-void armpmu_free_irqs(struct arm_pmu *armpmu);
-int armpmu_request_irq(struct arm_pmu *armpmu, int cpu);
-void armpmu_free_irq(struct arm_pmu *armpmu, int cpu);
+int armpmu_request_irq(int irq, int cpu);
+void armpmu_free_irq(int irq, int cpu);
 
 #define ARMV8_PMU_PDEV_NAME "armv8-pmu"
 
index 5a0c3e53e7c2057e24e8b652ce223b376cd734ad..7c4c2379e0103186258b6ec26441411d5cb84d13 100644 (file)
@@ -924,6 +924,7 @@ void phy_device_remove(struct phy_device *phydev);
 int phy_init_hw(struct phy_device *phydev);
 int phy_suspend(struct phy_device *phydev);
 int phy_resume(struct phy_device *phydev);
+int __phy_resume(struct phy_device *phydev);
 int phy_loopback(struct phy_device *phydev, bool enable);
 struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
                              phy_interface_t interface);
@@ -983,6 +984,10 @@ static inline int genphy_no_soft_reset(struct phy_device *phydev)
 {
        return 0;
 }
+int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad,
+                               u16 regnum);
+int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
+                                u16 regnum, u16 val);
 
 /* Clause 45 PHY */
 int genphy_c45_restart_aneg(struct phy_device *phydev);
@@ -1011,7 +1016,6 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
 int phy_drivers_register(struct phy_driver *new_driver, int n,
                         struct module *owner);
 void phy_state_machine(struct work_struct *work);
-void phy_change(struct phy_device *phydev);
 void phy_change_work(struct work_struct *work);
 void phy_mac_interrupt(struct phy_device *phydev);
 void phy_start_machine(struct phy_device *phydev);
index 769d372c1edf648bd98700fcfdb03f094c1a4620..2eea4b310fc2850e137c0c636b8bcafb24f04f0c 100644 (file)
@@ -283,7 +283,7 @@ bool device_dma_supported(struct device *dev);
 
 enum dev_dma_attr device_get_dma_attr(struct device *dev);
 
-void *device_get_match_data(struct device *dev);
+const void *device_get_match_data(struct device *dev);
 
 int device_get_phy_mode(struct device *dev);
 
index b884b7794187ee4c007b512107c41b7fe5055516..e6335227b84482c9598f1d73206024bf3a8c7646 100644 (file)
@@ -469,7 +469,7 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r,
  */
 static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
 {
-       if (size * sizeof(void *) > KMALLOC_MAX_SIZE)
+       if (size > KMALLOC_MAX_SIZE / sizeof(void *))
                return NULL;
        return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO);
 }
index c9df2527e0cdd60cef38e7d614dd72f5df21a4fc..668a21f04b09665018ffaf91989f32995fbbdfc4 100644 (file)
@@ -766,8 +766,10 @@ slow_path:
                if (!key ||
                    (params.obj_cmpfn ?
                     params.obj_cmpfn(&arg, rht_obj(ht, head)) :
-                    rhashtable_compare(&arg, rht_obj(ht, head))))
+                    rhashtable_compare(&arg, rht_obj(ht, head)))) {
+                       pprev = &head->next;
                        continue;
+               }
 
                data = rht_obj(ht, head);
 
index 1149533aa2fa2838d28b4351522314cb302bc0a4..9806184bb3d54eb5160db40f747574868837e787 100644 (file)
@@ -36,7 +36,18 @@ static inline void mmgrab(struct mm_struct *mm)
        atomic_inc(&mm->mm_count);
 }
 
-extern void mmdrop(struct mm_struct *mm);
+extern void __mmdrop(struct mm_struct *mm);
+
+static inline 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);
+}
 
 /**
  * mmget() - Pin the address space associated with a &struct mm_struct.
index 0dcf4e480ef73345174bfb7d1446e0e1a89daa5c..96fe289c4c6e496fefd005d3100c84bf58f81698 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/uidgid.h>
 #include <linux/atomic.h>
+#include <linux/ratelimit.h>
 
 struct key;
 
@@ -41,6 +42,9 @@ struct user_struct {
     defined(CONFIG_NET)
        atomic_long_t locked_vm;
 #endif
+
+       /* Miscellaneous per-user rate limit */
+       struct ratelimit_state ratelimit;
 };
 
 extern int uids_sysfs_init(void);
index dc368b8ce215ccc0f6a2b44a16dd2aaa603dbcd1..11c86fbfeb985429e11df0b2f9f7fc9767b5ba3e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Distributed under the terms of the GNU GPL, version 2
  *
- * Please see kernel/semaphore.c for documentation of these functions
+ * Please see kernel/locking/semaphore.c for documentation of these functions
  */
 #ifndef __LINUX_SEMAPHORE_H
 #define __LINUX_SEMAPHORE_H
index 5ebc0f869720a35d2790a6befc9f33fb54a4f9a1..99df17109e1b5141622b376655417f8ebba1f527 100644 (file)
@@ -3285,8 +3285,7 @@ int skb_zerocopy(struct sk_buff *to, struct sk_buff *from,
 void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len);
 int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen);
 void skb_scrub_packet(struct sk_buff *skb, bool xnet);
-unsigned int skb_gso_transport_seglen(const struct sk_buff *skb);
-bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu);
+bool skb_gso_validate_network_len(const struct sk_buff *skb, unsigned int mtu);
 bool skb_gso_validate_mac_len(const struct sk_buff *skb, unsigned int len);
 struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features);
 struct sk_buff *skb_vlan_untag(struct sk_buff *skb);
@@ -3646,7 +3645,7 @@ static inline bool __skb_checksum_validate_needed(struct sk_buff *skb,
        return true;
 }
 
-/* For small packets <= CHECKSUM_BREAK peform checksum complete directly
+/* For small packets <= CHECKSUM_BREAK perform checksum complete directly
  * in checksum_init.
  */
 #define CHECKSUM_BREAK 76
@@ -4038,6 +4037,12 @@ static inline bool skb_is_gso_v6(const struct sk_buff *skb)
        return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
 }
 
+/* Note: Should be called only if skb_is_gso(skb) is true */
+static inline bool skb_is_gso_sctp(const struct sk_buff *skb)
+{
+       return skb_shinfo(skb)->gso_type & SKB_GSO_SCTP;
+}
+
 static inline void skb_gso_reset(struct sk_buff *skb)
 {
        skb_shinfo(skb)->gso_size = 0;
@@ -4045,6 +4050,22 @@ static inline void skb_gso_reset(struct sk_buff *skb)
        skb_shinfo(skb)->gso_type = 0;
 }
 
+static inline void skb_increase_gso_size(struct skb_shared_info *shinfo,
+                                        u16 increment)
+{
+       if (WARN_ON_ONCE(shinfo->gso_size == GSO_BY_FRAGS))
+               return;
+       shinfo->gso_size += increment;
+}
+
+static inline void skb_decrease_gso_size(struct skb_shared_info *shinfo,
+                                        u16 decrement)
+{
+       if (WARN_ON_ONCE(shinfo->gso_size == GSO_BY_FRAGS))
+               return;
+       shinfo->gso_size -= decrement;
+}
+
 void __skb_warn_lro_forwarding(const struct sk_buff *skb);
 
 static inline bool skb_warn_if_lro(const struct sk_buff *skb)
@@ -4104,38 +4125,6 @@ static inline bool skb_head_is_locked(const struct sk_buff *skb)
        return !skb->head_frag || skb_cloned(skb);
 }
 
-/**
- * skb_gso_network_seglen - Return length of individual segments of a gso packet
- *
- * @skb: GSO skb
- *
- * skb_gso_network_seglen is used to determine the real size of the
- * individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP).
- *
- * The MAC/L2 header is not accounted for.
- */
-static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
-{
-       unsigned int hdr_len = skb_transport_header(skb) -
-                              skb_network_header(skb);
-       return hdr_len + skb_gso_transport_seglen(skb);
-}
-
-/**
- * skb_gso_mac_seglen - Return length of individual segments of a gso packet
- *
- * @skb: GSO skb
- *
- * skb_gso_mac_seglen is used to determine the real size of the
- * individual segments, including MAC/L2, Layer3 (IP, IPv6) and L4
- * headers (TCP/UDP).
- */
-static inline unsigned int skb_gso_mac_seglen(const struct sk_buff *skb)
-{
-       unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
-       return hdr_len + skb_gso_transport_seglen(skb);
-}
-
 /* Local Checksum Offload.
  * Compute outer checksum based on the assumption that the
  * inner checksum will be offloaded later.
index 7b6a59f722a39eda9db1b8de902001c434b0be80..a1a3f4ed94cea88c43ecc31d8f70aed80ef7618f 100644 (file)
@@ -337,8 +337,6 @@ extern void deactivate_file_page(struct page *page);
 extern void mark_page_lazyfree(struct page *page);
 extern void swap_setup(void);
 
-extern void add_page_to_unevictable_list(struct page *page);
-
 extern void lru_cache_add_active_or_unevictable(struct page *page,
                                                struct vm_area_struct *vma);
 
index 0a6c71e0ad01ec4f17845b0496b4a88a94f33949..47f8af22f2168f0376d77068ecbc2df930ae8f79 100644 (file)
@@ -364,6 +364,7 @@ struct tty_file_private {
 #define TTY_PTY_LOCK           16      /* pty private */
 #define TTY_NO_WRITE_SPLIT     17      /* Preserve write boundaries to driver */
 #define TTY_HUPPED             18      /* Post driver->hangup() */
+#define TTY_HUPPING            19      /* Hangup in progress */
 #define TTY_LDISC_HALTED       22      /* Line discipline is halted */
 
 /* Values for tty->flow_change */
index 5bdbd9f49395f883ca2dc5aa0d7bbde11f379063..07ee0f84a46caa9e2b1c446f96009f63b3b99f50 100644 (file)
@@ -90,6 +90,28 @@ static inline void u64_stats_update_end(struct u64_stats_sync *syncp)
 #endif
 }
 
+static inline unsigned long
+u64_stats_update_begin_irqsave(struct u64_stats_sync *syncp)
+{
+       unsigned long flags = 0;
+
+#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+       local_irq_save(flags);
+       write_seqcount_begin(&syncp->seq);
+#endif
+       return flags;
+}
+
+static inline void
+u64_stats_update_end_irqrestore(struct u64_stats_sync *syncp,
+                               unsigned long flags)
+{
+#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
+       write_seqcount_end(&syncp->seq);
+       local_irq_restore(flags);
+#endif
+}
+
 static inline void u64_stats_update_begin_raw(struct u64_stats_sync *syncp)
 {
 #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
index f1fcec2fd5f87f45530a70d082a70c9feb67ea3e..b7a99ce56bc9ad6cd4c8ff2c5681d6fbb781b875 100644 (file)
@@ -63,4 +63,7 @@
  */
 #define USB_QUIRK_DISCONNECT_SUSPEND           BIT(12)
 
+/* Device needs a pause after every control message. */
+#define USB_QUIRK_DELAY_CTRL_MSG               BIT(13)
+
 #endif /* __LINUX_USB_QUIRKS_H */
index 4a54ef96aff5b0ba8e9bf53cc754d09c0dd4dd55..0c3301421c57746c086996e67401a167c82fe98c 100644 (file)
@@ -456,7 +456,6 @@ extern int schedule_on_each_cpu(work_func_t func);
 int execute_in_process_context(work_func_t fn, struct execute_work *);
 
 extern bool flush_work(struct work_struct *work);
-extern bool cancel_work(struct work_struct *work);
 extern bool cancel_work_sync(struct work_struct *work);
 
 extern bool flush_delayed_work(struct delayed_work *dwork);
@@ -465,6 +464,7 @@ extern bool cancel_delayed_work_sync(struct delayed_work *dwork);
 
 extern void workqueue_set_max_active(struct workqueue_struct *wq,
                                     int max_active);
+extern struct work_struct *current_work(void);
 extern bool current_is_workqueue_rescuer(void);
 extern bool workqueue_congested(int cpu, struct workqueue_struct *wq);
 extern unsigned int work_busy(struct work_struct *work);
index c4df6cee48e6ab41520d73d4a9e12a7be76b0f07..bf00a5a41a90643437e3a750456ff534e9fa7945 100644 (file)
@@ -117,7 +117,7 @@ struct dmx_ts_feed {
  *               specified by @filter_value that will be used on the filter
  *               match logic.
  * @filter_mode:  Contains a 16 bytes (128 bits) filter mode.
- * @parent:      Pointer to struct dmx_section_feed.
+ * @parent:      Back-pointer to struct dmx_section_feed.
  * @priv:        Pointer to private data of the API client.
  *
  *
@@ -130,8 +130,9 @@ struct dmx_section_filter {
        u8 filter_value[DMX_MAX_FILTER_SIZE];
        u8 filter_mask[DMX_MAX_FILTER_SIZE];
        u8 filter_mode[DMX_MAX_FILTER_SIZE];
-       struct dmx_section_feed *parent; /* Back-pointer */
-       void *priv; /* Pointer to private data of the API client */
+       struct dmx_section_feed *parent;
+
+       void *priv;
 };
 
 /**
@@ -193,6 +194,10 @@ struct dmx_section_feed {
  * @buffer2:           Pointer to the tail of the filtered TS packets, or NULL.
  * @buffer2_length:    Length of the TS data in buffer2.
  * @source:            Indicates which TS feed is the source of the callback.
+ * @buffer_flags:      Address where buffer flags are stored. Those are
+ *                     used to report discontinuity users via DVB
+ *                     memory mapped API, as defined by
+ *                     &enum dmx_buffer_flags.
  *
  * This function callback prototype, provided by the client of the demux API,
  * is called from the demux code. The function is only called when filtering
@@ -245,7 +250,8 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1,
                         size_t buffer1_length,
                         const u8 *buffer2,
                         size_t buffer2_length,
-                        struct dmx_ts_feed *source);
+                        struct dmx_ts_feed *source,
+                        u32 *buffer_flags);
 
 /**
  * typedef dmx_section_cb - DVB demux TS filter callback function prototype
@@ -261,6 +267,10 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1,
  *                     including headers and CRC.
  * @source:            Indicates which section feed is the source of the
  *                     callback.
+ * @buffer_flags:      Address where buffer flags are stored. Those are
+ *                     used to report discontinuity users via DVB
+ *                     memory mapped API, as defined by
+ *                     &enum dmx_buffer_flags.
  *
  * This function callback prototype, provided by the client of the demux API,
  * is called from the demux code. The function is only called when
@@ -286,7 +296,8 @@ typedef int (*dmx_section_cb)(const u8 *buffer1,
                              size_t buffer1_len,
                              const u8 *buffer2,
                              size_t buffer2_len,
-                             struct dmx_section_filter *source);
+                             struct dmx_section_filter *source,
+                             u32 *buffer_flags);
 
 /*
  * DVB Front-End
index 2f5cb2c7b6a75dcf582d9f8fb6e97985c8b47888..baafa3b8aca4140ec3fe426138bada16e0a1da6f 100644 (file)
@@ -163,6 +163,7 @@ struct dmxdev_filter {
  * @demux:             pointer to &struct dmx_demux.
  * @filternum:         number of filters.
  * @capabilities:      demux capabilities as defined by &enum dmx_demux_caps.
+ * @may_do_mmap:       flag used to indicate if the device may do mmap.
  * @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.
@@ -180,6 +181,7 @@ struct dmxdev {
        int filternum;
        int capabilities;
 
+       unsigned int may_do_mmap:1;
        unsigned int exit:1;
 #define DMXDEV_CAP_DUPLEX 1
        struct dmx_frontend *dvr_orig_fe;
index b07092038f4bde977cd50a40c16e263d2f4293ed..3b6aeca7a49e44f5dd2a602842d14362951404ae 100644 (file)
@@ -115,6 +115,8 @@ struct dvb_demux_filter {
  * @pid:       PID to be filtered.
  * @timeout:   feed timeout.
  * @filter:    pointer to &struct dvb_demux_filter.
+ * @buffer_flags: Buffer flags used to report discontinuity users via DVB
+ *               memory mapped API, as defined by &enum dmx_buffer_flags.
  * @ts_type:   type of TS, as defined by &enum ts_filter_type.
  * @pes_type:  type of PES, as defined by &enum dmx_ts_pes.
  * @cc:                MPEG-TS packet continuity counter
@@ -145,6 +147,8 @@ struct dvb_demux_feed {
        ktime_t timeout;
        struct dvb_demux_filter *filter;
 
+       u32 buffer_flags;
+
        enum ts_filter_type ts_type;
        enum dmx_ts_pes pes_type;
 
index 01d1202d1a55b8ed30d92e4ad46b20cbd17409a0..8cb88452cd6c287ced6cea133419096ef1a22955 100644 (file)
@@ -85,6 +85,12 @@ struct dvb_buffer {
  * @nonblocking:
  *             If different than zero, device is operating on non-blocking
  *             mode.
+ * @flags:     buffer flags as defined by &enum dmx_buffer_flags.
+ *             Filled only at &DMX_DQBUF. &DMX_QBUF should zero this field.
+ * @count:     monotonic counter for filled buffers. Helps to identify
+ *             data stream loses. Filled only at &DMX_DQBUF. &DMX_QBUF should
+ *             zero this field.
+ *
  * @name:      name of the device type. Currently, it can either be
  *             "dvr" or "demux_filter".
  */
@@ -100,10 +106,14 @@ struct dvb_vb2_ctx {
        int     buf_siz;
        int     buf_cnt;
        int     nonblocking;
+
+       enum dmx_buffer_flags flags;
+       u32     count;
+
        char    name[DVB_VB2_NAME_MAX + 1];
 };
 
-#ifndef DVB_MMAP
+#ifndef CONFIG_DVB_MMAP
 static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
                               const char *name, int non_blocking)
 {
@@ -114,7 +124,7 @@ 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)
+#define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0)
 
 static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
                                    struct file *file,
@@ -153,9 +163,13 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
  * @ctx:       control struct for VB2 handler
  * @src:       place where the data is stored
  * @len:       number of bytes to be copied from @src
+ * @buffer_flags:
+ *             pointer to buffer flags as defined by &enum dmx_buffer_flags.
+ *             can be NULL.
  */
 int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
-                       const unsigned char *src, int len);
+                       const unsigned char *src, int len,
+                       enum dmx_buffer_flags *buffer_flags);
 
 /**
  * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV
index 6545b03e97f73fd5d439a092b9374dfea83d9319..4de35ed12bcc2f47b8bd0e25fb04c4b1423cab8e 100644 (file)
@@ -257,6 +257,18 @@ struct devlink_resource_size_params {
        enum devlink_resource_unit unit;
 };
 
+static inline void
+devlink_resource_size_params_init(struct devlink_resource_size_params *size_params,
+                                 u64 size_min, u64 size_max,
+                                 u64 size_granularity,
+                                 enum devlink_resource_unit unit)
+{
+       size_params->size_min = size_min;
+       size_params->size_max = size_max;
+       size_params->size_granularity = size_granularity;
+       size_params->unit = unit;
+}
+
 /**
  * struct devlink_resource - devlink resource
  * @name: name of the resource
@@ -278,7 +290,7 @@ struct devlink_resource {
        u64 size_new;
        bool size_valid;
        struct devlink_resource *parent;
-       struct devlink_resource_size_params *size_params;
+       struct devlink_resource_size_params size_params;
        struct list_head list;
        struct list_head resource_list;
        const struct devlink_resource_ops *resource_ops;
@@ -402,7 +414,7 @@ int devlink_resource_register(struct devlink *devlink,
                              u64 resource_size,
                              u64 resource_id,
                              u64 parent_resource_id,
-                             struct devlink_resource_size_params *size_params,
+                             const struct devlink_resource_size_params *size_params,
                              const struct devlink_resource_ops *resource_ops);
 void devlink_resources_unregister(struct devlink *devlink,
                                  struct devlink_resource *resource);
@@ -556,7 +568,7 @@ devlink_resource_register(struct devlink *devlink,
                          u64 resource_size,
                          u64 resource_id,
                          u64 parent_resource_id,
-                         struct devlink_resource_size_params *size_params,
+                         const struct devlink_resource_size_params *size_params,
                          const struct devlink_resource_ops *resource_ops)
 {
        return 0;
index 746abff9ce517ecbe1d580e5f53edfc93383da1a..f49b3a576becfbac4e6077410a2f1fce9aaaee46 100644 (file)
@@ -328,6 +328,13 @@ int ip_decrease_ttl(struct iphdr *iph)
        return --iph->ttl;
 }
 
+static inline int ip_mtu_locked(const struct dst_entry *dst)
+{
+       const struct rtable *rt = (const struct rtable *)dst;
+
+       return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU);
+}
+
 static inline
 int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
 {
@@ -335,7 +342,7 @@ int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
 
        return  pmtudisc == IP_PMTUDISC_DO ||
                (pmtudisc == IP_PMTUDISC_WANT &&
-                !(dst_metric_locked(dst, RTAX_MTU)));
+                !ip_mtu_locked(dst));
 }
 
 static inline bool ip_sk_accept_pmtu(const struct sock *sk)
@@ -361,7 +368,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
        struct net *net = dev_net(dst->dev);
 
        if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
-           dst_metric_locked(dst, RTAX_MTU) ||
+           ip_mtu_locked(dst) ||
            !forwarding)
                return dst_mtu(dst);
 
index 27d23a65f3cd0be2255859614690151e2d01b352..ac0866bb9e936192ee7ee186e1a9e675c6c761ee 100644 (file)
@@ -179,6 +179,9 @@ void rt6_disable_ip(struct net_device *dev, unsigned long event);
 void rt6_sync_down_dev(struct net_device *dev, unsigned long event);
 void rt6_multipath_rebalance(struct rt6_info *rt);
 
+void rt6_uncached_list_add(struct rt6_info *rt);
+void rt6_uncached_list_del(struct rt6_info *rt);
+
 static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb)
 {
        const struct dst_entry *dst = skb_dst(skb);
index f80524396c062db27dd4907a79a451fd9535e172..77d0a78cf7d2b8cf556f14d231cb06130c05aff9 100644 (file)
@@ -59,6 +59,7 @@ struct fib_nh_exception {
        int                             fnhe_genid;
        __be32                          fnhe_daddr;
        u32                             fnhe_pmtu;
+       bool                            fnhe_mtu_locked;
        __be32                          fnhe_gw;
        unsigned long                   fnhe_expires;
        struct rtable __rcu             *fnhe_rth_input;
index 906e902230662562c97f03a7ccd37e6339747eba..2b581bd938120a1e9004215296d647b699da95ea 100644 (file)
@@ -2063,6 +2063,9 @@ struct ieee80211_txq {
  * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on
  *     TDLS links.
  *
+ * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't
+ *     support QoS NDP for AP probing - that's most likely a driver bug.
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2106,6 +2109,7 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_REPORTS_LOW_ACK,
        IEEE80211_HW_SUPPORTS_TX_FRAG,
        IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
+       IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP,
 
        /* keep last, obviously */
        NUM_IEEE80211_HW_FLAGS
@@ -4149,7 +4153,7 @@ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid);
  * The TX headroom reserved by mac80211 for its own tx_status functions.
  * This is enough for the radiotap header.
  */
-#define IEEE80211_TX_STATUS_HEADROOM   14
+#define IEEE80211_TX_STATUS_HEADROOM   ALIGN(14, 4)
 
 /**
  * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
index ebc5a2ed86317dfdab8939d6259ed7ea7b0199fb..f83cacce33085e3922cd23cd51ccca393f85114b 100644 (file)
@@ -78,7 +78,7 @@ struct regulatory_request {
        int wiphy_idx;
        enum nl80211_reg_initiator initiator;
        enum nl80211_user_reg_hint_type user_reg_hint_type;
-       char alpha2[2];
+       char alpha2[3];
        enum nl80211_dfs_regions dfs_region;
        bool intersect;
        bool processed;
index 1eb9ce470e25ce0ece3eff33d2b84341f94a4036..20a92ca9e11582c13f4063b2f09c2d1787e4ccb2 100644 (file)
@@ -63,7 +63,8 @@ struct rtable {
        __be32                  rt_gateway;
 
        /* Miscellaneous cached information */
-       u32                     rt_pmtu;
+       u32                     rt_mtu_locked:1,
+                               rt_pmtu:31;
 
        u32                     rt_table_id;
 
@@ -227,6 +228,9 @@ struct in_ifaddr;
 void fib_add_ifaddr(struct in_ifaddr *);
 void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *);
 
+void rt_add_uncached_list(struct rtable *rt);
+void rt_del_uncached_list(struct rtable *rt);
+
 static inline void ip_rt_put(struct rtable *rt)
 {
        /* dst_release() accepts a NULL parameter.
index e2ab13687fb9741f3977b5452a958f8e886189f4..2092d33194dd1f237cba04849d17b37d61a922e7 100644 (file)
@@ -824,6 +824,16 @@ static inline void __qdisc_drop(struct sk_buff *skb, struct sk_buff **to_free)
        *to_free = skb;
 }
 
+static inline void __qdisc_drop_all(struct sk_buff *skb,
+                                   struct sk_buff **to_free)
+{
+       if (skb->prev)
+               skb->prev->next = *to_free;
+       else
+               skb->next = *to_free;
+       *to_free = skb;
+}
+
 static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
                                                   struct qdisc_skb_head *qh,
                                                   struct sk_buff **to_free)
@@ -956,6 +966,15 @@ static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
        return NET_XMIT_DROP;
 }
 
+static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch,
+                                struct sk_buff **to_free)
+{
+       __qdisc_drop_all(skb, to_free);
+       qdisc_qstats_drop(sch);
+
+       return NET_XMIT_DROP;
+}
+
 /* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how
    long it will take to send a packet given its size.
  */
index 169c92afcafa3d548f8238e91606b87c187559f4..ae23f3b389cac6bcf7f270a4cd2ae3498b2d5ad5 100644 (file)
@@ -1137,6 +1137,7 @@ struct proto {
 
 int proto_register(struct proto *prot, int alloc_slab);
 void proto_unregister(struct proto *prot);
+int sock_load_diag_module(int family, int protocol);
 
 #ifdef SOCK_REFCNT_DEBUG
 static inline void sk_refcnt_debug_inc(struct sock *sk)
index 81bdbf97319b216ad1d7955aa13c7cae2c8ac044..9185e45b997ff67ce2999c6b0665c8d693b44338 100644 (file)
@@ -64,6 +64,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
                UDP_SKB_CB(skb)->cscov = cscov;
                if (skb->ip_summed == CHECKSUM_COMPLETE)
                        skb->ip_summed = CHECKSUM_NONE;
+               skb->csum_valid = 0;
         }
 
        return 0;
index 73b2387e3f742490528696e97290990c9462d4f6..ff3ed435701f3e05b197ec1e32828f330da2646b 100644 (file)
@@ -1537,10 +1537,6 @@ struct ib_xrcd {
 
        struct mutex            tgt_qp_mutex;
        struct list_head        tgt_qp_list;
-       /*
-        * Implementation details of the RDMA core, don't use in drivers:
-        */
-       struct rdma_restrack_entry res;
 };
 
 struct ib_ah {
index c2d81167c8585ff68c6caf5127013c22b1bb8c11..2cdf8dcf4bdcbc70538768619098ac2c5a2e9c48 100644 (file)
@@ -28,10 +28,6 @@ enum rdma_restrack_type {
         * @RDMA_RESTRACK_QP: Queue pair (QP)
         */
        RDMA_RESTRACK_QP,
-       /**
-        * @RDMA_RESTRACK_XRCD: XRC domain (XRCD)
-        */
-       RDMA_RESTRACK_XRCD,
        /**
         * @RDMA_RESTRACK_MAX: Last entry, used for array dclarations
         */
index 6da44079aa58961cccde88f8366944f2c96166c0..38287d9d23a1f90b4e03f023db0fa2d5fa2175fd 100644 (file)
@@ -276,10 +276,7 @@ struct uverbs_object_tree_def {
  */
 
 struct uverbs_ptr_attr {
-       union {
-               u64             data;
-               void    __user *ptr;
-       };
+       u64             data;
        u16             len;
        /* Combination of bits from enum UVERBS_ATTR_F_XXXX */
        u16             flags;
@@ -351,38 +348,60 @@ static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr
 }
 
 static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
-                                size_t idx, const void *from)
+                                size_t idx, const void *from, size_t size)
 {
        const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
        u16 flags;
+       size_t min_size;
 
        if (IS_ERR(attr))
                return PTR_ERR(attr);
 
+       min_size = min_t(size_t, attr->ptr_attr.len, size);
+       if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size))
+               return -EFAULT;
+
        flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT;
-       return (!copy_to_user(attr->ptr_attr.ptr, from, attr->ptr_attr.len) &&
-               !put_user(flags, &attr->uattr->flags)) ? 0 : -EFAULT;
+       if (put_user(flags, &attr->uattr->flags))
+               return -EFAULT;
+
+       return 0;
 }
 
-static inline int _uverbs_copy_from(void *to, size_t to_size,
+static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr)
+{
+       return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data);
+}
+
+static inline int _uverbs_copy_from(void *to,
                                    const struct uverbs_attr_bundle *attrs_bundle,
-                                   size_t idx)
+                                   size_t idx,
+                                   size_t size)
 {
        const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
 
        if (IS_ERR(attr))
                return PTR_ERR(attr);
 
-       if (to_size <= sizeof(((struct ib_uverbs_attr *)0)->data))
+       /*
+        * Validation ensures attr->ptr_attr.len >= size. If the caller is
+        * using UVERBS_ATTR_SPEC_F_MIN_SZ then it must call copy_from with
+        * the right size.
+        */
+       if (unlikely(size < attr->ptr_attr.len))
+               return -EINVAL;
+
+       if (uverbs_attr_ptr_is_inline(attr))
                memcpy(to, &attr->ptr_attr.data, attr->ptr_attr.len);
-       else if (copy_from_user(to, attr->ptr_attr.ptr, attr->ptr_attr.len))
+       else if (copy_from_user(to, u64_to_user_ptr(attr->ptr_attr.data),
+                               attr->ptr_attr.len))
                return -EFAULT;
 
        return 0;
 }
 
 #define uverbs_copy_from(to, attrs_bundle, idx)                                      \
-       _uverbs_copy_from(to, sizeof(*(to)), attrs_bundle, idx)
+       _uverbs_copy_from(to, attrs_bundle, idx, sizeof(*to))
 
 /* =================================================
  *      Definitions -> Specs infrastructure
index d8d4a902a88dedbc93ac8da1ca99bb5f3d394d65..2280b2351739572c5db73579f8ffc0e16d511ebe 100644 (file)
@@ -68,6 +68,9 @@ struct scsi_cmnd {
        struct list_head list;  /* scsi_cmnd participates in queue lists */
        struct list_head eh_entry; /* entry for the host eh_cmd_q */
        struct delayed_work abort_work;
+
+       struct rcu_head rcu;
+
        int eh_eflags;          /* Used by error handlr */
 
        /*
index 1a1df0d21ee3f9648cc02a6bc067783ae5e5ef03..a8b7bf879cede4240d921a42f915a230163e5e4e 100644 (file)
@@ -571,8 +571,6 @@ struct Scsi_Host {
                struct blk_mq_tag_set   tag_set;
        };
 
-       struct rcu_head rcu;
-
        atomic_t host_busy;                /* commands actually active on low-level */
        atomic_t host_blocked;
 
index c2d1b15da136e9aa9273a90471ac8be7a1b6b413..a91f25151a5b96ce43d61e2f58841aefa4190baa 100644 (file)
@@ -15,6 +15,7 @@
 
 #define ARC_REG_MCIP_BCR       0x0d0
 #define ARC_REG_MCIP_IDU_BCR   0x0D5
+#define ARC_REG_GFRC_BUILD     0x0D6
 #define ARC_REG_MCIP_CMD       0x600
 #define ARC_REG_MCIP_WDATA     0x601
 #define ARC_REG_MCIP_READBACK  0x602
@@ -36,10 +37,14 @@ struct mcip_cmd {
 #define CMD_SEMA_RELEASE               0x12
 
 #define CMD_DEBUG_SET_MASK             0x34
+#define CMD_DEBUG_READ_MASK            0x35
 #define CMD_DEBUG_SET_SELECT           0x36
+#define CMD_DEBUG_READ_SELECT          0x37
 
 #define CMD_GFRC_READ_LO               0x42
 #define CMD_GFRC_READ_HI               0x43
+#define CMD_GFRC_SET_CORE              0x47
+#define CMD_GFRC_READ_CORE             0x48
 
 #define CMD_IDU_ENABLE                 0x71
 #define CMD_IDU_DISABLE                        0x72
index 4bb86d379bd581566e1a371655e380b531bb1353..9a4fa0c3264aac22ca794751e7144052e1fe0c35 100644 (file)
@@ -31,7 +31,7 @@
 #define AC97_HEADPHONE         0x04    /* Headphone Volume (optional) */
 #define AC97_MASTER_MONO       0x06    /* Master Volume Mono (optional) */
 #define AC97_MASTER_TONE       0x08    /* Master Tone (Bass & Treble) (optional) */
-#define AC97_PC_BEEP           0x0a    /* PC Beep Volume (optinal) */
+#define AC97_PC_BEEP           0x0a    /* PC Beep Volume (optional) */
 #define AC97_PHONE             0x0c    /* Phone Volume (optional) */
 #define AC97_MIC               0x0e    /* MIC Volume */
 #define AC97_LINE              0x10    /* Line In Volume */
index 409ef1397fd304a37652c73f3ab9d741225913df..1bfcb16f2d10ab02eeebcd462d16a44b55985dd2 100644 (file)
@@ -36,6 +36,8 @@ struct da7219_aad_pdata;
 struct da7219_pdata {
        bool wakeup_source;
 
+       const char *dai_clks_name;
+
        /* Mic */
        enum da7219_micbias_voltage micbias_lvl;
        enum da7219_mic_amp_in_sel mic_amp_in_sel;
index 67be2445941a613bcc74918d8964bfe3aef907ff..e3481eebdd98d860cebc21d462bdcd303fd4fdfc 100644 (file)
@@ -118,6 +118,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
  *   PCM substream. Will be called from the PCM drivers hwparams callback.
  * @compat_request_channel: Callback to request a DMA channel for platforms
  *   which do not use devicetree.
+ * @process: Callback used to apply processing on samples transferred from/to
+ *   user space.
  * @compat_filter_fn: Will be used as the filter function when requesting a
  *  channel for platforms which do not use devicetree. The filter parameter
  *  will be the DAI's DMA data.
@@ -140,6 +142,9 @@ struct snd_dmaengine_pcm_config {
        struct dma_chan *(*compat_request_channel)(
                        struct snd_soc_pcm_runtime *rtd,
                        struct snd_pcm_substream *substream);
+       int (*process)(struct snd_pcm_substream *substream,
+                      int channel, unsigned long hwoff,
+                      void *buf, unsigned long bytes);
        dma_filter_fn compat_filter_fn;
        struct device *dma_dev;
        const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
@@ -161,4 +166,6 @@ int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct dma_slave_config *slave_config);
 
+#define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
+
 #endif
index 68169e3749de164c140902413dc517e18c006c53..4c93ff5301bd21528ad194df0388553c86a9e634 100644 (file)
@@ -146,6 +146,8 @@ int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
                        int flags, unsigned int verb, unsigned int parm);
 bool snd_hdac_check_power_state(struct hdac_device *hdac,
                hda_nid_t nid, unsigned int target_state);
+unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac,
+                     hda_nid_t nid, unsigned int target_state);
 /**
  * snd_hdac_read_parm - read a codec parameter
  * @codec: the codec object
diff --git a/include/sound/rt5651.h b/include/sound/rt5651.h
deleted file mode 100644 (file)
index 18b79a7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * linux/sound/rt286.h -- Platform data for RT286
- *
- * Copyright 2013 Realtek Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_SND_RT5651_H
-#define __LINUX_SND_RT5651_H
-
-enum rt5651_jd_src {
-       RT5651_JD_NULL,
-       RT5651_JD1_1,
-       RT5651_JD1_2,
-       RT5651_JD2,
-};
-
-struct rt5651_platform_data {
-       /* IN2 can optionally be differential */
-       bool in2_diff;
-
-       bool dmic_en;
-       enum rt5651_jd_src jd_src;
-};
-
-#endif
index 656c4d58948da2eeb760bbfb9363dcb322ffadf9..9012e2b25360481e720b9ac8d7e03240285b4946 100644 (file)
@@ -30,6 +30,7 @@ enum rt5659_dmic2_data_pin {
 enum rt5659_jd_src {
        RT5659_JD_NULL,
        RT5659_JD3,
+       RT5659_JD_HDA_HEADER,
 };
 
 struct rt5659_platform_data {
index 344b96c206a39ec886a3cbb983008127266d9b48..a6ce2de4e20a837c79745c79cc7559a517a157fb 100644 (file)
@@ -269,6 +269,13 @@ struct device;
        .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
        .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
        .on_val = wflags}
+#define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \
+{      .id = snd_soc_dapm_pinctrl, .name = wname, \
+       .priv = (&(struct snd_soc_dapm_pinctrl_priv) \
+               { .active_state = active, .sleep_state = sleep,}), \
+       .reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \
+       .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
+
 
 
 /* dapm kcontrol types */
@@ -374,6 +381,8 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
                         struct snd_kcontrol *kcontrol, int event);
 int dapm_clock_event(struct snd_soc_dapm_widget *w,
                         struct snd_kcontrol *kcontrol, int event);
+int dapm_pinctrl_event(struct snd_soc_dapm_widget *w,
+                        struct snd_kcontrol *kcontrol, int event);
 
 /* dapm controls */
 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
@@ -500,6 +509,7 @@ enum snd_soc_dapm_type {
        snd_soc_dapm_pre,                       /* machine specific pre widget - exec first */
        snd_soc_dapm_post,                      /* machine specific post widget - exec last */
        snd_soc_dapm_supply,            /* power/clock supply */
+       snd_soc_dapm_pinctrl,           /* pinctrl */
        snd_soc_dapm_regulator_supply,  /* external regulator */
        snd_soc_dapm_clock_supply,      /* external clock */
        snd_soc_dapm_aif_in,            /* audio interface input */
@@ -581,6 +591,7 @@ struct snd_soc_dapm_widget {
 
        void *priv;                             /* widget specific data */
        struct regulator *regulator;            /* attached regulator */
+       struct pinctrl *pinctrl;                /* attached pinctrl */
        const struct snd_soc_pcm_stream *params; /* params for dai links */
        unsigned int num_params; /* number of params for dai links */
        unsigned int params_select; /* currently selected param for dai link */
@@ -683,6 +694,11 @@ struct snd_soc_dapm_stats {
        int neighbour_checks;
 };
 
+struct snd_soc_dapm_pinctrl_priv {
+       const char *active_state;
+       const char *sleep_state;
+};
+
 /**
  * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
  * @dapm: The DAPM context to initialize
index 747fd583b9dcf2afeb75e81de56a8ad6cc604507..ad266d7e95537c470837cdeae1a7afcad639d75c 100644 (file)
@@ -586,10 +586,17 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
                                unsigned int mask, unsigned int value);
 
 #ifdef CONFIG_SND_SOC_AC97_BUS
-struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
-struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+#define snd_soc_alloc_ac97_codec(codec) \
+       snd_soc_alloc_ac97_component(&codec->component)
+#define snd_soc_new_ac97_codec(codec, id, id_mask) \
+       snd_soc_new_ac97_component(&codec->component, id, id_mask)
+#define snd_soc_free_ac97_codec(ac97) \
+       snd_soc_free_ac97_component(ac97)
+
+struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
+struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
        unsigned int id, unsigned int id_mask);
-void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
+void snd_soc_free_ac97_component(struct snd_ac97 *ac97);
 
 int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
 int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
@@ -1807,6 +1814,7 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
 int snd_soc_of_get_dai_link_codecs(struct device *dev,
                                   struct device_node *of_node,
                                   struct snd_soc_dai_link *dai_link);
+void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link);
 
 int snd_soc_add_dai_link(struct snd_soc_card *card,
                                struct snd_soc_dai_link *dai_link);
index 200f731be557048c779691e3360018acbf4927c2..7b706ff213359eb31271c8869160c984171bce71 100644 (file)
@@ -86,8 +86,8 @@ TRACE_EVENT(mmc_request_start,
                  __entry->stop_flags, __entry->stop_retries,
                  __entry->sbc_opcode, __entry->sbc_arg,
                  __entry->sbc_flags, __entry->sbc_retries,
-                 __entry->blocks, __entry->blk_addr,
-                 __entry->blksz, __entry->data_flags, __entry->tag,
+                 __entry->blocks, __entry->blksz,
+                 __entry->blk_addr, __entry->data_flags, __entry->tag,
                  __entry->can_retune, __entry->doing_retune,
                  __entry->retune_now, __entry->need_retune,
                  __entry->hold_retune, __entry->retune_period)
index b8adf05c534e725d1e0e3b614181b008e2488f65..7dd8f34c37dfea26f8ec460d3937a46c8f109f4d 100644 (file)
@@ -368,7 +368,7 @@ TRACE_EVENT(xen_mmu_flush_tlb,
            TP_printk("%s", "")
        );
 
-TRACE_EVENT(xen_mmu_flush_tlb_single,
+TRACE_EVENT(xen_mmu_flush_tlb_one_user,
            TP_PROTO(unsigned long addr),
            TP_ARGS(addr),
            TP_STRUCT__entry(
index 85dc965afd892ccd34a4d9f41673c60412fd97c0..99c902e460c2534609c6c385543e527adc36fa57 100644 (file)
@@ -102,13 +102,13 @@ typedef struct siginfo {
                                short _addr_lsb; /* LSB of the reported address */
                                /* used when si_code=SEGV_BNDERR */
                                struct {
-                                       short _dummy_bnd;
+                                       void *_dummy_bnd;
                                        void __user *_lower;
                                        void __user *_upper;
                                } _addr_bnd;
                                /* used when si_code=SEGV_PKUERR */
                                struct {
-                                       short _dummy_pkey;
+                                       void *_dummy_pkey;
                                        __u32 _pkey;
                                } _addr_pkey;
                        };
index 91a31ffed828ddfbad55967022d3a1df32db5340..9a781f0611df0280be7d952258f486f805f27528 100644 (file)
@@ -63,6 +63,7 @@ struct drm_virtgpu_execbuffer {
 };
 
 #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */
+#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */
 
 struct drm_virtgpu_getparam {
        __u64 param;
index 20d1490d63773288d1d91130e96478ee7708bf26..3c50e07ee833116a726c19402f26cf63e91491e9 100644 (file)
@@ -131,7 +131,7 @@ enum {
 #define BLKTRACE_BDEV_SIZE     32
 
 /*
- * User setup structure passed with BLKTRACESTART
+ * User setup structure passed with BLKTRACESETUP
  */
 struct blk_user_trace_setup {
        char name[BLKTRACE_BDEV_SIZE];  /* output */
index 5f3c5a918f00d5ed3cb2c82b8803edeae456cad9..b4112f0b6dd36c33299930f4ffc16fc5230e465f 100644 (file)
@@ -211,6 +211,32 @@ struct dmx_stc {
        __u64 stc;
 };
 
+/**
+ * enum dmx_buffer_flags - DMX memory-mapped buffer flags
+ *
+ * @DMX_BUFFER_FLAG_HAD_CRC32_DISCARD:
+ *     Indicates that the Kernel discarded one or more frames due to wrong
+ *     CRC32 checksum.
+ * @DMX_BUFFER_FLAG_TEI:
+ *     Indicates that the Kernel has detected a Transport Error indicator
+ *     (TEI) on a filtered pid.
+ * @DMX_BUFFER_PKT_COUNTER_MISMATCH:
+ *     Indicates that the Kernel has detected a packet counter mismatch
+ *     on a filtered pid.
+ * @DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED:
+ *     Indicates that the Kernel has detected one or more frame discontinuity.
+ * @DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR:
+ *     Received at least one packet with a frame discontinuity indicator.
+ */
+
+enum dmx_buffer_flags {
+       DMX_BUFFER_FLAG_HAD_CRC32_DISCARD               = 1 << 0,
+       DMX_BUFFER_FLAG_TEI                             = 1 << 1,
+       DMX_BUFFER_PKT_COUNTER_MISMATCH                 = 1 << 2,
+       DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED          = 1 << 3,
+       DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR         = 1 << 4,
+};
+
 /**
  * struct dmx_buffer - dmx buffer info
  *
@@ -220,15 +246,24 @@ struct dmx_stc {
  *             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
+ * @flags:     bit array of buffer flags as defined by &enum dmx_buffer_flags.
+ *             Filled only at &DMX_DQBUF.
+ * @count:     monotonic counter for filled buffers. Helps to identify
+ *             data stream loses. Filled only at &DMX_DQBUF.
  *
  * Contains data exchanged by application and driver using one of the streaming
  * I/O methods.
+ *
+ * Please notice that, for &DMX_QBUF, only @index should be filled.
+ * On &DMX_DQBUF calls, all fields will be filled by the Kernel.
  */
 struct dmx_buffer {
        __u32                   index;
        __u32                   bytesused;
        __u32                   offset;
        __u32                   length;
+       __u32                   flags;
+       __u32                   count;
 };
 
 /**
index f8cb5760ea4fb3182f49b411e422d996ef467d60..820de5d222d22bafd1ae442ef86e8957d65df74d 100644 (file)
@@ -23,7 +23,6 @@
 #define _UAPI_LINUX_IF_ETHER_H
 
 #include <linux/types.h>
-#include <linux/libc-compat.h>
 
 /*
  *     IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
@@ -31,6 +30,7 @@
  */
 
 #define ETH_ALEN       6               /* Octets in one ethernet addr   */
+#define ETH_TLEN       2               /* Octets in ethernet type field */
 #define ETH_HLEN       14              /* Total octets in header.       */
 #define ETH_ZLEN       60              /* Min. octets in frame sans FCS */
 #define ETH_DATA_LEN   1500            /* Max. octets in payload        */
  *     This is an Ethernet frame header.
  */
 
+/* allow libcs like musl to deactivate this, glibc does not implement this. */
+#ifndef __UAPI_DEF_ETHHDR
+#define __UAPI_DEF_ETHHDR              1
+#endif
+
 #if __UAPI_DEF_ETHHDR
 struct ethhdr {
        unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
index 0fb5ef939732517293f222f2c85d88f2b4c1e973..7b26d4b0b0529649816ec1523d225eec7fa8ee26 100644 (file)
@@ -761,6 +761,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_TRACE_PAUSE           __KVM_DEPRECATED_MAIN_0x07
 #define KVM_TRACE_DISABLE         __KVM_DEPRECATED_MAIN_0x08
 #define KVM_GET_EMULATED_CPUID   _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
+#define KVM_GET_MSR_FEATURE_INDEX_LIST    _IOWR(KVMIO, 0x0a, struct kvm_msr_list)
 
 /*
  * Extension capability list.
@@ -934,6 +935,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_AIS_MIGRATION 150
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
+#define KVM_CAP_GET_MSR_FEATURES 153
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index fc29efaa918cb76fab92a65890cca1aab3ecf9ba..8254c937c9f45507cd14d400a6dd4b0f8dcecd43 100644 (file)
 
 #endif /* __GLIBC__ */
 
-/* Definitions for if_ether.h */
-/* allow libcs like musl to deactivate this, glibc does not implement this. */
-#ifndef __UAPI_DEF_ETHHDR
-#define __UAPI_DEF_ETHHDR              1
-#endif
-
 #endif /* _UAPI_LIBC_COMPAT_H */
index 4fe580d36e4151b87c9a1638234d4719726e0e30..f5bf06ecd87d3b254aef6030f4d528045e3f493d 100644 (file)
@@ -54,7 +54,6 @@
 #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
index 3d77fe91239a802367634d3cc29fd3903c1cee19..9008f31c7eb65c90a487d99d3f371a00ba526f3f 100644 (file)
@@ -42,7 +42,7 @@ typedef enum {
        SEV_RET_INVALID_PLATFORM_STATE,
        SEV_RET_INVALID_GUEST_STATE,
        SEV_RET_INAVLID_CONFIG,
-       SEV_RET_INVALID_len,
+       SEV_RET_INVALID_LEN,
        SEV_RET_ALREADY_OWNED,
        SEV_RET_INVALID_CERTIFICATE,
        SEV_RET_POLICY_FAILURE,
index e46d82b911669700662e5e4ec321b26db625f150..d5a1b8a492b93ddb6dd41cf23d759c4059bc8660 100644 (file)
@@ -69,8 +69,8 @@ struct ptrace_peeksiginfo_args {
 #define PTRACE_SECCOMP_GET_METADATA    0x420d
 
 struct seccomp_metadata {
-       unsigned long filter_off;       /* Input: which filter */
-       unsigned int flags;             /* Output: filter's flags */
+       __u64 filter_off;       /* Input: which filter */
+       __u64 flags;            /* Output: filter's flags */
 };
 
 /* Read signals from a shared (process wide) queue */
index 17a022c5b4144c48f0bb071d53d619f63983fbdb..da3315ed1bcde6be19093f32ae26064b7284ed02 100644 (file)
@@ -370,7 +370,7 @@ static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_d
 {
        return (protocol == UAC_VERSION_1) ?
                desc->baSourceID[desc->bNrInPins + 4] :
-               desc->baSourceID[desc->bNrInPins + 6];
+               2; /* in UAC2, this value is constant */
 }
 
 static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
@@ -378,7 +378,7 @@ static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_de
 {
        return (protocol == UAC_VERSION_1) ?
                &desc->baSourceID[desc->bNrInPins + 5] :
-               &desc->baSourceID[desc->bNrInPins + 7];
+               &desc->baSourceID[desc->bNrInPins + 6];
 }
 
 static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
index 4b0b0b756f3ee4cbf37a5d04e013fe84a5b6f604..0af83d80fb3ea42b7fe161e89073a6f7503bc6dd 100644 (file)
@@ -32,6 +32,22 @@ struct ocxl_ioctl_attach {
        __u64 reserved3;
 };
 
+struct ocxl_ioctl_metadata {
+       __u16 version; // struct version, always backwards compatible
+
+       // Version 0 fields
+       __u8  afu_version_major;
+       __u8  afu_version_minor;
+       __u32 pasid;            // PASID assigned to the current context
+
+       __u64 pp_mmio_size;     // Per PASID MMIO size
+       __u64 global_mmio_size;
+
+       // End version 0 fields
+
+       __u64 reserved[13]; // Total of 16*u64
+};
+
 struct ocxl_ioctl_irq_fd {
        __u64 irq_offset;
        __s32 eventfd;
@@ -45,5 +61,6 @@ struct ocxl_ioctl_irq_fd {
 #define OCXL_IOCTL_IRQ_ALLOC   _IOR(OCXL_MAGIC, 0x11, __u64)
 #define OCXL_IOCTL_IRQ_FREE    _IOW(OCXL_MAGIC, 0x12, __u64)
 #define OCXL_IOCTL_IRQ_SET_FD  _IOW(OCXL_MAGIC, 0x13, struct ocxl_ioctl_irq_fd)
+#define OCXL_IOCTL_GET_METADATA _IOR(OCXL_MAGIC, 0x14, struct ocxl_ioctl_metadata)
 
 #endif /* _UAPI_MISC_OCXL_H */
index 03557b5f9aa6b80031470ba0d317782ffa60f29c..46de0885e8001d3b3e1b8bbef0d1a8bad713e584 100644 (file)
@@ -65,7 +65,7 @@ struct ib_uverbs_attr {
        __u16 len;              /* only for pointers */
        __u16 flags;            /* combination of UVERBS_ATTR_F_XXXX */
        __u16 reserved;
-       __u64 data;             /* ptr to command, inline data or idr/fd */
+       __aligned_u64 data;     /* ptr to command, inline data or idr/fd */
 };
 
 struct ib_uverbs_ioctl_hdr {
@@ -73,7 +73,7 @@ struct ib_uverbs_ioctl_hdr {
        __u16 object_id;
        __u16 method_id;
        __u16 num_attrs;
-       __u64 reserved;
+       __aligned_u64 reserved;
        struct ib_uverbs_attr  attrs[0];
 };
 
index 07d61583fd02bd08b9748d974bca8b86a0706a3a..ed0a120d4f084fa0cfc10b5257ea9bce0c3d3a24 100644 (file)
@@ -242,6 +242,7 @@ typedef int __bitwise snd_pcm_format_t;
 #define        SNDRV_PCM_FORMAT_DSD_U16_BE     ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */
 #define        SNDRV_PCM_FORMAT_DSD_U32_BE     ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */
 #define        SNDRV_PCM_FORMAT_LAST           SNDRV_PCM_FORMAT_DSD_U32_BE
+#define        SNDRV_PCM_FORMAT_FIRST          SNDRV_PCM_FORMAT_S8
 
 #ifdef SNDRV_LITTLE_ENDIAN
 #define        SNDRV_PCM_FORMAT_S16            SNDRV_PCM_FORMAT_S16_LE
index a8100b9548398e8b102052f2c1418b21ea423825..21efbf6ace93dd391ca2a3f0f4bc67aa7ab67ca4 100644 (file)
@@ -89,6 +89,7 @@
 #include <linux/io.h>
 #include <linux/cache.h>
 #include <linux/rodata_test.h>
+#include <linux/jump_label.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -1000,6 +1001,7 @@ static int __ref kernel_init(void *unused)
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();
        ftrace_free_init_mem();
+       jump_label_invalidate_initmem();
        free_initmem();
        mark_readonly();
        system_state = SYSTEM_RUNNING;
index d7f309f74dec243f295e211d60cd76a9088460f9..a808f29d4c5a474bfde180cfa8b73a82843a453d 100644 (file)
@@ -325,9 +325,8 @@ err:
 static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct inode *inode;
-       struct ipc_namespace *ns = data;
+       struct ipc_namespace *ns = sb->s_fs_info;
 
-       sb->s_fs_info = ns;
        sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
        sb->s_blocksize = PAGE_SIZE;
        sb->s_blocksize_bits = PAGE_SHIFT;
@@ -344,44 +343,18 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static struct file_system_type mqueue_fs_type;
-/*
- * Return value is pinned only by reference in ->mq_mnt; it will
- * live until ipcns dies.  Caller does not need to drop it.
- */
-static struct vfsmount *mq_internal_mount(void)
-{
-       struct ipc_namespace *ns = current->nsproxy->ipc_ns;
-       struct vfsmount *m = ns->mq_mnt;
-       if (m)
-               return m;
-       m = kern_mount_data(&mqueue_fs_type, ns);
-       spin_lock(&mq_lock);
-       if (unlikely(ns->mq_mnt)) {
-               spin_unlock(&mq_lock);
-               if (!IS_ERR(m))
-                       kern_unmount(m);
-               return ns->mq_mnt;
-       }
-       if (!IS_ERR(m))
-               ns->mq_mnt = m;
-       spin_unlock(&mq_lock);
-       return m;
-}
-
 static struct dentry *mqueue_mount(struct file_system_type *fs_type,
                         int flags, const char *dev_name,
                         void *data)
 {
-       struct vfsmount *m;
-       if (flags & SB_KERNMOUNT)
-               return mount_nodev(fs_type, flags, data, mqueue_fill_super);
-       m = mq_internal_mount();
-       if (IS_ERR(m))
-               return ERR_CAST(m);
-       atomic_inc(&m->mnt_sb->s_active);
-       down_write(&m->mnt_sb->s_umount);
-       return dget(m->mnt_root);
+       struct ipc_namespace *ns;
+       if (flags & SB_KERNMOUNT) {
+               ns = data;
+               data = NULL;
+       } else {
+               ns = current->nsproxy->ipc_ns;
+       }
+       return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super);
 }
 
 static void init_once(void *foo)
@@ -771,16 +744,13 @@ static int prepare_open(struct dentry *dentry, int oflag, int ro,
 static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
                      struct mq_attr *attr)
 {
-       struct vfsmount *mnt = mq_internal_mount();
-       struct dentry *root;
+       struct vfsmount *mnt = current->nsproxy->ipc_ns->mq_mnt;
+       struct dentry *root = mnt->mnt_root;
        struct filename *name;
        struct path path;
        int fd, error;
        int ro;
 
-       if (IS_ERR(mnt))
-               return PTR_ERR(mnt);
-
        audit_mq_open(oflag, mode, attr);
 
        if (IS_ERR(name = getname(u_name)))
@@ -791,7 +761,6 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
                goto out_putname;
 
        ro = mnt_want_write(mnt);       /* we'll drop it in any case */
-       root = mnt->mnt_root;
        inode_lock(d_inode(root));
        path.dentry = lookup_one_len(name->name, root, strlen(name->name));
        if (IS_ERR(path.dentry)) {
@@ -840,9 +809,6 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
        struct vfsmount *mnt = ipc_ns->mq_mnt;
 
-       if (!mnt)
-               return -ENOENT;
-
        name = getname(u_name);
        if (IS_ERR(name))
                return PTR_ERR(name);
@@ -1569,26 +1535,28 @@ int mq_init_ns(struct ipc_namespace *ns)
        ns->mq_msgsize_max   = DFLT_MSGSIZEMAX;
        ns->mq_msg_default   = DFLT_MSG;
        ns->mq_msgsize_default  = DFLT_MSGSIZE;
-       ns->mq_mnt = NULL;
 
+       ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns);
+       if (IS_ERR(ns->mq_mnt)) {
+               int err = PTR_ERR(ns->mq_mnt);
+               ns->mq_mnt = NULL;
+               return err;
+       }
        return 0;
 }
 
 void mq_clear_sbinfo(struct ipc_namespace *ns)
 {
-       if (ns->mq_mnt)
-               ns->mq_mnt->mnt_sb->s_fs_info = NULL;
+       ns->mq_mnt->mnt_sb->s_fs_info = NULL;
 }
 
 void mq_put_mnt(struct ipc_namespace *ns)
 {
-       if (ns->mq_mnt)
-               kern_unmount(ns->mq_mnt);
+       kern_unmount(ns->mq_mnt);
 }
 
 static int __init init_mqueue_fs(void)
 {
-       struct vfsmount *m;
        int error;
 
        mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache",
@@ -1610,10 +1578,6 @@ static int __init init_mqueue_fs(void)
        if (error)
                goto out_filesystem;
 
-       m = kern_mount_data(&mqueue_fs_type, &init_ipc_ns);
-       if (IS_ERR(m))
-               goto out_filesystem;
-       init_ipc_ns.mq_mnt = m;
        return 0;
 
 out_filesystem:
index b1f66480135b3d8e21fedef41e71e0dfb3ba01c1..14750e7c5ee4872e4a7426e960bea7ae001e6623 100644 (file)
@@ -26,8 +26,10 @@ static void bpf_array_free_percpu(struct bpf_array *array)
 {
        int i;
 
-       for (i = 0; i < array->map.max_entries; i++)
+       for (i = 0; i < array->map.max_entries; i++) {
                free_percpu(array->pptrs[i]);
+               cond_resched();
+       }
 }
 
 static int bpf_array_alloc_percpu(struct bpf_array *array)
@@ -43,6 +45,7 @@ static int bpf_array_alloc_percpu(struct bpf_array *array)
                        return -ENOMEM;
                }
                array->pptrs[i] = ptr;
+               cond_resched();
        }
 
        return 0;
@@ -73,11 +76,11 @@ static int array_map_alloc_check(union bpf_attr *attr)
 static struct bpf_map *array_map_alloc(union bpf_attr *attr)
 {
        bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
-       int numa_node = bpf_map_attr_numa_node(attr);
+       int ret, numa_node = bpf_map_attr_numa_node(attr);
        u32 elem_size, index_mask, max_entries;
        bool unpriv = !capable(CAP_SYS_ADMIN);
+       u64 cost, array_size, mask64;
        struct bpf_array *array;
-       u64 array_size, mask64;
 
        elem_size = round_up(attr->value_size, 8);
 
@@ -109,8 +112,19 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr)
                array_size += (u64) max_entries * elem_size;
 
        /* make sure there is no u32 overflow later in round_up() */
-       if (array_size >= U32_MAX - PAGE_SIZE)
+       cost = array_size;
+       if (cost >= U32_MAX - PAGE_SIZE)
                return ERR_PTR(-ENOMEM);
+       if (percpu) {
+               cost += (u64)attr->max_entries * elem_size * num_possible_cpus();
+               if (cost >= U32_MAX - PAGE_SIZE)
+                       return ERR_PTR(-ENOMEM);
+       }
+       cost = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT;
+
+       ret = bpf_map_precharge_memlock(cost);
+       if (ret < 0)
+               return ERR_PTR(ret);
 
        /* allocate all map elements and zero-initialize them */
        array = bpf_map_area_alloc(array_size, numa_node);
@@ -121,20 +135,13 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr)
 
        /* copy mandatory map attributes */
        bpf_map_init_from_attr(&array->map, attr);
+       array->map.pages = cost;
        array->elem_size = elem_size;
 
-       if (!percpu)
-               goto out;
-
-       array_size += (u64) attr->max_entries * elem_size * num_possible_cpus();
-
-       if (array_size >= U32_MAX - PAGE_SIZE ||
-           bpf_array_alloc_percpu(array)) {
+       if (percpu && bpf_array_alloc_percpu(array)) {
                bpf_map_area_free(array);
                return ERR_PTR(-ENOMEM);
        }
-out:
-       array->map.pages = round_up(array_size, PAGE_SIZE) >> PAGE_SHIFT;
 
        return &array->map;
 }
index 29ca9208dcfadded0633c35387ddb3cd35be6b8b..d315b393abdd0f7dfa67abd706e0f973c3ef2c5a 100644 (file)
@@ -1590,7 +1590,7 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
         * 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);
+       ids = kcalloc(cnt, sizeof(u32), GFP_USER | __GFP_NOWARN);
        if (!ids)
                return -ENOMEM;
        rcu_read_lock();
index fbfdada6caeefa14b65e46e57f965c150a817fba..a4bb0b34375a6c652f49d7719c1bd7e0e02c89e0 100644 (file)
@@ -334,7 +334,7 @@ static int cpu_map_kthread_run(void *data)
 static struct bpf_cpu_map_entry *__cpu_map_entry_alloc(u32 qsize, u32 cpu,
                                                       int map_id)
 {
-       gfp_t gfp = GFP_ATOMIC|__GFP_NOWARN;
+       gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
        struct bpf_cpu_map_entry *rcpu;
        int numa, err;
 
index 7b469d10d0e93a3e6b37fdce57f1e78082c6c9e4..b4b5b81e7251e6fab9530d9d0dd2f343d2045c0e 100644 (file)
@@ -555,7 +555,10 @@ static void trie_free(struct bpf_map *map)
        struct lpm_trie_node __rcu **slot;
        struct lpm_trie_node *node;
 
-       raw_spin_lock(&trie->lock);
+       /* Wait for outstanding programs to complete
+        * update/lookup/delete/get_next_key and free the trie.
+        */
+       synchronize_rcu();
 
        /* Always start at the root and walk down to a node that has no
         * children. Then free that node, nullify its reference in the parent
@@ -566,10 +569,9 @@ static void trie_free(struct bpf_map *map)
                slot = &trie->root;
 
                for (;;) {
-                       node = rcu_dereference_protected(*slot,
-                                       lockdep_is_held(&trie->lock));
+                       node = rcu_dereference_protected(*slot, 1);
                        if (!node)
-                               goto unlock;
+                               goto out;
 
                        if (rcu_access_pointer(node->child[0])) {
                                slot = &node->child[0];
@@ -587,8 +589,8 @@ static void trie_free(struct bpf_map *map)
                }
        }
 
-unlock:
-       raw_spin_unlock(&trie->lock);
+out:
+       kfree(trie);
 }
 
 static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key)
index 48c33417d13c0ad40154f25aeade0c9b4cafd96a..a927e89dad6e9591066c3a87afc497a196ebd887 100644 (file)
@@ -521,8 +521,8 @@ static struct smap_psock *smap_init_psock(struct sock *sock,
 static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
 {
        struct bpf_stab *stab;
-       int err = -EINVAL;
        u64 cost;
+       int err;
 
        if (!capable(CAP_NET_ADMIN))
                return ERR_PTR(-EPERM);
@@ -547,6 +547,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
 
        /* make sure page count doesn't overflow */
        cost = (u64) stab->map.max_entries * sizeof(struct sock *);
+       err = -EINVAL;
        if (cost >= U32_MAX - PAGE_SIZE)
                goto free_stab;
 
index e24aa3241387de91483a89160e50ee41deede775..43f95d190eeaf8eb81ac64e2712d449662c35eb7 100644 (file)
@@ -1845,7 +1845,7 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
        union bpf_attr attr = {};
        int err;
 
-       if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
+       if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
                return -EPERM;
 
        err = check_uarg_tail_zero(uattr, sizeof(attr), size);
index 5fb69a85d9675dcf8a077d20f5314ee78949e884..c6eff108aa998721512fce01ab98ba31b3f1b92b 100644 (file)
@@ -1356,6 +1356,13 @@ static bool is_ctx_reg(struct bpf_verifier_env *env, int regno)
        return reg->type == PTR_TO_CTX;
 }
 
+static bool is_pkt_reg(struct bpf_verifier_env *env, int regno)
+{
+       const struct bpf_reg_state *reg = cur_regs(env) + regno;
+
+       return type_is_pkt_pointer(reg->type);
+}
+
 static int check_pkt_ptr_alignment(struct bpf_verifier_env *env,
                                   const struct bpf_reg_state *reg,
                                   int off, int size, bool strict)
@@ -1416,10 +1423,10 @@ static int check_generic_ptr_alignment(struct bpf_verifier_env *env,
 }
 
 static int check_ptr_alignment(struct bpf_verifier_env *env,
-                              const struct bpf_reg_state *reg,
-                              int off, int size)
+                              const struct bpf_reg_state *reg, int off,
+                              int size, bool strict_alignment_once)
 {
-       bool strict = env->strict_alignment;
+       bool strict = env->strict_alignment || strict_alignment_once;
        const char *pointer_desc = "";
 
        switch (reg->type) {
@@ -1576,9 +1583,9 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
  * if t==write && value_regno==-1, some unknown value is stored into memory
  * if t==read && value_regno==-1, don't care what we read from memory
  */
-static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno, int off,
-                           int bpf_size, enum bpf_access_type t,
-                           int value_regno)
+static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno,
+                           int off, int bpf_size, enum bpf_access_type t,
+                           int value_regno, bool strict_alignment_once)
 {
        struct bpf_reg_state *regs = cur_regs(env);
        struct bpf_reg_state *reg = regs + regno;
@@ -1590,7 +1597,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
                return size;
 
        /* alignment checks will add in reg->off themselves */
-       err = check_ptr_alignment(env, reg, off, size);
+       err = check_ptr_alignment(env, reg, off, size, strict_alignment_once);
        if (err)
                return err;
 
@@ -1735,21 +1742,23 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins
                return -EACCES;
        }
 
-       if (is_ctx_reg(env, insn->dst_reg)) {
-               verbose(env, "BPF_XADD stores into R%d context is not allowed\n",
-                       insn->dst_reg);
+       if (is_ctx_reg(env, insn->dst_reg) ||
+           is_pkt_reg(env, insn->dst_reg)) {
+               verbose(env, "BPF_XADD stores into R%d %s is not allowed\n",
+                       insn->dst_reg, is_ctx_reg(env, insn->dst_reg) ?
+                       "context" : "packet");
                return -EACCES;
        }
 
        /* check whether atomic_add can read the memory */
        err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
-                              BPF_SIZE(insn->code), BPF_READ, -1);
+                              BPF_SIZE(insn->code), BPF_READ, -1, true);
        if (err)
                return err;
 
        /* check whether atomic_add can write into the same memory */
        return check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
-                               BPF_SIZE(insn->code), BPF_WRITE, -1);
+                               BPF_SIZE(insn->code), BPF_WRITE, -1, true);
 }
 
 /* when register 'regno' is passed into function that will read 'access_size'
@@ -2388,7 +2397,8 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
         * is inferred from register state.
         */
        for (i = 0; i < meta.access_size; i++) {
-               err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B, BPF_WRITE, -1);
+               err = check_mem_access(env, insn_idx, meta.regno, i, BPF_B,
+                                      BPF_WRITE, -1, false);
                if (err)
                        return err;
        }
@@ -4632,7 +4642,7 @@ static int do_check(struct bpf_verifier_env *env)
                         */
                        err = check_mem_access(env, insn_idx, insn->src_reg, insn->off,
                                               BPF_SIZE(insn->code), BPF_READ,
-                                              insn->dst_reg);
+                                              insn->dst_reg, false);
                        if (err)
                                return err;
 
@@ -4684,7 +4694,7 @@ static int do_check(struct bpf_verifier_env *env)
                        /* check that memory (dst_reg + off) is writeable */
                        err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
                                               BPF_SIZE(insn->code), BPF_WRITE,
-                                              insn->src_reg);
+                                              insn->src_reg, false);
                        if (err)
                                return err;
 
@@ -4719,7 +4729,7 @@ static int do_check(struct bpf_verifier_env *env)
                        /* check that memory (dst_reg + off) is writeable */
                        err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
                                               BPF_SIZE(insn->code), BPF_WRITE,
-                                              -1);
+                                              -1, false);
                        if (err)
                                return err;
 
index 8cda3bc3ae22841f9c3a9478ae65cadba6b65f66..4bfb2908ec157204692424bc1b1a32a7ef185b29 100644 (file)
@@ -3183,6 +3183,16 @@ static int cgroup_enable_threaded(struct cgroup *cgrp)
        if (cgroup_is_threaded(cgrp))
                return 0;
 
+       /*
+        * If @cgroup is populated or has domain controllers enabled, it
+        * can't be switched.  While the below cgroup_can_be_thread_root()
+        * test can catch the same conditions, that's only when @parent is
+        * not mixable, so let's check it explicitly.
+        */
+       if (cgroup_is_populated(cgrp) ||
+           cgrp->subtree_control & ~cgrp_dfl_threaded_ss_mask)
+               return -EOPNOTSUPP;
+
        /* we're joining the parent's domain, ensure its validity */
        if (!cgroup_is_valid_domain(dom_cgrp) ||
            !cgroup_can_be_thread_root(dom_cgrp))
index 3247fe761f6018ef61ecb37124720f3fa092d441..3f5fa8902e7dc72096ab1c8da3f3638ac6dc32db 100644 (file)
@@ -488,25 +488,6 @@ get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat)
 }
 EXPORT_SYMBOL_GPL(get_compat_sigset);
 
-int
-put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
-                 unsigned int size)
-{
-       /* size <= sizeof(compat_sigset_t) <= sizeof(sigset_t) */
-#ifdef __BIG_ENDIAN
-       compat_sigset_t v;
-       switch (_NSIG_WORDS) {
-       case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
-       case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2];
-       case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1];
-       case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0];
-       }
-       return copy_to_user(compat, &v, size) ? -EFAULT : 0;
-#else
-       return copy_to_user(compat, set, size) ? -EFAULT : 0;
-#endif
-}
-
 #ifdef CONFIG_NUMA
 COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
                       compat_uptr_t __user *, pages32,
index 96db9ae5d5af751edd61189407aa064d591b54dd..709a55b9ad97341b44e8dfe6e14a84ba69fd22ab 100644 (file)
@@ -724,9 +724,15 @@ static inline void __update_cgrp_time(struct perf_cgroup *cgrp)
 
 static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx)
 {
-       struct perf_cgroup *cgrp_out = cpuctx->cgrp;
-       if (cgrp_out)
-               __update_cgrp_time(cgrp_out);
+       struct perf_cgroup *cgrp = cpuctx->cgrp;
+       struct cgroup_subsys_state *css;
+
+       if (cgrp) {
+               for (css = &cgrp->css; css; css = css->parent) {
+                       cgrp = container_of(css, struct perf_cgroup, css);
+                       __update_cgrp_time(cgrp);
+               }
+       }
 }
 
 static inline void update_cgrp_time_from_event(struct perf_event *event)
@@ -754,6 +760,7 @@ perf_cgroup_set_timestamp(struct task_struct *task,
 {
        struct perf_cgroup *cgrp;
        struct perf_cgroup_info *info;
+       struct cgroup_subsys_state *css;
 
        /*
         * ctx->lock held by caller
@@ -764,8 +771,12 @@ perf_cgroup_set_timestamp(struct task_struct *task,
                return;
 
        cgrp = perf_cgroup_from_task(task, ctx);
-       info = this_cpu_ptr(cgrp->info);
-       info->timestamp = ctx->timestamp;
+
+       for (css = &cgrp->css; css; css = css->parent) {
+               cgrp = container_of(css, struct perf_cgroup, css);
+               info = this_cpu_ptr(cgrp->info);
+               info->timestamp = ctx->timestamp;
+       }
 }
 
 static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list);
@@ -2246,7 +2257,7 @@ static void ctx_resched(struct perf_cpu_context *cpuctx,
                        struct perf_event_context *task_ctx,
                        enum event_type_t event_type)
 {
-       enum event_type_t ctx_event_type = event_type & EVENT_ALL;
+       enum event_type_t ctx_event_type;
        bool cpu_event = !!(event_type & EVENT_CPU);
 
        /*
@@ -2256,6 +2267,8 @@ static void ctx_resched(struct perf_cpu_context *cpuctx,
        if (event_type & EVENT_PINNED)
                event_type |= EVENT_FLEXIBLE;
 
+       ctx_event_type = event_type & EVENT_ALL;
+
        perf_pmu_disable(cpuctx->ctx.pmu);
        if (task_ctx)
                task_ctx_sched_out(cpuctx, task_ctx, event_type);
index a17fdb63dc3e470955dcfd5e5861920b9db2749f..6a5b61ebc66c956e6eeee6537786f4161d98f2ef 100644 (file)
@@ -64,7 +64,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr)
        return e;
 }
 
-static inline int init_kernel_text(unsigned long addr)
+int init_kernel_text(unsigned long addr)
 {
        if (addr >= (unsigned long)_sinittext &&
            addr < (unsigned long)_einittext)
index 21b0122cb39cb1c8f45976566e3b4f675d50450c..1d5632d8bbccfd941a6b0b1cf0ac380c4aeb0a5c 100644 (file)
 
 static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs);
 
+static void fei_post_handler(struct kprobe *kp, struct pt_regs *regs,
+                            unsigned long flags)
+{
+       /*
+        * A dummy post handler is required to prohibit optimizing, because
+        * jump optimization does not support execution path overriding.
+        */
+}
+
 struct fei_attr {
        struct list_head list;
        struct kprobe kp;
@@ -56,6 +65,7 @@ static struct fei_attr *fei_attr_new(const char *sym, unsigned long addr)
                        return NULL;
                }
                attr->kp.pre_handler = fei_kprobe_handler;
+               attr->kp.post_handler = fei_post_handler;
                attr->retval = adjust_error_retval(addr, 0);
                INIT_LIST_HEAD(&attr->list);
        }
index be8aa5b986662bb2164e508bdb59cf39a81d3f0a..e5d9d405ae4e55ce862318a152609cd80e7e0c6e 100644 (file)
@@ -592,7 +592,7 @@ static void check_mm(struct mm_struct *mm)
  * is dropped: either by a lazy thread or by
  * mmput. Free the page directory and the mm.
  */
-static void __mmdrop(struct mm_struct *mm)
+void __mmdrop(struct mm_struct *mm)
 {
        BUG_ON(mm == &init_mm);
        mm_free_pgd(mm);
@@ -603,18 +603,7 @@ static void __mmdrop(struct mm_struct *mm)
        put_user_ns(mm->user_ns);
        free_mm(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);
-}
-EXPORT_SYMBOL_GPL(mmdrop);
+EXPORT_SYMBOL_GPL(__mmdrop);
 
 static void mmdrop_async_fn(struct work_struct *work)
 {
index e6a9c36470ee93ff524fb93e24fdfced8b057582..82b8b18ee1ebcdf19e873b5bb3d4ab9f2748f539 100644 (file)
@@ -1726,25 +1726,14 @@ static int irq_domain_debug_show(struct seq_file *m, void *p)
        irq_domain_debug_show_one(m, d, 0);
        return 0;
 }
-
-static int irq_domain_debug_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, irq_domain_debug_show, inode->i_private);
-}
-
-static const struct file_operations dfs_domain_ops = {
-       .open           = irq_domain_debug_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(irq_domain_debug);
 
 static void debugfs_add_domain_dir(struct irq_domain *d)
 {
        if (!d->name || !domain_dir || d->debugfs_file)
                return;
        d->debugfs_file = debugfs_create_file(d->name, 0444, domain_dir, d,
-                                             &dfs_domain_ops);
+                                             &irq_domain_debug_fops);
 }
 
 static void debugfs_remove_domain_dir(struct irq_domain *d)
@@ -1760,7 +1749,8 @@ void __init irq_domain_debugfs_init(struct dentry *root)
        if (!domain_dir)
                return;
 
-       debugfs_create_file("default", 0444, domain_dir, NULL, &dfs_domain_ops);
+       debugfs_create_file("default", 0444, domain_dir, NULL,
+                           &irq_domain_debug_fops);
        mutex_lock(&irq_domain_mutex);
        list_for_each_entry(d, &irq_domain_list, link)
                debugfs_add_domain_dir(d);
index 5187dfe809ac46eede7a8163bd86a88e8a186379..4c5770407031f083dae0a6fcbc3f20abb8a30146 100644 (file)
@@ -16,6 +16,7 @@ struct cpumap {
        unsigned int            available;
        unsigned int            allocated;
        unsigned int            managed;
+       bool                    initialized;
        bool                    online;
        unsigned long           alloc_map[IRQ_MATRIX_SIZE];
        unsigned long           managed_map[IRQ_MATRIX_SIZE];
@@ -81,9 +82,11 @@ void irq_matrix_online(struct irq_matrix *m)
 
        BUG_ON(cm->online);
 
-       bitmap_zero(cm->alloc_map, m->matrix_bits);
-       cm->available = m->alloc_size - (cm->managed + m->systembits_inalloc);
-       cm->allocated = 0;
+       if (!cm->initialized) {
+               cm->available = m->alloc_size;
+               cm->available -= cm->managed + m->systembits_inalloc;
+               cm->initialized = true;
+       }
        m->global_available += cm->available;
        cm->online = true;
        m->online_maps++;
@@ -370,14 +373,16 @@ void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
        if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end))
                return;
 
-       if (cm->online) {
-               clear_bit(bit, cm->alloc_map);
-               cm->allocated--;
+       clear_bit(bit, cm->alloc_map);
+       cm->allocated--;
+
+       if (cm->online)
                m->total_allocated--;
-               if (!managed) {
-                       cm->available++;
+
+       if (!managed) {
+               cm->available++;
+               if (cm->online)
                        m->global_available++;
-               }
        }
        trace_irq_matrix_free(bit, cpu, m, cm);
 }
index b4517095db6af2f5130e6c871a7a9e32884c2a66..01ebdf1f9f40eb0b56810244bd115a62d07e88f2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/jump_label_ratelimit.h>
 #include <linux/bug.h>
 #include <linux/cpu.h>
+#include <asm/sections.h>
 
 #ifdef HAVE_JUMP_LABEL
 
@@ -366,12 +367,16 @@ static void __jump_label_update(struct static_key *key,
 {
        for (; (entry < stop) && (jump_entry_key(entry) == key); entry++) {
                /*
-                * entry->code set to 0 invalidates module init text sections
-                * kernel_text_address() verifies we are not in core kernel
-                * init code, see jump_label_invalidate_module_init().
+                * An entry->code of 0 indicates an entry which has been
+                * disabled because it was in an init text area.
                 */
-               if (entry->code && kernel_text_address(entry->code))
-                       arch_jump_label_transform(entry, jump_label_type(entry));
+               if (entry->code) {
+                       if (kernel_text_address(entry->code))
+                               arch_jump_label_transform(entry, jump_label_type(entry));
+                       else
+                               WARN_ONCE(1, "can't patch jump_label at %pS",
+                                         (void *)(unsigned long)entry->code);
+               }
        }
 }
 
@@ -417,6 +422,19 @@ void __init jump_label_init(void)
        cpus_read_unlock();
 }
 
+/* Disable any jump label entries in __init/__exit code */
+void __init jump_label_invalidate_initmem(void)
+{
+       struct jump_entry *iter_start = __start___jump_table;
+       struct jump_entry *iter_stop = __stop___jump_table;
+       struct jump_entry *iter;
+
+       for (iter = iter_start; iter < iter_stop; iter++) {
+               if (init_section_contains((void *)(unsigned long)iter->code, 1))
+                       iter->code = 0;
+       }
+}
+
 #ifdef CONFIG_MODULES
 
 static enum jump_label_type jump_label_init_type(struct jump_entry *entry)
@@ -633,6 +651,7 @@ static void jump_label_del_module(struct module *mod)
        }
 }
 
+/* Disable any jump label entries in module init code */
 static void jump_label_invalidate_module_init(struct module *mod)
 {
        struct jump_entry *iter_start = mod->jump_entries;
index da2ccf14235814df4dc4b21509500d0d777cacb4..102160ff5c661e475e773888bfc3267d832bd4d6 100644 (file)
@@ -978,67 +978,90 @@ static int prepare_kprobe(struct kprobe *p)
 }
 
 /* Caller must lock kprobe_mutex */
-static void arm_kprobe_ftrace(struct kprobe *p)
+static int arm_kprobe_ftrace(struct kprobe *p)
 {
-       int ret;
+       int ret = 0;
 
        ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
                                   (unsigned long)p->addr, 0, 0);
-       WARN(ret < 0, "Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret);
-       kprobe_ftrace_enabled++;
-       if (kprobe_ftrace_enabled == 1) {
+       if (ret) {
+               pr_debug("Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret);
+               return ret;
+       }
+
+       if (kprobe_ftrace_enabled == 0) {
                ret = register_ftrace_function(&kprobe_ftrace_ops);
-               WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
+               if (ret) {
+                       pr_debug("Failed to init kprobe-ftrace (%d)\n", ret);
+                       goto err_ftrace;
+               }
        }
+
+       kprobe_ftrace_enabled++;
+       return ret;
+
+err_ftrace:
+       /*
+        * Note: Since kprobe_ftrace_ops has IPMODIFY set, and ftrace requires a
+        * non-empty filter_hash for IPMODIFY ops, we're safe from an accidental
+        * empty filter_hash which would undesirably trace all functions.
+        */
+       ftrace_set_filter_ip(&kprobe_ftrace_ops, (unsigned long)p->addr, 1, 0);
+       return ret;
 }
 
 /* Caller must lock kprobe_mutex */
-static void disarm_kprobe_ftrace(struct kprobe *p)
+static int disarm_kprobe_ftrace(struct kprobe *p)
 {
-       int ret;
+       int ret = 0;
 
-       kprobe_ftrace_enabled--;
-       if (kprobe_ftrace_enabled == 0) {
+       if (kprobe_ftrace_enabled == 1) {
                ret = unregister_ftrace_function(&kprobe_ftrace_ops);
-               WARN(ret < 0, "Failed to init kprobe-ftrace (%d)\n", ret);
+               if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", ret))
+                       return ret;
        }
+
+       kprobe_ftrace_enabled--;
+
        ret = ftrace_set_filter_ip(&kprobe_ftrace_ops,
                           (unsigned long)p->addr, 1, 0);
        WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, ret);
+       return ret;
 }
 #else  /* !CONFIG_KPROBES_ON_FTRACE */
 #define prepare_kprobe(p)      arch_prepare_kprobe(p)
-#define arm_kprobe_ftrace(p)   do {} while (0)
-#define disarm_kprobe_ftrace(p)        do {} while (0)
+#define arm_kprobe_ftrace(p)   (-ENODEV)
+#define disarm_kprobe_ftrace(p)        (-ENODEV)
 #endif
 
 /* Arm a kprobe with text_mutex */
-static void arm_kprobe(struct kprobe *kp)
+static int arm_kprobe(struct kprobe *kp)
 {
-       if (unlikely(kprobe_ftrace(kp))) {
-               arm_kprobe_ftrace(kp);
-               return;
-       }
+       if (unlikely(kprobe_ftrace(kp)))
+               return arm_kprobe_ftrace(kp);
+
        cpus_read_lock();
        mutex_lock(&text_mutex);
        __arm_kprobe(kp);
        mutex_unlock(&text_mutex);
        cpus_read_unlock();
+
+       return 0;
 }
 
 /* Disarm a kprobe with text_mutex */
-static void disarm_kprobe(struct kprobe *kp, bool reopt)
+static int disarm_kprobe(struct kprobe *kp, bool reopt)
 {
-       if (unlikely(kprobe_ftrace(kp))) {
-               disarm_kprobe_ftrace(kp);
-               return;
-       }
+       if (unlikely(kprobe_ftrace(kp)))
+               return disarm_kprobe_ftrace(kp);
 
        cpus_read_lock();
        mutex_lock(&text_mutex);
        __disarm_kprobe(kp, reopt);
        mutex_unlock(&text_mutex);
        cpus_read_unlock();
+
+       return 0;
 }
 
 /*
@@ -1362,9 +1385,15 @@ out:
 
        if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) {
                ap->flags &= ~KPROBE_FLAG_DISABLED;
-               if (!kprobes_all_disarmed)
+               if (!kprobes_all_disarmed) {
                        /* Arm the breakpoint again. */
-                       arm_kprobe(ap);
+                       ret = arm_kprobe(ap);
+                       if (ret) {
+                               ap->flags |= KPROBE_FLAG_DISABLED;
+                               list_del_rcu(&p->list);
+                               synchronize_sched();
+                       }
+               }
        }
        return ret;
 }
@@ -1573,8 +1602,14 @@ int register_kprobe(struct kprobe *p)
        hlist_add_head_rcu(&p->hlist,
                       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
 
-       if (!kprobes_all_disarmed && !kprobe_disabled(p))
-               arm_kprobe(p);
+       if (!kprobes_all_disarmed && !kprobe_disabled(p)) {
+               ret = arm_kprobe(p);
+               if (ret) {
+                       hlist_del_rcu(&p->hlist);
+                       synchronize_sched();
+                       goto out;
+               }
+       }
 
        /* Try to optimize kprobe */
        try_to_optimize_kprobe(p);
@@ -1608,11 +1643,12 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
 static struct kprobe *__disable_kprobe(struct kprobe *p)
 {
        struct kprobe *orig_p;
+       int ret;
 
        /* Get an original kprobe for return */
        orig_p = __get_valid_kprobe(p);
        if (unlikely(orig_p == NULL))
-               return NULL;
+               return ERR_PTR(-EINVAL);
 
        if (!kprobe_disabled(p)) {
                /* Disable probe if it is a child probe */
@@ -1626,8 +1662,13 @@ static struct kprobe *__disable_kprobe(struct kprobe *p)
                         * should have already been disarmed, so
                         * skip unneed disarming process.
                         */
-                       if (!kprobes_all_disarmed)
-                               disarm_kprobe(orig_p, true);
+                       if (!kprobes_all_disarmed) {
+                               ret = disarm_kprobe(orig_p, true);
+                               if (ret) {
+                                       p->flags &= ~KPROBE_FLAG_DISABLED;
+                                       return ERR_PTR(ret);
+                               }
+                       }
                        orig_p->flags |= KPROBE_FLAG_DISABLED;
                }
        }
@@ -1644,8 +1685,8 @@ static int __unregister_kprobe_top(struct kprobe *p)
 
        /* Disable kprobe. This will disarm it if needed. */
        ap = __disable_kprobe(p);
-       if (ap == NULL)
-               return -EINVAL;
+       if (IS_ERR(ap))
+               return PTR_ERR(ap);
 
        if (ap == p)
                /*
@@ -2078,12 +2119,14 @@ static void kill_kprobe(struct kprobe *p)
 int disable_kprobe(struct kprobe *kp)
 {
        int ret = 0;
+       struct kprobe *p;
 
        mutex_lock(&kprobe_mutex);
 
        /* Disable this kprobe */
-       if (__disable_kprobe(kp) == NULL)
-               ret = -EINVAL;
+       p = __disable_kprobe(kp);
+       if (IS_ERR(p))
+               ret = PTR_ERR(p);
 
        mutex_unlock(&kprobe_mutex);
        return ret;
@@ -2116,7 +2159,9 @@ int enable_kprobe(struct kprobe *kp)
 
        if (!kprobes_all_disarmed && kprobe_disabled(p)) {
                p->flags &= ~KPROBE_FLAG_DISABLED;
-               arm_kprobe(p);
+               ret = arm_kprobe(p);
+               if (ret)
+                       p->flags |= KPROBE_FLAG_DISABLED;
        }
 out:
        mutex_unlock(&kprobe_mutex);
@@ -2407,11 +2452,12 @@ static const struct file_operations debugfs_kprobe_blacklist_ops = {
        .release        = seq_release,
 };
 
-static void arm_all_kprobes(void)
+static int arm_all_kprobes(void)
 {
        struct hlist_head *head;
        struct kprobe *p;
-       unsigned int i;
+       unsigned int i, total = 0, errors = 0;
+       int err, ret = 0;
 
        mutex_lock(&kprobe_mutex);
 
@@ -2428,46 +2474,74 @@ static void arm_all_kprobes(void)
        /* Arming kprobes doesn't optimize kprobe itself */
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, head, hlist)
-                       if (!kprobe_disabled(p))
-                               arm_kprobe(p);
+               /* Arm all kprobes on a best-effort basis */
+               hlist_for_each_entry_rcu(p, head, hlist) {
+                       if (!kprobe_disabled(p)) {
+                               err = arm_kprobe(p);
+                               if (err)  {
+                                       errors++;
+                                       ret = err;
+                               }
+                               total++;
+                       }
+               }
        }
 
-       printk(KERN_INFO "Kprobes globally enabled\n");
+       if (errors)
+               pr_warn("Kprobes globally enabled, but failed to arm %d out of %d probes\n",
+                       errors, total);
+       else
+               pr_info("Kprobes globally enabled\n");
 
 already_enabled:
        mutex_unlock(&kprobe_mutex);
-       return;
+       return ret;
 }
 
-static void disarm_all_kprobes(void)
+static int disarm_all_kprobes(void)
 {
        struct hlist_head *head;
        struct kprobe *p;
-       unsigned int i;
+       unsigned int i, total = 0, errors = 0;
+       int err, ret = 0;
 
        mutex_lock(&kprobe_mutex);
 
        /* If kprobes are already disarmed, just return */
        if (kprobes_all_disarmed) {
                mutex_unlock(&kprobe_mutex);
-               return;
+               return 0;
        }
 
        kprobes_all_disarmed = true;
-       printk(KERN_INFO "Kprobes globally disabled\n");
 
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
+               /* Disarm all kprobes on a best-effort basis */
                hlist_for_each_entry_rcu(p, head, hlist) {
-                       if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p))
-                               disarm_kprobe(p, false);
+                       if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) {
+                               err = disarm_kprobe(p, false);
+                               if (err) {
+                                       errors++;
+                                       ret = err;
+                               }
+                               total++;
+                       }
                }
        }
+
+       if (errors)
+               pr_warn("Kprobes globally disabled, but failed to disarm %d out of %d probes\n",
+                       errors, total);
+       else
+               pr_info("Kprobes globally disabled\n");
+
        mutex_unlock(&kprobe_mutex);
 
        /* Wait for disarming all kprobes by optimizer */
        wait_for_kprobe_optimizer();
+
+       return ret;
 }
 
 /*
@@ -2494,6 +2568,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
 {
        char buf[32];
        size_t buf_size;
+       int ret = 0;
 
        buf_size = min(count, (sizeof(buf)-1));
        if (copy_from_user(buf, user_buf, buf_size))
@@ -2504,17 +2579,20 @@ static ssize_t write_enabled_file_bool(struct file *file,
        case 'y':
        case 'Y':
        case '1':
-               arm_all_kprobes();
+               ret = arm_all_kprobes();
                break;
        case 'n':
        case 'N':
        case '0':
-               disarm_all_kprobes();
+               ret = disarm_all_kprobes();
                break;
        default:
                return -EINVAL;
        }
 
+       if (ret)
+               return ret;
+
        return count;
 }
 
index 858a07590e39d913ab3aebfdaad34c0730eb8c12..2048359f33d24785f15bb73228edd219b1b5f7fa 100644 (file)
@@ -1082,15 +1082,16 @@ static noinline int __sched
 __mutex_lock_interruptible_slowpath(struct mutex *lock);
 
 /**
- * mutex_lock_interruptible - acquire the mutex, interruptible
- * @lock: the mutex to be acquired
+ * mutex_lock_interruptible() - Acquire the mutex, interruptible by signals.
+ * @lock: The mutex to be acquired.
  *
- * Lock the mutex like mutex_lock(), and return 0 if the mutex has
- * been acquired or sleep until the mutex becomes available. If a
- * signal arrives while waiting for the lock then this function
- * returns -EINTR.
+ * Lock the mutex like mutex_lock().  If a signal is delivered while the
+ * process is sleeping, this function will return without acquiring the
+ * mutex.
  *
- * This function is similar to (but not equivalent to) down_interruptible().
+ * Context: Process context.
+ * Return: 0 if the lock was successfully acquired or %-EINTR if a
+ * signal arrived.
  */
 int __sched mutex_lock_interruptible(struct mutex *lock)
 {
@@ -1104,6 +1105,18 @@ int __sched mutex_lock_interruptible(struct mutex *lock)
 
 EXPORT_SYMBOL(mutex_lock_interruptible);
 
+/**
+ * mutex_lock_killable() - Acquire the mutex, interruptible by fatal signals.
+ * @lock: The mutex to be acquired.
+ *
+ * Lock the mutex like mutex_lock().  If a signal which will be fatal to
+ * the current process is delivered while the process is sleeping, this
+ * function will return without acquiring the mutex.
+ *
+ * Context: Process context.
+ * Return: 0 if the lock was successfully acquired or %-EINTR if a
+ * fatal signal arrived.
+ */
 int __sched mutex_lock_killable(struct mutex *lock)
 {
        might_sleep();
@@ -1115,6 +1128,16 @@ int __sched mutex_lock_killable(struct mutex *lock)
 }
 EXPORT_SYMBOL(mutex_lock_killable);
 
+/**
+ * mutex_lock_io() - Acquire the mutex and mark the process as waiting for I/O
+ * @lock: The mutex to be acquired.
+ *
+ * Lock the mutex like mutex_lock().  While the task is waiting for this
+ * mutex, it will be accounted as being in the IO wait state by the
+ * scheduler.
+ *
+ * Context: Process context.
+ */
 void __sched mutex_lock_io(struct mutex *lock)
 {
        int token;
index 38ece035039e35bf997e4161ec8e84cceaf4508f..d880296245c5954c432c539e2f14f3ade1c4719b 100644 (file)
@@ -379,6 +379,14 @@ queue:
        tail = encode_tail(smp_processor_id(), idx);
 
        node += idx;
+
+       /*
+        * Ensure that we increment the head node->count before initialising
+        * the actual node. If the compiler is kind enough to reorder these
+        * stores, then an IRQ could overwrite our assignments.
+        */
+       barrier();
+
        node->locked = 0;
        node->next = NULL;
        pv_init_node(node);
@@ -408,14 +416,15 @@ queue:
         */
        if (old & _Q_TAIL_MASK) {
                prev = decode_tail(old);
+
                /*
-                * The above xchg_tail() is also a load of @lock which
-                * generates, through decode_tail(), a pointer.  The address
-                * dependency matches the RELEASE of xchg_tail() such that
-                * the subsequent access to @prev happens after.
+                * We must ensure that the stores to @node are observed before
+                * the write to prev->next. The address dependency from
+                * xchg_tail is not sufficient to ensure this because the read
+                * component of xchg_tail is unordered with respect to the
+                * initialisation of @node.
                 */
-
-               WRITE_ONCE(prev->next, node);
+               smp_store_release(&prev->next, node);
 
                pv_wait_node(node, prev);
                arch_mcs_spin_lock_contended(&node->locked);
index 65cc0cb984e6aef64211da9ff693b4dc67968103..940633c632541d7aa31eb68ef7c271f17bb86369 100644 (file)
@@ -1616,11 +1616,12 @@ bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock,
 void __sched rt_mutex_futex_unlock(struct rt_mutex *lock)
 {
        DEFINE_WAKE_Q(wake_q);
+       unsigned long flags;
        bool postunlock;
 
-       raw_spin_lock_irq(&lock->wait_lock);
+       raw_spin_lock_irqsave(&lock->wait_lock, flags);
        postunlock = __rt_mutex_futex_unlock(lock, &wake_q);
-       raw_spin_unlock_irq(&lock->wait_lock);
+       raw_spin_unlock_irqrestore(&lock->wait_lock, flags);
 
        if (postunlock)
                rt_mutex_postunlock(&wake_q);
index 4849be5f9b3c30120f0f964dfd32f5bbf1546a54..895e6b76b25e0604b980e31fa8dba388b25e6581 100644 (file)
@@ -275,8 +275,15 @@ static unsigned long pfn_end(struct dev_pagemap *pgmap)
        return (res->start + resource_size(res)) >> PAGE_SHIFT;
 }
 
+static unsigned long pfn_next(unsigned long pfn)
+{
+       if (pfn % 1024 == 0)
+               cond_resched();
+       return pfn + 1;
+}
+
 #define for_each_device_pfn(pfn, map) \
-       for (pfn = pfn_first(map); pfn < pfn_end(map); pfn++)
+       for (pfn = pfn_first(map); pfn < pfn_end(map); pfn = pfn_next(pfn))
 
 static void devm_memremap_pages_release(void *data)
 {
@@ -337,10 +344,10 @@ 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;
+       struct resource *res = &pgmap->res;
        unsigned long pfn, pgoff, order;
        pgprot_t pgprot = PAGE_KERNEL;
-       int error, nid, is_ram, i = 0;
-       struct resource *res = &pgmap->res;
+       int error, nid, is_ram;
 
        align_start = res->start & ~(SECTION_SIZE - 1);
        align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
@@ -409,8 +416,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
                list_del(&page->lru);
                page->pgmap = pgmap;
                percpu_ref_get(pgmap->ref);
-               if (!(++i % 1024))
-                       cond_resched();
        }
 
        devm_add_action(dev, devm_memremap_pages_release, pgmap);
@@ -422,7 +427,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
  err_pfn_remap:
  err_radix:
        pgmap_radix_release(res, pgoff);
-       devres_free(pgmap);
        return ERR_PTR(error);
 }
 EXPORT_SYMBOL(devm_memremap_pages);
index ad2d420024f6d01086f07b47e60fd1fbde0ff1dc..e42764acedb4cd35ccb81d396b1391510b52db25 100644 (file)
@@ -4228,7 +4228,7 @@ static int modules_open(struct inode *inode, struct file *file)
                m->private = kallsyms_show_value() ? NULL : (void *)8ul;
        }
 
-       return 0;
+       return err;
 }
 
 static const struct file_operations proc_modules_operations = {
index 2cfef408fec931ac0ef3f3c95b31269ed1d3ea29..4b794f1d85613578bd10bc07d78a3d746a8f0db9 100644 (file)
@@ -640,7 +640,7 @@ device_initcall(register_warn_debugfs);
  */
 __visible void __stack_chk_fail(void)
 {
-       panic("stack-protector: Kernel stack is corrupted in: %p\n",
+       panic("stack-protector: Kernel stack is corrupted in: %pB\n",
                __builtin_return_address(0));
 }
 EXPORT_SYMBOL(__stack_chk_fail);
index fc1123583fa6edadb19214bb1922f7ce4ccdf1e1..f274fbef821d1bee0c457da42417f4b8153444cf 100644 (file)
@@ -2397,7 +2397,7 @@ skip:
 
                if (console_lock_spinning_disable_and_check()) {
                        printk_safe_exit_irqrestore(flags);
-                       return;
+                       goto out;
                }
 
                printk_safe_exit_irqrestore(flags);
@@ -2430,6 +2430,7 @@ skip:
        if (retry && console_trylock())
                goto again;
 
+out:
        if (wake_klogd)
                wake_up_klogd();
 }
index c3029402f15c3367bdd3d59210eee471b6bb41c0..c955b10c973c0444ec491c7e6b3779b77fe1fa15 100644 (file)
@@ -163,7 +163,7 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan)
 {
        struct rchan_buf *buf;
 
-       if (chan->n_subbufs > UINT_MAX / sizeof(size_t *))
+       if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
                return NULL;
 
        buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
index bf724c1952eaca3b1eb7cb6bf83b2fa436068f4d..c94895bc5a2c14dc05117a7050fb9b3964db0357 100644 (file)
@@ -2601,19 +2601,31 @@ static inline void finish_task(struct task_struct *prev)
 #endif
 }
 
-static inline void finish_lock_switch(struct rq *rq)
+static inline void
+prepare_lock_switch(struct rq *rq, struct task_struct *next, struct rq_flags *rf)
 {
+       /*
+        * Since the runqueue lock will be released by the next
+        * task (which is an invalid locking op but in the case
+        * of the scheduler it's an obvious special-case), so we
+        * do an early lockdep release here:
+        */
+       rq_unpin_lock(rq, rf);
+       spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
 #ifdef CONFIG_DEBUG_SPINLOCK
        /* this is a valid case when another task releases the spinlock */
-       rq->lock.owner = current;
+       rq->lock.owner = next;
 #endif
+}
+
+static inline void finish_lock_switch(struct rq *rq)
+{
        /*
         * If we are tracking spinlock dependencies then we have to
         * fix up the runqueue lock - which gets 'carried over' from
         * prev into current:
         */
        spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_);
-
        raw_spin_unlock_irq(&rq->lock);
 }
 
@@ -2844,14 +2856,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
 
        rq->clock_update_flags &= ~(RQCF_ACT_SKIP|RQCF_REQ_SKIP);
 
-       /*
-        * Since the runqueue lock will be released by the next
-        * task (which is an invalid locking op but in the case
-        * of the scheduler it's an obvious special-case), so we
-        * do an early lockdep release here:
-        */
-       rq_unpin_lock(rq, rf);
-       spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
+       prepare_lock_switch(rq, next, rf);
 
        /* Here we just switch the register state and the stack. */
        switch_to(prev, next, prev);
@@ -6678,13 +6683,18 @@ static int tg_cfs_schedulable_down(struct task_group *tg, void *data)
                parent_quota = parent_b->hierarchical_quota;
 
                /*
-                * Ensure max(child_quota) <= parent_quota, inherit when no
+                * Ensure max(child_quota) <= parent_quota.  On cgroup2,
+                * always take the min.  On cgroup1, only inherit when no
                 * limit is set:
                 */
-               if (quota == RUNTIME_INF)
-                       quota = parent_quota;
-               else if (parent_quota != RUNTIME_INF && quota > parent_quota)
-                       return -EINVAL;
+               if (cgroup_subsys_on_dfl(cpu_cgrp_subsys)) {
+                       quota = min(quota, parent_quota);
+               } else {
+                       if (quota == RUNTIME_INF)
+                               quota = parent_quota;
+                       else if (parent_quota != RUNTIME_INF && quota > parent_quota)
+                               return -EINVAL;
+               }
        }
        cfs_b->hierarchical_quota = quota;
 
index dd062a1c8cf043a26882e3b694d7c15588a2718c..7936f548e071e201a2125981dedce3e162711a24 100644 (file)
@@ -19,8 +19,6 @@
 
 #include "sched.h"
 
-#define SUGOV_KTHREAD_PRIORITY 50
-
 struct sugov_tunables {
        struct gov_attr_set attr_set;
        unsigned int rate_limit_us;
index 9bb0e0c412ec6617c5ef6cfa0b4f703a6a536a23..9df09782025cb54d3d381ed696624211c6e23769 100644 (file)
@@ -1153,6 +1153,7 @@ static void update_curr_dl(struct rq *rq)
        struct sched_dl_entity *dl_se = &curr->dl;
        u64 delta_exec, scaled_delta_exec;
        int cpu = cpu_of(rq);
+       u64 now;
 
        if (!dl_task(curr) || !on_dl_rq(dl_se))
                return;
@@ -1165,7 +1166,8 @@ static void update_curr_dl(struct rq *rq)
         * natural solution, but the full ramifications of this
         * approach need further study.
         */
-       delta_exec = rq_clock_task(rq) - curr->se.exec_start;
+       now = rq_clock_task(rq);
+       delta_exec = now - curr->se.exec_start;
        if (unlikely((s64)delta_exec <= 0)) {
                if (unlikely(dl_se->dl_yielded))
                        goto throttle;
@@ -1178,7 +1180,7 @@ static void update_curr_dl(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);
index 1ca0130ed4f937d8b1abcc0e64fd14ebb3a3cfb7..72c401b3b15ceadcf724176028f68ff1f7c82d8b 100644 (file)
@@ -32,7 +32,7 @@ static DEFINE_SPINLOCK(sched_debug_lock);
        if (m)                                  \
                seq_printf(m, x);               \
        else                                    \
-               printk(x);                      \
+               pr_cont(x);                     \
  } while (0)
 
 /*
@@ -501,12 +501,12 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
 {
        struct task_struct *g, *p;
 
-       SEQ_printf(m,
-       "\nrunnable tasks:\n"
-       " S           task   PID         tree-key  switches  prio"
-       "     wait-time             sum-exec        sum-sleep\n"
-       "-------------------------------------------------------"
-       "----------------------------------------------------\n");
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "runnable tasks:\n");
+       SEQ_printf(m, " S           task   PID         tree-key  switches  prio"
+                  "     wait-time             sum-exec        sum-sleep\n");
+       SEQ_printf(m, "-------------------------------------------------------"
+                  "----------------------------------------------------\n");
 
        rcu_read_lock();
        for_each_process_thread(g, p) {
@@ -527,9 +527,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
        unsigned long flags;
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "cfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
 #else
-       SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "cfs_rq[%d]:\n", cpu);
 #endif
        SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", "exec_clock",
                        SPLIT_NS(cfs_rq->exec_clock));
@@ -595,9 +597,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq)
 {
 #ifdef CONFIG_RT_GROUP_SCHED
-       SEQ_printf(m, "\nrt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "rt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
 #else
-       SEQ_printf(m, "\nrt_rq[%d]:\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "rt_rq[%d]:\n", cpu);
 #endif
 
 #define P(x) \
@@ -624,7 +628,8 @@ void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq)
 {
        struct dl_bw *dl_bw;
 
-       SEQ_printf(m, "\ndl_rq[%d]:\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "dl_rq[%d]:\n", cpu);
 
 #define PU(x) \
        SEQ_printf(m, "  .%-30s: %lu\n", #x, (unsigned long)(dl_rq->x))
index 663b2355a3aa772d8bcc8c90b55a3e0e0e3a6e17..aad49451584e6766d1b9a2f657397da345146c23 100644 (file)
@@ -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;
+       u64 now;
 
        if (curr->sched_class != &rt_sched_class)
                return;
 
+       now = rq_clock_task(rq);
        delta_exec = now - curr->se.exec_start;
        if (unlikely((s64)delta_exec <= 0))
                return;
index 940fa408a288f778fed1e61fa004cbf6e8fdac75..dc77548167ef0993487a61bcf6cbbabb2f6f2434 100644 (file)
@@ -1076,14 +1076,16 @@ long seccomp_get_metadata(struct task_struct *task,
 
        size = min_t(unsigned long, size, sizeof(kmd));
 
-       if (copy_from_user(&kmd, data, size))
+       if (size < sizeof(kmd.filter_off))
+               return -EINVAL;
+
+       if (copy_from_user(&kmd.filter_off, data, sizeof(kmd.filter_off)))
                return -EFAULT;
 
        filter = get_nth_filter(task, kmd.filter_off);
        if (IS_ERR(filter))
                return PTR_ERR(filter);
 
-       memset(&kmd, 0, sizeof(kmd));
        if (filter->log)
                kmd.flags |= SECCOMP_FILTER_FLAG_LOG;
 
index 75043046914e593a567be64d3167bd2158bc1eb7..10b7186d063830b9e45a84146ed243a9f0e80b07 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/export.h>
 #include <linux/hashtable.h>
 #include <linux/compat.h>
+#include <linux/nospec.h>
 
 #include "timekeeping.h"
 #include "posix-timers.h"
@@ -1346,11 +1347,15 @@ static const struct k_clock * const posix_clocks[] = {
 
 static const struct k_clock *clockid_to_kclock(const clockid_t id)
 {
-       if (id < 0)
+       clockid_t idx = id;
+
+       if (id < 0) {
                return (id & CLOCKFD_MASK) == CLOCKFD ?
                        &clock_posix_dynamic : &clock_posix_cpu;
+       }
 
-       if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
+       if (id >= ARRAY_SIZE(posix_clocks))
                return NULL;
-       return posix_clocks[id];
+
+       return posix_clocks[array_index_nospec(idx, ARRAY_SIZE(posix_clocks))];
 }
index 48150ab42de96449051b5e441cb405ef1a09445c..4a4fd567fb26654bc96d6fddc31c7ba0da7cd409 100644 (file)
@@ -1894,6 +1894,12 @@ int timers_dead_cpu(unsigned int cpu)
                raw_spin_lock_irq(&new_base->lock);
                raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
 
+               /*
+                * The current CPUs base clock might be stale. Update it
+                * before moving the timers over.
+                */
+               forward_timer_base(new_base);
+
                BUG_ON(old_base->running_timer);
 
                for (i = 0; i < WHEEL_SIZE; i++)
index fc2838ac8b7877b1ac16879dbdb178224eb1f0f3..01e6b3a38871e275bb81bc6a401848dc9eb6401e 100644 (file)
@@ -661,7 +661,41 @@ static const struct bpf_func_proto bpf_get_stackid_proto_tp = {
        .arg3_type      = ARG_ANYTHING,
 };
 
-BPF_CALL_3(bpf_perf_prog_read_value_tp, struct bpf_perf_event_data_kern *, ctx,
+static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
+{
+       switch (func_id) {
+       case BPF_FUNC_perf_event_output:
+               return &bpf_perf_event_output_proto_tp;
+       case BPF_FUNC_get_stackid:
+               return &bpf_get_stackid_proto_tp;
+       default:
+               return tracing_func_proto(func_id);
+       }
+}
+
+static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type,
+                                   struct bpf_insn_access_aux *info)
+{
+       if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
+               return false;
+       if (type != BPF_READ)
+               return false;
+       if (off % size != 0)
+               return false;
+
+       BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64));
+       return true;
+}
+
+const struct bpf_verifier_ops tracepoint_verifier_ops = {
+       .get_func_proto  = tp_prog_func_proto,
+       .is_valid_access = tp_prog_is_valid_access,
+};
+
+const struct bpf_prog_ops tracepoint_prog_ops = {
+};
+
+BPF_CALL_3(bpf_perf_prog_read_value, struct bpf_perf_event_data_kern *, ctx,
           struct bpf_perf_event_value *, buf, u32, size)
 {
        int err = -EINVAL;
@@ -678,8 +712,8 @@ clear:
        return err;
 }
 
-static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = {
-         .func           = bpf_perf_prog_read_value_tp,
+static const struct bpf_func_proto bpf_perf_prog_read_value_proto = {
+         .func           = bpf_perf_prog_read_value,
          .gpl_only       = true,
          .ret_type       = RET_INTEGER,
          .arg1_type      = ARG_PTR_TO_CTX,
@@ -687,7 +721,7 @@ static const struct bpf_func_proto bpf_perf_prog_read_value_proto_tp = {
          .arg3_type      = ARG_CONST_SIZE,
 };
 
-static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
+static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id)
 {
        switch (func_id) {
        case BPF_FUNC_perf_event_output:
@@ -695,34 +729,12 @@ static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
        case BPF_FUNC_get_stackid:
                return &bpf_get_stackid_proto_tp;
        case BPF_FUNC_perf_prog_read_value:
-               return &bpf_perf_prog_read_value_proto_tp;
+               return &bpf_perf_prog_read_value_proto;
        default:
                return tracing_func_proto(func_id);
        }
 }
 
-static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type,
-                                   struct bpf_insn_access_aux *info)
-{
-       if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE)
-               return false;
-       if (type != BPF_READ)
-               return false;
-       if (off % size != 0)
-               return false;
-
-       BUILD_BUG_ON(PERF_MAX_TRACE_SIZE % sizeof(__u64));
-       return true;
-}
-
-const struct bpf_verifier_ops tracepoint_verifier_ops = {
-       .get_func_proto  = tp_prog_func_proto,
-       .is_valid_access = tp_prog_is_valid_access,
-};
-
-const struct bpf_prog_ops tracepoint_prog_ops = {
-};
-
 static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
                                    struct bpf_insn_access_aux *info)
 {
@@ -779,7 +791,7 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,
 }
 
 const struct bpf_verifier_ops perf_event_verifier_ops = {
-       .get_func_proto         = tp_prog_func_proto,
+       .get_func_proto         = pe_prog_func_proto,
        .is_valid_access        = pe_prog_is_valid_access,
        .convert_ctx_access     = pe_prog_convert_ctx_access,
 };
@@ -872,6 +884,8 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
                return -EINVAL;
        if (copy_from_user(&query, uquery, sizeof(query)))
                return -EFAULT;
+       if (query.ids_len > BPF_TRACE_MAX_PROGS)
+               return -E2BIG;
 
        mutex_lock(&bpf_event_mutex);
        ret = bpf_prog_array_copy_info(event->tp_event->prog_array,
index 1fad24acd444581d8642e162c1c9ee441f4ccb52..ae4147eaebd4882d002347625e07c6aca652e7f2 100644 (file)
@@ -659,7 +659,7 @@ static int create_trace_kprobe(int argc, char **argv)
        char *symbol = NULL, *event = NULL, *group = NULL;
        int maxactive = 0;
        char *arg;
-       unsigned long offset = 0;
+       long offset = 0;
        void *addr = NULL;
        char buf[MAX_EVENT_NAME_LEN];
 
@@ -747,7 +747,7 @@ static int create_trace_kprobe(int argc, char **argv)
                symbol = argv[1];
                /* TODO: support .init module functions */
                ret = traceprobe_split_symbol_offset(symbol, &offset);
-               if (ret) {
+               if (ret || offset < 0 || offset > UINT_MAX) {
                        pr_info("Failed to parse either an address or a symbol.\n");
                        return ret;
                }
index d5935730867709232f547fd08ef6a3659ea819c9..daf54bda4dc8d7a86419e5107a2075d8df5095dc 100644 (file)
@@ -320,7 +320,7 @@ static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
 }
 
 /* Split symbol and offset. */
-int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
+int traceprobe_split_symbol_offset(char *symbol, long *offset)
 {
        char *tmp;
        int ret;
@@ -328,13 +328,11 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
        if (!offset)
                return -EINVAL;
 
-       tmp = strchr(symbol, '+');
+       tmp = strpbrk(symbol, "+-");
        if (tmp) {
-               /* skip sign because kstrtoul doesn't accept '+' */
-               ret = kstrtoul(tmp + 1, 0, offset);
+               ret = kstrtol(tmp, 0, offset);
                if (ret)
                        return ret;
-
                *tmp = '\0';
        } else
                *offset = 0;
index e101c5bb9eda517257810cf642a47b39bbc150a5..6a4d3fa9404232b59cb7fe2dd7c7c02fb1d74edd 100644 (file)
@@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name,
 extern void traceprobe_update_arg(struct probe_arg *arg);
 extern void traceprobe_free_probe_arg(struct probe_arg *arg);
 
-extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
+extern int traceprobe_split_symbol_offset(char *symbol, long *offset);
 
 /* Sum up total data length for dynamic arraies (strings) */
 static nokprobe_inline int
index 9a20acce460d53cf23f7057c7dc122b685ae639d..36288d8406756400f5008ee0631b810301504e0d 100644 (file)
@@ -101,6 +101,7 @@ struct user_struct root_user = {
        .sigpending     = ATOMIC_INIT(0),
        .locked_shm     = 0,
        .uid            = GLOBAL_ROOT_UID,
+       .ratelimit      = RATELIMIT_STATE_INIT(root_user.ratelimit, 0, 0),
 };
 
 /*
@@ -191,6 +192,8 @@ struct user_struct *alloc_uid(kuid_t uid)
 
                new->uid = uid;
                atomic_set(&new->__count, 1);
+               ratelimit_state_init(&new->ratelimit, HZ, 100);
+               ratelimit_set_flags(&new->ratelimit, RATELIMIT_MSG_ON_RELEASE);
 
                /*
                 * Before adding this, check whether we raced
index 017044c2623373455274a1d642cecc7e3c4811aa..6ec6ba65127b46e52bbfa611092a1140a8180728 100644 (file)
@@ -3018,14 +3018,6 @@ static bool __cancel_work(struct work_struct *work, bool is_dwork)
        return ret;
 }
 
-/*
- * See cancel_delayed_work()
- */
-bool cancel_work(struct work_struct *work)
-{
-       return __cancel_work(work, false);
-}
-
 /**
  * cancel_delayed_work - cancel a delayed work
  * @dwork: delayed_work to cancel
@@ -4179,6 +4171,22 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
 }
 EXPORT_SYMBOL_GPL(workqueue_set_max_active);
 
+/**
+ * current_work - retrieve %current task's work struct
+ *
+ * Determine if %current task is a workqueue worker and what it's working on.
+ * Useful to find out the context that the %current task is running in.
+ *
+ * Return: work struct if %current task is a workqueue worker, %NULL otherwise.
+ */
+struct work_struct *current_work(void)
+{
+       struct worker *worker = current_wq_worker();
+
+       return worker ? worker->current_work : NULL;
+}
+EXPORT_SYMBOL(current_work);
+
 /**
  * current_is_workqueue_rescuer - is %current workqueue rescuer?
  *
@@ -5321,7 +5329,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq)
 
        ret = device_register(&wq_dev->dev);
        if (ret) {
-               kfree(wq_dev);
+               put_device(&wq_dev->dev);
                wq->wq_dev = NULL;
                return ret;
        }
index 6088408ef26c5471146ee0c6a149f4ba1086d015..64155e310a9f2119ee7443268e767fc74b32043e 100644 (file)
@@ -1642,6 +1642,7 @@ config DMA_API_DEBUG
 
 menuconfig RUNTIME_TESTING_MENU
        bool "Runtime Testing"
+       def_bool y
 
 if RUNTIME_TESTING_MENU
 
index f93a945274af12575f8fbbceb821552b2a13e61e..590facba2c5083b36b54b0809408ccedb97d43b5 100644 (file)
@@ -3,7 +3,7 @@
  *
  * As should be obvious for Linux kernel code, license is GPLv2
  *
- * Copyright (c) 2007-2008 Joern Engel <joern@logfs.org>
+ * Copyright (c) 2007-2008 Joern Engel <joern@purestorage.com>
  * Bits and pieces stolen from Peter Zijlstra's code, which is
  * Copyright 2007, Red Hat Inc. Peter Zijlstra
  * GPLv2
@@ -76,6 +76,8 @@ struct btree_geo btree_geo128 = {
 };
 EXPORT_SYMBOL_GPL(btree_geo128);
 
+#define MAX_KEYLEN     (2 * LONG_PER_U64)
+
 static struct kmem_cache *btree_cachep;
 
 void *btree_alloc(gfp_t gfp_mask, void *pool_data)
@@ -313,7 +315,7 @@ void *btree_get_prev(struct btree_head *head, struct btree_geo *geo,
 {
        int i, height;
        unsigned long *node, *oldnode;
-       unsigned long *retry_key = NULL, key[geo->keylen];
+       unsigned long *retry_key = NULL, key[MAX_KEYLEN];
 
        if (keyzero(geo, __key))
                return NULL;
@@ -639,8 +641,8 @@ EXPORT_SYMBOL_GPL(btree_remove);
 int btree_merge(struct btree_head *target, struct btree_head *victim,
                struct btree_geo *geo, gfp_t gfp)
 {
-       unsigned long key[geo->keylen];
-       unsigned long dup[geo->keylen];
+       unsigned long key[MAX_KEYLEN];
+       unsigned long dup[MAX_KEYLEN];
        void *val;
        int err;
 
index c1b0fad31b109157427d1ec1e30e7e93e303465d..1077366f496ba6c7ef6905685c2435b090b81b1b 100644 (file)
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -150,6 +150,8 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
                return BUG_TRAP_TYPE_NONE;
 
        bug = find_bug(bugaddr);
+       if (!bug)
+               return BUG_TRAP_TYPE_NONE;
 
        file = NULL;
        line = 0;
@@ -191,7 +193,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
        if (file)
                pr_crit("kernel BUG at %s:%u!\n", file, line);
        else
-               pr_crit("Kernel BUG at %p [verbose debug info unavailable]\n",
+               pr_crit("Kernel BUG at %pB [verbose debug info unavailable]\n",
                        (void *)bugaddr);
 
        return BUG_TRAP_TYPE_BUG;
index 1b34d210452c5aba703aea04e648dd6ed56fd576..7f5cdc1e6b298f2c2121ebc33195fbc7c7d71145 100644 (file)
@@ -1491,12 +1491,12 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size,
        if (unlikely(virt == NULL))
                return;
 
-       entry = dma_entry_alloc();
-       if (!entry)
+       /* handle vmalloc and linear addresses */
+       if (!is_vmalloc_addr(virt) && !virt_addr_valid(virt))
                return;
 
-       /* handle vmalloc and linear addresses */
-       if (!is_vmalloc_addr(virt) && !virt_to_page(virt))
+       entry = dma_entry_alloc();
+       if (!entry)
                return;
 
        entry->type      = dma_debug_coherent;
@@ -1528,7 +1528,7 @@ void debug_dma_free_coherent(struct device *dev, size_t size,
        };
 
        /* handle vmalloc and linear addresses */
-       if (!is_vmalloc_addr(virt) && !virt_to_page(virt))
+       if (!is_vmalloc_addr(virt) && !virt_addr_valid(virt))
                return;
 
        if (is_vmalloc_addr(virt))
index 40b1f92f2214e8de08109b70ef4f999346b20b99..c9e8e21cb33406f33b539cfd25d82b5749071422 100644 (file)
@@ -84,6 +84,10 @@ again:
        return page_address(page);
 }
 
+/*
+ * NOTE: this function must never look at the dma_addr argument, because we want
+ * to be able to use it as a helper for iommu implementations as well.
+ */
 void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
                dma_addr_t dma_addr, unsigned long attrs)
 {
@@ -152,5 +156,6 @@ const struct dma_map_ops dma_direct_ops = {
        .map_sg                 = dma_direct_map_sg,
        .dma_supported          = dma_direct_supported,
        .mapping_error          = dma_direct_mapping_error,
+       .is_phys                = 1,
 };
 EXPORT_SYMBOL(dma_direct_ops);
index c98d77fcf3934d9e47b33ba4d02b509c25273d31..823b813f08f862b4c80463ad69f91ba9acf62703 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -36,8 +36,8 @@ int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,
 {
        struct radix_tree_iter iter;
        void __rcu **slot;
-       int base = idr->idr_base;
-       int id = *nextid;
+       unsigned int base = idr->idr_base;
+       unsigned int id = *nextid;
 
        if (WARN_ON_ONCE(radix_tree_is_internal_node(ptr)))
                return -EINVAL;
@@ -204,10 +204,11 @@ int idr_for_each(const struct idr *idr,
 
        radix_tree_for_each_slot(slot, &idr->idr_rt, &iter, 0) {
                int ret;
+               unsigned long id = iter.index + base;
 
-               if (WARN_ON_ONCE(iter.index > INT_MAX))
+               if (WARN_ON_ONCE(id > INT_MAX))
                        break;
-               ret = fn(iter.index + base, rcu_dereference_raw(*slot), data);
+               ret = fn(id, rcu_dereference_raw(*slot), data);
                if (ret)
                        return ret;
        }
@@ -230,8 +231,8 @@ void *idr_get_next(struct idr *idr, int *nextid)
 {
        struct radix_tree_iter iter;
        void __rcu **slot;
-       int base = idr->idr_base;
-       int id = *nextid;
+       unsigned long base = idr->idr_base;
+       unsigned long id = *nextid;
 
        id = (id < base) ? 0 : id - base;
        slot = radix_tree_iter_find(&idr->idr_rt, &iter, id);
@@ -431,7 +432,6 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
                        bitmap = this_cpu_xchg(ida_bitmap, NULL);
                        if (!bitmap)
                                return -EAGAIN;
-                       memset(bitmap, 0, sizeof(*bitmap));
                        bitmap->bitmap[0] = tmp >> RADIX_TREE_EXCEPTIONAL_SHIFT;
                        rcu_assign_pointer(*slot, bitmap);
                }
@@ -464,7 +464,6 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
                        bitmap = this_cpu_xchg(ida_bitmap, NULL);
                        if (!bitmap)
                                return -EAGAIN;
-                       memset(bitmap, 0, sizeof(*bitmap));
                        __set_bit(bit, bitmap->bitmap);
                        radix_tree_iter_replace(root, &iter, slot, bitmap);
                }
index b808a390e4c3e32d2789b059ab7752c6d533d7a3..54e5bbaa3200317534926e65982dcd3cbab71492 100644 (file)
@@ -91,7 +91,8 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
 
                if (ioremap_pmd_enabled() &&
                    ((next - addr) == PMD_SIZE) &&
-                   IS_ALIGNED(phys_addr + addr, PMD_SIZE)) {
+                   IS_ALIGNED(phys_addr + addr, PMD_SIZE) &&
+                   pmd_free_pte_page(pmd)) {
                        if (pmd_set_huge(pmd, phys_addr + addr, prot))
                                continue;
                }
@@ -117,7 +118,8 @@ static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr,
 
                if (ioremap_pud_enabled() &&
                    ((next - addr) == PUD_SIZE) &&
-                   IS_ALIGNED(phys_addr + addr, PUD_SIZE)) {
+                   IS_ALIGNED(phys_addr + addr, PUD_SIZE) &&
+                   pud_free_pmd_page(pud)) {
                        if (pud_set_huge(pud, phys_addr + addr, prot))
                                continue;
                }
index 30e7dd88148b0282c1f445047b360156e79278a0..9f96fa7bc0006e6eb38d4c88aba96d8ea04049fb 100644 (file)
@@ -322,6 +322,8 @@ EXPORT_SYMBOL_GPL(percpu_ref_switch_to_percpu);
  * This function normally doesn't block and can be called from any context
  * but it may block if @confirm_kill is specified and @ref is in the
  * process of switching to atomic mode by percpu_ref_switch_to_atomic().
+ *
+ * There are no implied RCU grace periods between kill and release.
  */
 void percpu_ref_kill_and_confirm(struct percpu_ref *ref,
                                 percpu_ref_func_t *confirm_kill)
index 0a7ae3288a248e239ee8057e66b914289f2aa693..8e00138d593fd3acf09716e7edf6c769c9ceee5b 100644 (file)
@@ -2125,7 +2125,7 @@ int ida_pre_get(struct ida *ida, gfp_t gfp)
                preempt_enable();
 
        if (!this_cpu_read(ida_bitmap)) {
-               struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp);
+               struct ida_bitmap *bitmap = kzalloc(sizeof(*bitmap), gfp);
                if (!bitmap)
                        return 0;
                if (this_cpu_cmpxchg(ida_bitmap, NULL, bitmap))
index 3825c30aaa36985e2e73c5d657bae3455b674cd9..47de025b624520f75e521bef46dc9b28baa6a1a0 100644 (file)
@@ -506,8 +506,10 @@ static void *rhashtable_lookup_one(struct rhashtable *ht,
                if (!key ||
                    (ht->p.obj_cmpfn ?
                     ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) :
-                    rhashtable_compare(&arg, rht_obj(ht, head))))
+                    rhashtable_compare(&arg, rht_obj(ht, head)))) {
+                       pprev = &head->next;
                        continue;
+               }
 
                if (!ht->rhlist)
                        return rht_obj(ht, head);
index b4e22345963f339ffe05c974bc111ae7da9dc58f..3e9335493fe493139574649ff4950f8e313cc01c 100644 (file)
 #include <linux/if_vlan.h>
 #include <linux/random.h>
 #include <linux/highmem.h>
+#include <linux/sched.h>
 
 /* General test specific settings */
 #define MAX_SUBTESTS   3
-#define MAX_TESTRUNS   10000
+#define MAX_TESTRUNS   1000
 #define MAX_DATA       128
 #define MAX_INSNS      512
 #define MAX_K          0xffffFFFF
@@ -5466,7 +5467,7 @@ static struct bpf_test tests[] = {
        {
                "BPF_MAXINSNS: Jump, gap, jump, ...",
                { },
-#ifdef CONFIG_BPF_JIT_ALWAYS_ON
+#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_X86)
                CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
 #else
                CLASSIC | FLAG_NO_DATA,
@@ -6582,6 +6583,7 @@ static __init int test_bpf(void)
                struct bpf_prog *fp;
                int err;
 
+               cond_resched();
                if (exclude_test(i))
                        continue;
 
index e372b97eee1301c1bd2e6c49b49e57c8ef4bff10..0e5b7a61460bb092226a3785abeaa2168d95d790 100644 (file)
@@ -1141,7 +1141,7 @@ static struct kmod_test_device *register_test_dev_kmod(void)
        mutex_lock(&reg_dev_mutex);
 
        /* int should suffice for number of devices, test for wrap */
-       if (unlikely(num_test_devs + 1) < 0) {
+       if (num_test_devs + 1 == INT_MAX) {
                pr_err("reached limit of number of test devices\n");
                goto out;
        }
index 76d3667fdea21c2c1842ce19818ddda05b7ceada..f4000c137dbed6da5754713f3d280a9e1caed528 100644 (file)
@@ -79,6 +79,21 @@ struct thread_data {
        struct test_obj *objs;
 };
 
+static u32 my_hashfn(const void *data, u32 len, u32 seed)
+{
+       const struct test_obj_rhl *obj = data;
+
+       return (obj->value.id % 10) << RHT_HASH_RESERVED_SPACE;
+}
+
+static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
+{
+       const struct test_obj_rhl *test_obj = obj;
+       const struct test_obj_val *val = arg->key;
+
+       return test_obj->value.id - val->id;
+}
+
 static struct rhashtable_params test_rht_params = {
        .head_offset = offsetof(struct test_obj, node),
        .key_offset = offsetof(struct test_obj, value),
@@ -87,6 +102,17 @@ static struct rhashtable_params test_rht_params = {
        .nulls_base = (3U << RHT_BASE_SHIFT),
 };
 
+static struct rhashtable_params test_rht_params_dup = {
+       .head_offset = offsetof(struct test_obj_rhl, list_node),
+       .key_offset = offsetof(struct test_obj_rhl, value),
+       .key_len = sizeof(struct test_obj_val),
+       .hashfn = jhash,
+       .obj_hashfn = my_hashfn,
+       .obj_cmpfn = my_cmpfn,
+       .nelem_hint = 128,
+       .automatic_shrinking = false,
+};
+
 static struct semaphore prestart_sem;
 static struct semaphore startup_sem = __SEMAPHORE_INITIALIZER(startup_sem, 0);
 
@@ -465,6 +491,112 @@ static int __init test_rhashtable_max(struct test_obj *array,
        return err;
 }
 
+static unsigned int __init print_ht(struct rhltable *rhlt)
+{
+       struct rhashtable *ht;
+       const struct bucket_table *tbl;
+       char buff[512] = "";
+       unsigned int i, cnt = 0;
+
+       ht = &rhlt->ht;
+       tbl = rht_dereference(ht->tbl, ht);
+       for (i = 0; i < tbl->size; i++) {
+               struct rhash_head *pos, *next;
+               struct test_obj_rhl *p;
+
+               pos = rht_dereference(tbl->buckets[i], ht);
+               next = !rht_is_a_nulls(pos) ? rht_dereference(pos->next, ht) : NULL;
+
+               if (!rht_is_a_nulls(pos)) {
+                       sprintf(buff, "%s\nbucket[%d] -> ", buff, i);
+               }
+
+               while (!rht_is_a_nulls(pos)) {
+                       struct rhlist_head *list = container_of(pos, struct rhlist_head, rhead);
+                       sprintf(buff, "%s[[", buff);
+                       do {
+                               pos = &list->rhead;
+                               list = rht_dereference(list->next, ht);
+                               p = rht_obj(ht, pos);
+
+                               sprintf(buff, "%s val %d (tid=%d)%s", buff, p->value.id, p->value.tid,
+                                       list? ", " : " ");
+                               cnt++;
+                       } while (list);
+
+                       pos = next,
+                       next = !rht_is_a_nulls(pos) ?
+                               rht_dereference(pos->next, ht) : NULL;
+
+                       sprintf(buff, "%s]]%s", buff, !rht_is_a_nulls(pos) ? " -> " : "");
+               }
+       }
+       printk(KERN_ERR "\n---- ht: ----%s\n-------------\n", buff);
+
+       return cnt;
+}
+
+static int __init test_insert_dup(struct test_obj_rhl *rhl_test_objects,
+                                 int cnt, bool slow)
+{
+       struct rhltable rhlt;
+       unsigned int i, ret;
+       const char *key;
+       int err = 0;
+
+       err = rhltable_init(&rhlt, &test_rht_params_dup);
+       if (WARN_ON(err))
+               return err;
+
+       for (i = 0; i < cnt; i++) {
+               rhl_test_objects[i].value.tid = i;
+               key = rht_obj(&rhlt.ht, &rhl_test_objects[i].list_node.rhead);
+               key += test_rht_params_dup.key_offset;
+
+               if (slow) {
+                       err = PTR_ERR(rhashtable_insert_slow(&rhlt.ht, key,
+                                                            &rhl_test_objects[i].list_node.rhead));
+                       if (err == -EAGAIN)
+                               err = 0;
+               } else
+                       err = rhltable_insert(&rhlt,
+                                             &rhl_test_objects[i].list_node,
+                                             test_rht_params_dup);
+               if (WARN(err, "error %d on element %d/%d (%s)\n", err, i, cnt, slow? "slow" : "fast"))
+                       goto skip_print;
+       }
+
+       ret = print_ht(&rhlt);
+       WARN(ret != cnt, "missing rhltable elements (%d != %d, %s)\n", ret, cnt, slow? "slow" : "fast");
+
+skip_print:
+       rhltable_destroy(&rhlt);
+
+       return 0;
+}
+
+static int __init test_insert_duplicates_run(void)
+{
+       struct test_obj_rhl rhl_test_objects[3] = {};
+
+       pr_info("test inserting duplicates\n");
+
+       /* two different values that map to same bucket */
+       rhl_test_objects[0].value.id = 1;
+       rhl_test_objects[1].value.id = 21;
+
+       /* and another duplicate with same as [0] value
+        * which will be second on the bucket list */
+       rhl_test_objects[2].value.id = rhl_test_objects[0].value.id;
+
+       test_insert_dup(rhl_test_objects, 2, false);
+       test_insert_dup(rhl_test_objects, 3, false);
+       test_insert_dup(rhl_test_objects, 2, true);
+       test_insert_dup(rhl_test_objects, 3, true);
+
+       return 0;
+}
+
 static int thread_lookup_test(struct thread_data *tdata)
 {
        unsigned int entries = tdata->entries;
@@ -613,6 +745,8 @@ static int __init test_rht_init(void)
        do_div(total_time, runs);
        pr_info("Average test time: %llu\n", total_time);
 
+       test_insert_duplicates_run();
+
        if (!tcount)
                return 0;
 
index 77ee6ced11b17a411d95f266faeaaf7dba309d4f..d7a708f82559ca38e768cb93fc0febb999711e4c 100644 (file)
@@ -1849,7 +1849,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 {
        const int default_width = 2 * sizeof(void *);
 
-       if (!ptr && *fmt != 'K') {
+       if (!ptr && *fmt != 'K' && *fmt != 'x') {
                /*
                 * Print (null) with the same width as a pointer so it makes
                 * tabular output look nice.
index 1b46e6e74881d3ce634511d98e4f177625b5501c..6afae32571cae669044319e8aa4438679e8a3b95 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -516,7 +516,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
        }
 
        if (ret & VM_FAULT_RETRY) {
-               if (nonblocking)
+               if (nonblocking && !(fault_flags & FAULT_FLAG_RETRY_NOWAIT))
                        *nonblocking = 0;
                return -EBUSY;
        }
@@ -890,7 +890,10 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
                                break;
                }
                if (*locked) {
-                       /* VM_FAULT_RETRY didn't trigger */
+                       /*
+                        * VM_FAULT_RETRY didn't trigger or it was a
+                        * FOLL_NOWAIT.
+                        */
                        if (!pages_done)
                                pages_done = ret;
                        break;
index 87ab9b8f56b53dae6875e19533b5e1e171d2533c..5a68730eebd62656e3c300581da9a9e71fd7ffc8 100644 (file)
@@ -555,7 +555,8 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
 
        VM_BUG_ON_PAGE(!PageCompound(page), page);
 
-       if (mem_cgroup_try_charge(page, vma->vm_mm, gfp, &memcg, true)) {
+       if (mem_cgroup_try_charge(page, vma->vm_mm, gfp | __GFP_NORETRY, &memcg,
+                                 true)) {
                put_page(page);
                count_vm_event(THP_FAULT_FALLBACK);
                return VM_FAULT_FALLBACK;
@@ -1316,7 +1317,7 @@ alloc:
        }
 
        if (unlikely(mem_cgroup_try_charge(new_page, vma->vm_mm,
-                                       huge_gfp, &memcg, true))) {
+                               huge_gfp | __GFP_NORETRY, &memcg, true))) {
                put_page(new_page);
                split_huge_pmd(vma, vmf->pmd, vmf->address);
                if (page)
@@ -2783,11 +2784,13 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
 
        list_for_each_safe(pos, next, &list) {
                page = list_entry((void *)pos, struct page, mapping);
-               lock_page(page);
+               if (!trylock_page(page))
+                       goto next;
                /* split_huge_page() removes page from list on success */
                if (!split_huge_page(page))
                        split++;
                unlock_page(page);
+next:
                put_page(page);
        }
 
index 7c204e3d132b808364fc1e87e3dace180f9ba173..976bbc5646fe8c6e386ddb0d42b8ba0ccb3e9777 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bootmem.h>
 #include <linux/sysfs.h>
 #include <linux/slab.h>
+#include <linux/mmdebug.h>
 #include <linux/sched/signal.h>
 #include <linux/rmap.h>
 #include <linux/string_helpers.h>
@@ -1583,7 +1584,7 @@ static struct page *alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
                page = NULL;
        } else {
                h->surplus_huge_pages++;
-               h->nr_huge_pages_node[page_to_nid(page)]++;
+               h->surplus_huge_pages_node[page_to_nid(page)]++;
        }
 
 out_unlock:
@@ -4374,6 +4375,12 @@ int hugetlb_reserve_pages(struct inode *inode,
        struct resv_map *resv_map;
        long gbl_reserve;
 
+       /* This should never happen */
+       if (from > to) {
+               VM_WARN(1, "%s called with a negative range\n", __func__);
+               return -EINVAL;
+       }
+
        /*
         * Only apply hugepage reservation if asked. At fault time, an
         * attempt will be made for VM_NORESERVE to allocate a page
index b7e2268dfc9a15c64eced7bfb857e9a32fc128c1..e42568284e06038ab70ec1344f63a2e5182ea90d 100644 (file)
@@ -530,7 +530,12 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
                        goto out;
                }
 
-               VM_BUG_ON_PAGE(PageCompound(page), page);
+               /* TODO: teach khugepaged to collapse THP mapped with pte */
+               if (PageCompound(page)) {
+                       result = SCAN_PAGE_COMPOUND;
+                       goto out;
+               }
+
                VM_BUG_ON_PAGE(!PageAnon(page), page);
 
                /*
@@ -960,7 +965,9 @@ static void collapse_huge_page(struct mm_struct *mm,
                goto out_nolock;
        }
 
-       if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg, true))) {
+       /* Do not oom kill for khugepaged charges */
+       if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp | __GFP_NORETRY,
+                                          &memcg, true))) {
                result = SCAN_CGROUP_CHARGE_FAIL;
                goto out_nolock;
        }
@@ -1319,7 +1326,9 @@ static void collapse_shmem(struct mm_struct *mm,
                goto out;
        }
 
-       if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg, true))) {
+       /* Do not oom kill for khugepaged charges */
+       if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp | __GFP_NORETRY,
+                                          &memcg, true))) {
                result = SCAN_CGROUP_CHARGE_FAIL;
                goto out;
        }
index 5a9ca2a1751bfe1c999dfe6dfcf4716966d0e888..48376bd3327423fcccc308a0a6655db399611510 100644 (file)
@@ -1101,34 +1101,6 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
                *out_nid = r->nid;
 }
 
-unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn,
-                                                     unsigned long max_pfn)
-{
-       struct memblock_type *type = &memblock.memory;
-       unsigned int right = type->cnt;
-       unsigned int mid, left = 0;
-       phys_addr_t addr = PFN_PHYS(pfn + 1);
-
-       do {
-               mid = (right + left) / 2;
-
-               if (addr < type->regions[mid].base)
-                       right = mid;
-               else if (addr >= (type->regions[mid].base +
-                                 type->regions[mid].size))
-                       left = mid + 1;
-               else {
-                       /* addr is within the region, so pfn + 1 is valid */
-                       return min(pfn + 1, max_pfn);
-               }
-       } while (left < right);
-
-       if (right == type->cnt)
-               return max_pfn;
-       else
-               return min(PHYS_PFN(type->regions[right].base), max_pfn);
-}
-
 /**
  * memblock_set_node - set node ID on memblock regions
  * @base: base of area to set node ID for
index 4b80ccee4535f103552735fe56d4362302692c96..8291b75f42c8494c80b35a5b5667ded79a126a96 100644 (file)
@@ -1139,8 +1139,6 @@ int memory_failure(unsigned long pfn, int flags)
                return 0;
        }
 
-       arch_unmap_kpfn(pfn);
-
        orig_head = hpage = compound_head(p);
        num_poisoned_pages_inc();
 
index dd8de96f55475c8de7edae699dd10d0adb8c4fb6..5fcfc24904d199dc1869205a8251a8e18bc115bf 100644 (file)
@@ -80,7 +80,7 @@
 
 #include "internal.h"
 
-#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
+#if defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) && !defined(CONFIG_COMPILE_TEST)
 #warning Unfortunate NUMA and NUMA Balancing config, growing page-frame for last_cpupid.
 #endif
 
index d879f1d8a44ade626a5ed91aa3973068f16d8bc2..32cba0332787f48dea47b5b09f9dac21c567ea84 100644 (file)
@@ -2124,6 +2124,9 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
        case MPOL_INTERLEAVE:
                return !!nodes_equal(a->v.nodes, b->v.nodes);
        case MPOL_PREFERRED:
+               /* a's ->flags is the same as b's */
+               if (a->flags & MPOL_F_LOCAL)
+                       return true;
                return a->v.preferred_node == b->v.preferred_node;
        default:
                BUG();
index 79398200e423b033e71a9f2a7210811c627020a0..74e5a6547c3ddb777e1b452e445d82bacbb936c7 100644 (file)
@@ -64,6 +64,12 @@ void clear_page_mlock(struct page *page)
        mod_zone_page_state(page_zone(page), NR_MLOCK,
                            -hpage_nr_pages(page));
        count_vm_event(UNEVICTABLE_PGCLEARED);
+       /*
+        * The previous TestClearPageMlocked() corresponds to the smp_mb()
+        * in __pagevec_lru_add_fn().
+        *
+        * See __pagevec_lru_add_fn for more explanation.
+        */
        if (!isolate_lru_page(page)) {
                putback_lru_page(page);
        } else {
index 81e18ceef579cd7726dfbabc45a5fbfd133a837b..1741dd23e7c1f7d4878cf38ff9ba021928f99267 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/stop_machine.h>
 #include <linux/sort.h>
 #include <linux/pfn.h>
+#include <xen/xen.h>
 #include <linux/backing-dev.h>
 #include <linux/fault-inject.h>
 #include <linux/page-isolation.h>
@@ -347,6 +348,9 @@ static inline bool update_defer_init(pg_data_t *pgdat,
        /* Always populate low zones for address-constrained allocations */
        if (zone_end < pgdat_end_pfn(pgdat))
                return true;
+       /* Xen PV domains need page structures early */
+       if (xen_pv_domain())
+               return true;
        (*nr_initialised)++;
        if ((*nr_initialised > pgdat->static_init_pgcnt) &&
            (pfn & (PAGES_PER_SECTION - 1)) == 0) {
@@ -1906,7 +1910,9 @@ static int move_freepages(struct zone *zone,
         * Remove at a later date when no bug reports exist related to
         * grouping pages by mobility
         */
-       VM_BUG_ON(page_zone(start_page) != page_zone(end_page));
+       VM_BUG_ON(pfn_valid(page_to_pfn(start_page)) &&
+                 pfn_valid(page_to_pfn(end_page)) &&
+                 page_zone(start_page) != page_zone(end_page));
 #endif
 
        if (num_movable)
@@ -3590,7 +3596,7 @@ static bool __need_fs_reclaim(gfp_t gfp_mask)
                return false;
 
        /* this guy won't enter reclaim */
-       if ((current->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC))
+       if (current->flags & PF_MEMALLOC)
                return false;
 
        /* We're only interested __GFP_FS allocations for now */
@@ -5350,17 +5356,8 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
                if (context != MEMMAP_EARLY)
                        goto not_early;
 
-               if (!early_pfn_valid(pfn)) {
-#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
-                       /*
-                        * Skip to the pfn preceding the next valid one (or
-                        * end_pfn), such that we hit a valid pfn (or end_pfn)
-                        * on our next iteration of the loop.
-                        */
-                       pfn = memblock_next_valid_pfn(pfn, end_pfn) - 1;
-#endif
+               if (!early_pfn_valid(pfn))
                        continue;
-               }
                if (!early_pfn_in_nid(pfn, nid))
                        continue;
                if (!update_defer_init(pgdat, pfn, end_pfn, &nr_initialised))
index d2a76642c4ae89ecc5489dc430a7cddbce351b5e..38de70ab1a0d625c9363f3c519f2ab2ec04a1fc5 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/log2.h>
 
 static int pcpu_populate_chunk(struct pcpu_chunk *chunk,
-                              int page_start, int page_end)
+                              int page_start, int page_end, gfp_t gfp)
 {
        return 0;
 }
@@ -45,18 +45,18 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk,
        /* nada */
 }
 
-static struct pcpu_chunk *pcpu_create_chunk(void)
+static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp)
 {
        const int nr_pages = pcpu_group_sizes[0] >> PAGE_SHIFT;
        struct pcpu_chunk *chunk;
        struct page *pages;
        int i;
 
-       chunk = pcpu_alloc_chunk();
+       chunk = pcpu_alloc_chunk(gfp);
        if (!chunk)
                return NULL;
 
-       pages = alloc_pages(GFP_KERNEL, order_base_2(nr_pages));
+       pages = alloc_pages(gfp, order_base_2(nr_pages));
        if (!pages) {
                pcpu_free_chunk(chunk);
                return NULL;
index 9158e5a81391ced4e268e3d5dd9879c2bc7280ce..d8078de912de38a15626771fea1b25c5b3baf0a6 100644 (file)
@@ -37,7 +37,7 @@ static struct page **pcpu_get_pages(void)
        lockdep_assert_held(&pcpu_alloc_mutex);
 
        if (!pages)
-               pages = pcpu_mem_zalloc(pages_size);
+               pages = pcpu_mem_zalloc(pages_size, GFP_KERNEL);
        return pages;
 }
 
@@ -73,18 +73,21 @@ static void pcpu_free_pages(struct pcpu_chunk *chunk,
  * @pages: array to put the allocated pages into, indexed by pcpu_page_idx()
  * @page_start: page index of the first page to be allocated
  * @page_end: page index of the last page to be allocated + 1
+ * @gfp: allocation flags passed to the underlying allocator
  *
  * Allocate pages [@page_start,@page_end) into @pages for all units.
  * The allocation is for @chunk.  Percpu core doesn't care about the
  * content of @pages and will pass it verbatim to pcpu_map_pages().
  */
 static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
-                           struct page **pages, int page_start, int page_end)
+                           struct page **pages, int page_start, int page_end,
+                           gfp_t gfp)
 {
-       const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM;
        unsigned int cpu, tcpu;
        int i;
 
+       gfp |= __GFP_HIGHMEM;
+
        for_each_possible_cpu(cpu) {
                for (i = page_start; i < page_end; i++) {
                        struct page **pagep = &pages[pcpu_page_idx(cpu, i)];
@@ -262,6 +265,7 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk,
  * @chunk: chunk of interest
  * @page_start: the start page
  * @page_end: the end page
+ * @gfp: allocation flags passed to the underlying memory allocator
  *
  * For each cpu, populate and map pages [@page_start,@page_end) into
  * @chunk.
@@ -270,7 +274,7 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk,
  * pcpu_alloc_mutex, does GFP_KERNEL allocation.
  */
 static int pcpu_populate_chunk(struct pcpu_chunk *chunk,
-                              int page_start, int page_end)
+                              int page_start, int page_end, gfp_t gfp)
 {
        struct page **pages;
 
@@ -278,7 +282,7 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk,
        if (!pages)
                return -ENOMEM;
 
-       if (pcpu_alloc_pages(chunk, pages, page_start, page_end))
+       if (pcpu_alloc_pages(chunk, pages, page_start, page_end, gfp))
                return -ENOMEM;
 
        if (pcpu_map_pages(chunk, pages, page_start, page_end)) {
@@ -325,12 +329,12 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk,
        pcpu_free_pages(chunk, pages, page_start, page_end);
 }
 
-static struct pcpu_chunk *pcpu_create_chunk(void)
+static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp)
 {
        struct pcpu_chunk *chunk;
        struct vm_struct **vms;
 
-       chunk = pcpu_alloc_chunk();
+       chunk = pcpu_alloc_chunk(gfp);
        if (!chunk)
                return NULL;
 
index 50e7fdf84055151d8c7e8bb220f7a73e96b7f3e4..9297098519a6fa793112c3653595c6b509c5fda1 100644 (file)
@@ -80,6 +80,7 @@
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
 #include <linux/kmemleak.h>
+#include <linux/sched.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -447,26 +448,25 @@ static void pcpu_next_fit_region(struct pcpu_chunk *chunk, int alloc_bits,
 /**
  * pcpu_mem_zalloc - allocate memory
  * @size: bytes to allocate
+ * @gfp: allocation flags
  *
  * Allocate @size bytes.  If @size is smaller than PAGE_SIZE,
- * kzalloc() is used; otherwise, vzalloc() is used.  The returned
- * memory is always zeroed.
- *
- * CONTEXT:
- * Does GFP_KERNEL allocation.
+ * kzalloc() is used; otherwise, the equivalent of vzalloc() is used.
+ * This is to facilitate passing through whitelisted flags.  The
+ * returned memory is always zeroed.
  *
  * RETURNS:
  * Pointer to the allocated area on success, NULL on failure.
  */
-static void *pcpu_mem_zalloc(size_t size)
+static void *pcpu_mem_zalloc(size_t size, gfp_t gfp)
 {
        if (WARN_ON_ONCE(!slab_is_available()))
                return NULL;
 
        if (size <= PAGE_SIZE)
-               return kzalloc(size, GFP_KERNEL);
+               return kzalloc(size, gfp);
        else
-               return vzalloc(size);
+               return __vmalloc(size, gfp | __GFP_ZERO, PAGE_KERNEL);
 }
 
 /**
@@ -1154,12 +1154,12 @@ static struct pcpu_chunk * __init pcpu_alloc_first_chunk(unsigned long tmp_addr,
        return chunk;
 }
 
-static struct pcpu_chunk *pcpu_alloc_chunk(void)
+static struct pcpu_chunk *pcpu_alloc_chunk(gfp_t gfp)
 {
        struct pcpu_chunk *chunk;
        int region_bits;
 
-       chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size);
+       chunk = pcpu_mem_zalloc(pcpu_chunk_struct_size, gfp);
        if (!chunk)
                return NULL;
 
@@ -1168,17 +1168,17 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void)
        region_bits = pcpu_chunk_map_bits(chunk);
 
        chunk->alloc_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits) *
-                                          sizeof(chunk->alloc_map[0]));
+                                          sizeof(chunk->alloc_map[0]), gfp);
        if (!chunk->alloc_map)
                goto alloc_map_fail;
 
        chunk->bound_map = pcpu_mem_zalloc(BITS_TO_LONGS(region_bits + 1) *
-                                          sizeof(chunk->bound_map[0]));
+                                          sizeof(chunk->bound_map[0]), gfp);
        if (!chunk->bound_map)
                goto bound_map_fail;
 
        chunk->md_blocks = pcpu_mem_zalloc(pcpu_chunk_nr_blocks(chunk) *
-                                          sizeof(chunk->md_blocks[0]));
+                                          sizeof(chunk->md_blocks[0]), gfp);
        if (!chunk->md_blocks)
                goto md_blocks_fail;
 
@@ -1277,9 +1277,11 @@ static void pcpu_chunk_depopulated(struct pcpu_chunk *chunk,
  * pcpu_addr_to_page           - translate address to physical address
  * pcpu_verify_alloc_info      - check alloc_info is acceptable during init
  */
-static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size);
-static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size);
-static struct pcpu_chunk *pcpu_create_chunk(void);
+static int pcpu_populate_chunk(struct pcpu_chunk *chunk,
+                              int page_start, int page_end, gfp_t gfp);
+static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk,
+                                 int page_start, int page_end);
+static struct pcpu_chunk *pcpu_create_chunk(gfp_t gfp);
 static void pcpu_destroy_chunk(struct pcpu_chunk *chunk);
 static struct page *pcpu_addr_to_page(void *addr);
 static int __init pcpu_verify_alloc_info(const struct pcpu_alloc_info *ai);
@@ -1339,6 +1341,8 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
 static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
                                 gfp_t gfp)
 {
+       /* whitelisted flags that can be passed to the backing allocators */
+       gfp_t pcpu_gfp = gfp & (GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
        bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL;
        bool do_warn = !(gfp & __GFP_NOWARN);
        static int warn_limit = 10;
@@ -1369,8 +1373,17 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
                return NULL;
        }
 
-       if (!is_atomic)
-               mutex_lock(&pcpu_alloc_mutex);
+       if (!is_atomic) {
+               /*
+                * pcpu_balance_workfn() allocates memory under this mutex,
+                * and it may wait for memory reclaim. Allow current task
+                * to become OOM victim, in case of memory pressure.
+                */
+               if (gfp & __GFP_NOFAIL)
+                       mutex_lock(&pcpu_alloc_mutex);
+               else if (mutex_lock_killable(&pcpu_alloc_mutex))
+                       return NULL;
+       }
 
        spin_lock_irqsave(&pcpu_lock, flags);
 
@@ -1421,7 +1434,7 @@ restart:
        }
 
        if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) {
-               chunk = pcpu_create_chunk();
+               chunk = pcpu_create_chunk(pcpu_gfp);
                if (!chunk) {
                        err = "failed to allocate new chunk";
                        goto fail;
@@ -1450,7 +1463,7 @@ area_found:
                                           page_start, page_end) {
                        WARN_ON(chunk->immutable);
 
-                       ret = pcpu_populate_chunk(chunk, rs, re);
+                       ret = pcpu_populate_chunk(chunk, rs, re, pcpu_gfp);
 
                        spin_lock_irqsave(&pcpu_lock, flags);
                        if (ret) {
@@ -1561,10 +1574,17 @@ void __percpu *__alloc_reserved_percpu(size_t size, size_t align)
  * pcpu_balance_workfn - manage the amount of free chunks and populated pages
  * @work: unused
  *
- * Reclaim all fully free chunks except for the first one.
+ * Reclaim all fully free chunks except for the first one.  This is also
+ * responsible for maintaining the pool of empty populated pages.  However,
+ * it is possible that this is called when physical memory is scarce causing
+ * OOM killer to be triggered.  We should avoid doing so until an actual
+ * allocation causes the failure as it is possible that requests can be
+ * serviced from already backed regions.
  */
 static void pcpu_balance_workfn(struct work_struct *work)
 {
+       /* gfp flags passed to underlying allocators */
+       const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
        LIST_HEAD(to_free);
        struct list_head *free_head = &pcpu_slot[pcpu_nr_slots - 1];
        struct pcpu_chunk *chunk, *next;
@@ -1600,6 +1620,7 @@ static void pcpu_balance_workfn(struct work_struct *work)
                        spin_unlock_irq(&pcpu_lock);
                }
                pcpu_destroy_chunk(chunk);
+               cond_resched();
        }
 
        /*
@@ -1645,7 +1666,7 @@ retry_pop:
                                           chunk->nr_pages) {
                        int nr = min(re - rs, nr_to_pop);
 
-                       ret = pcpu_populate_chunk(chunk, rs, rs + nr);
+                       ret = pcpu_populate_chunk(chunk, rs, rs + nr, gfp);
                        if (!ret) {
                                nr_to_pop -= nr;
                                spin_lock_irq(&pcpu_lock);
@@ -1662,7 +1683,7 @@ retry_pop:
 
        if (nr_to_pop) {
                /* ran out of chunks to populate, create a new one and retry */
-               chunk = pcpu_create_chunk();
+               chunk = pcpu_create_chunk(gfp);
                if (chunk) {
                        spin_lock_irq(&pcpu_lock);
                        pcpu_chunk_relocate(chunk, -1);
index 1907688b75ee0110253f3d96e1e3d7ea02433a2a..b859192433998a14096629b53ac5297a6a0dd2bb 100644 (file)
@@ -493,36 +493,45 @@ next:
                info = list_entry(pos, struct shmem_inode_info, shrinklist);
                inode = &info->vfs_inode;
 
-               if (nr_to_split && split >= nr_to_split) {
-                       iput(inode);
-                       continue;
-               }
+               if (nr_to_split && split >= nr_to_split)
+                       goto leave;
 
-               page = find_lock_page(inode->i_mapping,
+               page = find_get_page(inode->i_mapping,
                                (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT);
                if (!page)
                        goto drop;
 
+               /* No huge page at the end of the file: nothing to split */
                if (!PageTransHuge(page)) {
-                       unlock_page(page);
                        put_page(page);
                        goto drop;
                }
 
+               /*
+                * Leave the inode on the list if we failed to lock
+                * the page at this time.
+                *
+                * Waiting for the lock may lead to deadlock in the
+                * reclaim path.
+                */
+               if (!trylock_page(page)) {
+                       put_page(page);
+                       goto leave;
+               }
+
                ret = split_huge_page(page);
                unlock_page(page);
                put_page(page);
 
-               if (ret) {
-                       /* split failed: leave it on the list */
-                       iput(inode);
-                       continue;
-               }
+               /* If split failed leave the inode on the list */
+               if (ret)
+                       goto leave;
 
                split++;
 drop:
                list_del_init(&info->shrinklist);
                removed++;
+leave:
                iput(inode);
        }
 
index 567a7b96e41d63a06fe9f2332e7141161ee141a0..0f17330dd0e5a8552ecbfeaeb6c7139173cb6d3b 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -445,30 +445,6 @@ void lru_cache_add(struct page *page)
        __lru_cache_add(page);
 }
 
-/**
- * add_page_to_unevictable_list - add a page to the unevictable list
- * @page:  the page to be added to the unevictable list
- *
- * Add page directly to its zone's unevictable list.  To avoid races with
- * tasks that might be making the page evictable, through eg. munlock,
- * munmap or exit, while it's not on the lru, we want to add the page
- * while it's locked or otherwise "invisible" to other tasks.  This is
- * difficult to do when using the pagevec cache, so bypass that.
- */
-void add_page_to_unevictable_list(struct page *page)
-{
-       struct pglist_data *pgdat = page_pgdat(page);
-       struct lruvec *lruvec;
-
-       spin_lock_irq(&pgdat->lru_lock);
-       lruvec = mem_cgroup_page_lruvec(page, pgdat);
-       ClearPageActive(page);
-       SetPageUnevictable(page);
-       SetPageLRU(page);
-       add_page_to_lru_list(page, lruvec, LRU_UNEVICTABLE);
-       spin_unlock_irq(&pgdat->lru_lock);
-}
-
 /**
  * lru_cache_add_active_or_unevictable
  * @page:  the page to be added to LRU
@@ -484,13 +460,9 @@ void lru_cache_add_active_or_unevictable(struct page *page,
 {
        VM_BUG_ON_PAGE(PageLRU(page), page);
 
-       if (likely((vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) != VM_LOCKED)) {
+       if (likely((vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) != VM_LOCKED))
                SetPageActive(page);
-               lru_cache_add(page);
-               return;
-       }
-
-       if (!TestSetPageMlocked(page)) {
+       else if (!TestSetPageMlocked(page)) {
                /*
                 * We use the irq-unsafe __mod_zone_page_stat because this
                 * counter is not modified from interrupt context, and the pte
@@ -500,7 +472,7 @@ void lru_cache_add_active_or_unevictable(struct page *page,
                                    hpage_nr_pages(page));
                count_vm_event(UNEVICTABLE_PGMLOCKED);
        }
-       add_page_to_unevictable_list(page);
+       lru_cache_add(page);
 }
 
 /*
@@ -886,15 +858,55 @@ void lru_add_page_tail(struct page *page, struct page *page_tail,
 static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec,
                                 void *arg)
 {
-       int file = page_is_file_cache(page);
-       int active = PageActive(page);
-       enum lru_list lru = page_lru(page);
+       enum lru_list lru;
+       int was_unevictable = TestClearPageUnevictable(page);
 
        VM_BUG_ON_PAGE(PageLRU(page), page);
 
        SetPageLRU(page);
+       /*
+        * Page becomes evictable in two ways:
+        * 1) Within LRU lock [munlock_vma_pages() and __munlock_pagevec()].
+        * 2) Before acquiring LRU lock to put the page to correct LRU and then
+        *   a) do PageLRU check with lock [check_move_unevictable_pages]
+        *   b) do PageLRU check before lock [clear_page_mlock]
+        *
+        * (1) & (2a) are ok as LRU lock will serialize them. For (2b), we need
+        * following strict ordering:
+        *
+        * #0: __pagevec_lru_add_fn             #1: clear_page_mlock
+        *
+        * SetPageLRU()                         TestClearPageMlocked()
+        * smp_mb() // explicit ordering        // above provides strict
+        *                                      // ordering
+        * PageMlocked()                        PageLRU()
+        *
+        *
+        * if '#1' does not observe setting of PG_lru by '#0' and fails
+        * isolation, the explicit barrier will make sure that page_evictable
+        * check will put the page in correct LRU. Without smp_mb(), SetPageLRU
+        * can be reordered after PageMlocked check and can make '#1' to fail
+        * the isolation of the page whose Mlocked bit is cleared (#0 is also
+        * looking at the same page) and the evictable page will be stranded
+        * in an unevictable LRU.
+        */
+       smp_mb();
+
+       if (page_evictable(page)) {
+               lru = page_lru(page);
+               update_page_reclaim_stat(lruvec, page_is_file_cache(page),
+                                        PageActive(page));
+               if (was_unevictable)
+                       count_vm_event(UNEVICTABLE_PGRESCUED);
+       } else {
+               lru = LRU_UNEVICTABLE;
+               ClearPageActive(page);
+               SetPageUnevictable(page);
+               if (!was_unevictable)
+                       count_vm_event(UNEVICTABLE_PGCULLED);
+       }
+
        add_page_to_lru_list(page, lruvec, lru);
-       update_page_reclaim_stat(lruvec, file, active);
        trace_mm_lru_insertion(page, lru);
 }
 
@@ -913,7 +925,7 @@ EXPORT_SYMBOL(__pagevec_lru_add);
  * @pvec:      Where the resulting entries are placed
  * @mapping:   The address_space to search
  * @start:     The starting entry index
- * @nr_pages:  The maximum number of pages
+ * @nr_entries:        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
index 673942094328a710b059b2b50e149ce7eb3d5f11..ebff729cc9562709500353f30121f2c423296cc8 100644 (file)
@@ -1943,11 +1943,15 @@ void *vmalloc_exec(unsigned long size)
 }
 
 #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
-#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL
+#define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL)
 #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA)
-#define GFP_VMALLOC32 GFP_DMA | GFP_KERNEL
+#define GFP_VMALLOC32 (GFP_DMA | GFP_KERNEL)
 #else
-#define GFP_VMALLOC32 GFP_KERNEL
+/*
+ * 64b systems should always have either DMA or DMA32 zones. For others
+ * GFP_DMA32 should do the right thing and use the normal zone.
+ */
+#define GFP_VMALLOC32 GFP_DMA32 | GFP_KERNEL
 #endif
 
 /**
index 444749669187e189b98fcbbe0050413a9c84b20c..cd5dc3faaa57d667f14be1074e2e00bb5db8f330 100644 (file)
@@ -769,64 +769,7 @@ int remove_mapping(struct address_space *mapping, struct page *page)
  */
 void putback_lru_page(struct page *page)
 {
-       bool is_unevictable;
-       int was_unevictable = PageUnevictable(page);
-
-       VM_BUG_ON_PAGE(PageLRU(page), page);
-
-redo:
-       ClearPageUnevictable(page);
-
-       if (page_evictable(page)) {
-               /*
-                * For evictable pages, we can use the cache.
-                * In event of a race, worst case is we end up with an
-                * unevictable page on [in]active list.
-                * We know how to handle that.
-                */
-               is_unevictable = false;
-               lru_cache_add(page);
-       } else {
-               /*
-                * Put unevictable pages directly on zone's unevictable
-                * list.
-                */
-               is_unevictable = true;
-               add_page_to_unevictable_list(page);
-               /*
-                * When racing with an mlock or AS_UNEVICTABLE clearing
-                * (page is unlocked) make sure that if the other thread
-                * does not observe our setting of PG_lru and fails
-                * isolation/check_move_unevictable_pages,
-                * we see PG_mlocked/AS_UNEVICTABLE cleared below and move
-                * the page back to the evictable list.
-                *
-                * The other side is TestClearPageMlocked() or shmem_lock().
-                */
-               smp_mb();
-       }
-
-       /*
-        * page's status can change while we move it among lru. If an evictable
-        * page is on unevictable list, it never be freed. To avoid that,
-        * check after we added it to the list, again.
-        */
-       if (is_unevictable && page_evictable(page)) {
-               if (!isolate_lru_page(page)) {
-                       put_page(page);
-                       goto redo;
-               }
-               /* This means someone else dropped this page from LRU
-                * So, it will be freed or putback to LRU again. There is
-                * nothing to do here.
-                */
-       }
-
-       if (was_unevictable && !is_unevictable)
-               count_vm_event(UNEVICTABLE_PGRESCUED);
-       else if (!was_unevictable && is_unevictable)
-               count_vm_event(UNEVICTABLE_PGCULLED);
-
+       lru_cache_add(page);
        put_page(page);         /* drop ref from isolate */
 }
 
@@ -1836,6 +1779,20 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
        if (stat.nr_writeback && stat.nr_writeback == nr_taken)
                set_bit(PGDAT_WRITEBACK, &pgdat->flags);
 
+       /*
+        * If dirty pages are scanned that are not queued for IO, it
+        * implies that flushers are not doing their job. This can
+        * happen when memory pressure pushes dirty pages to the end of
+        * the LRU before the dirty limits are breached and the dirty
+        * data has expired. It can also happen when the proportion of
+        * dirty pages grows not through writes but through memory
+        * pressure reclaiming all the clean cache. And in some cases,
+        * the flushers simply cannot keep up with the allocation
+        * rate. Nudge the flusher threads in case they are asleep.
+        */
+       if (stat.nr_unqueued_dirty == nr_taken)
+               wakeup_flusher_threads(WB_REASON_VMSCAN);
+
        /*
         * Legacy memcg will stall in page writeback so avoid forcibly
         * stalling here.
@@ -1848,22 +1805,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
                if (stat.nr_dirty && stat.nr_dirty == stat.nr_congested)
                        set_bit(PGDAT_CONGESTED, &pgdat->flags);
 
-               /*
-                * If dirty pages are scanned that are not queued for IO, it
-                * implies that flushers are not doing their job. This can
-                * happen when memory pressure pushes dirty pages to the end of
-                * the LRU before the dirty limits are breached and the dirty
-                * data has expired. It can also happen when the proportion of
-                * dirty pages grows not through writes but through memory
-                * pressure reclaiming all the clean cache. And in some cases,
-                * the flushers simply cannot keep up with the allocation
-                * rate. Nudge the flusher threads in case they are asleep, but
-                * also allow kswapd to start writing pages during reclaim.
-                */
-               if (stat.nr_unqueued_dirty == nr_taken) {
-                       wakeup_flusher_threads(WB_REASON_VMSCAN);
+               /* Allow kswapd to start writing pages during reclaim. */
+               if (stat.nr_unqueued_dirty == nr_taken)
                        set_bit(PGDAT_DIRTY, &pgdat->flags);
-               }
 
                /*
                 * If kswapd scans pages marked marked for immediate
index f8cb83e7699bba6f015fa60fa35bab214c71975e..01a771e304fab17bf2ed884e415a080524393385 100644 (file)
@@ -360,7 +360,7 @@ u64 zpool_get_total_size(struct zpool *zpool)
 
 /**
  * zpool_evictable() - Test if zpool is potentially evictable
- * @pool       The zpool to test
+ * @zpool:     The zpool to test
  *
  * Zpool is only potentially evictable when it's created with struct
  * zpool_ops.evict and its driver implements struct zpool_driver.shrink.
index c004aa4fd3f481e6686ecdfe78f64885637556b9..61a5c41972dba22bc35179a13d40e900dea679b6 100644 (file)
@@ -1007,6 +1007,12 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
        u8 *src, *dst;
        struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) };
 
+       /* THP isn't supported */
+       if (PageTransHuge(page)) {
+               ret = -EINVAL;
+               goto reject;
+       }
+
        if (!zswap_enabled || !tree) {
                ret = -ENODEV;
                goto reject;
index 64aa9f755e1d251e19f1b713acfc163318a9b57d..45c9bf5ff3a0c1f33d5e9443f9237b1277df6502 100644 (file)
@@ -48,8 +48,8 @@ bool vlan_do_receive(struct sk_buff **skbp)
                 * original position later
                 */
                skb_push(skb, offset);
-               skb = *skbp = vlan_insert_tag(skb, skb->vlan_proto,
-                                             skb->vlan_tci);
+               skb = *skbp = vlan_insert_inner_tag(skb, skb->vlan_proto,
+                                                   skb->vlan_tci, skb->mac_len);
                if (!skb)
                        return false;
                skb_pull(skb, offset + VLAN_HLEN);
index f3a4efcf1456422a6c6f036e8b7364f89b407bfd..3aa5a93ad107c1490146240a112e3a9bf3a89b62 100644 (file)
@@ -160,7 +160,8 @@ static void req_done(struct virtqueue *vq)
                spin_unlock_irqrestore(&chan->lock, flags);
                /* Wakeup if anyone waiting for VirtIO ring space. */
                wake_up(chan->vc_wq);
-               p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
+               if (len)
+                       p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
        }
 }
 
index 79e32638372663314e1f47590b74ec7482d1fb8d..99abeadf416e6cf2b392bd833179cff333aa29c8 100644 (file)
@@ -157,7 +157,7 @@ static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node)
  * Return: 0 on success, a negative error code otherwise.
  */
 static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
-                                    int max_if_num)
+                                    unsigned int max_if_num)
 {
        void *data_ptr;
        size_t old_size;
@@ -201,7 +201,8 @@ unlock:
  */
 static void
 batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
-                                  int max_if_num, int del_if_num)
+                                  unsigned int max_if_num,
+                                  unsigned int del_if_num)
 {
        size_t chunk_size;
        size_t if_offset;
@@ -239,7 +240,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
  */
 static void
 batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
-                                      int max_if_num, int del_if_num)
+                                      unsigned int max_if_num,
+                                      unsigned int del_if_num)
 {
        size_t if_offset;
        void *data_ptr;
@@ -276,7 +278,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
  * Return: 0 on success, a negative error code otherwise.
  */
 static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
-                                    int max_if_num, int del_if_num)
+                                    unsigned int max_if_num,
+                                    unsigned int del_if_num)
 {
        spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
 
@@ -311,7 +314,8 @@ static struct batadv_orig_node *
 batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
 {
        struct batadv_orig_node *orig_node;
-       int size, hash_added;
+       int hash_added;
+       size_t size;
 
        orig_node = batadv_orig_hash_find(bat_priv, addr);
        if (orig_node)
@@ -893,7 +897,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
        u32 i;
        size_t word_index;
        u8 *w;
-       int if_num;
+       unsigned int if_num;
 
        for (i = 0; i < hash->size; i++) {
                head = &hash->table[i];
@@ -1023,7 +1027,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
        struct batadv_neigh_node *tmp_neigh_node = NULL;
        struct batadv_neigh_node *router = NULL;
        struct batadv_orig_node *orig_node_tmp;
-       int if_num;
+       unsigned int if_num;
        u8 sum_orig, sum_neigh;
        u8 *neigh_addr;
        u8 tq_avg;
@@ -1182,7 +1186,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
        u8 total_count;
        u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
        unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
-       int if_num;
+       unsigned int if_num;
        unsigned int tq_asym_penalty, inv_asym_penalty;
        unsigned int combined_tq;
        unsigned int tq_iface_penalty;
@@ -1702,9 +1706,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
 
        if (is_my_orig) {
                unsigned long *word;
-               int offset;
+               size_t offset;
                s32 bit_pos;
-               s16 if_num;
+               unsigned int if_num;
                u8 *weight;
 
                orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
@@ -2729,7 +2733,7 @@ static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
        struct batadv_neigh_ifinfo *router_ifinfo = NULL;
        struct batadv_neigh_node *router;
        struct batadv_gw_node *curr_gw;
-       int ret = -EINVAL;
+       int ret = 0;
        void *hdr;
 
        router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
index 27e165ac9302bc365e1f81034a1c1353e991b724..c74f81341dabbd980a673c3a0db7de94026f5c3d 100644 (file)
@@ -928,7 +928,7 @@ static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
        struct batadv_neigh_ifinfo *router_ifinfo = NULL;
        struct batadv_neigh_node *router;
        struct batadv_gw_node *curr_gw;
-       int ret = -EINVAL;
+       int ret = 0;
        void *hdr;
 
        router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
index fad47853ad3c5e0bae2ca2b404badc6797d7f1e9..b1a08374088b4e79aa30350d0d070834a48e3d04 100644 (file)
@@ -2161,22 +2161,25 @@ batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
 {
        struct batadv_bla_claim *claim;
        int idx = 0;
+       int ret = 0;
 
        rcu_read_lock();
        hlist_for_each_entry_rcu(claim, head, hash_entry) {
                if (idx++ < *idx_skip)
                        continue;
-               if (batadv_bla_claim_dump_entry(msg, portid, seq,
-                                               primary_if, claim)) {
+
+               ret = batadv_bla_claim_dump_entry(msg, portid, seq,
+                                                 primary_if, claim);
+               if (ret) {
                        *idx_skip = idx - 1;
                        goto unlock;
                }
        }
 
-       *idx_skip = idx;
+       *idx_skip = 0;
 unlock:
        rcu_read_unlock();
-       return 0;
+       return ret;
 }
 
 /**
@@ -2391,22 +2394,25 @@ batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
 {
        struct batadv_bla_backbone_gw *backbone_gw;
        int idx = 0;
+       int ret = 0;
 
        rcu_read_lock();
        hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
                if (idx++ < *idx_skip)
                        continue;
-               if (batadv_bla_backbone_dump_entry(msg, portid, seq,
-                                                  primary_if, backbone_gw)) {
+
+               ret = batadv_bla_backbone_dump_entry(msg, portid, seq,
+                                                    primary_if, backbone_gw);
+               if (ret) {
                        *idx_skip = idx - 1;
                        goto unlock;
                }
        }
 
-       *idx_skip = idx;
+       *idx_skip = 0;
 unlock:
        rcu_read_unlock();
-       return 0;
+       return ret;
 }
 
 /**
index 9703c791ffc5ac2fd375531073f134e6beb86141..87cd962d28d58a0792893d3d9a1aee79dc2c51cc 100644 (file)
@@ -393,7 +393,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
                   batadv_arp_hw_src(skb, hdr_size), &ip_src,
                   batadv_arp_hw_dst(skb, hdr_size), &ip_dst);
 
-       if (hdr_size == 0)
+       if (hdr_size < sizeof(struct batadv_unicast_packet))
                return;
 
        unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
index 22dde42fd80e63e79faebfdb0d807786f1b9a4b5..5afe641ee4b0daa366ae7c3ce919b26b2802acb1 100644 (file)
@@ -288,7 +288,8 @@ batadv_frag_merge_packets(struct hlist_head *chain)
        /* Move the existing MAC header to just before the payload. (Override
         * the fragment header.)
         */
-       skb_pull_rcsum(skb_out, hdr_size);
+       skb_pull(skb_out, hdr_size);
+       skb_out->ip_summed = CHECKSUM_NONE;
        memmove(skb_out->data - ETH_HLEN, skb_mac_header(skb_out), ETH_HLEN);
        skb_set_mac_header(skb_out, -ETH_HLEN);
        skb_reset_network_header(skb_out);
index 5f186bff284a37132eaa4862854308163269a22f..68b54a39c51d16f4f82ed35485273f7791c0e854 100644 (file)
@@ -763,6 +763,11 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
        hard_iface->soft_iface = soft_iface;
        bat_priv = netdev_priv(hard_iface->soft_iface);
 
+       if (bat_priv->num_ifaces >= UINT_MAX) {
+               ret = -ENOSPC;
+               goto err_dev;
+       }
+
        ret = netdev_master_upper_dev_link(hard_iface->net_dev,
                                           soft_iface, NULL, NULL, NULL);
        if (ret)
@@ -876,7 +881,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
        batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
 
        /* nobody uses this interface anymore */
-       if (!bat_priv->num_ifaces) {
+       if (bat_priv->num_ifaces == 0) {
                batadv_gw_check_client_stop(bat_priv);
 
                if (autodel == BATADV_IF_CLEANUP_AUTO)
@@ -912,7 +917,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
        if (ret)
                goto free_if;
 
-       hard_iface->if_num = -1;
+       hard_iface->if_num = 0;
        hard_iface->net_dev = net_dev;
        hard_iface->soft_iface = NULL;
        hard_iface->if_status = BATADV_IF_NOT_IN_USE;
index e91f29c7c638a5f9fede10b08cdd11f37d2ee1e6..5daa3d50da17721d56abccc644c63460fa4b9050 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/debugfs.h>
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
+#include <linux/eventpoll.h>
 #include <linux/export.h>
 #include <linux/fcntl.h>
 #include <linux/fs.h>
index dc9fa37ddd14145b90053e59beb78211f3a22d23..cdbe0e5e208b8b5903d80bbdca563d00f624ac20 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/compiler.h>
 #include <linux/debugfs.h>
 #include <linux/errno.h>
+#include <linux/eventpoll.h>
 #include <linux/export.h>
 #include <linux/fcntl.h>
 #include <linux/fs.h>
index cbdeb47ec3f606ddfe53a122392d82576914480b..d70640135e3ab2a925c8eab23ef918f6e81c016a 100644 (file)
@@ -543,8 +543,8 @@ update:
                bat_priv->mcast.enabled = true;
        }
 
-       return !(mcast_data.flags &
-                (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6));
+       return !(mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV4 &&
+                mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV6);
 }
 
 /**
index 58a7d9274435cffe99fdb661ce7005f5f6da35c1..74782426bb771b41d0dcc394813432be0a65c9b1 100644 (file)
@@ -1569,7 +1569,7 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
  * Return: 0 on success or negative error number in case of failure
  */
 int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
-                           int max_if_num)
+                           unsigned int max_if_num)
 {
        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
        struct batadv_algo_ops *bao = bat_priv->algo_ops;
@@ -1611,7 +1611,7 @@ err:
  * Return: 0 on success or negative error number in case of failure
  */
 int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
-                           int max_if_num)
+                           unsigned int max_if_num)
 {
        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
        struct batadv_hashtable *hash = bat_priv->orig_hash;
index 8e543a3cdc6c310297be13a5253ef33819b9df68..15d896b2de6f9083cee2e72b3086ecef4394bc14 100644 (file)
@@ -73,9 +73,9 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
 int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
 int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
 int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
-                           int max_if_num);
+                           unsigned int max_if_num);
 int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
-                           int max_if_num);
+                           unsigned int max_if_num);
 struct batadv_orig_node_vlan *
 batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
                          unsigned short vid);
index b6891e8b741c424496c58a21944f5bf30cff02ff..e61dc1293bb5aa1df1b76c8987f7ae39b506422f 100644 (file)
@@ -759,6 +759,7 @@ free_skb:
 /**
  * batadv_reroute_unicast_packet() - update the unicast header for re-routing
  * @bat_priv: the bat priv with all the soft interface information
+ * @skb: unicast packet to process
  * @unicast_packet: the unicast header to be updated
  * @dst_addr: the payload destination
  * @vid: VLAN identifier
@@ -770,7 +771,7 @@ free_skb:
  * Return: true if the packet header has been updated, false otherwise
  */
 static bool
-batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
+batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
                              struct batadv_unicast_packet *unicast_packet,
                              u8 *dst_addr, unsigned short vid)
 {
@@ -799,8 +800,10 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
        }
 
        /* update the packet header */
+       skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
        ether_addr_copy(unicast_packet->dest, orig_addr);
        unicast_packet->ttvn = orig_ttvn;
+       skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
 
        ret = true;
 out:
@@ -841,7 +844,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
         * the packet to
         */
        if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
-               if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
+               if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet,
                                                  ethhdr->h_dest, vid))
                        batadv_dbg_ratelimited(BATADV_DBG_TT,
                                               bat_priv,
@@ -887,7 +890,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
         * destination can possibly be updated and forwarded towards the new
         * target host
         */
-       if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
+       if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet,
                                          ethhdr->h_dest, vid)) {
                batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv,
                                       "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
@@ -910,12 +913,14 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
        if (!primary_if)
                return false;
 
+       /* update the packet header */
+       skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
        ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr);
+       unicast_packet->ttvn = curr_ttvn;
+       skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
 
        batadv_hardif_put(primary_if);
 
-       unicast_packet->ttvn = curr_ttvn;
-
        return true;
 }
 
@@ -968,14 +973,10 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
        struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL;
        int check, hdr_size = sizeof(*unicast_packet);
        enum batadv_subtype subtype;
-       struct ethhdr *ethhdr;
        int ret = NET_RX_DROP;
        bool is4addr, is_gw;
 
        unicast_packet = (struct batadv_unicast_packet *)skb->data;
-       unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
-       ethhdr = eth_hdr(skb);
-
        is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR;
        /* the caller function should have already pulled 2 bytes */
        if (is4addr)
@@ -995,12 +996,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
        if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
                goto free_skb;
 
+       unicast_packet = (struct batadv_unicast_packet *)skb->data;
+
        /* packet for me */
        if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
                /* If this is a unicast packet from another backgone gw,
                 * drop it.
                 */
-               orig_addr_gw = ethhdr->h_source;
+               orig_addr_gw = eth_hdr(skb)->h_source;
                orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw);
                if (orig_node_gw) {
                        is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw,
@@ -1015,6 +1018,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
                }
 
                if (is4addr) {
+                       unicast_4addr_packet =
+                               (struct batadv_unicast_4addr_packet *)skb->data;
                        subtype = unicast_4addr_packet->subtype;
                        batadv_dat_inc_counter(bat_priv, subtype);
 
index 900c5ce21cd410dc77bc0e008ae714c95e6af55a..367a81fb785f6c2e1e03d4cf1f0456f6a2b10408 100644 (file)
@@ -459,13 +459,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
 
        /* skb->dev & skb->pkt_type are set here */
        skb->protocol = eth_type_trans(skb, soft_iface);
-
-       /* should not be necessary anymore as we use skb_pull_rcsum()
-        * TODO: please verify this and remove this TODO
-        * -- Dec 21st 2009, Simon Wunderlich
-        */
-
-       /* skb->ip_summed = CHECKSUM_UNNECESSARY; */
+       skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 
        batadv_inc_counter(bat_priv, BATADV_CNT_RX);
        batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
index bb1578410e0cfa390a496299e3c0ed73925e8410..a5aa6d61f4e224785160d850ecc42577e4f376d5 100644 (file)
@@ -167,7 +167,7 @@ struct batadv_hard_iface {
        struct list_head list;
 
        /** @if_num: identificator of the interface */
-       s16 if_num;
+       unsigned int if_num;
 
        /** @if_status: status of the interface for batman-adv */
        char if_status;
@@ -1596,7 +1596,7 @@ struct batadv_priv {
        atomic_t batman_queue_left;
 
        /** @num_ifaces: number of interfaces assigned to this mesh interface */
-       char num_ifaces;
+       unsigned int num_ifaces;
 
        /** @mesh_obj: kobject for sysfs mesh subdirectory */
        struct kobject *mesh_obj;
@@ -2186,15 +2186,16 @@ struct batadv_algo_orig_ops {
         *  orig_node due to a new hard-interface being added into the mesh
         *  (optional)
         */
-       int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num);
+       int (*add_if)(struct batadv_orig_node *orig_node,
+                     unsigned int max_if_num);
 
        /**
         * @del_if: ask the routing algorithm to apply the needed changes to the
         *  orig_node due to an hard-interface being removed from the mesh
         *  (optional)
         */
-       int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num,
-                     int del_if_num);
+       int (*del_if)(struct batadv_orig_node *orig_node,
+                     unsigned int max_if_num, unsigned int del_if_num);
 
 #ifdef CONFIG_BATMAN_ADV_DEBUGFS
        /** @print: print the originator table (optional) */
index 01117ae84f1d3f1246626396fbcf66ee2a532792..a2ddae2f37d7a264ed3d75be73624e0eae51655c 100644 (file)
@@ -2296,8 +2296,14 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
        else
                sec_level = authreq_to_seclevel(auth);
 
-       if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK))
+       if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) {
+               /* If link is already encrypted with sufficient security we
+                * still need refresh encryption as per Core Spec 5.0 Vol 3,
+                * Part H 2.4.6
+                */
+               smp_ltk_encrypt(conn, hcon->sec_level);
                return 0;
+       }
 
        if (sec_level > hcon->pending_sec_level)
                hcon->pending_sec_level = sec_level;
index 27f1d4f2114ab9dadf908dfd10105c9daac30230..9b16eaf3381960def1d938d2977e6c967a02c72a 100644 (file)
@@ -214,7 +214,7 @@ static int br_validate_ipv4(struct net *net, struct sk_buff *skb)
 
        iph = ip_hdr(skb);
        if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
-               goto inhdr_error;
+               goto csum_error;
 
        len = ntohs(iph->tot_len);
        if (skb->len < len) {
@@ -236,6 +236,8 @@ static int br_validate_ipv4(struct net *net, struct sk_buff *skb)
         */
        return 0;
 
+csum_error:
+       __IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
 inhdr_error:
        __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
 drop:
index 0254c35b2bf002d0bb4f0b52d7895617ce066e24..126a8ea73c9681dc2772423715f4717e2d1ec409 100644 (file)
@@ -255,6 +255,9 @@ static ssize_t brport_show(struct kobject *kobj,
        struct brport_attribute *brport_attr = to_brport_attr(attr);
        struct net_bridge_port *p = to_brport(kobj);
 
+       if (!brport_attr->show)
+               return -EINVAL;
+
        return brport_attr->show(p, buf);
 }
 
index 51935270c6512529b87bb252dcc64f6be17719f1..9896f4975353db00af2ebf7432633c5e84ff7f7d 100644 (file)
@@ -168,6 +168,8 @@ static struct net_bridge_vlan *br_vlan_get_master(struct net_bridge *br, u16 vid
                masterv = br_vlan_find(vg, vid);
                if (WARN_ON(!masterv))
                        return NULL;
+               refcount_set(&masterv->refcnt, 1);
+               return masterv;
        }
        refcount_inc(&masterv->refcnt);
 
index 279527f8b1fe74f30d75da640da8ef23f789ba3c..620e54f082965daef2646abbff8302dc9c39ed7e 100644 (file)
@@ -172,32 +172,83 @@ ebt_among_mt(const struct sk_buff *skb, struct xt_action_param *par)
        return true;
 }
 
+static bool poolsize_invalid(const struct ebt_mac_wormhash *w)
+{
+       return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple));
+}
+
+static bool wormhash_offset_invalid(int off, unsigned int len)
+{
+       if (off == 0) /* not present */
+               return false;
+
+       if (off < (int)sizeof(struct ebt_among_info) ||
+           off % __alignof__(struct ebt_mac_wormhash))
+               return true;
+
+       off += sizeof(struct ebt_mac_wormhash);
+
+       return off > len;
+}
+
+static bool wormhash_sizes_valid(const struct ebt_mac_wormhash *wh, int a, int b)
+{
+       if (a == 0)
+               a = sizeof(struct ebt_among_info);
+
+       return ebt_mac_wormhash_size(wh) + a == b;
+}
+
 static int ebt_among_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_among_info *info = par->matchinfo;
        const struct ebt_entry_match *em =
                container_of(par->matchinfo, const struct ebt_entry_match, data);
-       int expected_length = sizeof(struct ebt_among_info);
+       unsigned int expected_length = sizeof(struct ebt_among_info);
        const struct ebt_mac_wormhash *wh_dst, *wh_src;
        int err;
 
+       if (expected_length > em->match_size)
+               return -EINVAL;
+
+       if (wormhash_offset_invalid(info->wh_dst_ofs, em->match_size) ||
+           wormhash_offset_invalid(info->wh_src_ofs, em->match_size))
+               return -EINVAL;
+
        wh_dst = ebt_among_wh_dst(info);
-       wh_src = ebt_among_wh_src(info);
+       if (poolsize_invalid(wh_dst))
+               return -EINVAL;
+
        expected_length += ebt_mac_wormhash_size(wh_dst);
+       if (expected_length > em->match_size)
+               return -EINVAL;
+
+       wh_src = ebt_among_wh_src(info);
+       if (poolsize_invalid(wh_src))
+               return -EINVAL;
+
+       if (info->wh_src_ofs < info->wh_dst_ofs) {
+               if (!wormhash_sizes_valid(wh_src, info->wh_src_ofs, info->wh_dst_ofs))
+                       return -EINVAL;
+       } else {
+               if (!wormhash_sizes_valid(wh_dst, info->wh_dst_ofs, info->wh_src_ofs))
+                       return -EINVAL;
+       }
+
        expected_length += ebt_mac_wormhash_size(wh_src);
 
        if (em->match_size != EBT_ALIGN(expected_length)) {
-               pr_info("wrong size: %d against expected %d, rounded to %zd\n",
-                       em->match_size, expected_length,
-                       EBT_ALIGN(expected_length));
+               pr_err_ratelimited("wrong size: %d against expected %d, rounded to %zd\n",
+                                  em->match_size, expected_length,
+                                  EBT_ALIGN(expected_length));
                return -EINVAL;
        }
        if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
-               pr_info("dst integrity fail: %x\n", -err);
+               pr_err_ratelimited("dst integrity fail: %x\n", -err);
                return -EINVAL;
        }
        if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
-               pr_info("src integrity fail: %x\n", -err);
+               pr_err_ratelimited("src integrity fail: %x\n", -err);
                return -EINVAL;
        }
        return 0;
index 61a9f1be1263afc95dfbc43cdffe5d0a6e8e7246..165b9d678cf1d3a199142ecd97c7e7995f23b0ac 100644 (file)
@@ -72,8 +72,8 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
        /* Check for overflow. */
        if (info->burst == 0 ||
            user2credits(info->avg * info->burst) < user2credits(info->avg)) {
-               pr_info("overflow, try lower: %u/%u\n",
-                       info->avg, info->burst);
+               pr_info_ratelimited("overflow, try lower: %u/%u\n",
+                                   info->avg, info->burst);
                return -EINVAL;
        }
 
index 02c4b409d31733c6192110139570e48980aa1740..a94d23b0a9af30babff7469c09e9acbf51c1c260 100644 (file)
@@ -1641,7 +1641,8 @@ static int compat_match_to_user(struct ebt_entry_match *m, void __user **dstptr,
        int off = ebt_compat_match_offset(match, m->match_size);
        compat_uint_t msize = m->match_size - off;
 
-       BUG_ON(off >= m->match_size);
+       if (WARN_ON(off >= m->match_size))
+               return -EINVAL;
 
        if (copy_to_user(cm->u.name, match->name,
            strlen(match->name) + 1) || put_user(msize, &cm->match_size))
@@ -1671,7 +1672,8 @@ static int compat_target_to_user(struct ebt_entry_target *t,
        int off = xt_compat_target_offset(target);
        compat_uint_t tsize = t->target_size - off;
 
-       BUG_ON(off >= t->target_size);
+       if (WARN_ON(off >= t->target_size))
+               return -EINVAL;
 
        if (copy_to_user(cm->u.name, target->name,
            strlen(target->name) + 1) || put_user(tsize, &cm->match_size))
@@ -1902,7 +1904,8 @@ static int ebt_buf_add(struct ebt_entries_buf_state *state,
        if (state->buf_kern_start == NULL)
                goto count_only;
 
-       BUG_ON(state->buf_kern_offset + sz > state->buf_kern_len);
+       if (WARN_ON(state->buf_kern_offset + sz > state->buf_kern_len))
+               return -EINVAL;
 
        memcpy(state->buf_kern_start + state->buf_kern_offset, data, sz);
 
@@ -1915,7 +1918,8 @@ static int ebt_buf_add_pad(struct ebt_entries_buf_state *state, unsigned int sz)
 {
        char *b = state->buf_kern_start;
 
-       BUG_ON(b && state->buf_kern_offset > state->buf_kern_len);
+       if (WARN_ON(b && state->buf_kern_offset > state->buf_kern_len))
+               return -EINVAL;
 
        if (b != NULL && sz > 0)
                memset(b + state->buf_kern_offset, 0, sz);
@@ -1992,8 +1996,10 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt,
        pad = XT_ALIGN(size_kern) - size_kern;
 
        if (pad > 0 && dst) {
-               BUG_ON(state->buf_kern_len <= pad);
-               BUG_ON(state->buf_kern_offset - (match_size + off) + size_kern > state->buf_kern_len - pad);
+               if (WARN_ON(state->buf_kern_len <= pad))
+                       return -EINVAL;
+               if (WARN_ON(state->buf_kern_offset - (match_size + off) + size_kern > state->buf_kern_len - pad))
+                       return -EINVAL;
                memset(dst + size_kern, 0, pad);
        }
        return off + match_size;
@@ -2043,7 +2049,8 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
                if (ret < 0)
                        return ret;
 
-               BUG_ON(ret < match32->match_size);
+               if (WARN_ON(ret < match32->match_size))
+                       return -EINVAL;
                growth += ret - match32->match_size;
                growth += ebt_compat_entry_padsize();
 
@@ -2053,7 +2060,9 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
                if (match_kern)
                        match_kern->match_size = ret;
 
-               WARN_ON(type == EBT_COMPAT_TARGET && size_left);
+               if (WARN_ON(type == EBT_COMPAT_TARGET && size_left))
+                       return -EINVAL;
+
                match32 = (struct compat_ebt_entry_mwt *) buf;
        }
 
@@ -2109,6 +2118,19 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
         *
         * offsets are relative to beginning of struct ebt_entry (i.e., 0).
         */
+       for (i = 0; i < 4 ; ++i) {
+               if (offsets[i] > *total)
+                       return -EINVAL;
+
+               if (i < 3 && offsets[i] == *total)
+                       return -EINVAL;
+
+               if (i == 0)
+                       continue;
+               if (offsets[i-1] > offsets[i])
+                       return -EINVAL;
+       }
+
        for (i = 0, j = 1 ; j < 4 ; j++, i++) {
                struct compat_ebt_entry_mwt *match32;
                unsigned int size;
@@ -2140,7 +2162,8 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
 
        startoff = state->buf_user_offset - startoff;
 
-       BUG_ON(*total < startoff);
+       if (WARN_ON(*total < startoff))
+               return -EINVAL;
        *total -= startoff;
        return 0;
 }
@@ -2267,7 +2290,8 @@ static int compat_do_replace(struct net *net, void __user *user,
        state.buf_kern_len = size64;
 
        ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state);
-       BUG_ON(ret < 0);        /* parses same data again */
+       if (WARN_ON(ret < 0))
+               goto out_unlock;
 
        vfree(entries_tmp);
        tmp.entries_size = size64;
index 1e492ef2a33d945699a327831640db04c1f158fa..4d4c82229e9e21cea5ab7011aaf03e7a28e2b394 100644 (file)
@@ -418,6 +418,7 @@ ceph_parse_options(char *options, const char *dev_name,
                                opt->flags |= CEPH_OPT_FSID;
                        break;
                case Opt_name:
+                       kfree(opt->name);
                        opt->name = kstrndup(argstr[0].from,
                                              argstr[0].to-argstr[0].from,
                                              GFP_KERNEL);
@@ -427,6 +428,9 @@ ceph_parse_options(char *options, const char *dev_name,
                        }
                        break;
                case Opt_secret:
+                       ceph_crypto_key_destroy(opt->key);
+                       kfree(opt->key);
+
                        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
                        if (!opt->key) {
                                err = -ENOMEM;
@@ -437,6 +441,9 @@ ceph_parse_options(char *options, const char *dev_name,
                                goto out;
                        break;
                case Opt_key:
+                       ceph_crypto_key_destroy(opt->key);
+                       kfree(opt->key);
+
                        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
                        if (!opt->key) {
                                err = -ENOMEM;
index dda9d7b9a840702d13b518507fef7a3723fce017..12be205357146f0dcd55cc6e6f71dfb65fdeb33b 100644 (file)
@@ -2382,8 +2382,11 @@ EXPORT_SYMBOL(netdev_set_num_tc);
  */
 int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
 {
+       bool disabling;
        int rc;
 
+       disabling = txq < dev->real_num_tx_queues;
+
        if (txq < 1 || txq > dev->num_tx_queues)
                return -EINVAL;
 
@@ -2399,15 +2402,19 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
                if (dev->num_tc)
                        netif_setup_tc(dev, txq);
 
-               if (txq < dev->real_num_tx_queues) {
+               dev->real_num_tx_queues = txq;
+
+               if (disabling) {
+                       synchronize_net();
                        qdisc_reset_all_tx_gt(dev, txq);
 #ifdef CONFIG_XPS
                        netif_reset_xps_queues_gt(dev, txq);
 #endif
                }
+       } else {
+               dev->real_num_tx_queues = txq;
        }
 
-       dev->real_num_tx_queues = txq;
        return 0;
 }
 EXPORT_SYMBOL(netif_set_real_num_tx_queues);
@@ -3271,15 +3278,23 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
 #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
 static void skb_update_prio(struct sk_buff *skb)
 {
-       struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap);
+       const struct netprio_map *map;
+       const struct sock *sk;
+       unsigned int prioidx;
 
-       if (!skb->priority && skb->sk && map) {
-               unsigned int prioidx =
-                       sock_cgroup_prioidx(&skb->sk->sk_cgrp_data);
+       if (skb->priority)
+               return;
+       map = rcu_dereference_bh(skb->dev->priomap);
+       if (!map)
+               return;
+       sk = skb_to_full_sk(skb);
+       if (!sk)
+               return;
 
-               if (prioidx < map->priomap_len)
-                       skb->priority = map->priomap[prioidx];
-       }
+       prioidx = sock_cgroup_prioidx(&sk->sk_cgrp_data);
+
+       if (prioidx < map->priomap_len)
+               skb->priority = map->priomap[prioidx];
 }
 #else
 #define skb_update_prio(skb)
@@ -6389,6 +6404,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
                .linking = true,
                .upper_info = upper_info,
        };
+       struct net_device *master_dev;
        int ret = 0;
 
        ASSERT_RTNL();
@@ -6400,11 +6416,14 @@ static int __netdev_upper_dev_link(struct net_device *dev,
        if (netdev_has_upper_dev(upper_dev, dev))
                return -EBUSY;
 
-       if (netdev_has_upper_dev(dev, upper_dev))
-               return -EEXIST;
-
-       if (master && netdev_master_upper_dev_get(dev))
-               return -EBUSY;
+       if (!master) {
+               if (netdev_has_upper_dev(dev, upper_dev))
+                       return -EEXIST;
+       } else {
+               master_dev = netdev_master_upper_dev_get(dev);
+               if (master_dev)
+                       return master_dev == upper_dev ? -EEXIST : -EBUSY;
+       }
 
        ret = call_netdevice_notifiers_info(NETDEV_PRECHANGEUPPER,
                                            &changeupper_info.info);
index 0ab1af04296cbf0562fa51a88e48fe17ea168c60..a04e1e88bf3ab49340d788589c365aaf45d9d3e2 100644 (file)
@@ -402,8 +402,6 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c
        if (colon)
                *colon = 0;
 
-       dev_load(net, ifr->ifr_name);
-
        /*
         *      See which interface the caller is talking about.
         */
@@ -423,6 +421,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c
        case SIOCGIFMAP:
        case SIOCGIFINDEX:
        case SIOCGIFTXQLEN:
+               dev_load(net, ifr->ifr_name);
                rcu_read_lock();
                ret = dev_ifsioc_locked(net, ifr, cmd);
                rcu_read_unlock();
@@ -431,6 +430,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c
                return ret;
 
        case SIOCETHTOOL:
+               dev_load(net, ifr->ifr_name);
                rtnl_lock();
                ret = dev_ethtool(net, ifr);
                rtnl_unlock();
@@ -447,6 +447,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c
        case SIOCGMIIPHY:
        case SIOCGMIIREG:
        case SIOCSIFNAME:
+               dev_load(net, ifr->ifr_name);
                if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
                        return -EPERM;
                rtnl_lock();
@@ -494,6 +495,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c
                /* fall through */
        case SIOCBONDSLAVEINFOQUERY:
        case SIOCBONDINFOQUERY:
+               dev_load(net, ifr->ifr_name);
                rtnl_lock();
                ret = dev_ifsioc(net, ifr, cmd);
                rtnl_unlock();
@@ -518,6 +520,7 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr, bool *need_c
                    cmd == SIOCGHWTSTAMP ||
                    (cmd >= SIOCDEVPRIVATE &&
                     cmd <= SIOCDEVPRIVATE + 15)) {
+                       dev_load(net, ifr->ifr_name);
                        rtnl_lock();
                        ret = dev_ifsioc(net, ifr, cmd);
                        rtnl_unlock();
index 18d385ed82370a7b6a9a2e31023b785a054e9e9f..effd4848c2b4be150f6fad3356946b8678c16164 100644 (file)
@@ -1695,10 +1695,11 @@ static int devlink_dpipe_table_put(struct sk_buff *skb,
                goto nla_put_failure;
 
        if (table->resource_valid) {
-               nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
-                                 table->resource_id, DEVLINK_ATTR_PAD);
-               nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
-                                 table->resource_units, DEVLINK_ATTR_PAD);
+               if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
+                                     table->resource_id, DEVLINK_ATTR_PAD) ||
+                   nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
+                                     table->resource_units, DEVLINK_ATTR_PAD))
+                       goto nla_put_failure;
        }
        if (devlink_dpipe_matches_put(table, skb))
                goto nla_put_failure;
@@ -1797,7 +1798,7 @@ send_done:
        if (!nlh) {
                err = devlink_dpipe_send_and_alloc_skb(&skb, info);
                if (err)
-                       goto err_skb_send_alloc;
+                       return err;
                goto send_done;
        }
 
@@ -1806,7 +1807,6 @@ send_done:
 nla_put_failure:
        err = -EMSGSIZE;
 err_table_put:
-err_skb_send_alloc:
        genlmsg_cancel(skb, hdr);
        nlmsg_free(skb);
        return err;
@@ -2072,7 +2072,7 @@ static int devlink_dpipe_entries_fill(struct genl_info *info,
                                             table->counters_enabled,
                                             &dump_ctx);
        if (err)
-               goto err_entries_dump;
+               return err;
 
 send_done:
        nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
@@ -2080,16 +2080,10 @@ send_done:
        if (!nlh) {
                err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
                if (err)
-                       goto err_skb_send_alloc;
+                       return err;
                goto send_done;
        }
        return genlmsg_reply(dump_ctx.skb, info);
-
-err_entries_dump:
-err_skb_send_alloc:
-       genlmsg_cancel(dump_ctx.skb, dump_ctx.hdr);
-       nlmsg_free(dump_ctx.skb);
-       return err;
 }
 
 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
@@ -2228,7 +2222,7 @@ send_done:
        if (!nlh) {
                err = devlink_dpipe_send_and_alloc_skb(&skb, info);
                if (err)
-                       goto err_skb_send_alloc;
+                       return err;
                goto send_done;
        }
        return genlmsg_reply(skb, info);
@@ -2236,7 +2230,6 @@ send_done:
 nla_put_failure:
        err = -EMSGSIZE;
 err_table_put:
-err_skb_send_alloc:
        genlmsg_cancel(skb, hdr);
        nlmsg_free(skb);
        return err;
@@ -2332,7 +2325,7 @@ devlink_resource_validate_children(struct devlink_resource *resource)
        list_for_each_entry(child_resource, &resource->resource_list, list)
                parts_size += child_resource->size_new;
 
-       if (parts_size > resource->size)
+       if (parts_size > resource->size_new)
                size_valid = false;
 out:
        resource->size_valid = size_valid;
@@ -2372,20 +2365,22 @@ static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
        return 0;
 }
 
-static void
+static int
 devlink_resource_size_params_put(struct devlink_resource *resource,
                                 struct sk_buff *skb)
 {
        struct devlink_resource_size_params *size_params;
 
-       size_params = resource->size_params;
-       nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
-                         size_params->size_granularity, DEVLINK_ATTR_PAD);
-       nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
-                         size_params->size_max, DEVLINK_ATTR_PAD);
-       nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
-                         size_params->size_min, DEVLINK_ATTR_PAD);
-       nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit);
+       size_params = &resource->size_params;
+       if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
+                             size_params->size_granularity, DEVLINK_ATTR_PAD) ||
+           nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
+                             size_params->size_max, DEVLINK_ATTR_PAD) ||
+           nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
+                             size_params->size_min, DEVLINK_ATTR_PAD) ||
+           nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
+               return -EMSGSIZE;
+       return 0;
 }
 
 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
@@ -2409,10 +2404,12 @@ static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
                nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
                                  resource->size_new, DEVLINK_ATTR_PAD);
        if (resource->resource_ops && resource->resource_ops->occ_get)
-               nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
-                                 resource->resource_ops->occ_get(devlink),
-                                 DEVLINK_ATTR_PAD);
-       devlink_resource_size_params_put(resource, skb);
+               if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
+                                     resource->resource_ops->occ_get(devlink),
+                                     DEVLINK_ATTR_PAD))
+                       goto nla_put_failure;
+       if (devlink_resource_size_params_put(resource, skb))
+               goto nla_put_failure;
        if (list_empty(&resource->resource_list))
                goto out;
 
@@ -3151,7 +3148,7 @@ int devlink_resource_register(struct devlink *devlink,
                              u64 resource_size,
                              u64 resource_id,
                              u64 parent_resource_id,
-                             struct devlink_resource_size_params *size_params,
+                             const struct devlink_resource_size_params *size_params,
                              const struct devlink_resource_ops *resource_ops)
 {
        struct devlink_resource *resource;
@@ -3194,7 +3191,8 @@ int devlink_resource_register(struct devlink *devlink,
        resource->id = resource_id;
        resource->resource_ops = resource_ops;
        resource->size_valid = true;
-       resource->size_params = size_params;
+       memcpy(&resource->size_params, size_params,
+              sizeof(resource->size_params));
        INIT_LIST_HEAD(&resource->resource_list);
        list_add_tail(&resource->list, resource_list);
 out:
index 494e6a5d73061acd87534d636ee393555b0ed40d..3f89c76d5c24c51b889343fcdf0d94577cde7dc0 100644 (file)
@@ -2520,11 +2520,14 @@ static int set_phy_tunable(struct net_device *dev, void __user *useraddr)
 static int ethtool_get_fecparam(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_fecparam fecparam = { ETHTOOL_GFECPARAM };
+       int rc;
 
        if (!dev->ethtool_ops->get_fecparam)
                return -EOPNOTSUPP;
 
-       dev->ethtool_ops->get_fecparam(dev, &fecparam);
+       rc = dev->ethtool_ops->get_fecparam(dev, &fecparam);
+       if (rc)
+               return rc;
 
        if (copy_to_user(useraddr, &fecparam, sizeof(fecparam)))
                return -EFAULT;
index 08ab4c65a998db9458ca92176fbc1e465fde255a..48aa7c7320db5f01838327b1abd8ed337be54dc6 100644 (file)
@@ -2087,6 +2087,10 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
        u32 off = skb_mac_header_len(skb);
        int ret;
 
+       /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+       if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+               return -ENOTSUPP;
+
        ret = skb_cow(skb, len_diff);
        if (unlikely(ret < 0))
                return ret;
@@ -2096,19 +2100,21 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb)
                return ret;
 
        if (skb_is_gso(skb)) {
+               struct skb_shared_info *shinfo = skb_shinfo(skb);
+
                /* SKB_GSO_TCPV4 needs to be changed into
                 * SKB_GSO_TCPV6.
                 */
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
-                       skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV4;
-                       skb_shinfo(skb)->gso_type |=  SKB_GSO_TCPV6;
+               if (shinfo->gso_type & SKB_GSO_TCPV4) {
+                       shinfo->gso_type &= ~SKB_GSO_TCPV4;
+                       shinfo->gso_type |=  SKB_GSO_TCPV6;
                }
 
                /* Due to IPv6 header, MSS needs to be downgraded. */
-               skb_shinfo(skb)->gso_size -= len_diff;
+               skb_decrease_gso_size(shinfo, len_diff);
                /* Header must be checked, and gso_segs recomputed. */
-               skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
-               skb_shinfo(skb)->gso_segs = 0;
+               shinfo->gso_type |= SKB_GSO_DODGY;
+               shinfo->gso_segs = 0;
        }
 
        skb->protocol = htons(ETH_P_IPV6);
@@ -2123,6 +2129,10 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
        u32 off = skb_mac_header_len(skb);
        int ret;
 
+       /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+       if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+               return -ENOTSUPP;
+
        ret = skb_unclone(skb, GFP_ATOMIC);
        if (unlikely(ret < 0))
                return ret;
@@ -2132,19 +2142,21 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb)
                return ret;
 
        if (skb_is_gso(skb)) {
+               struct skb_shared_info *shinfo = skb_shinfo(skb);
+
                /* SKB_GSO_TCPV6 needs to be changed into
                 * SKB_GSO_TCPV4.
                 */
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
-                       skb_shinfo(skb)->gso_type &= ~SKB_GSO_TCPV6;
-                       skb_shinfo(skb)->gso_type |=  SKB_GSO_TCPV4;
+               if (shinfo->gso_type & SKB_GSO_TCPV6) {
+                       shinfo->gso_type &= ~SKB_GSO_TCPV6;
+                       shinfo->gso_type |=  SKB_GSO_TCPV4;
                }
 
                /* Due to IPv4 header, MSS can be upgraded. */
-               skb_shinfo(skb)->gso_size += len_diff;
+               skb_increase_gso_size(shinfo, len_diff);
                /* Header must be checked, and gso_segs recomputed. */
-               skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
-               skb_shinfo(skb)->gso_segs = 0;
+               shinfo->gso_type |= SKB_GSO_DODGY;
+               shinfo->gso_segs = 0;
        }
 
        skb->protocol = htons(ETH_P_IP);
@@ -2243,6 +2255,10 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff)
        u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
        int ret;
 
+       /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+       if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+               return -ENOTSUPP;
+
        ret = skb_cow(skb, len_diff);
        if (unlikely(ret < 0))
                return ret;
@@ -2252,11 +2268,13 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff)
                return ret;
 
        if (skb_is_gso(skb)) {
+               struct skb_shared_info *shinfo = skb_shinfo(skb);
+
                /* Due to header grow, MSS needs to be downgraded. */
-               skb_shinfo(skb)->gso_size -= len_diff;
+               skb_decrease_gso_size(shinfo, len_diff);
                /* Header must be checked, and gso_segs recomputed. */
-               skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
-               skb_shinfo(skb)->gso_segs = 0;
+               shinfo->gso_type |= SKB_GSO_DODGY;
+               shinfo->gso_segs = 0;
        }
 
        return 0;
@@ -2267,6 +2285,10 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff)
        u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb);
        int ret;
 
+       /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */
+       if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb)))
+               return -ENOTSUPP;
+
        ret = skb_unclone(skb, GFP_ATOMIC);
        if (unlikely(ret < 0))
                return ret;
@@ -2276,11 +2298,13 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff)
                return ret;
 
        if (skb_is_gso(skb)) {
+               struct skb_shared_info *shinfo = skb_shinfo(skb);
+
                /* Due to header shrink, MSS can be upgraded. */
-               skb_shinfo(skb)->gso_size += len_diff;
+               skb_increase_gso_size(shinfo, len_diff);
                /* Header must be checked, and gso_segs recomputed. */
-               skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
-               skb_shinfo(skb)->gso_segs = 0;
+               shinfo->gso_type |= SKB_GSO_DODGY;
+               shinfo->gso_segs = 0;
        }
 
        return 0;
@@ -3381,17 +3405,13 @@ BPF_CALL_2(bpf_sock_ops_cb_flags_set, struct bpf_sock_ops_kern *, bpf_sock,
        struct sock *sk = bpf_sock->sk;
        int val = argval & BPF_SOCK_OPS_ALL_CB_FLAGS;
 
-       if (!sk_fullsock(sk))
+       if (!IS_ENABLED(CONFIG_INET) || !sk_fullsock(sk))
                return -EINVAL;
 
-#ifdef CONFIG_INET
        if (val)
                tcp_sk(sk)->bpf_sock_ops_cb_flags = val;
 
        return argval & (~BPF_SOCK_OPS_ALL_CB_FLAGS);
-#else
-       return -EINVAL;
-#endif
 }
 
 static const struct bpf_func_proto bpf_sock_ops_cb_flags_set_proto = {
index 0a3f88f08727f1f1217560407ff539c8a8c17496..98fd12721221e4aa26e4d11be9de6c0305fb6dd9 100644 (file)
@@ -66,6 +66,7 @@ struct net_rate_estimator {
 static void est_fetch_counters(struct net_rate_estimator *e,
                               struct gnet_stats_basic_packed *b)
 {
+       memset(b, 0, sizeof(*b));
        if (e->stats_lock)
                spin_lock(e->stats_lock);
 
index 09bd89c90a71c761728392ce0112b72b817d6240..1e7acdc30732ef1f201309df528d26e8494d2770 100644 (file)
@@ -4179,7 +4179,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 
        skb_queue_tail(&sk->sk_error_queue, skb);
        if (!sock_flag(sk, SOCK_DEAD))
-               sk->sk_data_ready(sk);
+               sk->sk_error_report(sk);
        return 0;
 }
 EXPORT_SYMBOL(sock_queue_err_skb);
@@ -4891,7 +4891,7 @@ EXPORT_SYMBOL_GPL(skb_scrub_packet);
  *
  * The MAC/L2 or network (IP, IPv6) headers are not accounted for.
  */
-unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
+static unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
 {
        const struct skb_shared_info *shinfo = skb_shinfo(skb);
        unsigned int thlen = 0;
@@ -4904,7 +4904,7 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
                        thlen += inner_tcp_hdrlen(skb);
        } else if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
                thlen = tcp_hdrlen(skb);
-       } else if (unlikely(shinfo->gso_type & SKB_GSO_SCTP)) {
+       } else if (unlikely(skb_is_gso_sctp(skb))) {
                thlen = sizeof(struct sctphdr);
        }
        /* UFO sets gso_size to the size of the fragmentation
@@ -4913,7 +4913,40 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
         */
        return thlen + shinfo->gso_size;
 }
-EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);
+
+/**
+ * skb_gso_network_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_network_seglen is used to determine the real size of the
+ * individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP).
+ *
+ * The MAC/L2 header is not accounted for.
+ */
+static unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
+{
+       unsigned int hdr_len = skb_transport_header(skb) -
+                              skb_network_header(skb);
+
+       return hdr_len + skb_gso_transport_seglen(skb);
+}
+
+/**
+ * skb_gso_mac_seglen - Return length of individual segments of a gso packet
+ *
+ * @skb: GSO skb
+ *
+ * skb_gso_mac_seglen is used to determine the real size of the
+ * individual segments, including MAC/L2, Layer3 (IP, IPv6) and L4
+ * headers (TCP/UDP).
+ */
+static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb)
+{
+       unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
+
+       return hdr_len + skb_gso_transport_seglen(skb);
+}
 
 /**
  * skb_gso_size_check - check the skb size, considering GSO_BY_FRAGS
@@ -4955,19 +4988,20 @@ static inline bool skb_gso_size_check(const struct sk_buff *skb,
 }
 
 /**
- * skb_gso_validate_mtu - Return in case such skb fits a given MTU
+ * skb_gso_validate_network_len - Will a split GSO skb fit into a given MTU?
  *
  * @skb: GSO skb
  * @mtu: MTU to validate against
  *
- * skb_gso_validate_mtu validates if a given skb will fit a wanted MTU
- * once split.
+ * skb_gso_validate_network_len validates if a given skb will fit a
+ * wanted MTU once split. It considers L3 headers, L4 headers, and the
+ * payload.
  */
-bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu)
+bool skb_gso_validate_network_len(const struct sk_buff *skb, unsigned int mtu)
 {
        return skb_gso_size_check(skb, skb_gso_network_seglen(skb), mtu);
 }
-EXPORT_SYMBOL_GPL(skb_gso_validate_mtu);
+EXPORT_SYMBOL_GPL(skb_gso_validate_network_len);
 
 /**
  * skb_gso_validate_mac_len - Will a split GSO skb fit in a given length?
@@ -4986,13 +5020,16 @@ EXPORT_SYMBOL_GPL(skb_gso_validate_mac_len);
 
 static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
 {
+       int mac_len;
+
        if (skb_cow(skb, skb_headroom(skb)) < 0) {
                kfree_skb(skb);
                return NULL;
        }
 
-       memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN,
-               2 * ETH_ALEN);
+       mac_len = skb->data - skb_mac_header(skb);
+       memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
+               mac_len - VLAN_HLEN - ETH_TLEN);
        skb->mac_header += VLAN_HLEN;
        return skb;
 }
index c501499a04fe973e80e18655b306d762d348ff44..85b0b64e7f9dd565b5e85579ce43b78ddb65dc86 100644 (file)
@@ -3261,6 +3261,27 @@ void proto_unregister(struct proto *prot)
 }
 EXPORT_SYMBOL(proto_unregister);
 
+int sock_load_diag_module(int family, int protocol)
+{
+       if (!protocol) {
+               if (!sock_is_registered(family))
+                       return -ENOENT;
+
+               return request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+                                     NETLINK_SOCK_DIAG, family);
+       }
+
+#ifdef CONFIG_INET
+       if (family == AF_INET &&
+           !rcu_access_pointer(inet_protos[protocol]))
+               return -ENOENT;
+#endif
+
+       return request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
+                             NETLINK_SOCK_DIAG, family, protocol);
+}
+EXPORT_SYMBOL(sock_load_diag_module);
+
 #ifdef CONFIG_PROC_FS
 static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
        __acquires(proto_list_mutex)
index 146b50e30659daca3bdc4413d800890ef482f521..c37b5be7c5e4f0b4b91267b34c5ba867e90cbc69 100644 (file)
@@ -220,8 +220,7 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
                return -EINVAL;
 
        if (sock_diag_handlers[req->sdiag_family] == NULL)
-               request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
-                               NETLINK_SOCK_DIAG, req->sdiag_family);
+               sock_load_diag_module(req->sdiag_family, 0);
 
        mutex_lock(&sock_diag_table_mutex);
        hndl = sock_diag_handlers[req->sdiag_family];
@@ -247,8 +246,7 @@ static int sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
        case TCPDIAG_GETSOCK:
        case DCCPDIAG_GETSOCK:
                if (inet_rcv_compat == NULL)
-                       request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
-                                       NETLINK_SOCK_DIAG, AF_INET);
+                       sock_load_diag_module(AF_INET, 0);
 
                mutex_lock(&sock_diag_table_mutex);
                if (inet_rcv_compat != NULL)
@@ -281,14 +279,12 @@ static int sock_diag_bind(struct net *net, int group)
        case SKNLGRP_INET_TCP_DESTROY:
        case SKNLGRP_INET_UDP_DESTROY:
                if (!sock_diag_handlers[AF_INET])
-                       request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
-                                      NETLINK_SOCK_DIAG, AF_INET);
+                       sock_load_diag_module(AF_INET, 0);
                break;
        case SKNLGRP_INET6_TCP_DESTROY:
        case SKNLGRP_INET6_UDP_DESTROY:
                if (!sock_diag_handlers[AF_INET6])
-                       request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
-                                      NETLINK_SOCK_DIAG, AF_INET6);
+                       sock_load_diag_module(AF_INET6, 0);
                break;
        }
        return 0;
index 15bdc002d90c0fba1a532a330348facdf50547c8..84cd4e3fd01b1dec5ed4234291dde60d4f1d1d61 100644 (file)
@@ -794,6 +794,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        if (skb == NULL)
                goto out_release;
 
+       if (sk->sk_state == DCCP_CLOSED) {
+               rc = -ENOTCONN;
+               goto out_discard;
+       }
+
        skb_reserve(skb, sk->sk_prot->max_header);
        rc = memcpy_from_msg(skb_put(skb, len), msg, len);
        if (rc != 0)
index 91dd09f798089e1a1144579f128e5c6dae3a9c0e..791aff68af88537dd8fcab0cbd4d844bb7a25807 100644 (file)
@@ -1338,6 +1338,12 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
        lock_sock(sk);
        err = __dn_setsockopt(sock, level, optname, optval, optlen, 0);
        release_sock(sk);
+#ifdef CONFIG_NETFILTER
+       /* we need to exclude all possible ENOPROTOOPTs except default case */
+       if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
+           optname != DSO_STREAM && optname != DSO_SEQPACKET)
+               err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
+#endif
 
        return err;
 }
@@ -1445,15 +1451,6 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
                dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation);
                break;
 
-       default:
-#ifdef CONFIG_NETFILTER
-               return nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
-#endif
-       case DSO_LINKINFO:
-       case DSO_STREAM:
-       case DSO_SEQPACKET:
-               return -ENOPROTOOPT;
-
        case DSO_MAXWINDOW:
                if (optlen != sizeof(unsigned long))
                        return -EINVAL;
@@ -1501,6 +1498,12 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char __us
                        return -EINVAL;
                scp->info_loc = u.info;
                break;
+
+       case DSO_LINKINFO:
+       case DSO_STREAM:
+       case DSO_SEQPACKET:
+       default:
+               return -ENOPROTOOPT;
        }
 
        return 0;
@@ -1514,6 +1517,20 @@ static int dn_getsockopt(struct socket *sock, int level, int optname, char __use
        lock_sock(sk);
        err = __dn_getsockopt(sock, level, optname, optval, optlen, 0);
        release_sock(sk);
+#ifdef CONFIG_NETFILTER
+       if (err == -ENOPROTOOPT && optname != DSO_STREAM &&
+           optname != DSO_SEQPACKET && optname != DSO_CONACCEPT &&
+           optname != DSO_CONREJECT) {
+               int len;
+
+               if (get_user(len, optlen))
+                       return -EFAULT;
+
+               err = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
+               if (err >= 0)
+                       err = put_user(len, optlen);
+       }
+#endif
 
        return err;
 }
@@ -1579,26 +1596,6 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
                r_data = &link;
                break;
 
-       default:
-#ifdef CONFIG_NETFILTER
-       {
-               int ret, len;
-
-               if (get_user(len, optlen))
-                       return -EFAULT;
-
-               ret = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
-               if (ret >= 0)
-                       ret = put_user(len, optlen);
-               return ret;
-       }
-#endif
-       case DSO_STREAM:
-       case DSO_SEQPACKET:
-       case DSO_CONACCEPT:
-       case DSO_CONREJECT:
-               return -ENOPROTOOPT;
-
        case DSO_MAXWINDOW:
                if (r_len > sizeof(unsigned long))
                        r_len = sizeof(unsigned long);
@@ -1630,6 +1627,13 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
                        r_len = sizeof(unsigned char);
                r_data = &scp->info_rem;
                break;
+
+       case DSO_STREAM:
+       case DSO_SEQPACKET:
+       case DSO_CONACCEPT:
+       case DSO_CONREJECT:
+       default:
+               return -ENOPROTOOPT;
        }
 
        if (r_data) {
index cb54b81d0bd9e68629dbc742e1242686fbcfb83e..42a7b85b84e1f66e83387867e6a3eea750647277 100644 (file)
@@ -194,7 +194,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds,
                ds->ports[i].dn = cd->port_dn[i];
                ds->ports[i].cpu_dp = dst->cpu_dp;
 
-               if (dsa_is_user_port(ds, i))
+               if (!dsa_is_user_port(ds, i))
                        continue;
 
                ret = dsa_slave_create(&ds->ports[i]);
index 974765b7d92a75546fe5ae5dbc332078a54f627a..e9f0489e422944ee15b40e10e39bc7200c4bb905 100644 (file)
@@ -206,9 +206,13 @@ static inline void lowpan_netlink_fini(void)
 static int lowpan_device_event(struct notifier_block *unused,
                               unsigned long event, void *ptr)
 {
-       struct net_device *wdev = netdev_notifier_info_to_dev(ptr);
+       struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
+       struct wpan_dev *wpan_dev;
 
-       if (wdev->type != ARPHRD_IEEE802154)
+       if (ndev->type != ARPHRD_IEEE802154)
+               return NOTIFY_DONE;
+       wpan_dev = ndev->ieee802154_ptr;
+       if (!wpan_dev)
                return NOTIFY_DONE;
 
        switch (event) {
@@ -217,8 +221,8 @@ static int lowpan_device_event(struct notifier_block *unused,
                 * also delete possible lowpan interfaces which belongs
                 * to the wpan interface.
                 */
-               if (wdev->ieee802154_ptr->lowpan_dev)
-                       lowpan_dellink(wdev->ieee802154_ptr->lowpan_dev, NULL);
+               if (wpan_dev->lowpan_dev)
+                       lowpan_dellink(wpan_dev->lowpan_dev, NULL);
                break;
        default:
                return NOTIFY_DONE;
index c586597da20dbb0e46eb0f693fd65bccfc8f3633..7d36a950d9610bed29c789b3c38c8dfa8299d253 100644 (file)
@@ -646,6 +646,11 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi,
                                            fi->fib_nh, cfg, extack))
                                return 1;
                }
+#ifdef CONFIG_IP_ROUTE_CLASSID
+               if (cfg->fc_flow &&
+                   cfg->fc_flow != fi->fib_nh->nh_tclassid)
+                       return 1;
+#endif
                if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) &&
                    (!cfg->fc_gw  || cfg->fc_gw == fi->fib_nh->nh_gw))
                        return 0;
index a383f299ce246bd84b28bad1909bae600ad699c0..4e5bc4b2f14e6786ceb7d63e5902f8fc17819dfa 100644 (file)
@@ -53,8 +53,7 @@ static DEFINE_MUTEX(inet_diag_table_mutex);
 static const struct inet_diag_handler *inet_diag_lock_handler(int proto)
 {
        if (!inet_diag_table[proto])
-               request_module("net-pf-%d-proto-%d-type-%d-%d", PF_NETLINK,
-                              NETLINK_SOCK_DIAG, AF_INET, proto);
+               sock_load_diag_module(AF_INET, proto);
 
        mutex_lock(&inet_diag_table_mutex);
        if (!inet_diag_table[proto])
index 26a3d0315728ed2b16ca46080a3546668100bc8e..e8ec28999f5ce0c5d496e9a97ca1748b18db0cf0 100644 (file)
@@ -119,6 +119,9 @@ out:
 
 static bool inet_fragq_should_evict(const struct inet_frag_queue *q)
 {
+       if (!hlist_unhashed(&q->list_evictor))
+               return false;
+
        return q->net->low_thresh == 0 ||
               frag_mem_limit(q->net) >= q->net->low_thresh;
 }
index 2dd21c3281a1cb4194dbb34dad086b701716220d..b54b948b059608fc3157fedf40e61519321c6912 100644 (file)
@@ -55,7 +55,7 @@ static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
        if (skb->ignore_df)
                return false;
 
-       if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
+       if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
                return false;
 
        return true;
index 45d97e9b2759dc7430f56cd4e563eab5bf7d3e44..0901de42ed85a6e1e9c5398eca298686eab3967e 100644 (file)
@@ -970,9 +970,6 @@ static void __gre_tunnel_init(struct net_device *dev)
 
        t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
-       dev->needed_headroom    = LL_MAX_HEADER + t_hlen + 4;
-       dev->mtu                = ETH_DATA_LEN - t_hlen - 4;
-
        dev->features           |= GRE_FEATURES;
        dev->hw_features        |= GRE_FEATURES;
 
@@ -1290,8 +1287,6 @@ static int erspan_tunnel_init(struct net_device *dev)
                       erspan_hdr_len(tunnel->erspan_ver);
        t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
-       dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
-       dev->mtu = ETH_DATA_LEN - t_hlen - 4;
        dev->features           |= GRE_FEATURES;
        dev->hw_features        |= GRE_FEATURES;
        dev->priv_flags         |= IFF_LIVE_ADDR_CHANGE;
index e8e675be60ec0044007c660bae1bb4d12c9a484e..66340ab750e69ff5775f7996192839a24ddc6e65 100644 (file)
@@ -248,7 +248,7 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
 
        /* common case: seglen is <= mtu
         */
-       if (skb_gso_validate_mtu(skb, mtu))
+       if (skb_gso_validate_network_len(skb, mtu))
                return ip_finish_output2(net, sk, skb);
 
        /* Slowpath -  GSO segment length exceeds the egress MTU.
index 008be04ac1cc5e3729ed2265f5cfe3b3b64e20f3..74c962b9b09c3c234388686fad4fb217c4e4a36e 100644 (file)
@@ -258,7 +258,8 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
                        src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
                        if (!ipv6_addr_v4mapped(&src_info->ipi6_addr))
                                return -EINVAL;
-                       ipc->oif = src_info->ipi6_ifindex;
+                       if (src_info->ipi6_ifindex)
+                               ipc->oif = src_info->ipi6_ifindex;
                        ipc->addr = src_info->ipi6_addr.s6_addr32[3];
                        continue;
                }
@@ -288,7 +289,8 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
                        if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo)))
                                return -EINVAL;
                        info = (struct in_pktinfo *)CMSG_DATA(cmsg);
-                       ipc->oif = info->ipi_ifindex;
+                       if (info->ipi_ifindex)
+                               ipc->oif = info->ipi_ifindex;
                        ipc->addr = info->ipi_spec_dst.s_addr;
                        break;
                }
@@ -1567,10 +1569,7 @@ int ip_getsockopt(struct sock *sk, int level,
                if (get_user(len, optlen))
                        return -EFAULT;
 
-               lock_sock(sk);
-               err = nf_getsockopt(sk, PF_INET, optname, optval,
-                               &len);
-               release_sock(sk);
+               err = nf_getsockopt(sk, PF_INET, optname, optval, &len);
                if (err >= 0)
                        err = put_user(len, optlen);
                return err;
@@ -1602,9 +1601,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
                if (get_user(len, optlen))
                        return -EFAULT;
 
-               lock_sock(sk);
                err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
-               release_sock(sk);
                if (err >= 0)
                        err = put_user(len, optlen);
                return err;
index d786a8441bce61d2624d0f4de94246345cc09119..6d21068f9b5531e34c0f8be180e2b835fdaae0d7 100644 (file)
@@ -710,16 +710,9 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
                }
        }
 
-       if (tunnel->fwmark) {
-               init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
-                                tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
-                                tunnel->fwmark);
-       }
-       else {
-               init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
-                                tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
-                                skb->mark);
-       }
+       init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
+                        tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link,
+                        tunnel->fwmark);
 
        if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
                goto tx_error;
index 4ffe302f9b8200f598f32341257aec4e2a4a6f42..e3e420f3ba7b2de96be867912695efb3ae2b193c 100644 (file)
@@ -252,6 +252,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
                        }
                        if (table_base + v
                            != arpt_next_entry(e)) {
+                               if (unlikely(stackidx >= private->stacksize)) {
+                                       verdict = NF_DROP;
+                                       break;
+                               }
                                jumpstack[stackidx++] = e;
                        }
 
index 9a71f3149507064225d18a4e8ef11780daebe2d2..e38395a8dcf2806677cde272f72b3809c4f404a8 100644 (file)
@@ -330,8 +330,13 @@ ipt_do_table(struct sk_buff *skb,
                                continue;
                        }
                        if (table_base + v != ipt_next_entry(e) &&
-                           !(e->ip.flags & IPT_F_GOTO))
+                           !(e->ip.flags & IPT_F_GOTO)) {
+                               if (unlikely(stackidx >= private->stacksize)) {
+                                       verdict = NF_DROP;
+                                       break;
+                               }
                                jumpstack[stackidx++] = e;
+                       }
 
                        e = get_entry(table_base, v);
                        continue;
index 3a84a60f6b39d4a17007880b3744bde037fca706..8a8ae61cea718c8a3df405cb1ec1b11d7db75e73 100644 (file)
@@ -107,12 +107,6 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c)
 
        local_bh_disable();
        if (refcount_dec_and_lock(&c->entries, &cn->lock)) {
-               list_del_rcu(&c->list);
-               spin_unlock(&cn->lock);
-               local_bh_enable();
-
-               unregister_netdevice_notifier(&c->notifier);
-
                /* In case anyone still accesses the file, the open/close
                 * functions are also incrementing the refcount on their own,
                 * so it's safe to remove the entry even if it's in use. */
@@ -120,6 +114,12 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c)
                if (cn->procdir)
                        proc_remove(c->pde);
 #endif
+               list_del_rcu(&c->list);
+               spin_unlock(&cn->lock);
+               local_bh_enable();
+
+               unregister_netdevice_notifier(&c->notifier);
+
                return;
        }
        local_bh_enable();
@@ -154,8 +154,12 @@ clusterip_config_find_get(struct net *net, __be32 clusterip, int entry)
 #endif
                if (unlikely(!refcount_inc_not_zero(&c->refcount)))
                        c = NULL;
-               else if (entry)
-                       refcount_inc(&c->entries);
+               else if (entry) {
+                       if (unlikely(!refcount_inc_not_zero(&c->entries))) {
+                               clusterip_config_put(c);
+                               c = NULL;
+                       }
+               }
        }
        rcu_read_unlock_bh();
 
@@ -228,7 +232,6 @@ clusterip_config_init(struct net *net, const struct ipt_clusterip_tgt_info *i,
        c->hash_mode = i->hash_mode;
        c->hash_initval = i->hash_initval;
        refcount_set(&c->refcount, 1);
-       refcount_set(&c->entries, 1);
 
        spin_lock_bh(&cn->lock);
        if (__clusterip_config_find(net, ip)) {
@@ -259,8 +262,10 @@ clusterip_config_init(struct net *net, const struct ipt_clusterip_tgt_info *i,
 
        c->notifier.notifier_call = clusterip_netdev_event;
        err = register_netdevice_notifier(&c->notifier);
-       if (!err)
+       if (!err) {
+               refcount_set(&c->entries, 1);
                return c;
+       }
 
 #ifdef CONFIG_PROC_FS
        proc_remove(c->pde);
@@ -269,7 +274,7 @@ err:
        spin_lock_bh(&cn->lock);
        list_del_rcu(&c->list);
        spin_unlock_bh(&cn->lock);
-       kfree(c);
+       clusterip_config_put(c);
 
        return ERR_PTR(err);
 }
@@ -492,12 +497,15 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
                                return PTR_ERR(config);
                }
        }
-       cipinfo->config = config;
 
        ret = nf_ct_netns_get(par->net, par->family);
-       if (ret < 0)
+       if (ret < 0) {
                pr_info("cannot load conntrack support for proto=%u\n",
                        par->family);
+               clusterip_config_entry_put(par->net, config);
+               clusterip_config_put(config);
+               return ret;
+       }
 
        if (!par->net->xt.clusterip_deprecated_warning) {
                pr_info("ipt_CLUSTERIP is deprecated and it will removed soon, "
@@ -505,6 +513,7 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
                par->net->xt.clusterip_deprecated_warning = true;
        }
 
+       cipinfo->config = config;
        return ret;
 }
 
index 270765236f5e8cc9e39c02f9b6fa0836f853f96d..aaaf9a81fbc9730050bde35217f47634fd8aca41 100644 (file)
@@ -98,17 +98,15 @@ static int ecn_tg_check(const struct xt_tgchk_param *par)
        const struct ipt_ECN_info *einfo = par->targinfo;
        const struct ipt_entry *e = par->entryinfo;
 
-       if (einfo->operation & IPT_ECN_OP_MASK) {
-               pr_info("unsupported ECN operation %x\n", einfo->operation);
+       if (einfo->operation & IPT_ECN_OP_MASK)
                return -EINVAL;
-       }
-       if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
-               pr_info("new ECT codepoint %x out of mask\n", einfo->ip_ect);
+
+       if (einfo->ip_ect & ~IPT_ECN_IP_MASK)
                return -EINVAL;
-       }
+
        if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) &&
            (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
-               pr_info("cannot use TCP operations on a non-tcp rule\n");
+               pr_info_ratelimited("cannot use operation on non-tcp rule\n");
                return -EINVAL;
        }
        return 0;
index 8bd0d7b266320ecf51e0782ad6ccc7d7ad276ebe..e8bed3390e58e0c324daf5202849485bcf5d0fe5 100644 (file)
@@ -74,13 +74,13 @@ static int reject_tg_check(const struct xt_tgchk_param *par)
        const struct ipt_entry *e = par->entryinfo;
 
        if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
-               pr_info("ECHOREPLY no longer supported.\n");
+               pr_info_ratelimited("ECHOREPLY no longer supported.\n");
                return -EINVAL;
        } else if (rejinfo->with == IPT_TCP_RESET) {
                /* Must specify that it's a TCP packet */
                if (e->ip.proto != IPPROTO_TCP ||
                    (e->ip.invflags & XT_INV_PROTO)) {
-                       pr_info("TCP_RESET invalid for non-tcp\n");
+                       pr_info_ratelimited("TCP_RESET invalid for non-tcp\n");
                        return -EINVAL;
                }
        }
index 37fb9552e85898d0ee9b311f22af31563c621de7..fd01f13c896a153c6ec54b2df5503da6c311cf4f 100644 (file)
@@ -105,14 +105,14 @@ static int rpfilter_check(const struct xt_mtchk_param *par)
        const struct xt_rpfilter_info *info = par->matchinfo;
        unsigned int options = ~XT_RPFILTER_OPTION_MASK;
        if (info->flags & options) {
-               pr_info("unknown options encountered");
+               pr_info_ratelimited("unknown options\n");
                return -EINVAL;
        }
 
        if (strcmp(par->table, "mangle") != 0 &&
            strcmp(par->table, "raw") != 0) {
-               pr_info("match only valid in the \'raw\' "
-                       "or \'mangle\' tables, not \'%s\'.\n", par->table);
+               pr_info_ratelimited("only valid in \'raw\' or \'mangle\' table, not \'%s\'\n",
+                                   par->table);
                return -EINVAL;
        }
 
index 25d2975da156fb015848a8fe7e0f6f8cc9d4842b..0cd46bffa46914efab9f26b7d85d7612f1b41450 100644 (file)
@@ -111,6 +111,7 @@ static int nf_flow_dnat_ip(const struct flow_offload *flow, struct sk_buff *skb,
        default:
                return -1;
        }
+       csum_replace4(&iph->check, addr, new_addr);
 
        return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr);
 }
@@ -185,7 +186,7 @@ static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
        if ((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0)
                return false;
 
-       if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
+       if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
                return false;
 
        return true;
index 49cc1c1df1bac0c9046f8d34db02c4bef18079e4..299e247b20326df8426ebf2bb3b6d91f1176527b 100644 (file)
@@ -128,10 +128,11 @@ static int ip_rt_redirect_silence __read_mostly   = ((HZ / 50) << (9 + 1));
 static int ip_rt_error_cost __read_mostly      = HZ;
 static int ip_rt_error_burst __read_mostly     = 5 * HZ;
 static int ip_rt_mtu_expires __read_mostly     = 10 * 60 * HZ;
-static int ip_rt_min_pmtu __read_mostly                = 512 + 20 + 20;
+static u32 ip_rt_min_pmtu __read_mostly                = 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly      = 256;
 
 static int ip_rt_gc_timeout __read_mostly      = RT_GC_TIMEOUT;
+
 /*
  *     Interface to generic destination cache.
  */
@@ -633,6 +634,7 @@ static inline u32 fnhe_hashfun(__be32 daddr)
 static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnhe)
 {
        rt->rt_pmtu = fnhe->fnhe_pmtu;
+       rt->rt_mtu_locked = fnhe->fnhe_mtu_locked;
        rt->dst.expires = fnhe->fnhe_expires;
 
        if (fnhe->fnhe_gw) {
@@ -643,7 +645,7 @@ static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception *fnh
 }
 
 static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
-                                 u32 pmtu, unsigned long expires)
+                                 u32 pmtu, bool lock, unsigned long expires)
 {
        struct fnhe_hash_bucket *hash;
        struct fib_nh_exception *fnhe;
@@ -680,8 +682,10 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
                        fnhe->fnhe_genid = genid;
                if (gw)
                        fnhe->fnhe_gw = gw;
-               if (pmtu)
+               if (pmtu) {
                        fnhe->fnhe_pmtu = pmtu;
+                       fnhe->fnhe_mtu_locked = lock;
+               }
                fnhe->fnhe_expires = max(1UL, expires);
                /* Update all cached dsts too */
                rt = rcu_dereference(fnhe->fnhe_rth_input);
@@ -705,6 +709,7 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,
                fnhe->fnhe_daddr = daddr;
                fnhe->fnhe_gw = gw;
                fnhe->fnhe_pmtu = pmtu;
+               fnhe->fnhe_mtu_locked = lock;
                fnhe->fnhe_expires = expires;
 
                /* Exception created; mark the cached routes for the nexthop
@@ -786,7 +791,8 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
                                struct fib_nh *nh = &FIB_RES_NH(res);
 
                                update_or_create_fnhe(nh, fl4->daddr, new_gw,
-                                               0, jiffies + ip_rt_gc_timeout);
+                                               0, false,
+                                               jiffies + ip_rt_gc_timeout);
                        }
                        if (kill_route)
                                rt->dst.obsolete = DST_OBSOLETE_KILL;
@@ -930,14 +936,23 @@ out_put_peer:
 
 static int ip_error(struct sk_buff *skb)
 {
-       struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
        struct rtable *rt = skb_rtable(skb);
+       struct net_device *dev = skb->dev;
+       struct in_device *in_dev;
        struct inet_peer *peer;
        unsigned long now;
        struct net *net;
        bool send;
        int code;
 
+       if (netif_is_l3_master(skb->dev)) {
+               dev = __dev_get_by_index(dev_net(skb->dev), IPCB(skb)->iif);
+               if (!dev)
+                       goto out;
+       }
+
+       in_dev = __in_dev_get_rcu(dev);
+
        /* IP on this device is disabled. */
        if (!in_dev)
                goto out;
@@ -999,15 +1014,18 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
 {
        struct dst_entry *dst = &rt->dst;
        struct fib_result res;
+       bool lock = false;
 
-       if (dst_metric_locked(dst, RTAX_MTU))
+       if (ip_mtu_locked(dst))
                return;
 
        if (ipv4_mtu(dst) < mtu)
                return;
 
-       if (mtu < ip_rt_min_pmtu)
+       if (mtu < ip_rt_min_pmtu) {
+               lock = true;
                mtu = ip_rt_min_pmtu;
+       }
 
        if (rt->rt_pmtu == mtu &&
            time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
@@ -1017,7 +1035,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
        if (fib_lookup(dev_net(dst->dev), fl4, &res, 0) == 0) {
                struct fib_nh *nh = &FIB_RES_NH(res);
 
-               update_or_create_fnhe(nh, fl4->daddr, 0, mtu,
+               update_or_create_fnhe(nh, fl4->daddr, 0, mtu, lock,
                                      jiffies + ip_rt_mtu_expires);
        }
        rcu_read_unlock();
@@ -1270,7 +1288,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
 
        mtu = READ_ONCE(dst->dev->mtu);
 
-       if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
+       if (unlikely(ip_mtu_locked(dst))) {
                if (rt->rt_uses_gateway && mtu > 576)
                        mtu = 576;
        }
@@ -1383,7 +1401,7 @@ struct uncached_list {
 
 static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list);
 
-static void rt_add_uncached_list(struct rtable *rt)
+void rt_add_uncached_list(struct rtable *rt)
 {
        struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list);
 
@@ -1394,14 +1412,8 @@ static void rt_add_uncached_list(struct rtable *rt)
        spin_unlock_bh(&ul->lock);
 }
 
-static void ipv4_dst_destroy(struct dst_entry *dst)
+void rt_del_uncached_list(struct rtable *rt)
 {
-       struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
-       struct rtable *rt = (struct rtable *) dst;
-
-       if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
-               kfree(p);
-
        if (!list_empty(&rt->rt_uncached)) {
                struct uncached_list *ul = rt->rt_uncached_list;
 
@@ -1411,6 +1423,17 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
        }
 }
 
+static void ipv4_dst_destroy(struct dst_entry *dst)
+{
+       struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
+       struct rtable *rt = (struct rtable *)dst;
+
+       if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
+               kfree(p);
+
+       rt_del_uncached_list(rt);
+}
+
 void rt_flush_dev(struct net_device *dev)
 {
        struct net *net = dev_net(dev);
@@ -1506,6 +1529,7 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
                rt->rt_is_input = 0;
                rt->rt_iif = 0;
                rt->rt_pmtu = 0;
+               rt->rt_mtu_locked = 0;
                rt->rt_gateway = 0;
                rt->rt_uses_gateway = 0;
                rt->rt_table_id = 0;
@@ -1826,6 +1850,8 @@ int fib_multipath_hash(const struct fib_info *fi, const struct flowi4 *fl4,
                                return skb_get_hash_raw(skb) >> 1;
                        memset(&hash_keys, 0, sizeof(hash_keys));
                        skb_flow_dissect_flow_keys(skb, &keys, flag);
+
+                       hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
                        hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src;
                        hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst;
                        hash_keys.ports.src = keys.ports.src;
@@ -2529,6 +2555,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
                rt->rt_is_input = ort->rt_is_input;
                rt->rt_iif = ort->rt_iif;
                rt->rt_pmtu = ort->rt_pmtu;
+               rt->rt_mtu_locked = ort->rt_mtu_locked;
 
                rt->rt_genid = rt_genid_ipv4(net);
                rt->rt_flags = ort->rt_flags;
@@ -2631,6 +2658,8 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src, u32 table_id,
        memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics));
        if (rt->rt_pmtu && expires)
                metrics[RTAX_MTU - 1] = rt->rt_pmtu;
+       if (rt->rt_mtu_locked && expires)
+               metrics[RTAX_LOCK - 1] |= BIT(RTAX_MTU);
        if (rtnetlink_put_metrics(skb, metrics) < 0)
                goto nla_put_failure;
 
@@ -2816,6 +2845,7 @@ void ip_rt_multicast_event(struct in_device *in_dev)
 static int ip_rt_gc_interval __read_mostly  = 60 * HZ;
 static int ip_rt_gc_min_interval __read_mostly = HZ / 2;
 static int ip_rt_gc_elasticity __read_mostly   = 8;
+static int ip_min_valid_pmtu __read_mostly     = IPV4_MIN_MTU;
 
 static int ipv4_sysctl_rtcache_flush(struct ctl_table *__ctl, int write,
                                        void __user *buffer,
@@ -2931,7 +2961,8 @@ static struct ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_min_pmtu,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &ip_min_valid_pmtu,
        },
        {
                .procname       = "min_adv_mss",
index 48636aee23c31244494b7c7acbc911a7f1823691..8b8059b7af4dd4b3394c7d5f6babd29db2312540 100644 (file)
@@ -3566,6 +3566,7 @@ int tcp_abort(struct sock *sk, int err)
 
        bh_unlock_sock(sk);
        local_bh_enable();
+       tcp_write_queue_purge(sk);
        release_sock(sk);
        return 0;
 }
index 7c843578f2333db58100cedbc2a9d0784f72d861..faddf4f9a707f1583fc71e0711e3db95b5d08255 100644 (file)
@@ -6,7 +6,7 @@
  * The algorithm is described in:
  * "TCP-Illinois: A Loss and Delay-Based Congestion Control Algorithm
  *  for High-Speed Networks"
- * http://www.ifp.illinois.edu/~srikant/Papers/liubassri06perf.pdf
+ * http://tamerbasar.csl.illinois.edu/LiuBasarSrikantPerfEvalArtJun2008.pdf
  *
  * Implemented from description in paper and ns-2 simulation.
  * Copyright (C) 2007 Stephen Hemminger <shemminger@linux-foundation.org>
index 575d3c1fb6e835e225834ca45f58b74ea29e000b..9a1b3c1c1c1473829e6d975f97a864b9acd4a6d6 100644 (file)
@@ -1971,11 +1971,6 @@ void tcp_enter_loss(struct sock *sk)
        /* F-RTO RFC5682 sec 3.1 step 1: retransmit SND.UNA if no previous
         * loss recovery is underway except recurring timeout(s) on
         * the same SND.UNA (sec 3.2). Disable F-RTO on path MTU probing
-        *
-        * In theory F-RTO can be used repeatedly during loss recovery.
-        * In practice this interacts badly with broken middle-boxes that
-        * falsely raise the receive window, which results in repeated
-        * timeouts and stop-and-go behavior.
         */
        tp->frto = net->ipv4.sysctl_tcp_frto &&
                   (new_recovery || icsk->icsk_retransmits) &&
@@ -2631,18 +2626,14 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack,
            tcp_try_undo_loss(sk, false))
                return;
 
-       /* The ACK (s)acks some never-retransmitted data meaning not all
-        * the data packets before the timeout were lost. Therefore we
-        * undo the congestion window and state. This is essentially
-        * the operation in F-RTO (RFC5682 section 3.1 step 3.b). Since
-        * a retransmitted skb is permantly marked, we can apply such an
-        * operation even if F-RTO was not used.
-        */
-       if ((flag & FLAG_ORIG_SACK_ACKED) &&
-           tcp_try_undo_loss(sk, tp->undo_marker))
-               return;
-
        if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */
+               /* Step 3.b. A timeout is spurious if not all data are
+                * lost, i.e., never-retransmitted data are (s)acked.
+                */
+               if ((flag & FLAG_ORIG_SACK_ACKED) &&
+                   tcp_try_undo_loss(sk, true))
+                       return;
+
                if (after(tp->snd_nxt, tp->high_seq)) {
                        if (flag & FLAG_DATA_SACKED || is_dupack)
                                tp->frto = 0; /* Step 3.a. loss was real */
@@ -4001,6 +3992,7 @@ void tcp_reset(struct sock *sk)
        /* This barrier is coupled with smp_rmb() in tcp_poll() */
        smp_wmb();
 
+       tcp_write_queue_purge(sk);
        tcp_done(sk);
 
        if (!sock_flag(sk, SOCK_DEAD))
index e9f985e42405a38fc95980da5debb7ac8b51fbb5..6818042cd8a9a1778f54637861647091afd9a769 100644 (file)
@@ -1730,7 +1730,7 @@ u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
         */
        segs = max_t(u32, bytes / mss_now, min_tso_segs);
 
-       return min_t(u32, segs, sk->sk_gso_max_segs);
+       return segs;
 }
 EXPORT_SYMBOL(tcp_tso_autosize);
 
@@ -1742,9 +1742,10 @@ static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now)
        const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
        u32 tso_segs = ca_ops->tso_segs_goal ? ca_ops->tso_segs_goal(sk) : 0;
 
-       return tso_segs ? :
-               tcp_tso_autosize(sk, mss_now,
-                                sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs);
+       if (!tso_segs)
+               tso_segs = tcp_tso_autosize(sk, mss_now,
+                               sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs);
+       return min_t(u32, tso_segs, sk->sk_gso_max_segs);
 }
 
 /* Returns the portion of skb which can be sent right away */
@@ -2027,6 +2028,24 @@ static inline void tcp_mtu_check_reprobe(struct sock *sk)
        }
 }
 
+static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
+{
+       struct sk_buff *skb, *next;
+
+       skb = tcp_send_head(sk);
+       tcp_for_write_queue_from_safe(skb, next, sk) {
+               if (len <= skb->len)
+                       break;
+
+               if (unlikely(TCP_SKB_CB(skb)->eor))
+                       return false;
+
+               len -= skb->len;
+       }
+
+       return true;
+}
+
 /* Create a new MTU probe if we are ready.
  * MTU probe is regularly attempting to increase the path MTU by
  * deliberately sending larger packets.  This discovers routing
@@ -2099,6 +2118,9 @@ static int tcp_mtu_probe(struct sock *sk)
                        return 0;
        }
 
+       if (!tcp_can_coalesce_send_queue_head(sk, probe_size))
+               return -1;
+
        /* We're allowed to probe.  Build it now. */
        nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false);
        if (!nskb)
@@ -2134,6 +2156,10 @@ static int tcp_mtu_probe(struct sock *sk)
                        /* We've eaten all the data from this skb.
                         * Throw it away. */
                        TCP_SKB_CB(nskb)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags;
+                       /* If this is the last SKB we copy and eor is set
+                        * we need to propagate it to the new skb.
+                        */
+                       TCP_SKB_CB(nskb)->eor = TCP_SKB_CB(skb)->eor;
                        tcp_unlink_write_queue(skb, sk);
                        sk_wmem_free_skb(sk, skb);
                } else {
index 71fc60f1b326f25fe4dbd73312a5a91758464069..f7d944855f8ebd0a312fe73a53a56ab8d451ee44 100644 (file)
@@ -34,6 +34,7 @@ static void tcp_write_err(struct sock *sk)
        sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
        sk->sk_error_report(sk);
 
+       tcp_write_queue_purge(sk);
        tcp_done(sk);
        __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONTIMEOUT);
 }
index bfaefe560b5ce32bbf383469d8f77795d1322ed9..e5ef7c38c934c2f9fdbf368e9815eea9701139e4 100644 (file)
@@ -2024,6 +2024,11 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
                err = udplite_checksum_init(skb, uh);
                if (err)
                        return err;
+
+               if (UDP_SKB_CB(skb)->partial_cov) {
+                       skb->csum = inet_compute_pseudo(skb, proto);
+                       return 0;
+               }
        }
 
        /* Note, we are only interested in != 0 or == 0, thus the
index 63faeee989a99dc7f714d1120cb3228349b1362d..2a9764bd17196966b41755269e03f487cb757288 100644 (file)
@@ -92,7 +92,8 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 
        skb_reset_network_header(skb);
        skb_mac_header_rebuild(skb);
-       eth_hdr(skb)->h_proto = skb->protocol;
+       if (skb->mac_len)
+               eth_hdr(skb)->h_proto = skb->protocol;
 
        err = 0;
 
index 94b8702603bc54f36542977ed0d9c3b93d43b6b7..be980c195fc55b0a23f144eb55641cb16a2eb2de 100644 (file)
@@ -30,7 +30,8 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
 
        mtu = dst_mtu(skb_dst(skb));
        if ((!skb_is_gso(skb) && skb->len > mtu) ||
-           (skb_is_gso(skb) && skb_gso_network_seglen(skb) > ip_skb_dst_mtu(skb->sk, skb))) {
+           (skb_is_gso(skb) &&
+            !skb_gso_validate_network_len(skb, ip_skb_dst_mtu(skb->sk, skb)))) {
                skb->protocol = htons(ETH_P_IP);
 
                if (skb->sk)
index 05017e2c849c12b43715fe4944759a3c91880ee8..fbebda67ac1bddf148f10a811a0646b5fdeca892 100644 (file)
@@ -100,8 +100,10 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        xdst->u.rt.rt_gateway = rt->rt_gateway;
        xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
        xdst->u.rt.rt_pmtu = rt->rt_pmtu;
+       xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;
        xdst->u.rt.rt_table_id = rt->rt_table_id;
        INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
+       rt_add_uncached_list(&xdst->u.rt);
 
        return 0;
 }
@@ -241,7 +243,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
        struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
 
        dst_destroy_metrics_generic(dst);
-
+       if (xdst->u.rt.rt_uncached_list)
+               rt_del_uncached_list(&xdst->u.rt);
        xfrm_dst_destroy(xdst);
 }
 
index fbf08ce3f5ab75c3d21c20741421f4153c4dcd67..a9f7eca0b6a3fd373c81db2c41591b0691994848 100644 (file)
@@ -146,10 +146,12 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
        struct sockaddr_in6     *usin = (struct sockaddr_in6 *) uaddr;
        struct inet_sock        *inet = inet_sk(sk);
        struct ipv6_pinfo       *np = inet6_sk(sk);
-       struct in6_addr         *daddr;
+       struct in6_addr         *daddr, old_daddr;
+       __be32                  fl6_flowlabel = 0;
+       __be32                  old_fl6_flowlabel;
+       __be16                  old_dport;
        int                     addr_type;
        int                     err;
-       __be32                  fl6_flowlabel = 0;
 
        if (usin->sin6_family == AF_INET) {
                if (__ipv6_only_sock(sk))
@@ -238,9 +240,13 @@ ipv4_connected:
                }
        }
 
+       /* save the current peer information before updating it */
+       old_daddr = sk->sk_v6_daddr;
+       old_fl6_flowlabel = np->flow_label;
+       old_dport = inet->inet_dport;
+
        sk->sk_v6_daddr = *daddr;
        np->flow_label = fl6_flowlabel;
-
        inet->inet_dport = usin->sin6_port;
 
        /*
@@ -250,11 +256,12 @@ ipv4_connected:
 
        err = ip6_datagram_dst_update(sk, true);
        if (err) {
-               /* Reset daddr and dport so that udp_v6_early_demux()
-                * fails to find this socket
+               /* Restore the socket peer info, to keep it consistent with
+                * the old socket state
                 */
-               memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr));
-               inet->inet_dport = 0;
+               sk->sk_v6_daddr = old_daddr;
+               np->flow_label = old_fl6_flowlabel;
+               inet->inet_dport = old_dport;
                goto out;
        }
 
index ec43d18b5ff91f360869fd348a23a23633cc8e33..547515e8450a1aae48f51a331353d04465a31fa0 100644 (file)
@@ -73,6 +73,11 @@ int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto)
                err = udplite_checksum_init(skb, uh);
                if (err)
                        return err;
+
+               if (UDP_SKB_CB(skb)->partial_cov) {
+                       skb->csum = ip6_compute_pseudo(skb, proto);
+                       return 0;
+               }
        }
 
        /* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)
index 3c353125546d8701febaad95f81bdaa675cd5d7d..1bbd0930063eeca7a75aab193a53fdae5f9e973b 100644 (file)
@@ -126,7 +126,8 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
        struct ip6_tnl *t, *cand = NULL;
        struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
        int dev_type = (gre_proto == htons(ETH_P_TEB) ||
-                       gre_proto == htons(ETH_P_ERSPAN)) ?
+                       gre_proto == htons(ETH_P_ERSPAN) ||
+                       gre_proto == htons(ETH_P_ERSPAN2)) ?
                       ARPHRD_ETHER : ARPHRD_IP6GRE;
        int score, cand_score = 4;
 
@@ -902,6 +903,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
                truncate = true;
        }
 
+       if (skb_cow_head(skb, dev->needed_headroom))
+               goto tx_err;
+
        t->parms.o_flags &= ~TUNNEL_KEY;
        IPCB(skb)->flags = 0;
 
@@ -944,6 +948,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
                                               md->u.md2.dir,
                                               get_hwid(&md->u.md2),
                                               truncate, false);
+               } else {
+                       goto tx_err;
                }
        } else {
                switch (skb->protocol) {
index 997c7f19ad62e61b04927f62eccaf54ca6f42801..a8a919520090920bd87e1c126c83cfae84405532 100644 (file)
@@ -412,7 +412,7 @@ static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
        if (skb->ignore_df)
                return false;
 
-       if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
+       if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
                return false;
 
        return true;
index 4b15fe92827867493cca7ad58d70701c0dea599f..6e0f21eed88a4f431a16c57b084c1edbe36619a8 100644 (file)
@@ -1982,14 +1982,14 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
 {
        struct net *net = dev_net(dev);
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-       struct ip6_tnl *nt, *t;
        struct ip_tunnel_encap ipencap;
+       struct ip6_tnl *nt, *t;
+       int err;
 
        nt = netdev_priv(dev);
 
        if (ip6_tnl_netlink_encap_parms(data, &ipencap)) {
-               int err = ip6_tnl_encap_setup(nt, &ipencap);
-
+               err = ip6_tnl_encap_setup(nt, &ipencap);
                if (err < 0)
                        return err;
        }
@@ -2005,7 +2005,11 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
                        return -EEXIST;
        }
 
-       return ip6_tnl_create2(dev);
+       err = ip6_tnl_create2(dev);
+       if (!err && tb[IFLA_MTU])
+               ip6_tnl_change_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
+
+       return err;
 }
 
 static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
index d78d41fc4b1a46e4e0a743487770ac4fe7d395b4..24535169663dc501700c95e354761dd824e5a962 100644 (file)
@@ -1367,10 +1367,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
                if (get_user(len, optlen))
                        return -EFAULT;
 
-               lock_sock(sk);
-               err = nf_getsockopt(sk, PF_INET6, optname, optval,
-                               &len);
-               release_sock(sk);
+               err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
                if (err >= 0)
                        err = put_user(len, optlen);
        }
@@ -1409,10 +1406,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
                if (get_user(len, optlen))
                        return -EFAULT;
 
-               lock_sock(sk);
-               err = compat_nf_getsockopt(sk, PF_INET6,
-                                          optname, optval, &len);
-               release_sock(sk);
+               err = compat_nf_getsockopt(sk, PF_INET6, optname, optval, &len);
                if (err >= 0)
                        err = put_user(len, optlen);
        }
index f61a5b613b52b065d8754af8adb9948f17eafc48..ba5e04c6ae17df3d39d4b0daa07f61563bdd02e9 100644 (file)
@@ -1554,7 +1554,8 @@ static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb,
        *(opt++) = (rd_len >> 3);
        opt += 6;
 
-       memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8);
+       skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt,
+                     rd_len - 8);
 }
 
 void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
index d95ceca7ff8f648ff301d91a2e3eb60fc2050f1c..531d6957af36c4af48176f9360e9d95f78a45d55 100644 (file)
 int ip6_route_me_harder(struct net *net, struct sk_buff *skb)
 {
        const struct ipv6hdr *iph = ipv6_hdr(skb);
+       struct sock *sk = sk_to_full_sk(skb->sk);
        unsigned int hh_len;
        struct dst_entry *dst;
        struct flowi6 fl6 = {
-               .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
+               .flowi6_oif = sk ? sk->sk_bound_dev_if : 0,
                .flowi6_mark = skb->mark,
-               .flowi6_uid = sock_net_uid(net, skb->sk),
+               .flowi6_uid = sock_net_uid(net, sk),
                .daddr = iph->daddr,
                .saddr = iph->saddr,
        };
        int err;
 
-       dst = ip6_route_output(net, skb->sk, &fl6);
+       dst = ip6_route_output(net, sk, &fl6);
        err = dst->error;
        if (err) {
                IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
@@ -50,7 +51,7 @@ int ip6_route_me_harder(struct net *net, struct sk_buff *skb)
        if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
            xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) {
                skb_dst_set(skb, NULL);
-               dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0);
+               dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
                if (IS_ERR(dst))
                        return PTR_ERR(dst);
                skb_dst_set(skb, dst);
index af4c917e083696559e5347060307e32f23fbc4a9..62358b93bbac5250676a067464c11e4e3d649faa 100644 (file)
@@ -352,6 +352,10 @@ ip6t_do_table(struct sk_buff *skb,
                        }
                        if (table_base + v != ip6t_next_entry(e) &&
                            !(e->ipv6.flags & IP6T_F_GOTO)) {
+                               if (unlikely(stackidx >= private->stacksize)) {
+                                       verdict = NF_DROP;
+                                       break;
+                               }
                                jumpstack[stackidx++] = e;
                        }
 
index fa51a205918dbb06731f7300d34921b3c4096737..38dea8ff680fe78e33720147646c5b5e4b557ac5 100644 (file)
@@ -85,14 +85,14 @@ static int reject_tg6_check(const struct xt_tgchk_param *par)
        const struct ip6t_entry *e = par->entryinfo;
 
        if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
-               pr_info("ECHOREPLY is not supported.\n");
+               pr_info_ratelimited("ECHOREPLY is not supported\n");
                return -EINVAL;
        } else if (rejinfo->with == IP6T_TCP_RESET) {
                /* Must specify that it's a TCP packet */
                if (!(e->ipv6.flags & IP6T_F_PROTO) ||
                    e->ipv6.proto != IPPROTO_TCP ||
                    (e->ipv6.invflags & XT_INV_PROTO)) {
-                       pr_info("TCP_RESET illegal for non-tcp\n");
+                       pr_info_ratelimited("TCP_RESET illegal for non-tcp\n");
                        return -EINVAL;
                }
        }
index b12e61b7b16ce9f3f98a0906558c98803a48a9a3..91ed25a24b79fde5f97999703b4699f84b2198b3 100644 (file)
@@ -48,10 +48,6 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
        }
 
        fl6.flowi6_mark = flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
-       if ((flags & XT_RPFILTER_LOOSE) == 0) {
-               fl6.flowi6_oif = dev->ifindex;
-               lookup_flags |= RT6_LOOKUP_F_IFACE;
-       }
 
        rt = (void *) ip6_route_lookup(net, &fl6, lookup_flags);
        if (rt->dst.error)
@@ -103,14 +99,14 @@ static int rpfilter_check(const struct xt_mtchk_param *par)
        unsigned int options = ~XT_RPFILTER_OPTION_MASK;
 
        if (info->flags & options) {
-               pr_info("unknown options encountered");
+               pr_info_ratelimited("unknown options\n");
                return -EINVAL;
        }
 
        if (strcmp(par->table, "mangle") != 0 &&
            strcmp(par->table, "raw") != 0) {
-               pr_info("match only valid in the \'raw\' "
-                       "or \'mangle\' tables, not \'%s\'.\n", par->table);
+               pr_info_ratelimited("only valid in \'raw\' or \'mangle\' table, not \'%s\'\n",
+                                   par->table);
                return -EINVAL;
        }
 
index 9642164107ce1d544b4a5563cb1eaf319ef95770..33719d5560c8ab4ee565ede2b03a107c06551e51 100644 (file)
@@ -122,12 +122,14 @@ static int srh_mt6_check(const struct xt_mtchk_param *par)
        const struct ip6t_srh *srhinfo = par->matchinfo;
 
        if (srhinfo->mt_flags & ~IP6T_SRH_MASK) {
-               pr_err("unknown srh match flags  %X\n", srhinfo->mt_flags);
+               pr_info_ratelimited("unknown srh match flags  %X\n",
+                                   srhinfo->mt_flags);
                return -EINVAL;
        }
 
        if (srhinfo->mt_invflags & ~IP6T_SRH_INV_MASK) {
-               pr_err("unknown srh invflags %X\n", srhinfo->mt_invflags);
+               pr_info_ratelimited("unknown srh invflags %X\n",
+                                   srhinfo->mt_invflags);
                return -EINVAL;
        }
 
index d346705d6ee6bfe87292bc77d7eb1614d214d2c9..207cb35569b1c3c382560088aeb6ecdd75a236b2 100644 (file)
@@ -178,7 +178,7 @@ static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
        if (skb->len <= mtu)
                return false;
 
-       if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
+       if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
                return false;
 
        return true;
index bed57ee65f7b10c5fb4ae9fc6f086d7bbfffa7af..6b7f075f811f2b317f09f11998a80d87d0616e15 100644 (file)
@@ -99,6 +99,10 @@ static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
            !l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff,
                                target, maniptype))
                return false;
+
+       /* must reload, offset might have changed */
+       ipv6h = (void *)skb->data + iphdroff;
+
 manip_addr:
        if (maniptype == NF_NAT_MANIP_SRC)
                ipv6h->saddr = target->src.u3.in6;
index cc5174c7254c5697fc5bcd66ffeecb00e408e28e..62fc84d7bdff0b91eccce94aaebc8a13c77f31d0 100644 (file)
@@ -180,7 +180,6 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
        }
 
        *dest = 0;
- again:
        rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, lookup_flags);
        if (rt->dst.error)
                goto put_rt_err;
@@ -189,15 +188,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
        if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL))
                goto put_rt_err;
 
-       if (oif && oif != rt->rt6i_idev->dev) {
-               /* multipath route? Try again with F_IFACE */
-               if ((lookup_flags & RT6_LOOKUP_F_IFACE) == 0) {
-                       lookup_flags |= RT6_LOOKUP_F_IFACE;
-                       fl6.flowi6_oif = oif->ifindex;
-                       ip6_rt_put(rt);
-                       goto again;
-               }
-       }
+       if (oif && oif != rt->rt6i_idev->dev)
+               goto put_rt_err;
 
        switch (priv->result) {
        case NFT_FIB_RESULT_OIF:
index 9dcfadddd800557e6c710a8e848dbfdb7d186393..b0d5c64e19780ce94feb112285ed1d85dbe07e9e 100644 (file)
@@ -128,7 +128,7 @@ struct uncached_list {
 
 static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list);
 
-static void rt6_uncached_list_add(struct rt6_info *rt)
+void rt6_uncached_list_add(struct rt6_info *rt)
 {
        struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list);
 
@@ -139,7 +139,7 @@ static void rt6_uncached_list_add(struct rt6_info *rt)
        spin_unlock_bh(&ul->lock);
 }
 
-static void rt6_uncached_list_del(struct rt6_info *rt)
+void rt6_uncached_list_del(struct rt6_info *rt)
 {
        if (!list_empty(&rt->rt6i_uncached)) {
                struct uncached_list *ul = rt->rt6i_uncached_list;
@@ -1509,7 +1509,30 @@ static void rt6_exceptions_remove_prefsrc(struct rt6_info *rt)
        }
 }
 
-static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu)
+static bool rt6_mtu_change_route_allowed(struct inet6_dev *idev,
+                                        struct rt6_info *rt, int mtu)
+{
+       /* If the new MTU is lower than the route PMTU, this new MTU will be the
+        * lowest MTU in the path: always allow updating the route PMTU to
+        * reflect PMTU decreases.
+        *
+        * If the new MTU is higher, and the route PMTU is equal to the local
+        * MTU, this means the old MTU is the lowest in the path, so allow
+        * updating it: if other nodes now have lower MTUs, PMTU discovery will
+        * handle this.
+        */
+
+       if (dst_mtu(&rt->dst) >= mtu)
+               return true;
+
+       if (dst_mtu(&rt->dst) == idev->cnf.mtu6)
+               return true;
+
+       return false;
+}
+
+static void rt6_exceptions_update_pmtu(struct inet6_dev *idev,
+                                      struct rt6_info *rt, int mtu)
 {
        struct rt6_exception_bucket *bucket;
        struct rt6_exception *rt6_ex;
@@ -1518,20 +1541,22 @@ static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu)
        bucket = rcu_dereference_protected(rt->rt6i_exception_bucket,
                                        lockdep_is_held(&rt6_exception_lock));
 
-       if (bucket) {
-               for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
-                       hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
-                               struct rt6_info *entry = rt6_ex->rt6i;
-                               /* For RTF_CACHE with rt6i_pmtu == 0
-                                * (i.e. a redirected route),
-                                * the metrics of its rt->dst.from has already
-                                * been updated.
-                                */
-                               if (entry->rt6i_pmtu && entry->rt6i_pmtu > mtu)
-                                       entry->rt6i_pmtu = mtu;
-                       }
-                       bucket++;
+       if (!bucket)
+               return;
+
+       for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) {
+               hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) {
+                       struct rt6_info *entry = rt6_ex->rt6i;
+
+                       /* For RTF_CACHE with rt6i_pmtu == 0 (i.e. a redirected
+                        * route), the metrics of its rt->dst.from have already
+                        * been updated.
+                        */
+                       if (entry->rt6i_pmtu &&
+                           rt6_mtu_change_route_allowed(idev, entry, mtu))
+                               entry->rt6i_pmtu = mtu;
                }
+               bucket++;
        }
 }
 
@@ -3809,25 +3834,13 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
           Since RFC 1981 doesn't include administrative MTU increase
           update PMTU increase is a MUST. (i.e. jumbo frame)
         */
-       /*
-          If new MTU is less than route PMTU, this new MTU will be the
-          lowest MTU in the path, update the route PMTU to reflect PMTU
-          decreases; if new MTU is greater than route PMTU, and the
-          old MTU is the lowest MTU in the path, update the route PMTU
-          to reflect the increase. In this case if the other nodes' MTU
-          also have the lowest MTU, TOO BIG MESSAGE will be lead to
-          PMTU discovery.
-        */
        if (rt->dst.dev == arg->dev &&
-           dst_metric_raw(&rt->dst, RTAX_MTU) &&
            !dst_metric_locked(&rt->dst, RTAX_MTU)) {
                spin_lock_bh(&rt6_exception_lock);
-               if (dst_mtu(&rt->dst) >= arg->mtu ||
-                   (dst_mtu(&rt->dst) < arg->mtu &&
-                    dst_mtu(&rt->dst) == idev->cnf.mtu6)) {
+               if (dst_metric_raw(&rt->dst, RTAX_MTU) &&
+                   rt6_mtu_change_route_allowed(idev, rt, arg->mtu))
                        dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu);
-               }
-               rt6_exceptions_update_pmtu(rt, arg->mtu);
+               rt6_exceptions_update_pmtu(idev, rt, arg->mtu);
                spin_unlock_bh(&rt6_exception_lock);
        }
        return 0;
@@ -4099,6 +4112,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
                                r_cfg.fc_encap_type = nla_get_u16(nla);
                }
 
+               r_cfg.fc_flags |= (rtnh->rtnh_flags & RTNH_F_ONLINK);
                rt = ip6_route_info_create(&r_cfg, extack);
                if (IS_ERR(rt)) {
                        err = PTR_ERR(rt);
index bd6cc688bd199ae98cc1be8d0851b08cb6709486..7a78dcfda68a17e10e5e951db21d8113c7f65301 100644 (file)
@@ -93,7 +93,8 @@ static void set_tun_src(struct net *net, struct net_device *dev,
 /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */
 int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
 {
-       struct net *net = dev_net(skb_dst(skb)->dev);
+       struct dst_entry *dst = skb_dst(skb);
+       struct net *net = dev_net(dst->dev);
        struct ipv6hdr *hdr, *inner_hdr;
        struct ipv6_sr_hdr *isrh;
        int hdrlen, tot_len, err;
@@ -134,7 +135,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
        isrh->nexthdr = proto;
 
        hdr->daddr = isrh->segments[isrh->first_segment];
-       set_tun_src(net, skb->dev, &hdr->daddr, &hdr->saddr);
+       set_tun_src(net, ip6_dst_idev(dst)->dev, &hdr->daddr, &hdr->saddr);
 
 #ifdef CONFIG_IPV6_SEG6_HMAC
        if (sr_has_hmac(isrh)) {
@@ -418,7 +419,7 @@ static int seg6_build_state(struct nlattr *nla,
 
        slwt = seg6_lwt_lwtunnel(newts);
 
-       err = dst_cache_init(&slwt->cache, GFP_KERNEL);
+       err = dst_cache_init(&slwt->cache, GFP_ATOMIC);
        if (err) {
                kfree(newts);
                return err;
index 3873d387713575558801b0352227efd4c4ac45f6..0195598f7bb5ad86bcd333fd33a93410c314bfc0 100644 (file)
@@ -182,7 +182,7 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
 #ifdef CONFIG_IPV6_SIT_6RD
        struct ip_tunnel *t = netdev_priv(dev);
 
-       if (t->dev == sitn->fb_tunnel_dev) {
+       if (dev == sitn->fb_tunnel_dev) {
                ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0);
                t->ip6rd.relay_prefix = 0;
                t->ip6rd.prefixlen = 16;
@@ -1578,6 +1578,13 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev,
        if (err < 0)
                return err;
 
+       if (tb[IFLA_MTU]) {
+               u32 mtu = nla_get_u32(tb[IFLA_MTU]);
+
+               if (mtu >= IPV6_MIN_MTU && mtu <= 0xFFF8 - dev->hard_header_len)
+                       dev->mtu = mtu;
+       }
+
 #ifdef CONFIG_IPV6_SIT_6RD
        if (ipip6_netlink_6rd_parms(data, &ip6rd))
                err = ipip6_tunnel_update_6rd(nt, &ip6rd);
index bb935a3b7feadafa883a329020d0f90b9c2ee615..de1b0b8c53b0ba26836d40a53dfa6fe077c7ebef 100644 (file)
@@ -92,7 +92,8 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 
        skb_reset_network_header(skb);
        skb_mac_header_rebuild(skb);
-       eth_hdr(skb)->h_proto = skb->protocol;
+       if (skb->mac_len)
+               eth_hdr(skb)->h_proto = skb->protocol;
 
        err = 0;
 
index 8ae87d4ec5ff607d431513bb2ef42d5c2c93450a..5959ce9620eb92ece2830d6a59ed21d562a3a1cf 100644 (file)
@@ -82,7 +82,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
 
        if ((!skb_is_gso(skb) && skb->len > mtu) ||
            (skb_is_gso(skb) &&
-            skb_gso_network_seglen(skb) > ip6_skb_dst_mtu(skb))) {
+            !skb_gso_validate_network_len(skb, ip6_skb_dst_mtu(skb)))) {
                skb->dev = dst->dev;
                skb->protocol = htons(ETH_P_IPV6);
 
index 09fb44ee3b45d7577a13649eca4048c9cdafb274..416fe67271a920f5a86dd3007c03e3113f857f8a 100644 (file)
@@ -113,6 +113,9 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
        xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
        xdst->u.rt6.rt6i_src = rt->rt6i_src;
+       INIT_LIST_HEAD(&xdst->u.rt6.rt6i_uncached);
+       rt6_uncached_list_add(&xdst->u.rt6);
+       atomic_inc(&dev_net(dev)->ipv6.rt6_stats->fib_rt_uncache);
 
        return 0;
 }
@@ -244,6 +247,8 @@ static void xfrm6_dst_destroy(struct dst_entry *dst)
        if (likely(xdst->u.rt6.rt6i_idev))
                in6_dev_put(xdst->u.rt6.rt6i_idev);
        dst_destroy_metrics_generic(dst);
+       if (xdst->u.rt6.rt6i_uncached_list)
+               rt6_uncached_list_del(&xdst->u.rt6);
        xfrm_dst_destroy(xdst);
 }
 
index 1e8cc7bcbca3a4fe830b7668fd9b143988e4fb46..9e2643ab4ccbfce863f637e4f15833329a27d666 100644 (file)
@@ -2433,9 +2433,11 @@ static int afiucv_iucv_init(void)
        af_iucv_dev->driver = &af_iucv_driver;
        err = device_register(af_iucv_dev);
        if (err)
-               goto out_driver;
+               goto out_iucv_dev;
        return 0;
 
+out_iucv_dev:
+       put_device(af_iucv_dev);
 out_driver:
        driver_unregister(&af_iucv_driver);
 out_iucv:
index f297d53a11aa0be823d4235449c9a6474f39469f..34355fd19f27dc2a0703cc92d84e7ba091568917 100644 (file)
@@ -1381,24 +1381,32 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
                .parse_msg = kcm_parse_func_strparser,
                .read_sock_done = kcm_read_sock_done,
        };
-       int err;
+       int err = 0;
 
        csk = csock->sk;
        if (!csk)
                return -EINVAL;
 
+       lock_sock(csk);
+
        /* Only allow TCP sockets to be attached for now */
        if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) ||
-           csk->sk_protocol != IPPROTO_TCP)
-               return -EOPNOTSUPP;
+           csk->sk_protocol != IPPROTO_TCP) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
 
        /* Don't allow listeners or closed sockets */
-       if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE)
-               return -EOPNOTSUPP;
+       if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
 
        psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL);
-       if (!psock)
-               return -ENOMEM;
+       if (!psock) {
+               err = -ENOMEM;
+               goto out;
+       }
 
        psock->mux = mux;
        psock->sk = csk;
@@ -1407,7 +1415,7 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
        err = strp_init(&psock->strp, csk, &cb);
        if (err) {
                kmem_cache_free(kcm_psockp, psock);
-               return err;
+               goto out;
        }
 
        write_lock_bh(&csk->sk_callback_lock);
@@ -1419,7 +1427,8 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
                write_unlock_bh(&csk->sk_callback_lock);
                strp_done(&psock->strp);
                kmem_cache_free(kcm_psockp, psock);
-               return -EALREADY;
+               err = -EALREADY;
+               goto out;
        }
 
        psock->save_data_ready = csk->sk_data_ready;
@@ -1455,7 +1464,10 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
        /* Schedule RX work in case there are already bytes queued */
        strp_check_rcv(&psock->strp);
 
-       return 0;
+out:
+       release_sock(csk);
+
+       return err;
 }
 
 static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info)
@@ -1507,6 +1519,7 @@ static void kcm_unattach(struct kcm_psock *psock)
 
        if (WARN_ON(psock->rx_kcm)) {
                write_unlock_bh(&csk->sk_callback_lock);
+               release_sock(csk);
                return;
        }
 
index 194a7483bb930edbeb4a8071d6a7dcc95cd0a0c8..14b67dfacc4b48c5bba370da8090792bcd137de0 100644 (file)
@@ -111,6 +111,13 @@ struct l2tp_net {
        spinlock_t l2tp_session_hlist_lock;
 };
 
+#if IS_ENABLED(CONFIG_IPV6)
+static bool l2tp_sk_is_v6(struct sock *sk)
+{
+       return sk->sk_family == PF_INET6 &&
+              !ipv6_addr_v4mapped(&sk->sk_v6_daddr);
+}
+#endif
 
 static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
 {
@@ -136,51 +143,6 @@ l2tp_session_id_hash_2(struct l2tp_net *pn, u32 session_id)
 
 }
 
-/* Lookup the tunnel socket, possibly involving the fs code if the socket is
- * owned by userspace.  A struct sock returned from this function must be
- * released using l2tp_tunnel_sock_put once you're done with it.
- */
-static struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel)
-{
-       int err = 0;
-       struct socket *sock = NULL;
-       struct sock *sk = NULL;
-
-       if (!tunnel)
-               goto out;
-
-       if (tunnel->fd >= 0) {
-               /* Socket is owned by userspace, who might be in the process
-                * of closing it.  Look the socket up using the fd to ensure
-                * consistency.
-                */
-               sock = sockfd_lookup(tunnel->fd, &err);
-               if (sock)
-                       sk = sock->sk;
-       } else {
-               /* Socket is owned by kernelspace */
-               sk = tunnel->sock;
-               sock_hold(sk);
-       }
-
-out:
-       return sk;
-}
-
-/* Drop a reference to a tunnel socket obtained via. l2tp_tunnel_sock_put */
-static void l2tp_tunnel_sock_put(struct sock *sk)
-{
-       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
-       if (tunnel) {
-               if (tunnel->fd >= 0) {
-                       /* Socket is owned by userspace */
-                       sockfd_put(sk->sk_socket);
-               }
-               sock_put(sk);
-       }
-       sock_put(sk);
-}
-
 /* Session hash list.
  * The session_id SHOULD be random according to RFC2661, but several
  * L2TP implementations (Cisco and Microsoft) use incrementing
@@ -193,6 +155,13 @@ l2tp_session_id_hash(struct l2tp_tunnel *tunnel, u32 session_id)
        return &tunnel->session_hlist[hash_32(session_id, L2TP_HASH_BITS)];
 }
 
+void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
+{
+       sock_put(tunnel->sock);
+       /* the tunnel is freed in the socket destructor */
+}
+EXPORT_SYMBOL(l2tp_tunnel_free);
+
 /* Lookup a tunnel. A new reference is held on the returned tunnel. */
 struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
 {
@@ -345,13 +314,11 @@ int l2tp_session_register(struct l2tp_session *session,
                        }
 
                l2tp_tunnel_inc_refcount(tunnel);
-               sock_hold(tunnel->sock);
                hlist_add_head_rcu(&session->global_hlist, g_head);
 
                spin_unlock_bh(&pn->l2tp_session_hlist_lock);
        } else {
                l2tp_tunnel_inc_refcount(tunnel);
-               sock_hold(tunnel->sock);
        }
 
        hlist_add_head(&session->hlist, head);
@@ -969,7 +936,7 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct l2tp_tunnel *tunnel;
 
-       tunnel = l2tp_sock_to_tunnel(sk);
+       tunnel = l2tp_tunnel(sk);
        if (tunnel == NULL)
                goto pass_up;
 
@@ -977,13 +944,10 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
                 tunnel->name, skb->len);
 
        if (l2tp_udp_recv_core(tunnel, skb, tunnel->recv_payload_hook))
-               goto pass_up_put;
+               goto pass_up;
 
-       sock_put(sk);
        return 0;
 
-pass_up_put:
-       sock_put(sk);
 pass_up:
        return 1;
 }
@@ -1092,7 +1056,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
        /* Queue the packet to IP for output */
        skb->ignore_df = 1;
 #if IS_ENABLED(CONFIG_IPV6)
-       if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped)
+       if (l2tp_sk_is_v6(tunnel->sock))
                error = inet6_csk_xmit(tunnel->sock, skb, NULL);
        else
 #endif
@@ -1155,6 +1119,15 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
                goto out_unlock;
        }
 
+       /* The user-space may change the connection status for the user-space
+        * provided socket at run time: we must check it under the socket lock
+        */
+       if (tunnel->fd >= 0 && sk->sk_state != TCP_ESTABLISHED) {
+               kfree_skb(skb);
+               ret = NET_XMIT_DROP;
+               goto out_unlock;
+       }
+
        /* Get routing info from the tunnel socket */
        skb_dst_drop(skb);
        skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
@@ -1174,7 +1147,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
 
                /* Calculate UDP checksum if configured to do so */
 #if IS_ENABLED(CONFIG_IPV6)
-               if (sk->sk_family == PF_INET6 && !tunnel->v4mapped)
+               if (l2tp_sk_is_v6(sk))
                        udp6_set_csum(udp_get_no_check6_tx(sk),
                                      skb, &inet6_sk(sk)->saddr,
                                      &sk->sk_v6_daddr, udp_len);
@@ -1207,14 +1180,12 @@ EXPORT_SYMBOL_GPL(l2tp_xmit_skb);
 static void l2tp_tunnel_destruct(struct sock *sk)
 {
        struct l2tp_tunnel *tunnel = l2tp_tunnel(sk);
-       struct l2tp_net *pn;
 
        if (tunnel == NULL)
                goto end;
 
        l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: closing...\n", tunnel->name);
 
-
        /* Disable udp encapsulation */
        switch (tunnel->encap) {
        case L2TP_ENCAPTYPE_UDP:
@@ -1231,18 +1202,11 @@ static void l2tp_tunnel_destruct(struct sock *sk)
        sk->sk_destruct = tunnel->old_sk_destruct;
        sk->sk_user_data = NULL;
 
-       /* Remove the tunnel struct from the tunnel list */
-       pn = l2tp_pernet(tunnel->l2tp_net);
-       spin_lock_bh(&pn->l2tp_tunnel_list_lock);
-       list_del_rcu(&tunnel->list);
-       spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
-
-       tunnel->sock = NULL;
-       l2tp_tunnel_dec_refcount(tunnel);
-
        /* Call the original destructor */
        if (sk->sk_destruct)
                (*sk->sk_destruct)(sk);
+
+       kfree_rcu(tunnel, rcu);
 end:
        return;
 }
@@ -1303,49 +1267,43 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_closeall);
 /* Tunnel socket destroy hook for UDP encapsulation */
 static void l2tp_udp_encap_destroy(struct sock *sk)
 {
-       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
-       if (tunnel) {
-               l2tp_tunnel_closeall(tunnel);
-               sock_put(sk);
-       }
+       struct l2tp_tunnel *tunnel = l2tp_tunnel(sk);
+
+       if (tunnel)
+               l2tp_tunnel_delete(tunnel);
 }
 
 /* Workqueue tunnel deletion function */
 static void l2tp_tunnel_del_work(struct work_struct *work)
 {
-       struct l2tp_tunnel *tunnel = NULL;
-       struct socket *sock = NULL;
-       struct sock *sk = NULL;
-
-       tunnel = container_of(work, struct l2tp_tunnel, del_work);
+       struct l2tp_tunnel *tunnel = container_of(work, struct l2tp_tunnel,
+                                                 del_work);
+       struct sock *sk = tunnel->sock;
+       struct socket *sock = sk->sk_socket;
+       struct l2tp_net *pn;
 
        l2tp_tunnel_closeall(tunnel);
 
-       sk = l2tp_tunnel_sock_lookup(tunnel);
-       if (!sk)
-               goto out;
-
-       sock = sk->sk_socket;
-
-       /* If the tunnel socket was created by userspace, then go through the
-        * inet layer to shut the socket down, and let userspace close it.
-        * Otherwise, if we created the socket directly within the kernel, use
+       /* If the tunnel socket was created within the kernel, use
         * the sk API to release it here.
-        * In either case the tunnel resources are freed in the socket
-        * destructor when the tunnel socket goes away.
         */
-       if (tunnel->fd >= 0) {
-               if (sock)
-                       inet_shutdown(sock, 2);
-       } else {
+       if (tunnel->fd < 0) {
                if (sock) {
                        kernel_sock_shutdown(sock, SHUT_RDWR);
                        sock_release(sock);
                }
        }
 
-       l2tp_tunnel_sock_put(sk);
-out:
+       /* Remove the tunnel struct from the tunnel list */
+       pn = l2tp_pernet(tunnel->l2tp_net);
+       spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+       list_del_rcu(&tunnel->list);
+       spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+
+       /* drop initial ref */
+       l2tp_tunnel_dec_refcount(tunnel);
+
+       /* drop workqueue ref */
        l2tp_tunnel_dec_refcount(tunnel);
 }
 
@@ -1515,9 +1473,14 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
                encap = cfg->encap;
 
        /* Quick sanity checks */
+       err = -EPROTONOSUPPORT;
+       if (sk->sk_type != SOCK_DGRAM) {
+               pr_debug("tunl %hu: fd %d wrong socket type\n",
+                        tunnel_id, fd);
+               goto err;
+       }
        switch (encap) {
        case L2TP_ENCAPTYPE_UDP:
-               err = -EPROTONOSUPPORT;
                if (sk->sk_protocol != IPPROTO_UDP) {
                        pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
                               tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
@@ -1525,7 +1488,6 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
                }
                break;
        case L2TP_ENCAPTYPE_IP:
-               err = -EPROTONOSUPPORT;
                if (sk->sk_protocol != IPPROTO_L2TP) {
                        pr_err("tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
                               tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
@@ -1565,24 +1527,6 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
        if (cfg != NULL)
                tunnel->debug = cfg->debug;
 
-#if IS_ENABLED(CONFIG_IPV6)
-       if (sk->sk_family == PF_INET6) {
-               struct ipv6_pinfo *np = inet6_sk(sk);
-
-               if (ipv6_addr_v4mapped(&np->saddr) &&
-                   ipv6_addr_v4mapped(&sk->sk_v6_daddr)) {
-                       struct inet_sock *inet = inet_sk(sk);
-
-                       tunnel->v4mapped = true;
-                       inet->inet_saddr = np->saddr.s6_addr32[3];
-                       inet->inet_rcv_saddr = sk->sk_v6_rcv_saddr.s6_addr32[3];
-                       inet->inet_daddr = sk->sk_v6_daddr.s6_addr32[3];
-               } else {
-                       tunnel->v4mapped = false;
-               }
-       }
-#endif
-
        /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
        tunnel->encap = encap;
        if (encap == L2TP_ENCAPTYPE_UDP) {
@@ -1598,13 +1542,22 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
                sk->sk_user_data = tunnel;
        }
 
+       /* Bump the reference count. The tunnel context is deleted
+        * only when this drops to zero. A reference is also held on
+        * the tunnel socket to ensure that it is not released while
+        * the tunnel is extant. Must be done before sk_destruct is
+        * set.
+        */
+       refcount_set(&tunnel->ref_count, 1);
+       sock_hold(sk);
+       tunnel->sock = sk;
+       tunnel->fd = fd;
+
        /* Hook on the tunnel socket destructor so that we can cleanup
         * if the tunnel socket goes away.
         */
        tunnel->old_sk_destruct = sk->sk_destruct;
        sk->sk_destruct = &l2tp_tunnel_destruct;
-       tunnel->sock = sk;
-       tunnel->fd = fd;
        lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock");
 
        sk->sk_allocation = GFP_ATOMIC;
@@ -1614,11 +1567,6 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
 
        /* Add tunnel to our list */
        INIT_LIST_HEAD(&tunnel->list);
-
-       /* Bump the reference count. The tunnel context is deleted
-        * only when this drops to zero. Must be done before list insertion
-        */
-       refcount_set(&tunnel->ref_count, 1);
        spin_lock_bh(&pn->l2tp_tunnel_list_lock);
        list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
        spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
@@ -1659,8 +1607,6 @@ void l2tp_session_free(struct l2tp_session *session)
 
        if (tunnel) {
                BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
-               sock_put(tunnel->sock);
-               session->tunnel = NULL;
                l2tp_tunnel_dec_refcount(tunnel);
        }
 
index 9bbee90e99637fed1bc40b8eba5ea44d4e3b74ef..2718d0b284d040810b3027ba62b911f77fc6f932 100644 (file)
@@ -188,9 +188,6 @@ struct l2tp_tunnel {
        struct sock             *sock;          /* Parent socket */
        int                     fd;             /* Parent fd, if tunnel socket
                                                 * was created by userspace */
-#if IS_ENABLED(CONFIG_IPV6)
-       bool                    v4mapped;
-#endif
 
        struct work_struct      del_work;
 
@@ -214,27 +211,8 @@ static inline void *l2tp_session_priv(struct l2tp_session *session)
        return &session->priv[0];
 }
 
-static inline struct l2tp_tunnel *l2tp_sock_to_tunnel(struct sock *sk)
-{
-       struct l2tp_tunnel *tunnel;
-
-       if (sk == NULL)
-               return NULL;
-
-       sock_hold(sk);
-       tunnel = (struct l2tp_tunnel *)(sk->sk_user_data);
-       if (tunnel == NULL) {
-               sock_put(sk);
-               goto out;
-       }
-
-       BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
-
-out:
-       return tunnel;
-}
-
 struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
+void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
 
 struct l2tp_session *l2tp_session_get(const struct net *net,
                                      struct l2tp_tunnel *tunnel,
@@ -283,7 +261,7 @@ static inline void l2tp_tunnel_inc_refcount(struct l2tp_tunnel *tunnel)
 static inline void l2tp_tunnel_dec_refcount(struct l2tp_tunnel *tunnel)
 {
        if (refcount_dec_and_test(&tunnel->ref_count))
-               kfree_rcu(tunnel, rcu);
+               l2tp_tunnel_free(tunnel);
 }
 
 /* Session reference counts. Incremented when code obtains a reference
index ff61124fdf593ff14116179a2564aaec6173ef07..3428fba6f2b7952972e0d31394d814754b9dc664 100644 (file)
@@ -234,17 +234,13 @@ static void l2tp_ip_close(struct sock *sk, long timeout)
 static void l2tp_ip_destroy_sock(struct sock *sk)
 {
        struct sk_buff *skb;
-       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+       struct l2tp_tunnel *tunnel = sk->sk_user_data;
 
        while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
                kfree_skb(skb);
 
-       if (tunnel) {
-               l2tp_tunnel_closeall(tunnel);
-               sock_put(sk);
-       }
-
-       sk_refcnt_debug_dec(sk);
+       if (tunnel)
+               l2tp_tunnel_delete(tunnel);
 }
 
 static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
index 192344688c06b9fe0f921f5612ad6f9b32d56b85..6f009eaa5fbe89cac538f6760d5ab2d61332e22a 100644 (file)
@@ -248,16 +248,14 @@ static void l2tp_ip6_close(struct sock *sk, long timeout)
 
 static void l2tp_ip6_destroy_sock(struct sock *sk)
 {
-       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+       struct l2tp_tunnel *tunnel = sk->sk_user_data;
 
        lock_sock(sk);
        ip6_flush_pending_frames(sk);
        release_sock(sk);
 
-       if (tunnel) {
-               l2tp_tunnel_closeall(tunnel);
-               sock_put(sk);
-       }
+       if (tunnel)
+               l2tp_tunnel_delete(tunnel);
 
        inet6_destroy_sock(sk);
 }
index 59f246d7b2906a1fcf53d76bc6f020dd9b2462b1..3b02f24ea9ec458544109a952f67d8fe69a5fc02 100644 (file)
@@ -416,20 +416,28 @@ abort:
  * Session (and tunnel control) socket create/destroy.
  *****************************************************************************/
 
+static void pppol2tp_put_sk(struct rcu_head *head)
+{
+       struct pppol2tp_session *ps;
+
+       ps = container_of(head, typeof(*ps), rcu);
+       sock_put(ps->__sk);
+}
+
 /* Called by l2tp_core when a session socket is being closed.
  */
 static void pppol2tp_session_close(struct l2tp_session *session)
 {
-       struct sock *sk;
-
-       BUG_ON(session->magic != L2TP_SESSION_MAGIC);
+       struct pppol2tp_session *ps;
 
-       sk = pppol2tp_session_get_sock(session);
-       if (sk) {
-               if (sk->sk_socket)
-                       inet_shutdown(sk->sk_socket, SEND_SHUTDOWN);
-               sock_put(sk);
-       }
+       ps = l2tp_session_priv(session);
+       mutex_lock(&ps->sk_lock);
+       ps->__sk = rcu_dereference_protected(ps->sk,
+                                            lockdep_is_held(&ps->sk_lock));
+       RCU_INIT_POINTER(ps->sk, NULL);
+       if (ps->__sk)
+               call_rcu(&ps->rcu, pppol2tp_put_sk);
+       mutex_unlock(&ps->sk_lock);
 }
 
 /* Really kill the session socket. (Called from sock_put() if
@@ -449,14 +457,6 @@ static void pppol2tp_session_destruct(struct sock *sk)
        }
 }
 
-static void pppol2tp_put_sk(struct rcu_head *head)
-{
-       struct pppol2tp_session *ps;
-
-       ps = container_of(head, typeof(*ps), rcu);
-       sock_put(ps->__sk);
-}
-
 /* Called when the PPPoX socket (session) is closed.
  */
 static int pppol2tp_release(struct socket *sock)
@@ -480,26 +480,17 @@ static int pppol2tp_release(struct socket *sock)
        sock_orphan(sk);
        sock->sk = NULL;
 
+       /* If the socket is associated with a session,
+        * l2tp_session_delete will call pppol2tp_session_close which
+        * will drop the session's ref on the socket.
+        */
        session = pppol2tp_sock_to_session(sk);
-
-       if (session != NULL) {
-               struct pppol2tp_session *ps;
-
+       if (session) {
                l2tp_session_delete(session);
-
-               ps = l2tp_session_priv(session);
-               mutex_lock(&ps->sk_lock);
-               ps->__sk = rcu_dereference_protected(ps->sk,
-                                                    lockdep_is_held(&ps->sk_lock));
-               RCU_INIT_POINTER(ps->sk, NULL);
-               mutex_unlock(&ps->sk_lock);
-               call_rcu(&ps->rcu, pppol2tp_put_sk);
-
-               /* Rely on the sock_put() call at the end of the function for
-                * dropping the reference held by pppol2tp_sock_to_session().
-                * The last reference will be dropped by pppol2tp_put_sk().
-                */
+               /* drop the ref obtained by pppol2tp_sock_to_session */
+               sock_put(sk);
        }
+
        release_sock(sk);
 
        /* This will delete the session context via
@@ -796,6 +787,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
 
 out_no_ppp:
        /* This is how we get the session context from the socket. */
+       sock_hold(sk);
        sk->sk_user_data = session;
        rcu_assign_pointer(ps->sk, sk);
        mutex_unlock(&ps->sk_lock);
index a8b1616cec418e533574ccdc1718df7a8c7cc0a3..1f3188d0384028ef338e86c291441c20493cbcb5 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
  * Copyright(c) 2015-2017 Intel Deutschland GmbH
+ * Copyright (C) 2018        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
@@ -304,9 +305,6 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
                         * driver so reject the timeout update.
                         */
                        status = WLAN_STATUS_REQUEST_DECLINED;
-                       ieee80211_send_addba_resp(sta->sdata, sta->sta.addr,
-                                                 tid, dialog_token, status,
-                                                 1, buf_size, timeout);
                        goto end;
                }
 
index 46028e12e216546be92996c71895a06656451d98..f4195a0f027989c4829b2f84d678373894d2fa1c 100644 (file)
@@ -2892,7 +2892,7 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
        }
        if (beacon->probe_resp_len) {
                new_beacon->probe_resp_len = beacon->probe_resp_len;
-               beacon->probe_resp = pos;
+               new_beacon->probe_resp = pos;
                memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
                pos += beacon->probe_resp_len;
        }
index 1f466d12a6bcd62061f4bab78d400544da93dd5c..94c7ee9df33b639bce674d67cb0f244e975c7dbb 100644 (file)
@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = {
        FLAG(REPORTS_LOW_ACK),
        FLAG(SUPPORTS_TX_FRAG),
        FLAG(SUPPORTS_TDLS_BUFFER_STA),
+       FLAG(DOESNT_SUPPORT_QOS_NDP),
 #undef FLAG
 };
 
index 26900025de2f5c3c0d84e146b9827c5073ef53fc..ae9c33cd8adaab4a235e3710026faf437a92fc0a 100644 (file)
@@ -1467,7 +1467,7 @@ struct ieee802_11_elems {
        const struct ieee80211_timeout_interval_ie *timeout_int;
        const u8 *opmode_notif;
        const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
-       const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;
+       struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;
        const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
 
        /* length of them, respectively */
index 73ac607beb5d704b3c74845baade196d0f66888b..6a381cbe1e33064f71f40110effc8a8fc6ad9ee4 100644 (file)
@@ -1255,13 +1255,12 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
 }
 
 static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
-                              struct ieee80211_mgmt *mgmt, size_t len)
+                              struct ieee80211_mgmt *mgmt, size_t len,
+                              struct ieee802_11_elems *elems)
 {
        struct ieee80211_mgmt *mgmt_fwd;
        struct sk_buff *skb;
        struct ieee80211_local *local = sdata->local;
-       u8 *pos = mgmt->u.action.u.chan_switch.variable;
-       size_t offset_ttl;
 
        skb = dev_alloc_skb(local->tx_headroom + len);
        if (!skb)
@@ -1269,13 +1268,9 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
        skb_reserve(skb, local->tx_headroom);
        mgmt_fwd = skb_put(skb, len);
 
-       /* offset_ttl is based on whether the secondary channel
-        * offset is available or not. Subtract 1 from the mesh TTL
-        * and disable the initiator flag before forwarding.
-        */
-       offset_ttl = (len < 42) ? 7 : 10;
-       *(pos + offset_ttl) -= 1;
-       *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
+       elems->mesh_chansw_params_ie->mesh_ttl--;
+       elems->mesh_chansw_params_ie->mesh_flags &=
+               ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
 
        memcpy(mgmt_fwd, mgmt, len);
        eth_broadcast_addr(mgmt_fwd->da);
@@ -1323,7 +1318,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
 
        /* forward or re-broadcast the CSA frame */
        if (fwd_csa) {
-               if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0)
+               if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0)
                        mcsa_dbg(sdata, "Failed to forward the CSA frame");
        }
 }
index 39b660b9a90894f72f7601be38f41f84da0f6b70..5f303abac5ad6ee4289c2b9b90185d806bc37565 100644 (file)
@@ -896,7 +896,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
        struct ieee80211_hdr_3addr *nullfunc;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-       skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, true);
+       skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif,
+               !ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP));
        if (!skb)
                return;
 
index fd580614085b3ff8c191a39b8b0c76beb339b361..56fe16b075381ff59fa6f949e0f973bc4a311d0a 100644 (file)
@@ -3921,7 +3921,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
        if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FROMDS |
                                              IEEE80211_FCTL_TODS)) !=
            fast_rx->expected_ds_bits)
-               goto drop;
+               return false;
 
        /* assign the key to drop unencrypted frames (later)
         * and strip the IV/MIC if necessary
index ee0181778a4297515de9bf0c75a947e7c45924a2..0293348357474ab411d5068218a521e59a54249e 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2008, Intel Corporation
  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (C) 2018        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
@@ -27,7 +28,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
                                 u32 sta_flags, u8 *bssid,
                                 struct ieee80211_csa_ie *csa_ie)
 {
-       enum nl80211_band new_band;
+       enum nl80211_band new_band = current_band;
        int new_freq;
        u8 new_chan_no;
        struct ieee80211_channel *new_chan;
@@ -55,15 +56,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
                                elems->ext_chansw_ie->new_operating_class,
                                &new_band)) {
                        sdata_info(sdata,
-                                  "cannot understand ECSA IE operating class %d, disconnecting\n",
+                                  "cannot understand ECSA IE operating class, %d, ignoring\n",
                                   elems->ext_chansw_ie->new_operating_class);
-                       return -EINVAL;
                }
                new_chan_no = elems->ext_chansw_ie->new_ch_num;
                csa_ie->count = elems->ext_chansw_ie->count;
                csa_ie->mode = elems->ext_chansw_ie->mode;
        } else if (elems->ch_switch_ie) {
-               new_band = current_band;
                new_chan_no = elems->ch_switch_ie->new_ch_num;
                csa_ie->count = elems->ch_switch_ie->count;
                csa_ie->mode = elems->ch_switch_ie->mode;
index 0c5627f8a104e17fb54f55c09da597ef84af5be3..af0b608ee8ed11bdab91a163e4f8e8036f991185 100644 (file)
@@ -314,7 +314,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
 
        if (ieee80211_hw_check(hw, USES_RSS)) {
                sta->pcpu_rx_stats =
-                       alloc_percpu(struct ieee80211_sta_rx_stats);
+                       alloc_percpu_gfp(struct ieee80211_sta_rx_stats, gfp);
                if (!sta->pcpu_rx_stats)
                        goto free;
        }
@@ -433,6 +433,7 @@ free_txq:
        if (sta->sta.txq[0])
                kfree(to_txq_info(sta->sta.txq[0]));
 free:
+       free_percpu(sta->pcpu_rx_stats);
 #ifdef CONFIG_MAC80211_MESH
        kfree(sta->mesh);
 #endif
index 25904af38839a202dc2c65b0b0f9864b277dc81c..69722504e3e14971c1645c32b6534e3fc10172c5 100644 (file)
@@ -3574,6 +3574,14 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
        if (!IS_ERR_OR_NULL(sta)) {
                struct ieee80211_fast_tx *fast_tx;
 
+               /* We need a bit of data queued to build aggregates properly, so
+                * instruct the TCP stack to allow more than a single ms of data
+                * to be queued in the stack. The value is a bit-shift of 1
+                * second, so 8 is ~4ms of queued data. Only affects local TCP
+                * sockets.
+                */
+               sk_pacing_shift_update(skb->sk, 8);
+
                fast_tx = rcu_dereference(sta->fast_tx);
 
                if (fast_tx &&
index e545a3c9365f8a8fe172a2a2d4ad0a14af49f9a8..7a4de6d618b169d0f72b04386965b6e02ba27ada 100644 (file)
@@ -122,7 +122,7 @@ bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
        if (skb->len <= mtu)
                return false;
 
-       if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
+       if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
                return false;
 
        return true;
index 3e17d32b629d18e97f85fe8e543431562cdf3c6e..58d5d05aec24c5fcc0bb23f2ccceea887bfaa029 100644 (file)
@@ -260,7 +260,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
                buf_len = strlen(buf);
 
                ct = nf_ct_get(skb, &ctinfo);
-               if (ct && (ct->status & IPS_NAT_MASK)) {
+               if (ct) {
                        bool mangled;
 
                        /* If mangling fails this function will return 0
index fbce552a796e14a6249e6e9a5d0d2ea16aaf3f09..7d7466dbf66338f817bb6698b9dbd637de26d3ed 100644 (file)
@@ -41,7 +41,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
                                 const struct nf_conn *ct,
                                 u16 *rover)
 {
-       unsigned int range_size, min, i;
+       unsigned int range_size, min, max, i;
        __be16 *portptr;
        u_int16_t off;
 
@@ -71,7 +71,10 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
                }
        } else {
                min = ntohs(range->min_proto.all);
-               range_size = ntohs(range->max_proto.all) - min + 1;
+               max = ntohs(range->max_proto.all);
+               if (unlikely(max < min))
+                       swap(max, min);
+               range_size = max - min + 1;
        }
 
        if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
index 8b9fe30de0cdda1df772f8b16b03850603008f06..c4acc7340eb1014bb0941bf6054908c178595770 100644 (file)
@@ -5037,9 +5037,9 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        const struct nf_flowtable_type *type;
+       struct nft_flowtable *flowtable, *ft;
        u8 genmask = nft_genmask_next(net);
        int family = nfmsg->nfgen_family;
-       struct nft_flowtable *flowtable;
        struct nft_table *table;
        struct nft_ctx ctx;
        int err, i, k;
@@ -5099,6 +5099,22 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
                goto err3;
 
        for (i = 0; i < flowtable->ops_len; i++) {
+               if (!flowtable->ops[i].dev)
+                       continue;
+
+               list_for_each_entry(ft, &table->flowtables, list) {
+                       for (k = 0; k < ft->ops_len; k++) {
+                               if (!ft->ops[k].dev)
+                                       continue;
+
+                               if (flowtable->ops[i].dev == ft->ops[k].dev &&
+                                   flowtable->ops[i].pf == ft->ops[k].pf) {
+                                       err = -EBUSY;
+                                       goto err4;
+                               }
+                       }
+               }
+
                err = nf_register_net_hook(net, &flowtable->ops[i]);
                if (err < 0)
                        goto err4;
@@ -5120,7 +5136,7 @@ err5:
        i = flowtable->ops_len;
 err4:
        for (k = i - 1; k >= 0; k--)
-               nf_unregister_net_hook(net, &flowtable->ops[i]);
+               nf_unregister_net_hook(net, &flowtable->ops[k]);
 
        kfree(flowtable->ops);
 err3:
@@ -5145,6 +5161,11 @@ static int nf_tables_delflowtable(struct net *net, struct sock *nlsk,
        struct nft_table *table;
        struct nft_ctx ctx;
 
+       if (!nla[NFTA_FLOWTABLE_TABLE] ||
+           (!nla[NFTA_FLOWTABLE_NAME] &&
+            !nla[NFTA_FLOWTABLE_HANDLE]))
+               return -EINVAL;
+
        table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE],
                                       family, genmask);
        if (IS_ERR(table))
@@ -5402,6 +5423,7 @@ err:
 static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
 {
        cancel_delayed_work_sync(&flowtable->data.gc_work);
+       kfree(flowtable->ops);
        kfree(flowtable->name);
        flowtable->data.type->free(&flowtable->data);
        rhashtable_destroy(&flowtable->data.rhashtable);
index 3f1624ee056f96570254cf5d8737f38b82a87593..d40591fe1b2f64c3531b35abcadd8dbfc6d67c8a 100644 (file)
@@ -674,7 +674,7 @@ static const struct nft_set_ops *
 nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc,
                    u32 flags)
 {
-       if (desc->size) {
+       if (desc->size && !(flags & NFT_SET_TIMEOUT)) {
                switch (desc->klen) {
                case 4:
                        return &nft_hash_fast_ops;
index 2f685ee1f9c87dc6cee3b1c333e7d62ad36de806..4aa01c90e9d1edf24a9fef99f46351bceae2d5c0 100644 (file)
@@ -423,6 +423,36 @@ textify_hooks(char *buf, size_t size, unsigned int mask, uint8_t nfproto)
        return buf;
 }
 
+/**
+ * xt_check_proc_name - check that name is suitable for /proc file creation
+ *
+ * @name: file name candidate
+ * @size: length of buffer
+ *
+ * some x_tables modules wish to create a file in /proc.
+ * This function makes sure that the name is suitable for this
+ * purpose, it checks that name is NUL terminated and isn't a 'special'
+ * name, like "..".
+ *
+ * returns negative number on error or 0 if name is useable.
+ */
+int xt_check_proc_name(const char *name, unsigned int size)
+{
+       if (name[0] == '\0')
+               return -EINVAL;
+
+       if (strnlen(name, size) == size)
+               return -ENAMETOOLONG;
+
+       if (strcmp(name, ".") == 0 ||
+           strcmp(name, "..") == 0 ||
+           strchr(name, '/'))
+               return -EINVAL;
+
+       return 0;
+}
+EXPORT_SYMBOL(xt_check_proc_name);
+
 int xt_check_match(struct xt_mtchk_param *par,
                   unsigned int size, u_int8_t proto, bool inv_proto)
 {
@@ -434,36 +464,35 @@ int xt_check_match(struct xt_mtchk_param *par,
                 * ebt_among is exempt from centralized matchsize checking
                 * because it uses a dynamic-size data set.
                 */
-               pr_err("%s_tables: %s.%u match: invalid size "
-                      "%u (kernel) != (user) %u\n",
-                      xt_prefix[par->family], par->match->name,
-                      par->match->revision,
-                      XT_ALIGN(par->match->matchsize), size);
+               pr_err_ratelimited("%s_tables: %s.%u match: invalid size %u (kernel) != (user) %u\n",
+                                  xt_prefix[par->family], par->match->name,
+                                  par->match->revision,
+                                  XT_ALIGN(par->match->matchsize), size);
                return -EINVAL;
        }
        if (par->match->table != NULL &&
            strcmp(par->match->table, par->table) != 0) {
-               pr_err("%s_tables: %s match: only valid in %s table, not %s\n",
-                      xt_prefix[par->family], par->match->name,
-                      par->match->table, par->table);
+               pr_info_ratelimited("%s_tables: %s match: only valid in %s table, not %s\n",
+                                   xt_prefix[par->family], par->match->name,
+                                   par->match->table, par->table);
                return -EINVAL;
        }
        if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
                char used[64], allow[64];
 
-               pr_err("%s_tables: %s match: used from hooks %s, but only "
-                      "valid from %s\n",
-                      xt_prefix[par->family], par->match->name,
-                      textify_hooks(used, sizeof(used), par->hook_mask,
-                                    par->family),
-                      textify_hooks(allow, sizeof(allow), par->match->hooks,
-                                    par->family));
+               pr_info_ratelimited("%s_tables: %s match: used from hooks %s, but only valid from %s\n",
+                                   xt_prefix[par->family], par->match->name,
+                                   textify_hooks(used, sizeof(used),
+                                                 par->hook_mask, par->family),
+                                   textify_hooks(allow, sizeof(allow),
+                                                 par->match->hooks,
+                                                 par->family));
                return -EINVAL;
        }
        if (par->match->proto && (par->match->proto != proto || inv_proto)) {
-               pr_err("%s_tables: %s match: only valid for protocol %u\n",
-                      xt_prefix[par->family], par->match->name,
-                      par->match->proto);
+               pr_info_ratelimited("%s_tables: %s match: only valid for protocol %u\n",
+                                   xt_prefix[par->family], par->match->name,
+                                   par->match->proto);
                return -EINVAL;
        }
        if (par->match->checkentry != NULL) {
@@ -814,36 +843,35 @@ int xt_check_target(struct xt_tgchk_param *par,
        int ret;
 
        if (XT_ALIGN(par->target->targetsize) != size) {
-               pr_err("%s_tables: %s.%u target: invalid size "
-                      "%u (kernel) != (user) %u\n",
-                      xt_prefix[par->family], par->target->name,
-                      par->target->revision,
-                      XT_ALIGN(par->target->targetsize), size);
+               pr_err_ratelimited("%s_tables: %s.%u target: invalid size %u (kernel) != (user) %u\n",
+                                  xt_prefix[par->family], par->target->name,
+                                  par->target->revision,
+                                  XT_ALIGN(par->target->targetsize), size);
                return -EINVAL;
        }
        if (par->target->table != NULL &&
            strcmp(par->target->table, par->table) != 0) {
-               pr_err("%s_tables: %s target: only valid in %s table, not %s\n",
-                      xt_prefix[par->family], par->target->name,
-                      par->target->table, par->table);
+               pr_info_ratelimited("%s_tables: %s target: only valid in %s table, not %s\n",
+                                   xt_prefix[par->family], par->target->name,
+                                   par->target->table, par->table);
                return -EINVAL;
        }
        if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
                char used[64], allow[64];
 
-               pr_err("%s_tables: %s target: used from hooks %s, but only "
-                      "usable from %s\n",
-                      xt_prefix[par->family], par->target->name,
-                      textify_hooks(used, sizeof(used), par->hook_mask,
-                                    par->family),
-                      textify_hooks(allow, sizeof(allow), par->target->hooks,
-                                    par->family));
+               pr_info_ratelimited("%s_tables: %s target: used from hooks %s, but only usable from %s\n",
+                                   xt_prefix[par->family], par->target->name,
+                                   textify_hooks(used, sizeof(used),
+                                                 par->hook_mask, par->family),
+                                   textify_hooks(allow, sizeof(allow),
+                                                 par->target->hooks,
+                                                 par->family));
                return -EINVAL;
        }
        if (par->target->proto && (par->target->proto != proto || inv_proto)) {
-               pr_err("%s_tables: %s target: only valid for protocol %u\n",
-                      xt_prefix[par->family], par->target->name,
-                      par->target->proto);
+               pr_info_ratelimited("%s_tables: %s target: only valid for protocol %u\n",
+                                   xt_prefix[par->family], par->target->name,
+                                   par->target->proto);
                return -EINVAL;
        }
        if (par->target->checkentry != NULL) {
@@ -1004,10 +1032,6 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)
        if (sz < sizeof(*info))
                return NULL;
 
-       /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
-       if ((size >> PAGE_SHIFT) + 2 > totalram_pages)
-               return NULL;
-
        /* __GFP_NORETRY is not fully supported by kvmalloc but it should
         * work reasonably well if sz is too large and bail out rather
         * than shoot all processes down before realizing there is nothing
index c502419d63061c7aa5d3205187e7429294b3cc97..f368ee6741db556ec06aa3569b21872acfeb710d 100644 (file)
@@ -120,8 +120,8 @@ static int audit_tg_check(const struct xt_tgchk_param *par)
        const struct xt_audit_info *info = par->targinfo;
 
        if (info->type > XT_AUDIT_TYPE_MAX) {
-               pr_info("Audit type out of range (valid range: 0..%hhu)\n",
-                       XT_AUDIT_TYPE_MAX);
+               pr_info_ratelimited("Audit type out of range (valid range: 0..%hhu)\n",
+                                   XT_AUDIT_TYPE_MAX);
                return -ERANGE;
        }
 
index 0f642ef8cd2669e737dd0cdb5958abcced8be7d2..9f4151ec3e06e73460243f2b0c5c49762b37bb6d 100644 (file)
@@ -36,13 +36,13 @@ static int checksum_tg_check(const struct xt_tgchk_param *par)
        const struct xt_CHECKSUM_info *einfo = par->targinfo;
 
        if (einfo->operation & ~XT_CHECKSUM_OP_FILL) {
-               pr_info("unsupported CHECKSUM operation %x\n", einfo->operation);
+               pr_info_ratelimited("unsupported CHECKSUM operation %x\n",
+                                   einfo->operation);
                return -EINVAL;
        }
-       if (!einfo->operation) {
-               pr_info("no CHECKSUM operation enabled\n");
+       if (!einfo->operation)
                return -EINVAL;
-       }
+
        return 0;
 }
 
index da56c06a443c0bcf0dd1e767b4d4848179a7ce73..f3f1caac949bad44db0fd992b7a74d27f216cbed 100644 (file)
@@ -91,8 +91,8 @@ static int connsecmark_tg_check(const struct xt_tgchk_param *par)
 
        if (strcmp(par->table, "mangle") != 0 &&
            strcmp(par->table, "security") != 0) {
-               pr_info("target only valid in the \'mangle\' "
-                       "or \'security\' tables, not \'%s\'.\n", par->table);
+               pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\'\n",
+                                   par->table);
                return -EINVAL;
        }
 
@@ -102,14 +102,14 @@ static int connsecmark_tg_check(const struct xt_tgchk_param *par)
                break;
 
        default:
-               pr_info("invalid mode: %hu\n", info->mode);
+               pr_info_ratelimited("invalid mode: %hu\n", info->mode);
                return -EINVAL;
        }
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0)
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
        return ret;
 }
 
index 5a152e2acfd5816718981c2db470ce3fa69b1ce6..8790190c6feb3cf1bce5577319fc043a5c55dc2c 100644 (file)
@@ -82,15 +82,14 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name,
 
        proto = xt_ct_find_proto(par);
        if (!proto) {
-               pr_info("You must specify a L4 protocol, and not use "
-                       "inversions on it.\n");
+               pr_info_ratelimited("You must specify a L4 protocol and not use inversions on it\n");
                return -ENOENT;
        }
 
        helper = nf_conntrack_helper_try_module_get(helper_name, par->family,
                                                    proto);
        if (helper == NULL) {
-               pr_info("No such helper \"%s\"\n", helper_name);
+               pr_info_ratelimited("No such helper \"%s\"\n", helper_name);
                return -ENOENT;
        }
 
@@ -124,6 +123,7 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
        const struct nf_conntrack_l4proto *l4proto;
        struct ctnl_timeout *timeout;
        struct nf_conn_timeout *timeout_ext;
+       const char *errmsg = NULL;
        int ret = 0;
        u8 proto;
 
@@ -131,29 +131,29 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
        timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook);
        if (timeout_find_get == NULL) {
                ret = -ENOENT;
-               pr_info("Timeout policy base is empty\n");
+               errmsg = "Timeout policy base is empty";
                goto out;
        }
 
        proto = xt_ct_find_proto(par);
        if (!proto) {
                ret = -EINVAL;
-               pr_info("You must specify a L4 protocol, and not use "
-                       "inversions on it.\n");
+               errmsg = "You must specify a L4 protocol and not use inversions on it";
                goto out;
        }
 
        timeout = timeout_find_get(par->net, timeout_name);
        if (timeout == NULL) {
                ret = -ENOENT;
-               pr_info("No such timeout policy \"%s\"\n", timeout_name);
+               pr_info_ratelimited("No such timeout policy \"%s\"\n",
+                                   timeout_name);
                goto out;
        }
 
        if (timeout->l3num != par->family) {
                ret = -EINVAL;
-               pr_info("Timeout policy `%s' can only be used by L3 protocol "
-                       "number %d\n", timeout_name, timeout->l3num);
+               pr_info_ratelimited("Timeout policy `%s' can only be used by L%d protocol number %d\n",
+                                   timeout_name, 3, timeout->l3num);
                goto err_put_timeout;
        }
        /* Make sure the timeout policy matches any existing protocol tracker,
@@ -162,9 +162,8 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
        l4proto = __nf_ct_l4proto_find(par->family, proto);
        if (timeout->l4proto->l4proto != l4proto->l4proto) {
                ret = -EINVAL;
-               pr_info("Timeout policy `%s' can only be used by L4 protocol "
-                       "number %d\n",
-                       timeout_name, timeout->l4proto->l4proto);
+               pr_info_ratelimited("Timeout policy `%s' can only be used by L%d protocol number %d\n",
+                                   timeout_name, 4, timeout->l4proto->l4proto);
                goto err_put_timeout;
        }
        timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
@@ -180,6 +179,8 @@ err_put_timeout:
        __xt_ct_tg_timeout_put(timeout);
 out:
        rcu_read_unlock();
+       if (errmsg)
+               pr_info_ratelimited("%s\n", errmsg);
        return ret;
 #else
        return -EOPNOTSUPP;
index 3f83d38c4e5bb975f80a6834965a18c92f254dcc..098ed851b7a782e15caa1c1e7ff52a7c909b340a 100644 (file)
@@ -66,10 +66,8 @@ static int dscp_tg_check(const struct xt_tgchk_param *par)
 {
        const struct xt_DSCP_info *info = par->targinfo;
 
-       if (info->dscp > XT_DSCP_MAX) {
-               pr_info("dscp %x out of range\n", info->dscp);
+       if (info->dscp > XT_DSCP_MAX)
                return -EDOM;
-       }
        return 0;
 }
 
index 1535e87ed9bd4fa47a7f431afab82320cf5e8530..4653b071bed41cc853572a25cc57271f060277e3 100644 (file)
@@ -105,10 +105,8 @@ static int ttl_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_TTL_info *info = par->targinfo;
 
-       if (info->mode > IPT_TTL_MAXMODE) {
-               pr_info("TTL: invalid or unknown mode %u\n", info->mode);
+       if (info->mode > IPT_TTL_MAXMODE)
                return -EINVAL;
-       }
        if (info->mode != IPT_TTL_SET && info->ttl == 0)
                return -EINVAL;
        return 0;
@@ -118,15 +116,10 @@ static int hl_tg6_check(const struct xt_tgchk_param *par)
 {
        const struct ip6t_HL_info *info = par->targinfo;
 
-       if (info->mode > IP6T_HL_MAXMODE) {
-               pr_info("invalid or unknown mode %u\n", info->mode);
+       if (info->mode > IP6T_HL_MAXMODE)
                return -EINVAL;
-       }
-       if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
-               pr_info("increment/decrement does not "
-                       "make sense with value 0\n");
+       if (info->mode != IP6T_HL_SET && info->hop_limit == 0)
                return -EINVAL;
-       }
        return 0;
 }
 
index 60e6dbe124605569f249f0e15c7304b231fe1500..9c75f419cd80446694e4661ebb676b264f85cd1f 100644 (file)
@@ -9,6 +9,8 @@
  * the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/icmp.h>
@@ -312,29 +314,30 @@ hmark_tg_v4(struct sk_buff *skb, const struct xt_action_param *par)
 static int hmark_tg_check(const struct xt_tgchk_param *par)
 {
        const struct xt_hmark_info *info = par->targinfo;
+       const char *errmsg = "proto mask must be zero with L3 mode";
 
-       if (!info->hmodulus) {
-               pr_info("xt_HMARK: hash modulus can't be zero\n");
+       if (!info->hmodulus)
                return -EINVAL;
-       }
+
        if (info->proto_mask &&
-           (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3))) {
-               pr_info("xt_HMARK: proto mask must be zero with L3 mode\n");
-               return -EINVAL;
-       }
+           (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)))
+               goto err;
+
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK) &&
            (info->flags & (XT_HMARK_FLAG(XT_HMARK_SPORT_MASK) |
-                            XT_HMARK_FLAG(XT_HMARK_DPORT_MASK)))) {
-               pr_info("xt_HMARK: spi-mask and port-mask can't be combined\n");
+                            XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))))
                return -EINVAL;
-       }
+
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI) &&
            (info->flags & (XT_HMARK_FLAG(XT_HMARK_SPORT) |
                             XT_HMARK_FLAG(XT_HMARK_DPORT)))) {
-               pr_info("xt_HMARK: spi-set and port-set can't be combined\n");
-               return -EINVAL;
+               errmsg = "spi-set and port-set can't be combined";
+               goto err;
        }
        return 0;
+err:
+       pr_info_ratelimited("%s\n", errmsg);
+       return -EINVAL;
 }
 
 static struct xt_target hmark_tg_reg[] __read_mostly = {
index 6c2482b709b1eca341926a8393f45dfead358561..1ac6600bfafd60b6b4d5aaf88a41fb57c6ec195b 100644 (file)
@@ -146,11 +146,11 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
        timer_setup(&info->timer->timer, idletimer_tg_expired, 0);
        info->timer->refcnt = 1;
 
+       INIT_WORK(&info->timer->work, idletimer_tg_work);
+
        mod_timer(&info->timer->timer,
                  msecs_to_jiffies(info->timeout * 1000) + jiffies);
 
-       INIT_WORK(&info->timer->work, idletimer_tg_work);
-
        return 0;
 
 out_free_attr:
@@ -191,7 +191,10 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par)
                pr_debug("timeout value is zero\n");
                return -EINVAL;
        }
-
+       if (info->timeout >= INT_MAX / 1000) {
+               pr_debug("timeout value is too big\n");
+               return -EINVAL;
+       }
        if (info->label[0] == '\0' ||
            strnlen(info->label,
                    MAX_IDLETIMER_LABEL_SIZE) == MAX_IDLETIMER_LABEL_SIZE) {
index 1dcad893df781395fe2773b58e99e615b84ffcc5..19846445504dcab1ada188224c4de67139df8dc6 100644 (file)
@@ -111,10 +111,8 @@ static int led_tg_check(const struct xt_tgchk_param *par)
        struct xt_led_info_internal *ledinternal;
        int err;
 
-       if (ledinfo->id[0] == '\0') {
-               pr_info("No 'id' parameter given.\n");
+       if (ledinfo->id[0] == '\0')
                return -EINVAL;
-       }
 
        mutex_lock(&xt_led_mutex);
 
@@ -138,13 +136,14 @@ static int led_tg_check(const struct xt_tgchk_param *par)
 
        err = led_trigger_register(&ledinternal->netfilter_led_trigger);
        if (err) {
-               pr_err("Trigger name is already in use.\n");
+               pr_info_ratelimited("Trigger name is already in use.\n");
                goto exit_alloc;
        }
 
-       /* See if we need to set up a timer */
-       if (ledinfo->delay > 0)
-               timer_setup(&ledinternal->timer, led_timeout_callback, 0);
+       /* Since the letinternal timer can be shared between multiple targets,
+        * always set it up, even if the current target does not need it
+        */
+       timer_setup(&ledinternal->timer, led_timeout_callback, 0);
 
        list_add_tail(&ledinternal->list, &xt_led_triggers);
 
@@ -181,8 +180,7 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par)
 
        list_del(&ledinternal->list);
 
-       if (ledinfo->delay > 0)
-               del_timer_sync(&ledinternal->timer);
+       del_timer_sync(&ledinternal->timer);
 
        led_trigger_unregister(&ledinternal->netfilter_led_trigger);
 
index a360b99a958af224a2aa98fb6fe080a885b733ef..a9aca80a32aeb4c9b92757a20710960b094aa7aa 100644 (file)
@@ -8,6 +8,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
@@ -67,13 +69,13 @@ static int nfqueue_tg_check(const struct xt_tgchk_param *par)
        init_hashrandom(&jhash_initval);
 
        if (info->queues_total == 0) {
-               pr_err("NFQUEUE: number of total queues is 0\n");
+               pr_info_ratelimited("number of total queues is 0\n");
                return -EINVAL;
        }
        maxid = info->queues_total - 1 + info->queuenum;
        if (maxid > 0xffff) {
-               pr_err("NFQUEUE: number of queues (%u) out of range (got %u)\n",
-                      info->queues_total, maxid);
+               pr_info_ratelimited("number of queues (%u) out of range (got %u)\n",
+                                   info->queues_total, maxid);
                return -ERANGE;
        }
        if (par->target->revision == 2 && info->flags > 1)
index 9faf5e050b796186b3204a02ece181726a26cb1a..4ad5fe27e08bcc6732f8f8a9977530b908430578 100644 (file)
@@ -60,18 +60,20 @@ static int checkentry_lsm(struct xt_secmark_target_info *info)
                                       &info->secid);
        if (err) {
                if (err == -EINVAL)
-                       pr_info("invalid security context \'%s\'\n", info->secctx);
+                       pr_info_ratelimited("invalid security context \'%s\'\n",
+                                           info->secctx);
                return err;
        }
 
        if (!info->secid) {
-               pr_info("unable to map security context \'%s\'\n", info->secctx);
+               pr_info_ratelimited("unable to map security context \'%s\'\n",
+                                   info->secctx);
                return -ENOENT;
        }
 
        err = security_secmark_relabel_packet(info->secid);
        if (err) {
-               pr_info("unable to obtain relabeling permission\n");
+               pr_info_ratelimited("unable to obtain relabeling permission\n");
                return err;
        }
 
@@ -86,14 +88,14 @@ static int secmark_tg_check(const struct xt_tgchk_param *par)
 
        if (strcmp(par->table, "mangle") != 0 &&
            strcmp(par->table, "security") != 0) {
-               pr_info("target only valid in the \'mangle\' "
-                       "or \'security\' tables, not \'%s\'.\n", par->table);
+               pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\'\n",
+                                   par->table);
                return -EINVAL;
        }
 
        if (mode && mode != info->mode) {
-               pr_info("mode already set to %hu cannot mix with "
-                       "rules for mode %hu\n", mode, info->mode);
+               pr_info_ratelimited("mode already set to %hu cannot mix with rules for mode %hu\n",
+                                   mode, info->mode);
                return -EINVAL;
        }
 
@@ -101,7 +103,7 @@ static int secmark_tg_check(const struct xt_tgchk_param *par)
        case SECMARK_MODE_SEL:
                break;
        default:
-               pr_info("invalid mode: %hu\n", info->mode);
+               pr_info_ratelimited("invalid mode: %hu\n", info->mode);
                return -EINVAL;
        }
 
index 99bb8e410f229e3a8233ce60192c2ca0a4483b84..98efb202f8b4a14d329df1cc4614ac4088fbf151 100644 (file)
@@ -273,8 +273,7 @@ static int tcpmss_tg4_check(const struct xt_tgchk_param *par)
            (par->hook_mask & ~((1 << NF_INET_FORWARD) |
                           (1 << NF_INET_LOCAL_OUT) |
                           (1 << NF_INET_POST_ROUTING))) != 0) {
-               pr_info("path-MTU clamping only supported in "
-                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
+               pr_info_ratelimited("path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\n");
                return -EINVAL;
        }
        if (par->nft_compat)
@@ -283,7 +282,7 @@ static int tcpmss_tg4_check(const struct xt_tgchk_param *par)
        xt_ematch_foreach(ematch, e)
                if (find_syn_match(ematch))
                        return 0;
-       pr_info("Only works on TCP SYN packets\n");
+       pr_info_ratelimited("Only works on TCP SYN packets\n");
        return -EINVAL;
 }
 
@@ -298,8 +297,7 @@ static int tcpmss_tg6_check(const struct xt_tgchk_param *par)
            (par->hook_mask & ~((1 << NF_INET_FORWARD) |
                           (1 << NF_INET_LOCAL_OUT) |
                           (1 << NF_INET_POST_ROUTING))) != 0) {
-               pr_info("path-MTU clamping only supported in "
-                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
+               pr_info_ratelimited("path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\n");
                return -EINVAL;
        }
        if (par->nft_compat)
@@ -308,7 +306,7 @@ static int tcpmss_tg6_check(const struct xt_tgchk_param *par)
        xt_ematch_foreach(ematch, e)
                if (find_syn_match(ematch))
                        return 0;
-       pr_info("Only works on TCP SYN packets\n");
+       pr_info_ratelimited("Only works on TCP SYN packets\n");
        return -EINVAL;
 }
 #endif
index 17d7705e3bd41d5bbaf0ff6aba98a56f472a8388..8c89323c06afed8232e6e227683d8faa3dabc3a7 100644 (file)
@@ -540,8 +540,7 @@ static int tproxy_tg6_check(const struct xt_tgchk_param *par)
            !(i->invflags & IP6T_INV_PROTO))
                return 0;
 
-       pr_info("Can be used only in combination with "
-               "either -p tcp or -p udp\n");
+       pr_info_ratelimited("Can be used only with -p tcp or -p udp\n");
        return -EINVAL;
 }
 #endif
@@ -559,8 +558,7 @@ static int tproxy_tg4_check(const struct xt_tgchk_param *par)
            && !(i->invflags & IPT_INV_PROTO))
                return 0;
 
-       pr_info("Can be used only in combination with "
-               "either -p tcp or -p udp\n");
+       pr_info_ratelimited("Can be used only with -p tcp or -p udp\n");
        return -EINVAL;
 }
 
index 911a7c0da5040c6aa0ea30e117ac7571b9129ce5..89e281b3bfc24eece9e485375fc0a59825089298 100644 (file)
@@ -164,48 +164,47 @@ addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
 
 static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
 {
+       const char *errmsg = "both incoming and outgoing interface limitation cannot be selected";
        struct xt_addrtype_info_v1 *info = par->matchinfo;
 
        if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&
-           info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) {
-               pr_info("both incoming and outgoing "
-                       "interface limitation cannot be selected\n");
-               return -EINVAL;
-       }
+           info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)
+               goto err;
 
        if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
            (1 << NF_INET_LOCAL_IN)) &&
            info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) {
-               pr_info("output interface limitation "
-                       "not valid in PREROUTING and INPUT\n");
-               return -EINVAL;
+               errmsg = "output interface limitation not valid in PREROUTING and INPUT";
+               goto err;
        }
 
        if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
            (1 << NF_INET_LOCAL_OUT)) &&
            info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) {
-               pr_info("input interface limitation "
-                       "not valid in POSTROUTING and OUTPUT\n");
-               return -EINVAL;
+               errmsg = "input interface limitation not valid in POSTROUTING and OUTPUT";
+               goto err;
        }
 
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        if (par->family == NFPROTO_IPV6) {
                if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) {
-                       pr_err("ipv6 BLACKHOLE matching not supported\n");
-                       return -EINVAL;
+                       errmsg = "ipv6 BLACKHOLE matching not supported";
+                       goto err;
                }
                if ((info->source | info->dest) >= XT_ADDRTYPE_PROHIBIT) {
-                       pr_err("ipv6 PROHIBIT (THROW, NAT ..) matching not supported\n");
-                       return -EINVAL;
+                       errmsg = "ipv6 PROHIBIT (THROW, NAT ..) matching not supported";
+                       goto err;
                }
                if ((info->source | info->dest) & XT_ADDRTYPE_BROADCAST) {
-                       pr_err("ipv6 does not support BROADCAST matching\n");
-                       return -EINVAL;
+                       errmsg = "ipv6 does not support BROADCAST matching";
+                       goto err;
                }
        }
 #endif
        return 0;
+err:
+       pr_info_ratelimited("%s\n", errmsg);
+       return -EINVAL;
 }
 
 static struct xt_match addrtype_mt_reg[] __read_mostly = {
index 06b090d8e9014d6bf6adfb742b5c2620197b98fb..a2cf8a6236d63deb1516dd6aea88161ac12b7022 100644 (file)
@@ -7,6 +7,8 @@
  * published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/skbuff.h>
@@ -34,7 +36,7 @@ static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len,
        program.filter = insns;
 
        if (bpf_prog_create(ret, &program)) {
-               pr_info("bpf: check failed: parse error\n");
+               pr_info_ratelimited("check failed: parse error\n");
                return -EINVAL;
        }
 
index 891f4e7e8ea7f507eebf1a22fa5dd818fc3ab49c..7df2dece57d30f6c4e921cf3eeff40f5319b672a 100644 (file)
@@ -12,6 +12,8 @@
  * published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/skbuff.h>
 #include <linux/module.h>
 #include <linux/netfilter/x_tables.h>
@@ -48,7 +50,7 @@ static int cgroup_mt_check_v1(const struct xt_mtchk_param *par)
        }
 
        if (info->has_path && info->has_classid) {
-               pr_info("xt_cgroup: both path and classid specified\n");
+               pr_info_ratelimited("path and classid specified\n");
                return -EINVAL;
        }
 
@@ -56,8 +58,8 @@ static int cgroup_mt_check_v1(const struct xt_mtchk_param *par)
        if (info->has_path) {
                cgrp = cgroup_get_from_path(info->path);
                if (IS_ERR(cgrp)) {
-                       pr_info("xt_cgroup: invalid path, errno=%ld\n",
-                               PTR_ERR(cgrp));
+                       pr_info_ratelimited("invalid path, errno=%ld\n",
+                                           PTR_ERR(cgrp));
                        return -EINVAL;
                }
                info->priv = cgrp;
index 57ef175dfbfaa86db8368c10fbbd51ba3b2a691c..0068688995c82def03435c153d77cdb687517685 100644 (file)
@@ -135,14 +135,12 @@ static int xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
        struct xt_cluster_match_info *info = par->matchinfo;
 
        if (info->total_nodes > XT_CLUSTER_NODES_MAX) {
-               pr_info("you have exceeded the maximum "
-                       "number of cluster nodes (%u > %u)\n",
-                       info->total_nodes, XT_CLUSTER_NODES_MAX);
+               pr_info_ratelimited("you have exceeded the maximum number of cluster nodes (%u > %u)\n",
+                                   info->total_nodes, XT_CLUSTER_NODES_MAX);
                return -EINVAL;
        }
        if (info->node_mask >= (1ULL << info->total_nodes)) {
-               pr_info("this node mask cannot be "
-                       "higher than the total number of nodes\n");
+               pr_info_ratelimited("node mask cannot exceed total number of nodes\n");
                return -EDOM;
        }
        return 0;
index cad0b7b5eb35654d066072d1b7cf31510e98aa45..93cb018c3055f8fb660a2558fd86cac07285d47b 100644 (file)
@@ -112,8 +112,8 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par)
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0)
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
 
        /*
         * This filter cannot function correctly unless connection tracking
index 23372879e6e3004398454f6c96944422db8e1cc7..4fa4efd243532a5507cf9eba4a8a08cb7e63e01b 100644 (file)
@@ -57,14 +57,15 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par)
        int ret;
 
        if (info->options & ~options) {
-               pr_err("Unknown options in mask %x\n", info->options);
+               pr_info_ratelimited("Unknown options in mask %x\n",
+                                   info->options);
                return -EINVAL;
        }
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0) {
-               pr_info("cannot load conntrack support for proto=%u\n",
-                                                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
                return ret;
        }
 
index ec377cc6a369c71025136fc4b8b3cf3fce177eea..809639ce6f5a480c92718026cd91e6933d890817 100644 (file)
@@ -79,8 +79,8 @@ static int connmark_tg_check(const struct xt_tgchk_param *par)
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0)
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
        return ret;
 }
 
@@ -109,8 +109,8 @@ static int connmark_mt_check(const struct xt_mtchk_param *par)
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0)
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
        return ret;
 }
 
index 39cf1d019240e61f504bc8ced96a63c41c9bd839..df80fe7d391c0651ec3d874807d4c8985bdcedc5 100644 (file)
@@ -272,8 +272,8 @@ static int conntrack_mt_check(const struct xt_mtchk_param *par)
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0)
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
        return ret;
 }
 
index 236ac8008909d3abdf1d236406fc0bb0bb48dffd..a4c2b862f820af17ae9e36bab0e6cede0dc58cfc 100644 (file)
@@ -46,10 +46,8 @@ static int dscp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_dscp_info *info = par->matchinfo;
 
-       if (info->dscp > XT_DSCP_MAX) {
-               pr_info("dscp %x out of range\n", info->dscp);
+       if (info->dscp > XT_DSCP_MAX)
                return -EDOM;
-       }
 
        return 0;
 }
index 3c831a8efebc65840af55347c880cd188a465435..c7ad4afa5fb8cc8e455d47b50193e8f81930cdfb 100644 (file)
@@ -97,7 +97,7 @@ static int ecn_mt_check4(const struct xt_mtchk_param *par)
 
        if (info->operation & (XT_ECN_OP_MATCH_ECE | XT_ECN_OP_MATCH_CWR) &&
            (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) {
-               pr_info("cannot match TCP bits in rule for non-tcp packets\n");
+               pr_info_ratelimited("cannot match TCP bits for non-tcp packets\n");
                return -EINVAL;
        }
 
@@ -139,7 +139,7 @@ static int ecn_mt_check6(const struct xt_mtchk_param *par)
 
        if (info->operation & (XT_ECN_OP_MATCH_ECE | XT_ECN_OP_MATCH_CWR) &&
            (ip->proto != IPPROTO_TCP || ip->invflags & IP6T_INV_PROTO)) {
-               pr_info("cannot match TCP bits in rule for non-tcp packets\n");
+               pr_info_ratelimited("cannot match TCP bits for non-tcp packets\n");
                return -EINVAL;
        }
 
index ca6847403ca218c478d208080aab3e3c92a0a615..3360f13dc208b6af1ca238f0018ee8ad6df3924c 100644 (file)
@@ -523,7 +523,8 @@ static u64 user2rate(u64 user)
        if (user != 0) {
                return div64_u64(XT_HASHLIMIT_SCALE_v2, user);
        } else {
-               pr_warn("invalid rate from userspace: %llu\n", user);
+               pr_info_ratelimited("invalid rate from userspace: %llu\n",
+                                   user);
                return 0;
        }
 }
@@ -774,7 +775,7 @@ hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par,
                if (!dh->rateinfo.prev_window &&
                    (dh->rateinfo.current_rate <= dh->rateinfo.burst)) {
                        spin_unlock(&dh->lock);
-                       rcu_read_unlock_bh();
+                       local_bh_enable();
                        return !(cfg->mode & XT_HASHLIMIT_INVERT);
                } else {
                        goto overlimit;
@@ -865,33 +866,34 @@ static int hashlimit_mt_check_common(const struct xt_mtchk_param *par,
        }
 
        if (cfg->mode & ~XT_HASHLIMIT_ALL) {
-               pr_info("Unknown mode mask %X, kernel too old?\n",
-                                               cfg->mode);
+               pr_info_ratelimited("Unknown mode mask %X, kernel too old?\n",
+                                   cfg->mode);
                return -EINVAL;
        }
 
        /* Check for overflow. */
        if (revision >= 3 && cfg->mode & XT_HASHLIMIT_RATE_MATCH) {
                if (cfg->avg == 0 || cfg->avg > U32_MAX) {
-                       pr_info("hashlimit invalid rate\n");
+                       pr_info_ratelimited("invalid rate\n");
                        return -ERANGE;
                }
 
                if (cfg->interval == 0) {
-                       pr_info("hashlimit invalid interval\n");
+                       pr_info_ratelimited("invalid interval\n");
                        return -EINVAL;
                }
        } else if (cfg->mode & XT_HASHLIMIT_BYTES) {
                if (user2credits_byte(cfg->avg) == 0) {
-                       pr_info("overflow, rate too high: %llu\n", cfg->avg);
+                       pr_info_ratelimited("overflow, rate too high: %llu\n",
+                                           cfg->avg);
                        return -EINVAL;
                }
        } else if (cfg->burst == 0 ||
-                   user2credits(cfg->avg * cfg->burst, revision) <
-                   user2credits(cfg->avg, revision)) {
-                       pr_info("overflow, try lower: %llu/%llu\n",
-                               cfg->avg, cfg->burst);
-                       return -ERANGE;
+                  user2credits(cfg->avg * cfg->burst, revision) <
+                  user2credits(cfg->avg, revision)) {
+               pr_info_ratelimited("overflow, try lower: %llu/%llu\n",
+                                   cfg->avg, cfg->burst);
+               return -ERANGE;
        }
 
        mutex_lock(&hashlimit_mutex);
@@ -915,8 +917,9 @@ static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par)
        struct hashlimit_cfg3 cfg = {};
        int ret;
 
-       if (info->name[sizeof(info->name) - 1] != '\0')
-               return -EINVAL;
+       ret = xt_check_proc_name(info->name, sizeof(info->name));
+       if (ret)
+               return ret;
 
        ret = cfg_copy(&cfg, (void *)&info->cfg, 1);
 
@@ -933,8 +936,9 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par)
        struct hashlimit_cfg3 cfg = {};
        int ret;
 
-       if (info->name[sizeof(info->name) - 1] != '\0')
-               return -EINVAL;
+       ret = xt_check_proc_name(info->name, sizeof(info->name));
+       if (ret)
+               return ret;
 
        ret = cfg_copy(&cfg, (void *)&info->cfg, 2);
 
@@ -948,9 +952,11 @@ static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par)
 static int hashlimit_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_hashlimit_mtinfo3 *info = par->matchinfo;
+       int ret;
 
-       if (info->name[sizeof(info->name) - 1] != '\0')
-               return -EINVAL;
+       ret = xt_check_proc_name(info->name, sizeof(info->name));
+       if (ret)
+               return ret;
 
        return hashlimit_mt_check_common(par, &info->hinfo, &info->cfg,
                                         info->name, 3);
index 38a78151c0e99124b3071374b99897a1eefffdd5..fd077aeaaed951497d6a40b701efc734bf026b27 100644 (file)
@@ -61,8 +61,8 @@ static int helper_mt_check(const struct xt_mtchk_param *par)
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0) {
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
                return ret;
        }
        info->name[sizeof(info->name) - 1] = '\0';
index 7ca64a50db04d0144b8f38f9c5bedb9c30958f6a..57f1df5757011d227fc6914f82b7a8dff7469e11 100644 (file)
@@ -72,7 +72,7 @@ static int comp_mt_check(const struct xt_mtchk_param *par)
 
        /* Must specify no unknown invflags */
        if (compinfo->invflags & ~XT_IPCOMP_INV_MASK) {
-               pr_err("unknown flags %X\n", compinfo->invflags);
+               pr_info_ratelimited("unknown flags %X\n", compinfo->invflags);
                return -EINVAL;
        }
        return 0;
index 42540d26c2b8ec34ab62422fe5894588df2306b6..1d950a6100af16b3d248d63201bd5a1874532272 100644 (file)
@@ -158,7 +158,8 @@ static int ipvs_mt_check(const struct xt_mtchk_param *par)
            && par->family != NFPROTO_IPV6
 #endif
                ) {
-               pr_info("protocol family %u not supported\n", par->family);
+               pr_info_ratelimited("protocol family %u not supported\n",
+                                   par->family);
                return -EINVAL;
        }
 
index 8aee572771f2b698a2f8e12a226be7af71adbd04..c43482bf48e687aba3a0c9d8d7b5c5f74d924485 100644 (file)
@@ -216,7 +216,7 @@ static int l2tp_mt_check(const struct xt_mtchk_param *par)
        /* Check for invalid flags */
        if (info->flags & ~(XT_L2TP_TID | XT_L2TP_SID | XT_L2TP_VERSION |
                            XT_L2TP_TYPE)) {
-               pr_info("unknown flags: %x\n", info->flags);
+               pr_info_ratelimited("unknown flags: %x\n", info->flags);
                return -EINVAL;
        }
 
@@ -225,7 +225,8 @@ static int l2tp_mt_check(const struct xt_mtchk_param *par)
            (!(info->flags & XT_L2TP_SID)) &&
            ((!(info->flags & XT_L2TP_TYPE)) ||
             (info->type != XT_L2TP_TYPE_CONTROL))) {
-               pr_info("invalid flags combination: %x\n", info->flags);
+               pr_info_ratelimited("invalid flags combination: %x\n",
+                                   info->flags);
                return -EINVAL;
        }
 
@@ -234,19 +235,22 @@ static int l2tp_mt_check(const struct xt_mtchk_param *par)
         */
        if (info->flags & XT_L2TP_VERSION) {
                if ((info->version < 2) || (info->version > 3)) {
-                       pr_info("wrong L2TP version: %u\n", info->version);
+                       pr_info_ratelimited("wrong L2TP version: %u\n",
+                                           info->version);
                        return -EINVAL;
                }
 
                if (info->version == 2) {
                        if ((info->flags & XT_L2TP_TID) &&
                            (info->tid > 0xffff)) {
-                               pr_info("v2 tid > 0xffff: %u\n", info->tid);
+                               pr_info_ratelimited("v2 tid > 0xffff: %u\n",
+                                                   info->tid);
                                return -EINVAL;
                        }
                        if ((info->flags & XT_L2TP_SID) &&
                            (info->sid > 0xffff)) {
-                               pr_info("v2 sid > 0xffff: %u\n", info->sid);
+                               pr_info_ratelimited("v2 sid > 0xffff: %u\n",
+                                                   info->sid);
                                return -EINVAL;
                        }
                }
@@ -268,13 +272,13 @@ static int l2tp_mt_check4(const struct xt_mtchk_param *par)
 
        if ((ip->proto != IPPROTO_UDP) &&
            (ip->proto != IPPROTO_L2TP)) {
-               pr_info("missing protocol rule (udp|l2tpip)\n");
+               pr_info_ratelimited("missing protocol rule (udp|l2tpip)\n");
                return -EINVAL;
        }
 
        if ((ip->proto == IPPROTO_L2TP) &&
            (info->version == 2)) {
-               pr_info("v2 doesn't support IP mode\n");
+               pr_info_ratelimited("v2 doesn't support IP mode\n");
                return -EINVAL;
        }
 
@@ -295,13 +299,13 @@ static int l2tp_mt_check6(const struct xt_mtchk_param *par)
 
        if ((ip->proto != IPPROTO_UDP) &&
            (ip->proto != IPPROTO_L2TP)) {
-               pr_info("missing protocol rule (udp|l2tpip)\n");
+               pr_info_ratelimited("missing protocol rule (udp|l2tpip)\n");
                return -EINVAL;
        }
 
        if ((ip->proto == IPPROTO_L2TP) &&
            (info->version == 2)) {
-               pr_info("v2 doesn't support IP mode\n");
+               pr_info_ratelimited("v2 doesn't support IP mode\n");
                return -EINVAL;
        }
 
index 61403b77361cbfdf55db2a6c824a21003fb82b22..55d18cd676356cc98985929c79a9436a091fe226 100644 (file)
@@ -106,8 +106,8 @@ static int limit_mt_check(const struct xt_mtchk_param *par)
        /* Check for overflow. */
        if (r->burst == 0
            || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
-               pr_info("Overflow, try lower: %u/%u\n",
-                       r->avg, r->burst);
+               pr_info_ratelimited("Overflow, try lower: %u/%u\n",
+                                   r->avg, r->burst);
                return -ERANGE;
        }
 
index 0fd14d1eb09d14ba3c1797c33b022e3e0c50c97b..bdb689cdc829df85372dbdaa0acf47c6772e47d8 100644 (file)
@@ -8,6 +8,8 @@
  * published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
@@ -19,8 +21,7 @@ static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
        const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
 
        if (mr->rangesize != 1) {
-               pr_info("%s: multiple ranges no longer supported\n",
-                       par->target->name);
+               pr_info_ratelimited("multiple ranges no longer supported\n");
                return -EINVAL;
        }
        return nf_ct_netns_get(par->net, par->family);
index 6f92d25590a85d8db7bb6ccec30a298f7206448e..c8674deed4eb43c024438308284f53a270e693ab 100644 (file)
@@ -6,6 +6,8 @@
  * it under the terms of the GNU General Public License version 2 (or any
  * later at your option) as published by the Free Software Foundation.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
@@ -39,8 +41,8 @@ nfacct_mt_checkentry(const struct xt_mtchk_param *par)
 
        nfacct = nfnl_acct_find_get(par->net, info->name);
        if (nfacct == NULL) {
-               pr_info("xt_nfacct: accounting object with name `%s' "
-                       "does not exists\n", info->name);
+               pr_info_ratelimited("accounting object `%s' does not exists\n",
+                                   info->name);
                return -ENOENT;
        }
        info->nfacct = nfacct;
index bb33598e4530de1b468fa66ff292fb2283c6d517..9d6d67b953ac8f6d6b02c9b428e960f14a7dbcda 100644 (file)
@@ -107,9 +107,7 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)
             info->invert & XT_PHYSDEV_OP_BRIDGED) &&
            par->hook_mask & ((1 << NF_INET_LOCAL_OUT) |
            (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) {
-               pr_info("using --physdev-out and --physdev-is-out are only "
-                       "supported in the FORWARD and POSTROUTING chains with "
-                       "bridged traffic.\n");
+               pr_info_ratelimited("--physdev-out and --physdev-is-out only supported in the FORWARD and POSTROUTING chains with bridged traffic\n");
                if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
                        return -EINVAL;
        }
index 5639fb03bdd924812f08179ab88dfeaba2d8ffc9..13f8ccf946d622a21a057381839e65beb5e97c20 100644 (file)
@@ -132,26 +132,29 @@ policy_mt(const struct sk_buff *skb, struct xt_action_param *par)
 static int policy_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_policy_info *info = par->matchinfo;
+       const char *errmsg = "neither incoming nor outgoing policy selected";
+
+       if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT)))
+               goto err;
 
-       if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
-               pr_info("neither incoming nor outgoing policy selected\n");
-               return -EINVAL;
-       }
        if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
            (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {
-               pr_info("output policy not valid in PREROUTING and INPUT\n");
-               return -EINVAL;
+               errmsg = "output policy not valid in PREROUTING and INPUT";
+               goto err;
        }
        if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
            (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_POLICY_MATCH_IN) {
-               pr_info("input policy not valid in POSTROUTING and OUTPUT\n");
-               return -EINVAL;
+               errmsg = "input policy not valid in POSTROUTING and OUTPUT";
+               goto err;
        }
        if (info->len > XT_POLICY_MAX_ELEM) {
-               pr_info("too many policy elements\n");
-               return -EINVAL;
+               errmsg = "too many policy elements";
+               goto err;
        }
        return 0;
+err:
+       pr_info_ratelimited("%s\n", errmsg);
+       return -EINVAL;
 }
 
 static struct xt_match policy_mt_reg[] __read_mostly = {
index 245fa350a7a85390e6767c4a0c5862f4213000fe..81ee1d6543b2696a2345b00d134399ab1d999e90 100644 (file)
@@ -342,8 +342,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
        net_get_random_once(&hash_rnd, sizeof(hash_rnd));
 
        if (info->check_set & ~XT_RECENT_VALID_FLAGS) {
-               pr_info("Unsupported user space flags (%08x)\n",
-                       info->check_set);
+               pr_info_ratelimited("Unsupported userspace flags (%08x)\n",
+                                   info->check_set);
                return -EINVAL;
        }
        if (hweight8(info->check_set &
@@ -357,13 +357,13 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
        if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
                return -EINVAL;
        if (info->hit_count >= XT_RECENT_MAX_NSTAMPS) {
-               pr_info("hitcount (%u) is larger than allowed maximum (%u)\n",
-                       info->hit_count, XT_RECENT_MAX_NSTAMPS - 1);
+               pr_info_ratelimited("hitcount (%u) is larger than allowed maximum (%u)\n",
+                                   info->hit_count, XT_RECENT_MAX_NSTAMPS - 1);
                return -EINVAL;
        }
-       if (info->name[0] == '\0' ||
-           strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
-               return -EINVAL;
+       ret = xt_check_proc_name(info->name, sizeof(info->name));
+       if (ret)
+               return ret;
 
        if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot)
                nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1;
@@ -587,7 +587,7 @@ recent_mt_proc_write(struct file *file, const char __user *input,
                add = true;
                break;
        default:
-               pr_info("Need \"+ip\", \"-ip\" or \"/\"\n");
+               pr_info_ratelimited("Need \"+ip\", \"-ip\" or \"/\"\n");
                return -EINVAL;
        }
 
@@ -601,10 +601,8 @@ recent_mt_proc_write(struct file *file, const char __user *input,
                succ   = in4_pton(c, size, (void *)&addr, '\n', NULL);
        }
 
-       if (!succ) {
-               pr_info("illegal address written to procfs\n");
+       if (!succ)
                return -EINVAL;
-       }
 
        spin_lock_bh(&recent_lock);
        e = recent_entry_lookup(t, &addr, family, 0);
index 16b6b11ee83f04aab79d9ff32742ee326711f480..6f4c5217d8358cadb1537b0f4c3a3b4c1ab43175 100644 (file)
@@ -92,12 +92,12 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
        index = ip_set_nfnl_get_byindex(par->net, info->match_set.index);
 
        if (index == IPSET_INVALID_ID) {
-               pr_warn("Cannot find set identified by id %u to match\n",
-                       info->match_set.index);
+               pr_info_ratelimited("Cannot find set identified by id %u to match\n",
+                                   info->match_set.index);
                return -ENOENT;
        }
        if (info->match_set.u.flags[IPSET_DIM_MAX - 1] != 0) {
-               pr_warn("Protocol error: set match dimension is over the limit!\n");
+               pr_info_ratelimited("set match dimension is over the limit!\n");
                ip_set_nfnl_put(par->net, info->match_set.index);
                return -ERANGE;
        }
@@ -143,12 +143,12 @@ set_match_v1_checkentry(const struct xt_mtchk_param *par)
        index = ip_set_nfnl_get_byindex(par->net, info->match_set.index);
 
        if (index == IPSET_INVALID_ID) {
-               pr_warn("Cannot find set identified by id %u to match\n",
-                       info->match_set.index);
+               pr_info_ratelimited("Cannot find set identified by id %u to match\n",
+                                   info->match_set.index);
                return -ENOENT;
        }
        if (info->match_set.dim > IPSET_DIM_MAX) {
-               pr_warn("Protocol error: set match dimension is over the limit!\n");
+               pr_info_ratelimited("set match dimension is over the limit!\n");
                ip_set_nfnl_put(par->net, info->match_set.index);
                return -ERANGE;
        }
@@ -241,8 +241,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
        if (info->add_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(par->net, info->add_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find add_set index %u as target\n",
-                               info->add_set.index);
+                       pr_info_ratelimited("Cannot find add_set index %u as target\n",
+                                           info->add_set.index);
                        return -ENOENT;
                }
        }
@@ -250,8 +250,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
        if (info->del_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(par->net, info->del_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find del_set index %u as target\n",
-                               info->del_set.index);
+                       pr_info_ratelimited("Cannot find del_set index %u as target\n",
+                                           info->del_set.index);
                        if (info->add_set.index != IPSET_INVALID_ID)
                                ip_set_nfnl_put(par->net, info->add_set.index);
                        return -ENOENT;
@@ -259,7 +259,7 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
        }
        if (info->add_set.u.flags[IPSET_DIM_MAX - 1] != 0 ||
            info->del_set.u.flags[IPSET_DIM_MAX - 1] != 0) {
-               pr_warn("Protocol error: SET target dimension is over the limit!\n");
+               pr_info_ratelimited("SET target dimension over the limit!\n");
                if (info->add_set.index != IPSET_INVALID_ID)
                        ip_set_nfnl_put(par->net, info->add_set.index);
                if (info->del_set.index != IPSET_INVALID_ID)
@@ -316,8 +316,8 @@ set_target_v1_checkentry(const struct xt_tgchk_param *par)
        if (info->add_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(par->net, info->add_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find add_set index %u as target\n",
-                               info->add_set.index);
+                       pr_info_ratelimited("Cannot find add_set index %u as target\n",
+                                           info->add_set.index);
                        return -ENOENT;
                }
        }
@@ -325,8 +325,8 @@ set_target_v1_checkentry(const struct xt_tgchk_param *par)
        if (info->del_set.index != IPSET_INVALID_ID) {
                index = ip_set_nfnl_get_byindex(par->net, info->del_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find del_set index %u as target\n",
-                               info->del_set.index);
+                       pr_info_ratelimited("Cannot find del_set index %u as target\n",
+                                           info->del_set.index);
                        if (info->add_set.index != IPSET_INVALID_ID)
                                ip_set_nfnl_put(par->net, info->add_set.index);
                        return -ENOENT;
@@ -334,7 +334,7 @@ set_target_v1_checkentry(const struct xt_tgchk_param *par)
        }
        if (info->add_set.dim > IPSET_DIM_MAX ||
            info->del_set.dim > IPSET_DIM_MAX) {
-               pr_warn("Protocol error: SET target dimension is over the limit!\n");
+               pr_info_ratelimited("SET target dimension over the limit!\n");
                if (info->add_set.index != IPSET_INVALID_ID)
                        ip_set_nfnl_put(par->net, info->add_set.index);
                if (info->del_set.index != IPSET_INVALID_ID)
@@ -444,8 +444,8 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)
                index = ip_set_nfnl_get_byindex(par->net,
                                                info->add_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find add_set index %u as target\n",
-                               info->add_set.index);
+                       pr_info_ratelimited("Cannot find add_set index %u as target\n",
+                                           info->add_set.index);
                        return -ENOENT;
                }
        }
@@ -454,8 +454,8 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)
                index = ip_set_nfnl_get_byindex(par->net,
                                                info->del_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find del_set index %u as target\n",
-                               info->del_set.index);
+                       pr_info_ratelimited("Cannot find del_set index %u as target\n",
+                                           info->del_set.index);
                        if (info->add_set.index != IPSET_INVALID_ID)
                                ip_set_nfnl_put(par->net,
                                                info->add_set.index);
@@ -465,7 +465,7 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)
 
        if (info->map_set.index != IPSET_INVALID_ID) {
                if (strncmp(par->table, "mangle", 7)) {
-                       pr_warn("--map-set only usable from mangle table\n");
+                       pr_info_ratelimited("--map-set only usable from mangle table\n");
                        return -EINVAL;
                }
                if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) |
@@ -473,14 +473,14 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)
                     !(par->hook_mask & (1 << NF_INET_FORWARD |
                                         1 << NF_INET_LOCAL_OUT |
                                         1 << NF_INET_POST_ROUTING))) {
-                       pr_warn("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n");
+                       pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n");
                        return -EINVAL;
                }
                index = ip_set_nfnl_get_byindex(par->net,
                                                info->map_set.index);
                if (index == IPSET_INVALID_ID) {
-                       pr_warn("Cannot find map_set index %u as target\n",
-                               info->map_set.index);
+                       pr_info_ratelimited("Cannot find map_set index %u as target\n",
+                                           info->map_set.index);
                        if (info->add_set.index != IPSET_INVALID_ID)
                                ip_set_nfnl_put(par->net,
                                                info->add_set.index);
@@ -494,7 +494,7 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)
        if (info->add_set.dim > IPSET_DIM_MAX ||
            info->del_set.dim > IPSET_DIM_MAX ||
            info->map_set.dim > IPSET_DIM_MAX) {
-               pr_warn("Protocol error: SET target dimension is over the limit!\n");
+               pr_info_ratelimited("SET target dimension over the limit!\n");
                if (info->add_set.index != IPSET_INVALID_ID)
                        ip_set_nfnl_put(par->net, info->add_set.index);
                if (info->del_set.index != IPSET_INVALID_ID)
index 575d2153e3b819f32e9a262abddca95a108eee02..2ac7f674d19b16a2392b5c035fa34f58b9c7b910 100644 (file)
@@ -171,7 +171,8 @@ static int socket_mt_v1_check(const struct xt_mtchk_param *par)
                return err;
 
        if (info->flags & ~XT_SOCKET_FLAGS_V1) {
-               pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V1);
+               pr_info_ratelimited("unknown flags 0x%x\n",
+                                   info->flags & ~XT_SOCKET_FLAGS_V1);
                return -EINVAL;
        }
        return 0;
@@ -187,7 +188,8 @@ static int socket_mt_v2_check(const struct xt_mtchk_param *par)
                return err;
 
        if (info->flags & ~XT_SOCKET_FLAGS_V2) {
-               pr_info("unknown flags 0x%x\n", info->flags & ~XT_SOCKET_FLAGS_V2);
+               pr_info_ratelimited("unknown flags 0x%x\n",
+                                   info->flags & ~XT_SOCKET_FLAGS_V2);
                return -EINVAL;
        }
        return 0;
@@ -203,8 +205,8 @@ static int socket_mt_v3_check(const struct xt_mtchk_param *par)
        if (err)
                return err;
        if (info->flags & ~XT_SOCKET_FLAGS_V3) {
-               pr_info("unknown flags 0x%x\n",
-                       info->flags & ~XT_SOCKET_FLAGS_V3);
+               pr_info_ratelimited("unknown flags 0x%x\n",
+                                   info->flags & ~XT_SOCKET_FLAGS_V3);
                return -EINVAL;
        }
        return 0;
index 5fbd79194d21ee1f26fa669162b8de92d965f8c8..0b41c0befe3cf1d499de79202d5a50aaf5bf6905 100644 (file)
@@ -44,8 +44,8 @@ static int state_mt_check(const struct xt_mtchk_param *par)
 
        ret = nf_ct_netns_get(par->net, par->family);
        if (ret < 0)
-               pr_info("cannot load conntrack support for proto=%u\n",
-                       par->family);
+               pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
+                                   par->family);
        return ret;
 }
 
index 1b01eec1fbda5368e31a8b3917286d8b05a4604c..0160f505e337c7370d8f6e4ff6d46ab6d6048bce 100644 (file)
@@ -235,13 +235,13 @@ static int time_mt_check(const struct xt_mtchk_param *par)
 
        if (info->daytime_start > XT_TIME_MAX_DAYTIME ||
            info->daytime_stop > XT_TIME_MAX_DAYTIME) {
-               pr_info("invalid argument - start or "
-                       "stop time greater than 23:59:59\n");
+               pr_info_ratelimited("invalid argument - start or stop time greater than 23:59:59\n");
                return -EDOM;
        }
 
        if (info->flags & ~XT_TIME_ALL_FLAGS) {
-               pr_info("unknown flags 0x%x\n", info->flags & ~XT_TIME_ALL_FLAGS);
+               pr_info_ratelimited("unknown flags 0x%x\n",
+                                   info->flags & ~XT_TIME_ALL_FLAGS);
                return -EINVAL;
        }
 
index 2ad445c1d27ccda471132e035229188b77a579eb..07e8478068f0a1fafc0b41bb939ed508d40e3f21 100644 (file)
@@ -2308,7 +2308,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
        if (cb->start) {
                ret = cb->start(cb);
                if (ret)
-                       goto error_unlock;
+                       goto error_put;
        }
 
        nlk->cb_running = true;
@@ -2328,6 +2328,8 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
         */
        return -EINTR;
 
+error_put:
+       module_put(control->module);
 error_unlock:
        sock_put(sk);
        mutex_unlock(nlk->cb_mutex);
index 6f02499ef00725abb6d249a61fd005dbdd413ac0..b9ce82c9440f1cde865a456ca926a6f5782c29a7 100644 (file)
@@ -1106,7 +1106,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
        if (!err)
                delivered = true;
        else if (err != -ESRCH)
-               goto error;
+               return err;
        return delivered ? 0 : -ESRCH;
  error:
        kfree_skb(skb);
index 367d8c02710181f06bf1a422e41239ed12e77d90..2ceefa183ceed6ba3d06f2aae958104a514f2146 100644 (file)
@@ -149,6 +149,10 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
 
        pr_debug("uri: %s, len: %zu\n", uri, uri_len);
 
+       /* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */
+       if (WARN_ON_ONCE(uri_len > U8_MAX - 4))
+               return NULL;
+
        sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL);
        if (sdreq == NULL)
                return NULL;
index c0b83dc9d99305850a61b647fe362b6ed52c50aa..f018eafc2a0de57f53a4632c8b924734f25eb8d3 100644 (file)
@@ -61,7 +61,8 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
 };
 
 static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
-       [NFC_SDP_ATTR_URI] = { .type = NLA_STRING },
+       [NFC_SDP_ATTR_URI] = { .type = NLA_STRING,
+                              .len = U8_MAX - 4 },
        [NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
 };
 
index 04b94281a30b2b97a449efbb71fb3958afa44177..b891a91577f8030e55e973f4a4cf74f0c4637916 100644 (file)
@@ -242,14 +242,20 @@ static struct dp_meter *dp_meter_create(struct nlattr **a)
 
                band->type = nla_get_u32(attr[OVS_BAND_ATTR_TYPE]);
                band->rate = nla_get_u32(attr[OVS_BAND_ATTR_RATE]);
+               if (band->rate == 0) {
+                       err = -EINVAL;
+                       goto exit_free_meter;
+               }
+
                band->burst_size = nla_get_u32(attr[OVS_BAND_ATTR_BURST]);
                /* Figure out max delta_t that is enough to fill any bucket.
                 * Keep max_delta_t size to the bucket units:
                 * pkts => 1/1000 packets, kilobits => bits.
+                *
+                * Start with a full bucket.
                 */
-               band_max_delta_t = (band->burst_size + band->rate) * 1000;
-               /* Start with a full bucket. */
-               band->bucket = band_max_delta_t;
+               band->bucket = (band->burst_size + band->rate) * 1000;
+               band_max_delta_t = band->bucket / band->rate;
                if (band_max_delta_t > meter->max_delta_t)
                        meter->max_delta_t = band_max_delta_t;
                band++;
index 50615d5efac1529a0fd617c2692b1e9419da7137..9cf089b9754eaadbc58d9fdd9c455876a07712ca 100644 (file)
@@ -114,5 +114,6 @@ static struct rpmsg_driver qcom_smd_qrtr_driver = {
 
 module_rpmsg_driver(qcom_smd_qrtr_driver);
 
+MODULE_ALIAS("rpmsg:IPCRTR");
 MODULE_DESCRIPTION("Qualcomm IPC-Router SMD interface driver");
 MODULE_LICENSE("GPL v2");
index 94e190febfddd0670c0a16b35501acda16df548d..2da3176bf7924d9132647d28a3c3263716ead608 100644 (file)
@@ -224,7 +224,7 @@ static struct rds_connection *__rds_conn_create(struct net *net,
        if (rds_destroy_pending(conn))
                ret = -ENETDOWN;
        else
-               ret = trans->conn_alloc(conn, gfp);
+               ret = trans->conn_alloc(conn, GFP_ATOMIC);
        if (ret) {
                rcu_read_unlock();
                kfree(conn->c_path);
index c061d6eb465d528966a513173950463ded396c5e..22571189f21e7e4a805af1b7edaed1c9f3c918ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Oracle.  All rights reserved.
+ * Copyright (c) 2006, 2018 Oracle.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -142,12 +142,20 @@ int rds_tcp_accept_one(struct socket *sock)
        if (ret)
                goto out;
 
-       new_sock->type = sock->type;
-       new_sock->ops = sock->ops;
        ret = sock->ops->accept(sock, new_sock, O_NONBLOCK, true);
        if (ret < 0)
                goto out;
 
+       /* sock_create_lite() does not get a hold on the owner module so we
+        * need to do it here.  Note that sock_release() uses sock->ops to
+        * determine if it needs to decrement the reference count.  So set
+        * sock->ops after calling accept() in case that fails.  And there's
+        * no need to do try_module_get() as the listener should have a hold
+        * already.
+        */
+       new_sock->ops = sock->ops;
+       __module_get(new_sock->ops->owner);
+
        ret = rds_tcp_keepalive(new_sock);
        if (ret < 0)
                goto out;
index 42410e910affbdf39691a0cb080c053b1e8aa661..cf73dc006c3bf0d3866461c63a5a7c51c161c90b 100644 (file)
@@ -445,7 +445,7 @@ send_fragmentable:
                                        (char *)&opt, sizeof(opt));
                if (ret == 0) {
                        ret = kernel_sendmsg(conn->params.local->socket, &msg,
-                                            iov, 1, iov[0].iov_len);
+                                            iov, 2, len);
 
                        opt = IPV6_PMTUDISC_DO;
                        kernel_setsockopt(conn->params.local->socket,
index cc21e8db25b0b730bbe66dbee6d358177df9ae09..9d45d8b567447c7eb8e35a997d953ed63197d715 100644 (file)
@@ -517,9 +517,10 @@ try_again:
                        ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID,
                                       sizeof(unsigned int), &id32);
                } else {
+                       unsigned long idl = call->user_call_ID;
+
                        ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID,
-                                      sizeof(unsigned long),
-                                      &call->user_call_ID);
+                                      sizeof(unsigned long), &idl);
                }
                if (ret < 0)
                        goto error_unlock_call;
index b3f2c15affa7b2d1b533163b6d88b3d518635d7d..9d2cabf1dc7ea52581ee9a42cdc1b462d7fbce57 100644 (file)
@@ -352,7 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
        return res;
 out:
        if (res == ACT_P_CREATED)
-               tcf_idr_cleanup(*act, est);
+               tcf_idr_release(*act, bind);
 
        return ret;
 }
index b7ba9b06b147ed034dced7c826fbbdf6122e31a3..2a5c8fd860cf1ef31ade2ed2a4d5078241799e46 100644 (file)
@@ -350,7 +350,7 @@ static int tcf_csum_sctp(struct sk_buff *skb, unsigned int ihl,
 {
        struct sctphdr *sctph;
 
-       if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_SCTP)
+       if (skb_is_gso(skb) && skb_is_gso_sctp(skb))
                return 1;
 
        sctph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*sctph));
@@ -626,7 +626,8 @@ static void tcf_csum_cleanup(struct tc_action *a)
        struct tcf_csum_params *params;
 
        params = rcu_dereference_protected(p->params, 1);
-       kfree_rcu(params, rcu);
+       if (params)
+               kfree_rcu(params, rcu);
 }
 
 static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
index 06e380ae09283fe57ce6131b42b72393540f392e..7e06b9b626134d57094c8a48597f7ab486724f13 100644 (file)
@@ -80,9 +80,12 @@ static void ipt_destroy_target(struct xt_entry_target *t)
 static void tcf_ipt_release(struct tc_action *a)
 {
        struct tcf_ipt *ipt = to_ipt(a);
-       ipt_destroy_target(ipt->tcfi_t);
+
+       if (ipt->tcfi_t) {
+               ipt_destroy_target(ipt->tcfi_t);
+               kfree(ipt->tcfi_t);
+       }
        kfree(ipt->tcfi_tname);
-       kfree(ipt->tcfi_t);
 }
 
 static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
@@ -187,7 +190,7 @@ err2:
        kfree(tname);
 err1:
        if (ret == ACT_P_CREATED)
-               tcf_idr_cleanup(*a, est);
+               tcf_idr_release(*a, bind);
        return err;
 }
 
index 349beaffb29e4ae1dec0c9c25005f69197513603..fef08835f26d9c92004bfd001109bd4b8ac9ac79 100644 (file)
@@ -176,7 +176,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
                p = to_pedit(*a);
                keys = kmalloc(ksize, GFP_KERNEL);
                if (keys == NULL) {
-                       tcf_idr_cleanup(*a, est);
+                       tcf_idr_release(*a, bind);
                        kfree(keys_ex);
                        return -ENOMEM;
                }
index 95d3c9097b2516507826702b471563b07722b9f6..faebf82b99f1999405c27a9ad3ce930a953fd742 100644 (file)
@@ -194,7 +194,7 @@ failure:
        qdisc_put_rtab(P_tab);
        qdisc_put_rtab(R_tab);
        if (ret == ACT_P_CREATED)
-               tcf_idr_cleanup(*a, est);
+               tcf_idr_release(*a, bind);
        return err;
 }
 
index 1ba0df23875624e360acf4cc8131dcce8bc67ac4..74c5d7e6a0fac0581e0863e624b886e5d1a68f93 100644 (file)
@@ -103,7 +103,8 @@ static void tcf_sample_cleanup(struct tc_action *a)
 
        psample_group = rtnl_dereference(s->psample_group);
        RCU_INIT_POINTER(s->psample_group, NULL);
-       psample_group_put(psample_group);
+       if (psample_group)
+               psample_group_put(psample_group);
 }
 
 static bool tcf_sample_dev_ok_push(struct net_device *dev)
index 425eac11f6da0859f7dac97b0ef64fd7a6dc6181..b1f38063ada09e4af59a0630d512d6434790ae21 100644 (file)
@@ -121,7 +121,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
                d = to_defact(*a);
                ret = alloc_defdata(d, defdata);
                if (ret < 0) {
-                       tcf_idr_cleanup(*a, est);
+                       tcf_idr_release(*a, bind);
                        return ret;
                }
                d->tcf_action = parm->action;
index fa975262dbacf19013a3d3b0390c3a49837bfa15..7b0700f52b505c8c2d2b375f5bdee8ac9c585b24 100644 (file)
@@ -152,7 +152,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
        ASSERT_RTNL();
        p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL);
        if (unlikely(!p)) {
-               if (ovr)
+               if (ret == ACT_P_CREATED)
                        tcf_idr_release(*a, bind);
                return -ENOMEM;
        }
@@ -190,7 +190,8 @@ static void tcf_skbmod_cleanup(struct tc_action *a)
        struct tcf_skbmod_params  *p;
 
        p = rcu_dereference_protected(d->skbmod_p, 1);
-       kfree_rcu(p, rcu);
+       if (p)
+               kfree_rcu(p, rcu);
 }
 
 static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
index 0e23aac09ad63aa3a5edc1b7db6bda958182559d..1281ca463727a35e0ed95720908514b1b628676b 100644 (file)
@@ -153,6 +153,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
                metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
                break;
        default:
+               ret = -EINVAL;
                goto err_out;
        }
 
@@ -207,11 +208,12 @@ static void tunnel_key_release(struct tc_action *a)
        struct tcf_tunnel_key_params *params;
 
        params = rcu_dereference_protected(t->params, 1);
+       if (params) {
+               if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+                       dst_release(&params->tcft_enc_metadata->dst);
 
-       if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
-               dst_release(&params->tcft_enc_metadata->dst);
-
-       kfree_rcu(params, rcu);
+               kfree_rcu(params, rcu);
+       }
 }
 
 static int tunnel_key_dump_addresses(struct sk_buff *skb,
index e1a1b3f3983a61adc3fb471713b27899fb7688b6..c49cb61adedffc91788f02ef39a075f0b3ca75ff 100644 (file)
@@ -195,7 +195,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
        ASSERT_RTNL();
        p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (!p) {
-               if (ovr)
+               if (ret == ACT_P_CREATED)
                        tcf_idr_release(*a, bind);
                return -ENOMEM;
        }
@@ -225,7 +225,8 @@ static void tcf_vlan_cleanup(struct tc_action *a)
        struct tcf_vlan_params *p;
 
        p = rcu_dereference_protected(v->vlan_p, 1);
-       kfree_rcu(p, rcu);
+       if (p)
+               kfree_rcu(p, rcu);
 }
 
 static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
index 2bc1bc23d42ecd85c1387d6408944d8a7a69c7d4..247b7cc20c131b3bc9f97aa5588139d57837ffc7 100644 (file)
@@ -376,17 +376,12 @@ struct tcf_net {
 static unsigned int tcf_net_id;
 
 static int tcf_block_insert(struct tcf_block *block, struct net *net,
-                           u32 block_index, struct netlink_ext_ack *extack)
+                           struct netlink_ext_ack *extack)
 {
        struct tcf_net *tn = net_generic(net, tcf_net_id);
-       int err;
 
-       err = idr_alloc_u32(&tn->idr, block, &block_index, block_index,
-                           GFP_KERNEL);
-       if (err)
-               return err;
-       block->index = block_index;
-       return 0;
+       return idr_alloc_u32(&tn->idr, block, &block->index, block->index,
+                            GFP_KERNEL);
 }
 
 static void tcf_block_remove(struct tcf_block *block, struct net *net)
@@ -397,6 +392,7 @@ static void tcf_block_remove(struct tcf_block *block, struct net *net)
 }
 
 static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
+                                         u32 block_index,
                                          struct netlink_ext_ack *extack)
 {
        struct tcf_block *block;
@@ -419,10 +415,13 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
                err = -ENOMEM;
                goto err_chain_create;
        }
-       block->net = qdisc_net(q);
        block->refcnt = 1;
        block->net = net;
-       block->q = q;
+       block->index = block_index;
+
+       /* Don't store q pointer for blocks which are shared */
+       if (!tcf_block_shared(block))
+               block->q = q;
        return block;
 
 err_chain_create:
@@ -518,13 +517,12 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
        }
 
        if (!block) {
-               block = tcf_block_create(net, q, extack);
+               block = tcf_block_create(net, q, ei->block_index, extack);
                if (IS_ERR(block))
                        return PTR_ERR(block);
                created = true;
-               if (ei->block_index) {
-                       err = tcf_block_insert(block, net,
-                                              ei->block_index, extack);
+               if (tcf_block_shared(block)) {
+                       err = tcf_block_insert(block, net, extack);
                        if (err)
                                goto err_block_insert;
                }
@@ -1399,13 +1397,18 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
                    nla_get_u32(tca[TCA_CHAIN]) != chain->index)
                        continue;
                if (!tcf_chain_dump(chain, q, parent, skb, cb,
-                                   index_start, &index))
+                                   index_start, &index)) {
+                       err = -EMSGSIZE;
                        break;
+               }
        }
 
        cb->args[0] = index;
 
 out:
+       /* If we did no progress, the error (EMSGSIZE) is real */
+       if (skb->len == 0 && err)
+               return err;
        return skb->len;
 }
 
index 6c7601a530e35489d38de939264a854209399676..ed8b6a24b9e9325cc99f17e6ed00ead73fe0171e 100644 (file)
@@ -96,7 +96,7 @@ struct tc_u_hnode {
 
 struct tc_u_common {
        struct tc_u_hnode __rcu *hlist;
-       struct tcf_block        *block;
+       void                    *ptr;
        int                     refcnt;
        struct idr              handle_idr;
        struct hlist_node       hnode;
@@ -330,9 +330,25 @@ static struct hlist_head *tc_u_common_hash;
 #define U32_HASH_SHIFT 10
 #define U32_HASH_SIZE (1 << U32_HASH_SHIFT)
 
+static void *tc_u_common_ptr(const struct tcf_proto *tp)
+{
+       struct tcf_block *block = tp->chain->block;
+
+       /* The block sharing is currently supported only
+        * for classless qdiscs. In that case we use block
+        * for tc_u_common identification. In case the
+        * block is not shared, block->q is a valid pointer
+        * and we can use that. That works for classful qdiscs.
+        */
+       if (tcf_block_shared(block))
+               return block;
+       else
+               return block->q;
+}
+
 static unsigned int tc_u_hash(const struct tcf_proto *tp)
 {
-       return hash_ptr(tp->chain->block, U32_HASH_SHIFT);
+       return hash_ptr(tc_u_common_ptr(tp), U32_HASH_SHIFT);
 }
 
 static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)
@@ -342,7 +358,7 @@ static struct tc_u_common *tc_u_common_find(const struct tcf_proto *tp)
 
        h = tc_u_hash(tp);
        hlist_for_each_entry(tc, &tc_u_common_hash[h], hnode) {
-               if (tc->block == tp->chain->block)
+               if (tc->ptr == tc_u_common_ptr(tp))
                        return tc;
        }
        return NULL;
@@ -371,7 +387,7 @@ static int u32_init(struct tcf_proto *tp)
                        kfree(root_ht);
                        return -ENOBUFS;
                }
-               tp_c->block = tp->chain->block;
+               tp_c->ptr = tc_u_common_ptr(tp);
                INIT_HLIST_NODE(&tp_c->hnode);
                idr_init(&tp_c->handle_idr);
 
index 190570f21b208d5a17943360a3a6f85e1c2a2187..7e3fbe9cc936be376b66a5b12bf8957c3b601f2c 100644 (file)
@@ -106,6 +106,14 @@ static inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q,
 
        __skb_queue_tail(&q->skb_bad_txq, skb);
 
+       if (qdisc_is_percpu_stats(q)) {
+               qdisc_qstats_cpu_backlog_inc(q, skb);
+               qdisc_qstats_cpu_qlen_inc(q);
+       } else {
+               qdisc_qstats_backlog_inc(q, skb);
+               q->q.qlen++;
+       }
+
        if (lock)
                spin_unlock(lock);
 }
@@ -196,14 +204,6 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
                        break;
                if (unlikely(skb_get_queue_mapping(nskb) != mapping)) {
                        qdisc_enqueue_skb_bad_txq(q, nskb);
-
-                       if (qdisc_is_percpu_stats(q)) {
-                               qdisc_qstats_cpu_backlog_inc(q, nskb);
-                               qdisc_qstats_cpu_qlen_inc(q);
-                       } else {
-                               qdisc_qstats_backlog_inc(q, nskb);
-                               q->q.qlen++;
-                       }
                        break;
                }
                skb->next = nskb;
@@ -628,6 +628,7 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
        int band = prio2band[skb->priority & TC_PRIO_MAX];
        struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
        struct skb_array *q = band2list(priv, band);
+       unsigned int pkt_len = qdisc_pkt_len(skb);
        int err;
 
        err = skb_array_produce(q, skb);
@@ -636,7 +637,10 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
                return qdisc_drop_cpu(skb, qdisc, to_free);
 
        qdisc_qstats_cpu_qlen_inc(qdisc);
-       qdisc_qstats_cpu_backlog_inc(qdisc, skb);
+       /* Note: skb can not be used after skb_array_produce(),
+        * so we better not use qdisc_qstats_cpu_backlog_inc()
+        */
+       this_cpu_add(qdisc->cpu_qstats->backlog, pkt_len);
        return NET_XMIT_SUCCESS;
 }
 
index 7c179addebcd2967e9fb9c280d8bbe64e33ebe5d..7d6801fc5340eff65b81037519ada115cbc23e20 100644 (file)
@@ -509,7 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
        }
 
        if (unlikely(sch->q.qlen >= sch->limit))
-               return qdisc_drop(skb, sch, to_free);
+               return qdisc_drop_all(skb, sch, to_free);
 
        qdisc_qstats_backlog_inc(sch, skb);
 
index 229172d509cc5d189b926f15ec06785c7f6303ab..03225a8df9730cee7e020331b42a805d42b6f25c 100644 (file)
@@ -188,7 +188,8 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
        int ret;
 
        if (qdisc_pkt_len(skb) > q->max_size) {
-               if (skb_is_gso(skb) && skb_gso_mac_seglen(skb) <= q->max_size)
+               if (skb_is_gso(skb) &&
+                   skb_gso_validate_mac_len(skb, q->max_size))
                        return tbf_segment(skb, sch, to_free);
                return qdisc_drop(skb, sch, to_free);
        }
index 291c97b07058218635fcfcd06214aa79d74ec80d..8f6c2e8c0953647868e9223801c5060ce9895760 100644 (file)
@@ -81,6 +81,12 @@ const char *sctp_cname(const union sctp_subtype cid)
        case SCTP_CID_RECONF:
                return "RECONF";
 
+       case SCTP_CID_I_DATA:
+               return "I_DATA";
+
+       case SCTP_CID_I_FWD_TSN:
+               return "I_FWD_TSN";
+
        default:
                break;
        }
index 141c9c466ec172ff67930cf38eb02a49e01a12ab..b381d78548ac7391ba64ebff333835d0627ffdb8 100644 (file)
@@ -106,6 +106,7 @@ int sctp_rcv(struct sk_buff *skb)
        int family;
        struct sctp_af *af;
        struct net *net = dev_net(skb->dev);
+       bool is_gso = skb_is_gso(skb) && skb_is_gso_sctp(skb);
 
        if (skb->pkt_type != PACKET_HOST)
                goto discard_it;
@@ -123,8 +124,7 @@ int sctp_rcv(struct sk_buff *skb)
         * it's better to just linearize it otherwise crc computing
         * takes longer.
         */
-       if ((!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) &&
-            skb_linearize(skb)) ||
+       if ((!is_gso && skb_linearize(skb)) ||
            !pskb_may_pull(skb, sizeof(struct sctphdr)))
                goto discard_it;
 
@@ -135,7 +135,7 @@ int sctp_rcv(struct sk_buff *skb)
        if (skb_csum_unnecessary(skb))
                __skb_decr_checksum_unnecessary(skb);
        else if (!sctp_checksum_disable &&
-                !(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) &&
+                !is_gso &&
                 sctp_rcv_checksum(net, skb) < 0)
                goto discard_it;
        skb->csum_valid = 1;
@@ -897,15 +897,12 @@ int sctp_hash_transport(struct sctp_transport *t)
        rhl_for_each_entry_rcu(transport, tmp, list, node)
                if (transport->asoc->ep == t->asoc->ep) {
                        rcu_read_unlock();
-                       err = -EEXIST;
-                       goto out;
+                       return -EEXIST;
                }
        rcu_read_unlock();
 
        err = rhltable_insert_key(&sctp_transport_hashtable, &arg,
                                  &t->node, sctp_hash_params);
-
-out:
        if (err)
                pr_err_once("insert transport fail, errno %d\n", err);
 
@@ -1221,7 +1218,7 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net,
         * issue as packets hitting this are mostly INIT or INIT-ACK and
         * those cannot be on GSO-style anyway.
         */
-       if ((skb_shinfo(skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP)
+       if (skb_is_gso(skb) && skb_is_gso_sctp(skb))
                return NULL;
 
        ch = (struct sctp_chunkhdr *)skb->data;
index 48392552ee7c1ea75a134375b55ffb0ebf59064e..23ebc5318edc47c51230a95256064f5b2974d2f4 100644 (file)
@@ -170,7 +170,7 @@ next_chunk:
 
                chunk = list_entry(entry, struct sctp_chunk, list);
 
-               if ((skb_shinfo(chunk->skb)->gso_type & SKB_GSO_SCTP) == SKB_GSO_SCTP) {
+               if (skb_is_gso(chunk->skb) && skb_is_gso_sctp(chunk->skb)) {
                        /* GSO-marked skbs but without frags, handle
                         * them normally
                         */
index 35bc7106d1827a80f1135fe4797bec36cb7c669a..123e9f2dc22652ba0e7bf26cd329682b9afefa0c 100644 (file)
@@ -45,7 +45,7 @@ static struct sk_buff *sctp_gso_segment(struct sk_buff *skb,
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        struct sctphdr *sh;
 
-       if (!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP))
+       if (!skb_is_gso_sctp(skb))
                goto out;
 
        sh = sctp_hdr(skb);
index cedf672487f9d47d76625c3cd32ab6c04676a6e8..f799043abec9a48a26ba152cfa3aaa63b7df47ea 100644 (file)
@@ -6,7 +6,7 @@
  *
  * This file is part of the SCTP kernel implementation
  *
- * These functions manipulate sctp tsn mapping array.
+ * This file contains sctp stream maniuplation primitives and helpers.
  *
  * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
index 8c7cf8f08711f93a460354faa220d3d564dcbe75..d3764c18129971c22ce37d60285ec06ef5fe60a1 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This file is part of the SCTP kernel implementation
  *
- * These functions manipulate sctp stream queue/scheduling.
+ * These functions implement sctp stream message interleaving, mostly
+ * including I-DATA and I-FORWARD-TSN chunks process.
  *
  * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
@@ -954,12 +955,8 @@ static void sctp_renege_events(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
        __u32 freed = 0;
        __u16 needed;
 
-       if (chunk) {
-               needed = ntohs(chunk->chunk_hdr->length);
-               needed -= sizeof(struct sctp_idata_chunk);
-       } else {
-               needed = SCTP_DEFAULT_MAXWINDOW;
-       }
+       needed = ntohs(chunk->chunk_hdr->length) -
+                sizeof(struct sctp_idata_chunk);
 
        if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) {
                freed = sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed);
@@ -971,9 +968,8 @@ static void sctp_renege_events(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
                                                       needed);
        }
 
-       if (chunk && freed >= needed)
-               if (sctp_ulpevent_idata(ulpq, chunk, gfp) <= 0)
-                       sctp_intl_start_pd(ulpq, gfp);
+       if (freed >= needed && sctp_ulpevent_idata(ulpq, chunk, gfp) <= 0)
+               sctp_intl_start_pd(ulpq, gfp);
 
        sk_mem_reclaim(asoc->base.sk);
 }
index da1a5cdefd13e96ac4acbec1a891a73af09dfa77..1e0d780855c31f79b58b7a9155ede688ce99a8e1 100644 (file)
@@ -978,10 +978,6 @@ out:
                lsmc->clcsock = NULL;
        }
        release_sock(lsk);
-       /* no more listening, wake up smc_close_wait_listen_clcsock and
-        * accept
-        */
-       lsk->sk_state_change(lsk);
        sock_put(&lsmc->sk); /* sock_hold in smc_listen */
 }
 
@@ -1406,8 +1402,10 @@ static int smc_create(struct net *net, struct socket *sock, int protocol,
        smc->use_fallback = false; /* assume rdma capability first */
        rc = sock_create_kern(net, PF_INET, SOCK_STREAM,
                              IPPROTO_TCP, &smc->clcsock);
-       if (rc)
+       if (rc) {
                sk_common_release(sk);
+               goto out;
+       }
        smc->sk.sk_sndbuf = max(smc->clcsock->sk->sk_sndbuf, SMC_BUF_MIN_SIZE);
        smc->sk.sk_rcvbuf = max(smc->clcsock->sk->sk_rcvbuf, SMC_BUF_MIN_SIZE);
 
index 3cd086e5bd28c10eff887d94b51358757db094be..b42395d24cba50b0e30c39ab6275cdaa1eca3235 100644 (file)
@@ -269,7 +269,7 @@ static void smc_cdc_rx_handler(struct ib_wc *wc, void *buf)
 
        if (wc->byte_len < offsetof(struct smc_cdc_msg, reserved))
                return; /* short message */
-       if (cdc->len != sizeof(*cdc))
+       if (cdc->len != SMC_WR_TX_SIZE)
                return; /* invalid message */
        smc_cdc_msg_recv(cdc, link, wc->wr_id);
 }
index e339c0186dcfc2990d50c0b733e050a10f24b661..fa41d988174146f6888d29db743b074d7b1ee1db 100644 (file)
@@ -30,27 +30,6 @@ static void smc_close_cleanup_listen(struct sock *parent)
                smc_close_non_accepted(sk);
 }
 
-static void smc_close_wait_listen_clcsock(struct smc_sock *smc)
-{
-       DEFINE_WAIT_FUNC(wait, woken_wake_function);
-       struct sock *sk = &smc->sk;
-       signed long timeout;
-
-       timeout = SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME;
-       add_wait_queue(sk_sleep(sk), &wait);
-       do {
-               release_sock(sk);
-               if (smc->clcsock)
-                       timeout = wait_woken(&wait, TASK_UNINTERRUPTIBLE,
-                                            timeout);
-               sched_annotate_sleep();
-               lock_sock(sk);
-               if (!smc->clcsock)
-                       break;
-       } while (timeout);
-       remove_wait_queue(sk_sleep(sk), &wait);
-}
-
 /* wait for sndbuf data being transmitted */
 static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
 {
@@ -204,9 +183,11 @@ again:
                        rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
                        /* wake up kernel_accept of smc_tcp_listen_worker */
                        smc->clcsock->sk->sk_data_ready(smc->clcsock->sk);
-                       smc_close_wait_listen_clcsock(smc);
                }
                smc_close_cleanup_listen(sk);
+               release_sock(sk);
+               flush_work(&smc->tcp_listen_work);
+               lock_sock(sk);
                break;
        case SMC_ACTIVE:
                smc_close_stream_wait(smc, timeout);
index 2424c7100aaf63cf19e9d63aaa110f25c6aefe3a..645dd226177b67c15eb6d0a63ee1d9f300e97dcf 100644 (file)
@@ -177,6 +177,7 @@ static int smc_lgr_create(struct smc_sock *smc, __be32 peer_in_addr,
 
        lnk = &lgr->lnk[SMC_SINGLE_LINK];
        /* initialize link */
+       lnk->link_id = SMC_SINGLE_LINK;
        lnk->smcibdev = smcibdev;
        lnk->ibport = ibport;
        lnk->path_mtu = smcibdev->pattr[ibport - 1].active_mtu;
@@ -465,7 +466,7 @@ create:
                rc = smc_link_determine_gid(conn->lgr);
        }
        conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE;
-       conn->local_tx_ctrl.len = sizeof(struct smc_cdc_msg);
+       conn->local_tx_ctrl.len = SMC_WR_TX_SIZE;
 #ifndef KERNEL_HAS_ATOMIC64
        spin_lock_init(&conn->acurs_lock);
 #endif
index 92fe4cc8c82c2f0e860c40e40e61e1fa1ccea427..b4aa4fcedb96e5feeaa29c1126589502480b5fe2 100644 (file)
@@ -92,7 +92,7 @@ int smc_llc_send_confirm_link(struct smc_link *link, u8 mac[],
        memcpy(confllc->sender_mac, mac, ETH_ALEN);
        memcpy(confllc->sender_gid, gid, SMC_GID_SIZE);
        hton24(confllc->sender_qp_num, link->roce_qp->qp_num);
-       /* confllc->link_num = SMC_SINGLE_LINK; already done by memset above */
+       confllc->link_num = link->link_id;
        memcpy(confllc->link_uid, lgr->id, SMC_LGR_ID_SIZE);
        confllc->max_links = SMC_LINKS_PER_LGR_MAX;
        /* send llc message */
index a93c99b518cab69b67d53a71298d15ce17c4d06b..08847c3b8c39f708a0d11fb35184852b22a40835 100644 (file)
@@ -2587,6 +2587,11 @@ void sock_unregister(int family)
 }
 EXPORT_SYMBOL(sock_unregister);
 
+bool sock_is_registered(int family)
+{
+       return family < NPROTO && rcu_access_pointer(net_families[family]);
+}
+
 static int __init sock_init(void)
 {
        int err;
index c8001471da6c3c53be6c63dde1311302b093f415..3e3dce3d4c63dc1856571583182e9538ae7c9de3 100644 (file)
@@ -813,7 +813,7 @@ err_out:
        return err;
 }
 
-int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
+int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
 {
        int err;
        char *name;
@@ -835,20 +835,27 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
 
        name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
 
-       rtnl_lock();
        bearer = tipc_bearer_find(net, name);
-       if (!bearer) {
-               rtnl_unlock();
+       if (!bearer)
                return -EINVAL;
-       }
 
        bearer_disable(net, bearer);
-       rtnl_unlock();
 
        return 0;
 }
 
-int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
+int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
+{
+       int err;
+
+       rtnl_lock();
+       err = __tipc_nl_bearer_disable(skb, info);
+       rtnl_unlock();
+
+       return err;
+}
+
+int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
 {
        int err;
        char *bearer;
@@ -890,15 +897,18 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
                        prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
        }
 
+       return tipc_enable_bearer(net, bearer, domain, prio, attrs);
+}
+
+int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
+{
+       int err;
+
        rtnl_lock();
-       err = tipc_enable_bearer(net, bearer, domain, prio, attrs);
-       if (err) {
-               rtnl_unlock();
-               return err;
-       }
+       err = __tipc_nl_bearer_enable(skb, info);
        rtnl_unlock();
 
-       return 0;
+       return err;
 }
 
 int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
@@ -944,7 +954,7 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
        return 0;
 }
 
-int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
+int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
 {
        int err;
        char *name;
@@ -965,22 +975,17 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
                return -EINVAL;
        name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
 
-       rtnl_lock();
        b = tipc_bearer_find(net, name);
-       if (!b) {
-               rtnl_unlock();
+       if (!b)
                return -EINVAL;
-       }
 
        if (attrs[TIPC_NLA_BEARER_PROP]) {
                struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
 
                err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_BEARER_PROP],
                                              props);
-               if (err) {
-                       rtnl_unlock();
+               if (err)
                        return err;
-               }
 
                if (props[TIPC_NLA_PROP_TOL])
                        b->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
@@ -989,11 +994,21 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
                if (props[TIPC_NLA_PROP_WIN])
                        b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
        }
-       rtnl_unlock();
 
        return 0;
 }
 
+int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
+{
+       int err;
+
+       rtnl_lock();
+       err = __tipc_nl_bearer_set(skb, info);
+       rtnl_unlock();
+
+       return err;
+}
+
 static int __tipc_nl_add_media(struct tipc_nl_msg *msg,
                               struct tipc_media *media, int nlflags)
 {
@@ -1115,7 +1130,7 @@ err_out:
        return err;
 }
 
-int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
+int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
 {
        int err;
        char *name;
@@ -1133,22 +1148,17 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
                return -EINVAL;
        name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
 
-       rtnl_lock();
        m = tipc_media_find(name);
-       if (!m) {
-               rtnl_unlock();
+       if (!m)
                return -EINVAL;
-       }
 
        if (attrs[TIPC_NLA_MEDIA_PROP]) {
                struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
 
                err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_MEDIA_PROP],
                                              props);
-               if (err) {
-                       rtnl_unlock();
+               if (err)
                        return err;
-               }
 
                if (props[TIPC_NLA_PROP_TOL])
                        m->tolerance = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
@@ -1157,7 +1167,17 @@ int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
                if (props[TIPC_NLA_PROP_WIN])
                        m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
        }
-       rtnl_unlock();
 
        return 0;
 }
+
+int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
+{
+       int err;
+
+       rtnl_lock();
+       err = __tipc_nl_media_set(skb, info);
+       rtnl_unlock();
+
+       return err;
+}
index 42d6eeeb646ddca457aec269de1650b1269cb411..a53613d95bc9fee54bb8762d10b97ce3118d5d29 100644 (file)
@@ -188,15 +188,19 @@ extern struct tipc_media udp_media_info;
 #endif
 
 int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info);
+int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info);
+int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info);
+int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info);
 
 int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info);
+int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info);
 
 int tipc_media_set_priority(const char *name, u32 new_value);
 int tipc_media_set_window(const char *name, u32 new_value);
index 122162a3181648bad80f110cb94291f4a282e81f..04e516d18054533a08dfaad83cd833ffffe18a29 100644 (file)
@@ -189,6 +189,7 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid,
        grp->loopback = mreq->flags & TIPC_GROUP_LOOPBACK;
        grp->events = mreq->flags & TIPC_GROUP_MEMBER_EVTS;
        grp->open = group_is_open;
+       *grp->open = false;
        filter |= global ? TIPC_SUB_CLUSTER_SCOPE : TIPC_SUB_NODE_SCOPE;
        if (tipc_topsrv_kern_subscr(net, portid, type, 0, ~0,
                                    filter, &grp->subid))
index 719c5924b6383e6bf548baf57fdb713283012d87..1a2fde0d6f61398f5552750d782eded94668f56f 100644 (file)
@@ -200,7 +200,7 @@ out:
        return skb->len;
 }
 
-int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
+int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
 {
        struct net *net = sock_net(skb->sk);
        struct tipc_net *tn = net_generic(net, tipc_net_id);
@@ -241,10 +241,19 @@ int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
                if (!tipc_addr_node_valid(addr))
                        return -EINVAL;
 
-               rtnl_lock();
                tipc_net_start(net, addr);
-               rtnl_unlock();
        }
 
        return 0;
 }
+
+int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
+{
+       int err;
+
+       rtnl_lock();
+       err = __tipc_nl_net_set(skb, info);
+       rtnl_unlock();
+
+       return err;
+}
index c7c254902873976797c11fca9f5bcb41a4839e10..c0306aa2374b7c1c845bc6b8182740ae26eea9e4 100644 (file)
@@ -47,5 +47,6 @@ void tipc_net_stop(struct net *net);
 
 int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
+int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
 
 #endif
index e48f0b2c01b962dfa2b3516f9ec2f0c3b461db95..4492cda45566503627ad20a648524fdd59e3cbde 100644 (file)
@@ -285,10 +285,6 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
        if (!trans_buf)
                return -ENOMEM;
 
-       err = (*cmd->transcode)(cmd, trans_buf, msg);
-       if (err)
-               goto trans_out;
-
        attrbuf = kmalloc((tipc_genl_family.maxattr + 1) *
                        sizeof(struct nlattr *), GFP_KERNEL);
        if (!attrbuf) {
@@ -296,27 +292,34 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
                goto trans_out;
        }
 
-       err = nla_parse(attrbuf, tipc_genl_family.maxattr,
-                       (const struct nlattr *)trans_buf->data,
-                       trans_buf->len, NULL, NULL);
-       if (err)
-               goto parse_out;
-
        doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
        if (!doit_buf) {
                err = -ENOMEM;
-               goto parse_out;
+               goto attrbuf_out;
        }
 
-       doit_buf->sk = msg->dst_sk;
-
        memset(&info, 0, sizeof(info));
        info.attrs = attrbuf;
 
+       rtnl_lock();
+       err = (*cmd->transcode)(cmd, trans_buf, msg);
+       if (err)
+               goto doit_out;
+
+       err = nla_parse(attrbuf, tipc_genl_family.maxattr,
+                       (const struct nlattr *)trans_buf->data,
+                       trans_buf->len, NULL, NULL);
+       if (err)
+               goto doit_out;
+
+       doit_buf->sk = msg->dst_sk;
+
        err = (*cmd->doit)(doit_buf, &info);
+doit_out:
+       rtnl_unlock();
 
        kfree_skb(doit_buf);
-parse_out:
+attrbuf_out:
        kfree(attrbuf);
 trans_out:
        kfree_skb(trans_buf);
@@ -722,13 +725,13 @@ static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd,
 
        media = tipc_media_find(lc->name);
        if (media) {
-               cmd->doit = &tipc_nl_media_set;
+               cmd->doit = &__tipc_nl_media_set;
                return tipc_nl_compat_media_set(skb, msg);
        }
 
        bearer = tipc_bearer_find(msg->net, lc->name);
        if (bearer) {
-               cmd->doit = &tipc_nl_bearer_set;
+               cmd->doit = &__tipc_nl_bearer_set;
                return tipc_nl_compat_bearer_set(skb, msg);
        }
 
@@ -1089,12 +1092,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg)
                return tipc_nl_compat_dumpit(&dump, msg);
        case TIPC_CMD_ENABLE_BEARER:
                msg->req_type = TIPC_TLV_BEARER_CONFIG;
-               doit.doit = tipc_nl_bearer_enable;
+               doit.doit = __tipc_nl_bearer_enable;
                doit.transcode = tipc_nl_compat_bearer_enable;
                return tipc_nl_compat_doit(&doit, msg);
        case TIPC_CMD_DISABLE_BEARER:
                msg->req_type = TIPC_TLV_BEARER_NAME;
-               doit.doit = tipc_nl_bearer_disable;
+               doit.doit = __tipc_nl_bearer_disable;
                doit.transcode = tipc_nl_compat_bearer_disable;
                return tipc_nl_compat_doit(&doit, msg);
        case TIPC_CMD_SHOW_LINK_STATS:
@@ -1148,12 +1151,12 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg)
                return tipc_nl_compat_dumpit(&dump, msg);
        case TIPC_CMD_SET_NODE_ADDR:
                msg->req_type = TIPC_TLV_NET_ADDR;
-               doit.doit = tipc_nl_net_set;
+               doit.doit = __tipc_nl_net_set;
                doit.transcode = tipc_nl_compat_net_set;
                return tipc_nl_compat_doit(&doit, msg);
        case TIPC_CMD_SET_NETID:
                msg->req_type = TIPC_TLV_UNSIGNED;
-               doit.doit = tipc_nl_net_set;
+               doit.doit = __tipc_nl_net_set;
                doit.transcode = tipc_nl_compat_net_set;
                return tipc_nl_compat_doit(&doit, msg);
        case TIPC_CMD_GET_NETID:
index b0323ec7971ed04cca532674fc85e9882f03c373..7dfa9fc99ec3d442f89f5fc1a7471f6c00e2b6fd 100644 (file)
@@ -473,6 +473,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
        sk->sk_write_space = tipc_write_space;
        sk->sk_destruct = tipc_sock_destruct;
        tsk->conn_timeout = CONN_TIMEOUT_DEFAULT;
+       tsk->group_is_open = true;
        atomic_set(&tsk->dupl_rcvcnt, 0);
 
        /* Start out with safe limits until we receive an advertised window */
index b0d5fcea47e73488b355b479022f77cb6b97f1c8..d824d548447ef71a88ca0f738c7baee7e8b18b51 100644 (file)
@@ -45,17 +45,27 @@ MODULE_AUTHOR("Mellanox Technologies");
 MODULE_DESCRIPTION("Transport Layer Security Support");
 MODULE_LICENSE("Dual BSD/GPL");
 
+enum {
+       TLSV4,
+       TLSV6,
+       TLS_NUM_PROTS,
+};
+
 enum {
        TLS_BASE_TX,
        TLS_SW_TX,
        TLS_NUM_CONFIG,
 };
 
-static struct proto tls_prots[TLS_NUM_CONFIG];
+static struct proto *saved_tcpv6_prot;
+static DEFINE_MUTEX(tcpv6_prot_mutex);
+static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG];
 
 static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
 {
-       sk->sk_prot = &tls_prots[ctx->tx_conf];
+       int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
+
+       sk->sk_prot = &tls_prots[ip_ver][ctx->tx_conf];
 }
 
 int wait_on_pending_writer(struct sock *sk, long *timeo)
@@ -308,8 +318,11 @@ static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
                        goto out;
                }
                lock_sock(sk);
-               memcpy(crypto_info_aes_gcm_128->iv, ctx->iv,
+               memcpy(crypto_info_aes_gcm_128->iv,
+                      ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
                       TLS_CIPHER_AES_GCM_128_IV_SIZE);
+               memcpy(crypto_info_aes_gcm_128->rec_seq, ctx->rec_seq,
+                      TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
                release_sock(sk);
                if (copy_to_user(optval,
                                 crypto_info_aes_gcm_128,
@@ -375,7 +388,7 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval,
        rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info));
        if (rc) {
                rc = -EFAULT;
-               goto out;
+               goto err_crypto_info;
        }
 
        /* check version */
@@ -450,8 +463,21 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
        return do_tls_setsockopt(sk, optname, optval, optlen);
 }
 
+static void build_protos(struct proto *prot, struct proto *base)
+{
+       prot[TLS_BASE_TX] = *base;
+       prot[TLS_BASE_TX].setsockopt    = tls_setsockopt;
+       prot[TLS_BASE_TX].getsockopt    = tls_getsockopt;
+       prot[TLS_BASE_TX].close         = tls_sk_proto_close;
+
+       prot[TLS_SW_TX] = prot[TLS_BASE_TX];
+       prot[TLS_SW_TX].sendmsg         = tls_sw_sendmsg;
+       prot[TLS_SW_TX].sendpage        = tls_sw_sendpage;
+}
+
 static int tls_init(struct sock *sk)
 {
+       int ip_ver = sk->sk_family == AF_INET6 ? TLSV6 : TLSV4;
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct tls_context *ctx;
        int rc = 0;
@@ -476,6 +502,17 @@ static int tls_init(struct sock *sk)
        ctx->getsockopt = sk->sk_prot->getsockopt;
        ctx->sk_proto_close = sk->sk_prot->close;
 
+       /* Build IPv6 TLS whenever the address of tcpv6_prot changes */
+       if (ip_ver == TLSV6 &&
+           unlikely(sk->sk_prot != smp_load_acquire(&saved_tcpv6_prot))) {
+               mutex_lock(&tcpv6_prot_mutex);
+               if (likely(sk->sk_prot != saved_tcpv6_prot)) {
+                       build_protos(tls_prots[TLSV6], sk->sk_prot);
+                       smp_store_release(&saved_tcpv6_prot, sk->sk_prot);
+               }
+               mutex_unlock(&tcpv6_prot_mutex);
+       }
+
        ctx->tx_conf = TLS_BASE_TX;
        update_sk_prot(sk, ctx);
 out:
@@ -490,21 +527,9 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
        .init                   = tls_init,
 };
 
-static void build_protos(struct proto *prot, struct proto *base)
-{
-       prot[TLS_BASE_TX] = *base;
-       prot[TLS_BASE_TX].setsockopt    = tls_setsockopt;
-       prot[TLS_BASE_TX].getsockopt    = tls_getsockopt;
-       prot[TLS_BASE_TX].close         = tls_sk_proto_close;
-
-       prot[TLS_SW_TX] = prot[TLS_BASE_TX];
-       prot[TLS_SW_TX].sendmsg         = tls_sw_sendmsg;
-       prot[TLS_SW_TX].sendpage        = tls_sw_sendpage;
-}
-
 static int __init tls_register(void)
 {
-       build_protos(tls_prots, &tcp_prot);
+       build_protos(tls_prots[TLSV4], &tcp_prot);
 
        tcp_register_ulp(&tcp_tls_ulp_ops);
 
index d545e1d0dea22cf15426c73224a8ce38855f202b..2d465bdeccbc7c60288c56c8be24f87fc8facf05 100644 (file)
@@ -1825,7 +1825,7 @@ out:
 }
 
 /* We use paged skbs for stream sockets, and limit occupancy to 32768
- * bytes, and a minimun of a full page.
+ * bytes, and a minimum of a full page.
  */
 #define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
 
index 1abcc4fc4df18e81df5cfb072e81ce6970f5e6bc..41722046b9370c1861a51787dceabfe2b6215274 100644 (file)
@@ -34,9 +34,10 @@ config CFG80211
 
          When built as a module it will be called cfg80211.
 
+if CFG80211
+
 config NL80211_TESTMODE
        bool "nl80211 testmode command"
-       depends on CFG80211
        help
          The nl80211 testmode command helps implementing things like
          factory calibration or validation tools for wireless chips.
@@ -51,7 +52,6 @@ config NL80211_TESTMODE
 
 config CFG80211_DEVELOPER_WARNINGS
        bool "enable developer warnings"
-       depends on CFG80211
        default n
        help
          This option enables some additional warnings that help
@@ -68,7 +68,7 @@ config CFG80211_DEVELOPER_WARNINGS
 
 config CFG80211_CERTIFICATION_ONUS
        bool "cfg80211 certification onus"
-       depends on CFG80211 && EXPERT
+       depends on EXPERT
        default n
        ---help---
          You should disable this option unless you are both capable
@@ -159,7 +159,6 @@ config CFG80211_REG_RELAX_NO_IR
 
 config CFG80211_DEFAULT_PS
        bool "enable powersave by default"
-       depends on CFG80211
        default y
        help
          This option enables powersave mode by default.
@@ -170,7 +169,6 @@ config CFG80211_DEFAULT_PS
 
 config CFG80211_DEBUGFS
        bool "cfg80211 DebugFS entries"
-       depends on CFG80211
        depends on DEBUG_FS
        ---help---
          You can enable this if you want debugfs entries for cfg80211.
@@ -180,7 +178,6 @@ config CFG80211_DEBUGFS
 config CFG80211_CRDA_SUPPORT
        bool "support CRDA" if EXPERT
        default y
-       depends on CFG80211
        help
          You should enable this option unless you know for sure you have no
          need for it, for example when using internal regdb (above) or the
@@ -190,7 +187,6 @@ config CFG80211_CRDA_SUPPORT
 
 config CFG80211_WEXT
        bool "cfg80211 wireless extensions compatibility" if !CFG80211_WEXT_EXPORT
-       depends on CFG80211
        select WEXT_CORE
        default y if CFG80211_WEXT_EXPORT
        help
@@ -199,11 +195,12 @@ config CFG80211_WEXT
 
 config CFG80211_WEXT_EXPORT
        bool
-       depends on CFG80211
        help
          Drivers should select this option if they require cfg80211's
          wext compatibility symbols to be exported.
 
+endif # CFG80211
+
 config LIB80211
        tristate
        default n
index 51aa55618ef755f97a4a61c5a24d2eb016cfba42..b12da6ef3c122beced98723f6aa3465abb3daa74 100644 (file)
@@ -170,9 +170,28 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
                enum nl80211_bss_scan_width scan_width;
                struct ieee80211_supported_band *sband =
                                rdev->wiphy.bands[setup->chandef.chan->band];
-               scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
-               setup->basic_rates = ieee80211_mandatory_rates(sband,
-                                                              scan_width);
+
+               if (setup->chandef.chan->band == NL80211_BAND_2GHZ) {
+                       int i;
+
+                       /*
+                        * Older versions selected the mandatory rates for
+                        * 2.4 GHz as well, but were broken in that only
+                        * 1 Mbps was regarded as a mandatory rate. Keep
+                        * using just 1 Mbps as the default basic rate for
+                        * mesh to be interoperable with older versions.
+                        */
+                       for (i = 0; i < sband->n_bitrates; i++) {
+                               if (sband->bitrates[i].bitrate == 10) {
+                                       setup->basic_rates = BIT(i);
+                                       break;
+                               }
+                       }
+               } else {
+                       scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
+                       setup->basic_rates = ieee80211_mandatory_rates(sband,
+                                                                      scan_width);
+               }
        }
 
        err = cfg80211_chandef_dfs_required(&rdev->wiphy,
index fdb3646274a5673e1e77a832401c1d6b890ff070..701cfd7acc1bc477aa03bdf8ccb30e72755d1e33 100644 (file)
@@ -1032,6 +1032,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
        wdev->current_bss = NULL;
        wdev->ssid_len = 0;
        wdev->conn_owner_nlportid = 0;
+       kzfree(wdev->connect_keys);
+       wdev->connect_keys = NULL;
 
        nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
 
index 8e70291e586a97cab0a57e94a01d2fb7942b08b4..e87d6c4dd5b6a8269b450abf9b84bb6f0c4a6ad3 100644 (file)
@@ -217,7 +217,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
                if (skb->len <= mtu)
                        goto ok;
 
-               if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu))
+               if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
                        goto ok;
        }
 
index ccfdc7115a83f709e2a5980c5dc0d65cd5859467..a00ec715aa4681a89e348a058450320bbafe6cfb 100644 (file)
@@ -283,7 +283,7 @@ static struct crypto_comp * __percpu *ipcomp_alloc_tfms(const char *alg_name)
                struct crypto_comp *tfm;
 
                /* This can be any valid CPU ID so we don't need locking. */
-               tfm = __this_cpu_read(*pos->tfms);
+               tfm = this_cpu_read(*pos->tfms);
 
                if (!strcmp(crypto_comp_name(tfm), alg_name)) {
                        pos->users++;
index 7a23078132cf523e83a489d61222bc44f5394c4c..625b3fca570419455656021b61bf132fb08e8b2a 100644 (file)
@@ -1458,10 +1458,13 @@ xfrm_tmpl_resolve(struct xfrm_policy **pols, int npols, const struct flowi *fl,
 static int xfrm_get_tos(const struct flowi *fl, int family)
 {
        const struct xfrm_policy_afinfo *afinfo;
-       int tos = 0;
+       int tos;
 
        afinfo = xfrm_policy_get_afinfo(family);
-       tos = afinfo ? afinfo->get_tos(fl) : 0;
+       if (!afinfo)
+               return 0;
+
+       tos = afinfo->get_tos(fl);
 
        rcu_read_unlock();
 
@@ -1891,7 +1894,7 @@ static void xfrm_policy_queue_process(struct timer_list *t)
        spin_unlock(&pq->hold_queue.lock);
 
        dst_hold(xfrm_dst_path(dst));
-       dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, 0);
+       dst = xfrm_lookup(net, xfrm_dst_path(dst), &fl, sk, XFRM_LOOKUP_QUEUE);
        if (IS_ERR(dst))
                goto purge_queue;
 
@@ -2729,14 +2732,14 @@ static const void *xfrm_get_dst_nexthop(const struct dst_entry *dst,
        while (dst->xfrm) {
                const struct xfrm_state *xfrm = dst->xfrm;
 
+               dst = xfrm_dst_child(dst);
+
                if (xfrm->props.mode == XFRM_MODE_TRANSPORT)
                        continue;
                if (xfrm->type->flags & XFRM_TYPE_REMOTE_COADDR)
                        daddr = xfrm->coaddr;
                else if (!(xfrm->type->flags & XFRM_TYPE_LOCAL_COADDR))
                        daddr = &xfrm->id.daddr;
-
-               dst = xfrm_dst_child(dst);
        }
        return daddr;
 }
index 1d38c6acf8afbbab13a1ad1d05b4f67d6816d38b..9e3a5e85f8285e67323e6069f642fc8610ecd44b 100644 (file)
@@ -660,7 +660,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
                } else {
                        XFRM_SKB_CB(skb)->seq.output.low = oseq + 1;
                        XFRM_SKB_CB(skb)->seq.output.hi = oseq_hi;
-                       xo->seq.low = oseq = oseq + 1;
+                       xo->seq.low = oseq + 1;
                        xo->seq.hi = oseq_hi;
                        oseq += skb_shinfo(skb)->gso_segs;
                }
index 54e21f19d722c43d0b1fd102777a3467cee5b009..f9d2f2233f09531697b35209fe86754d23971e3f 100644 (file)
@@ -2056,6 +2056,11 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
        struct xfrm_mgr *km;
        struct xfrm_policy *pol = NULL;
 
+#ifdef CONFIG_COMPAT
+       if (in_compat_syscall())
+               return -EOPNOTSUPP;
+#endif
+
        if (!optval && !optlen) {
                xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
                xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
index 7f52b8eb177db4978750caed402aa34f6a31d7b4..080035f056d992c49f8cbcc776d579c9769c67eb 100644 (file)
@@ -121,22 +121,17 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
        struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
        struct xfrm_replay_state_esn *rs;
 
-       if (p->flags & XFRM_STATE_ESN) {
-               if (!rt)
-                       return -EINVAL;
+       if (!rt)
+               return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0;
 
-               rs = nla_data(rt);
+       rs = nla_data(rt);
 
-               if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
-                       return -EINVAL;
-
-               if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) &&
-                   nla_len(rt) != sizeof(*rs))
-                       return -EINVAL;
-       }
+       if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+               return -EINVAL;
 
-       if (!rt)
-               return 0;
+       if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) &&
+           nla_len(rt) != sizeof(*rs))
+               return -EINVAL;
 
        /* As only ESP and AH support ESN feature. */
        if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))
index 0e349b80686e76a421759b931ec04d194e446768..ba942e3ead890de9f4632d25a5fc1fd000676296 100644 (file)
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+ifndef CROSS_COMPILE
 hostprogs-$(CONFIG_SAMPLE_SECCOMP) := bpf-fancy dropper bpf-direct
 
 HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include
@@ -16,7 +17,6 @@ HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include
 bpf-direct-objs := bpf-direct.o
 
 # Try to match the kernel target.
-ifndef CROSS_COMPILE
 ifndef CONFIG_64BIT
 
 # s390 has -m31 flag to build 31 bit binaries
@@ -35,12 +35,4 @@ HOSTLOADLIBES_bpf-fancy += $(MFLAG)
 HOSTLOADLIBES_dropper += $(MFLAG)
 endif
 always := $(hostprogs-m)
-else
-# MIPS system calls are defined based on the -mabi that is passed
-# to the toolchain which may or may not be a valid option
-# for the host toolchain. So disable tests if target architecture
-# is MIPS but the host isn't.
-ifndef CONFIG_MIPS
-always := $(hostprogs-m)
-endif
 endif
index 47cddf32aeba025f2741dbc7f48d596f4f6653fa..4f2b25d43ec9b46923e52ae5d6f2bf789a6465b4 100644 (file)
@@ -256,6 +256,8 @@ __objtool_obj := $(objtree)/tools/objtool/objtool
 
 objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
 
+objtool_args += $(if $(part-of-module), --module,)
+
 ifndef CONFIG_FRAME_POINTER
 objtool_args += --no-fp
 endif
@@ -264,6 +266,12 @@ objtool_args += --no-unreachable
 else
 objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable)
 endif
+ifdef CONFIG_RETPOLINE
+ifneq ($(RETPOLINE_CFLAGS),)
+  objtool_args += --retpoline
+endif
+endif
+
 
 ifdef CONFIG_MODVERSIONS
 objtool_o = $(@D)/.tmp_$(@F)
index 5589bae34af6299ca26bc0ae7760dc1586949430..a6f538b31ad6c381d28f348707831a6dfd45a872 100644 (file)
@@ -297,11 +297,11 @@ cmd_dt_S_dtb=                                             \
        echo '\#include <asm-generic/vmlinux.lds.h>';   \
        echo '.section .dtb.init.rodata,"a"';           \
        echo '.balign STRUCT_ALIGNMENT';                \
-       echo '.global __dtb_$(*F)_begin';               \
-       echo '__dtb_$(*F)_begin:';                      \
+       echo '.global __dtb_$(subst -,_,$(*F))_begin';  \
+       echo '__dtb_$(subst -,_,$(*F))_begin:';         \
        echo '.incbin "$<" ';                           \
-       echo '__dtb_$(*F)_end:';                        \
-       echo '.global __dtb_$(*F)_end';                 \
+       echo '__dtb_$(subst -,_,$(*F))_end:';           \
+       echo '.global __dtb_$(subst -,_,$(*F))_end';    \
        echo '.balign STRUCT_ALIGNMENT';                \
 ) > $@
 
index fa3d39b6f23bbc0c3ea412b2e05584cddc8482a2..449b68c4c90cbecc6ee76b777e4fde603f3694b7 100644 (file)
  * (Note: it'd be easy to port over the complete mkdep state machine,
  *  but I don't think the added complexity is worth it)
  */
-/*
- * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
- * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
- * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
- * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
- * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
- * those files will have correct dependencies.
- */
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -233,8 +225,13 @@ static int str_ends_with(const char *s, int slen, const char *sub)
 static void parse_config_file(const char *p)
 {
        const char *q, *r;
+       const char *start = p;
 
        while ((p = strstr(p, "CONFIG_"))) {
+               if (p > start && (isalnum(p[-1]) || p[-1] == '_')) {
+                       p += 7;
+                       continue;
+               }
                p += 7;
                q = p;
                while (*q && (isalnum(*q) || *q == '_'))
@@ -286,8 +283,6 @@ static int is_ignored_file(const char *s, int len)
 {
        return str_ends_with(s, len, "include/generated/autoconf.h") ||
               str_ends_with(s, len, "include/generated/autoksyms.h") ||
-              str_ends_with(s, len, "arch/um/include/uml-config.h") ||
-              str_ends_with(s, len, "include/linux/kconfig.h") ||
               str_ends_with(s, len, ".ver");
 }
 
index 94b664817ad91e2e48c8fef6361a20ab2a632763..d84a5674e95e3aeeb77a445db46096b3bdf31e3d 100755 (executable)
@@ -15,7 +15,7 @@ signal(SIGPIPE, SIG_DFL)
 if len(sys.argv) < 3:
     sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0])
     sys.stderr.write("The options are:\n")
-    sys.stderr.write("-c       cateogrize output based on symbole type\n")
+    sys.stderr.write("-c       categorize output based on symbol type\n")
     sys.stderr.write("-d       Show delta of Data Section\n")
     sys.stderr.write("-t       Show delta of text Section\n")
     sys.exit(-1)
index 1249b727644b742db1c215eda9691e3d5e69d877..8fd6437beda80778554cd43c47d3e120e0f0c4d2 100644 (file)
@@ -56,10 +56,10 @@ statement S;
 p << r.p;
 @@
 
-coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep")
+coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdup")
 
 @script:python depends on report@
 p << r.p;
 @@
 
-coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep")
+coccilib.report.print_report(p[0], "WARNING opportunity for kmemdup")
index 9ee9bf7fd1a2113bfb869cf53b6d26d2f0852455..65792650c63057f0ed7edf7223dad30c06ac2391 100644 (file)
@@ -595,7 +595,7 @@ static void optimize_result(void)
                 * original char code */
                if (!best_table_len[i]) {
 
-                       /* find the token with the breates profit value */
+                       /* find the token with the best profit value */
                        best = find_best_token();
                        if (token_profit[best] == 0)
                                break;
index 5c12dc91ef348ea5a64a31edeb98657cc93512b4..df26c7b0fe13b611087ad8fe73fb7b1ae2257971 100644 (file)
@@ -178,7 +178,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
        case S_HEX:
        done:
                if (sym_string_valid(sym, p)) {
-                       sym->def[def].val = strdup(p);
+                       sym->def[def].val = xstrdup(p);
                        sym->flags |= def_flags;
                } else {
                        if (def != S_DEF_AUTO)
index 2858738b22d5aeac27154f74af433540839d37a6..240880a89111df06e95da0b44b08fa8aa184fa58 100644 (file)
@@ -101,7 +101,7 @@ static struct message *message__new(const char *msg, char *option,
        if (self->files == NULL)
                goto out_fail;
 
-       self->msg = strdup(msg);
+       self->msg = xstrdup(msg);
        if (self->msg == NULL)
                goto out_fail_msg;
 
index 4e23febbe4b2836451ab91327c634b268555bc53..2d5ec2d0e95293c8293adacb229dc2ecb5e6f170 100644 (file)
@@ -115,6 +115,7 @@ int file_write_dep(const char *name);
 void *xmalloc(size_t size);
 void *xcalloc(size_t nmemb, size_t size);
 void *xrealloc(void *p, size_t size);
+char *xstrdup(const char *s);
 
 struct gstr {
        size_t len;
index a10bd9d6fafd003a57aeb2baf24d4bc6dd04c982..6c0bcd9c472d6bee0b9fdadab18e9d46e5b05cdb 100755 (executable)
@@ -55,7 +55,8 @@ EOF
            echo " *** required header files."                            1>&2
            echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
            echo " *** "                                                  1>&2
-           echo " *** Install ncurses (ncurses-devel) and try again."    1>&2
+           echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2
+           echo " *** depending on your distribution) and try again."    1>&2
            echo " *** "                                                  1>&2
            exit 1
        fi
index 99222855544c3a7c2f67b3c33b3796eb36e5ff80..36cd3e1f1c28895b1a64740d8bcac17454197d70 100644 (file)
@@ -212,6 +212,7 @@ void menu_add_option(int token, char *arg)
                        sym_defconfig_list = current_entry->sym;
                else if (sym_defconfig_list != current_entry->sym)
                        zconf_error("trying to redefine defconfig symbol");
+               sym_defconfig_list->flags |= SYMBOL_AUTO;
                break;
        case T_OPT_ENV:
                prop_add_env(arg);
index cca9663be5ddd918703d534ef95368ccc44db322..2220bc4b051bd914e34bd20beb351b98da5ecc86 100644 (file)
@@ -183,7 +183,7 @@ static void sym_validate_range(struct symbol *sym)
                sprintf(str, "%lld", val2);
        else
                sprintf(str, "0x%llx", val2);
-       sym->curr.val = strdup(str);
+       sym->curr.val = xstrdup(str);
 }
 
 static void sym_set_changed(struct symbol *sym)
@@ -849,7 +849,7 @@ struct symbol *sym_lookup(const char *name, int flags)
                                   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
                                return symbol;
                }
-               new_name = strdup(name);
+               new_name = xstrdup(name);
        } else {
                new_name = NULL;
                hash = 0;
index b98a79e30e04a4017bd33264e85b2c40e46bc3af..c6f6e21b809ffe7a6f60acd2a7f016ee88971d5c 100644 (file)
@@ -154,3 +154,14 @@ void *xrealloc(void *p, size_t size)
        fprintf(stderr, "Out of memory.\n");
        exit(1);
 }
+
+char *xstrdup(const char *s)
+{
+       char *p;
+
+       p = strdup(s);
+       if (p)
+               return p;
+       fprintf(stderr, "Out of memory.\n");
+       exit(1);
+}
index 02de6fe302a9aec4fc747e5728f5d59f48946174..88b650eb9cc9141233d5da9be8702b9069de65e6 100644 (file)
@@ -332,16 +332,12 @@ void zconf_nextfile(const char *name)
                                "Inclusion path:\n  current file : '%s'\n",
                                zconf_curname(), zconf_lineno(),
                                zconf_curname());
-                       iter = current_file->parent;
-                       while (iter && \
-                              strcmp(iter->name,current_file->name)) {
-                               fprintf(stderr, "  included from: '%s:%d'\n",
-                                       iter->name, iter->lineno-1);
+                       iter = current_file;
+                       do {
                                iter = iter->parent;
-                       }
-                       if (iter)
                                fprintf(stderr, "  included from: '%s:%d'\n",
-                                       iter->name, iter->lineno+1);
+                                       iter->name, iter->lineno - 1);
+                       } while (strcmp(iter->name, current_file->name));
                        exit(1);
                }
        }
index 4be98050b961fe73df6bf6516b1e5a7f8135d149..ad6305b0f40cb962edf922ae73639c75b63c60c0 100644 (file)
@@ -127,7 +127,7 @@ no_mainmenu_stmt: /* empty */
         * later regardless of whether it comes from the 'prompt' in
         * mainmenu_stmt or here
         */
-       menu_add_prompt(P_MENU, strdup("Linux Kernel Configuration"), NULL);
+       menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
 };
 
 
@@ -276,6 +276,7 @@ choice: T_CHOICE word_opt T_EOL
        sym->flags |= SYMBOL_AUTO;
        menu_add_entry(sym);
        menu_add_expr(P_CHOICE, NULL, NULL);
+       free($2);
        printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
 };
 
index c0d129d7f4304abfac7f2e7d699000df02678f73..be56a1153014af54af0db2bf23c92306c4a8b4fb 100755 (executable)
@@ -246,7 +246,7 @@ else
 fi;
 
 # final build of init/
-${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"
+${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init
 
 archive_builtin
 
index 6f9e4ce568cd87fd8b529a2e8c08c615c6f790a5..9bb0a7f2863e3750ced13183d083281d320f9109 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/cred.h>
 #include <linux/key-type.h>
 #include <linux/digsig.h>
+#include <linux/vmalloc.h>
 #include <crypto/public_key.h>
 #include <keys/system_keyring.h>
 
index 929e14978c421b227e592e937d9157ca2235b2f7..fa728f662a6f3e094dccacca44d1ebc099e5a0c6 100644 (file)
 #include <keys/big_key-type.h>
 #include <crypto/aead.h>
 
+struct big_key_buf {
+       unsigned int            nr_pages;
+       void                    *virt;
+       struct scatterlist      *sg;
+       struct page             *pages[];
+};
+
 /*
  * Layout of key payload words.
  */
@@ -91,10 +98,9 @@ static DEFINE_MUTEX(big_key_aead_lock);
 /*
  * Encrypt/decrypt big_key data
  */
-static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
+static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t datalen, u8 *key)
 {
        int ret;
-       struct scatterlist sgio;
        struct aead_request *aead_req;
        /* We always use a zero nonce. The reason we can get away with this is
         * because we're using a different randomly generated key for every
@@ -109,8 +115,7 @@ static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
                return -ENOMEM;
 
        memset(zero_nonce, 0, sizeof(zero_nonce));
-       sg_init_one(&sgio, data, datalen + (op == BIG_KEY_ENC ? ENC_AUTHTAG_SIZE : 0));
-       aead_request_set_crypt(aead_req, &sgio, &sgio, datalen, zero_nonce);
+       aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce);
        aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
        aead_request_set_ad(aead_req, 0);
 
@@ -129,22 +134,82 @@ error:
        return ret;
 }
 
+/*
+ * Free up the buffer.
+ */
+static void big_key_free_buffer(struct big_key_buf *buf)
+{
+       unsigned int i;
+
+       if (buf->virt) {
+               memset(buf->virt, 0, buf->nr_pages * PAGE_SIZE);
+               vunmap(buf->virt);
+       }
+
+       for (i = 0; i < buf->nr_pages; i++)
+               if (buf->pages[i])
+                       __free_page(buf->pages[i]);
+
+       kfree(buf);
+}
+
+/*
+ * Allocate a buffer consisting of a set of pages with a virtual mapping
+ * applied over them.
+ */
+static void *big_key_alloc_buffer(size_t len)
+{
+       struct big_key_buf *buf;
+       unsigned int npg = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       unsigned int i, l;
+
+       buf = kzalloc(sizeof(struct big_key_buf) +
+                     sizeof(struct page) * npg +
+                     sizeof(struct scatterlist) * npg,
+                     GFP_KERNEL);
+       if (!buf)
+               return NULL;
+
+       buf->nr_pages = npg;
+       buf->sg = (void *)(buf->pages + npg);
+       sg_init_table(buf->sg, npg);
+
+       for (i = 0; i < buf->nr_pages; i++) {
+               buf->pages[i] = alloc_page(GFP_KERNEL);
+               if (!buf->pages[i])
+                       goto nomem;
+
+               l = min_t(size_t, len, PAGE_SIZE);
+               sg_set_page(&buf->sg[i], buf->pages[i], l, 0);
+               len -= l;
+       }
+
+       buf->virt = vmap(buf->pages, buf->nr_pages, VM_MAP, PAGE_KERNEL);
+       if (!buf->virt)
+               goto nomem;
+
+       return buf;
+
+nomem:
+       big_key_free_buffer(buf);
+       return NULL;
+}
+
 /*
  * Preparse a big key
  */
 int big_key_preparse(struct key_preparsed_payload *prep)
 {
+       struct big_key_buf *buf;
        struct path *path = (struct path *)&prep->payload.data[big_key_path];
        struct file *file;
        u8 *enckey;
-       u8 *data = NULL;
        ssize_t written;
-       size_t datalen = prep->datalen;
+       size_t datalen = prep->datalen, enclen = datalen + ENC_AUTHTAG_SIZE;
        int ret;
 
-       ret = -EINVAL;
        if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data)
-               goto error;
+               return -EINVAL;
 
        /* Set an arbitrary quota */
        prep->quotalen = 16;
@@ -157,13 +222,12 @@ int big_key_preparse(struct key_preparsed_payload *prep)
                 *
                 * File content is stored encrypted with randomly generated key.
                 */
-               size_t enclen = datalen + ENC_AUTHTAG_SIZE;
                loff_t pos = 0;
 
-               data = kmalloc(enclen, GFP_KERNEL);
-               if (!data)
+               buf = big_key_alloc_buffer(enclen);
+               if (!buf)
                        return -ENOMEM;
-               memcpy(data, prep->data, datalen);
+               memcpy(buf->virt, prep->data, datalen);
 
                /* generate random key */
                enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
@@ -176,7 +240,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
                        goto err_enckey;
 
                /* encrypt aligned data */
-               ret = big_key_crypt(BIG_KEY_ENC, data, datalen, enckey);
+               ret = big_key_crypt(BIG_KEY_ENC, buf, datalen, enckey);
                if (ret)
                        goto err_enckey;
 
@@ -187,7 +251,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
                        goto err_enckey;
                }
 
-               written = kernel_write(file, data, enclen, &pos);
+               written = kernel_write(file, buf->virt, enclen, &pos);
                if (written != enclen) {
                        ret = written;
                        if (written >= 0)
@@ -202,7 +266,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
                *path = file->f_path;
                path_get(path);
                fput(file);
-               kzfree(data);
+               big_key_free_buffer(buf);
        } else {
                /* Just store the data in a buffer */
                void *data = kmalloc(datalen, GFP_KERNEL);
@@ -220,7 +284,7 @@ err_fput:
 err_enckey:
        kzfree(enckey);
 error:
-       kzfree(data);
+       big_key_free_buffer(buf);
        return ret;
 }
 
@@ -298,15 +362,15 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
                return datalen;
 
        if (datalen > BIG_KEY_FILE_THRESHOLD) {
+               struct big_key_buf *buf;
                struct path *path = (struct path *)&key->payload.data[big_key_path];
                struct file *file;
-               u8 *data;
                u8 *enckey = (u8 *)key->payload.data[big_key_data];
                size_t enclen = datalen + ENC_AUTHTAG_SIZE;
                loff_t pos = 0;
 
-               data = kmalloc(enclen, GFP_KERNEL);
-               if (!data)
+               buf = big_key_alloc_buffer(enclen);
+               if (!buf)
                        return -ENOMEM;
 
                file = dentry_open(path, O_RDONLY, current_cred());
@@ -316,26 +380,26 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
                }
 
                /* read file to kernel and decrypt */
-               ret = kernel_read(file, data, enclen, &pos);
+               ret = kernel_read(file, buf->virt, enclen, &pos);
                if (ret >= 0 && ret != enclen) {
                        ret = -EIO;
                        goto err_fput;
                }
 
-               ret = big_key_crypt(BIG_KEY_DEC, data, enclen, enckey);
+               ret = big_key_crypt(BIG_KEY_DEC, buf, enclen, enckey);
                if (ret)
                        goto err_fput;
 
                ret = datalen;
 
                /* copy decrypted data to user */
-               if (copy_to_user(buffer, data, datalen) != 0)
+               if (copy_to_user(buffer, buf->virt, datalen) != 0)
                        ret = -EFAULT;
 
 err_fput:
                fput(file);
 error:
-               kzfree(data);
+               big_key_free_buffer(buf);
        } else {
                ret = datalen;
                if (copy_to_user(buffer, key->payload.data[big_key_data],
index f8a64e15e5bfb8c94f8d376d261f14ea610f99ec..baa5f8ef89d259d372bb5f15dcdeb9515af88c6e 100644 (file)
@@ -5,7 +5,6 @@
 
 config AC97_BUS_NEW
        tristate
-       select AC97
        help
          This is the new AC97 bus type, successor of AC97_BUS. The ported
          drivers which benefit from the AC97 automatic probing should "select"
index 0b3026d937b101918581edab80aa3b2803ecec5a..8a77620a38548ef8ad36d5b9bf154a14a785f568 100644 (file)
@@ -889,7 +889,7 @@ static int snd_ctl_elem_read(struct snd_card *card,
 
        index_offset = snd_ctl_get_ioff(kctl, &control->id);
        vd = &kctl->vd[index_offset];
-       if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get == NULL)
+       if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL)
                return -EPERM;
 
        snd_ctl_build_ioff(&control->id, kctl, index_offset);
index b044c0a5a674b116e9441c13558deb0c0a4e70f9..02298c9c602046b56406b7da87d0c86ff89f2a24 100644 (file)
@@ -1762,10 +1762,9 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
                return -ENOMEM;
        _snd_pcm_hw_params_any(params);
        err = snd_pcm_hw_refine(substream, params);
-       format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
-       kfree(params);
        if (err < 0)
-               return err;
+               goto error;
+       format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
        for (fmt = 0; fmt < 32; ++fmt) {
                if (snd_mask_test(format_mask, fmt)) {
                        int f = snd_pcm_oss_format_to(fmt);
@@ -1773,7 +1772,10 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
                                formats |= f;
                }
        }
-       return formats;
+
+ error:
+       kfree(params);
+       return err < 0 ? err : formats;
 }
 
 static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
index 60db32785f6229773fdf752a93e01f7bf42398eb..61a07fe34cd271e60dc0c31a7dddae750c2532b1 100644 (file)
@@ -255,12 +255,12 @@ static int seq_free_client1(struct snd_seq_client *client)
 
        if (!client)
                return 0;
-       snd_seq_delete_all_ports(client);
-       snd_seq_queue_client_leave(client->number);
        spin_lock_irqsave(&clients_lock, flags);
        clienttablock[client->number] = 1;
        clienttab[client->number] = NULL;
        spin_unlock_irqrestore(&clients_lock, flags);
+       snd_seq_delete_all_ports(client);
+       snd_seq_queue_client_leave(client->number);
        snd_use_lock_sync(&client->use_lock);
        snd_seq_queue_client_termination(client->number);
        if (client->pool)
@@ -910,7 +910,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
 static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
                                        struct snd_seq_event *event,
                                        struct file *file, int blocking,
-                                       int atomic, int hop)
+                                       int atomic, int hop,
+                                       struct mutex *mutexp)
 {
        struct snd_seq_event_cell *cell;
        int err;
@@ -948,7 +949,8 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
                return -ENXIO; /* queue is not allocated */
 
        /* allocate an event cell */
-       err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file);
+       err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic,
+                               file, mutexp);
        if (err < 0)
                return err;
 
@@ -1003,7 +1005,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
 {
        struct snd_seq_client *client = file->private_data;
        int written = 0, len;
-       int err = -EINVAL;
+       int err;
        struct snd_seq_event event;
 
        if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT))
@@ -1017,12 +1019,15 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
                return -ENXIO;
 
        /* allocate the pool now if the pool is not allocated yet */ 
+       mutex_lock(&client->ioctl_mutex);
        if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
-               if (snd_seq_pool_init(client->pool) < 0)
-                       return -ENOMEM;
+               err = snd_seq_pool_init(client->pool);
+               if (err < 0)
+                       goto out;
        }
 
        /* only process whole events */
+       err = -EINVAL;
        while (count >= sizeof(struct snd_seq_event)) {
                /* Read in the event header from the user */
                len = sizeof(event);
@@ -1069,7 +1074,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
                /* ok, enqueue it */
                err = snd_seq_client_enqueue_event(client, &event, file,
                                                   !(file->f_flags & O_NONBLOCK),
-                                                  0, 0);
+                                                  0, 0, &client->ioctl_mutex);
                if (err < 0)
                        break;
 
@@ -1080,6 +1085,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
                written += len;
        }
 
+ out:
+       mutex_unlock(&client->ioctl_mutex);
        return written ? written : err;
 }
 
@@ -1834,9 +1841,11 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
            (! snd_seq_write_pool_allocated(client) ||
             info->output_pool != client->pool->size)) {
                if (snd_seq_write_pool_allocated(client)) {
+                       /* is the pool in use? */
+                       if (atomic_read(&client->pool->counter))
+                               return -EBUSY;
                        /* remove all existing cells */
                        snd_seq_pool_mark_closing(client->pool);
-                       snd_seq_queue_client_leave_cells(client->number);
                        snd_seq_pool_done(client->pool);
                }
                client->pool->size = info->output_pool;
@@ -2256,7 +2265,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
        if (! cptr->accept_output)
                result = -EPERM;
        else /* send it */
-               result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop);
+               result = snd_seq_client_enqueue_event(cptr, ev, file, blocking,
+                                                     atomic, hop, NULL);
 
        snd_seq_client_unlock(cptr);
        return result;
index a8c2822e01984ff207c8a46b5ebd67546ee8b2eb..72c0302a55d23c05720d6062bef600b40fec6971 100644 (file)
@@ -125,7 +125,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
                return -EINVAL;
 
        snd_use_lock_use(&f->use_lock);
-       err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */
+       err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL, NULL); /* always non-blocking */
        if (err < 0) {
                if ((err == -ENOMEM) || (err == -EAGAIN))
                        atomic_inc(&f->overflow);
index f763682584a8f09837240b683a2da5413149b728..ab1112e90f88dbd29bae5eea8edd175175504edc 100644 (file)
@@ -220,7 +220,8 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell)
  */
 static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
                              struct snd_seq_event_cell **cellp,
-                             int nonblock, struct file *file)
+                             int nonblock, struct file *file,
+                             struct mutex *mutexp)
 {
        struct snd_seq_event_cell *cell;
        unsigned long flags;
@@ -244,7 +245,11 @@ static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
                set_current_state(TASK_INTERRUPTIBLE);
                add_wait_queue(&pool->output_sleep, &wait);
                spin_unlock_irq(&pool->lock);
+               if (mutexp)
+                       mutex_unlock(mutexp);
                schedule();
+               if (mutexp)
+                       mutex_lock(mutexp);
                spin_lock_irq(&pool->lock);
                remove_wait_queue(&pool->output_sleep, &wait);
                /* interrupted? */
@@ -287,7 +292,7 @@ __error:
  */
 int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
                      struct snd_seq_event_cell **cellp, int nonblock,
-                     struct file *file)
+                     struct file *file, struct mutex *mutexp)
 {
        int ncells, err;
        unsigned int extlen;
@@ -304,7 +309,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
        if (ncells >= pool->total_elements)
                return -ENOMEM;
 
-       err = snd_seq_cell_alloc(pool, &cell, nonblock, file);
+       err = snd_seq_cell_alloc(pool, &cell, nonblock, file, mutexp);
        if (err < 0)
                return err;
 
@@ -330,7 +335,8 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
                        int size = sizeof(struct snd_seq_event);
                        if (len < size)
                                size = len;
-                       err = snd_seq_cell_alloc(pool, &tmp, nonblock, file);
+                       err = snd_seq_cell_alloc(pool, &tmp, nonblock, file,
+                                                mutexp);
                        if (err < 0)
                                goto __error;
                        if (cell->event.data.ext.ptr == NULL)
index 32f959c17786d9ac8c071ba0e6fd070dc06da78b..3abe306c394af95c8dbdb99475f7829a17efc33c 100644 (file)
@@ -66,7 +66,8 @@ struct snd_seq_pool {
 void snd_seq_cell_free(struct snd_seq_event_cell *cell);
 
 int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
-                     struct snd_seq_event_cell **cellp, int nonblock, struct file *file);
+                     struct snd_seq_event_cell **cellp, int nonblock,
+                     struct file *file, struct mutex *mutexp);
 
 /* return number of unused (free) cells */
 static inline int snd_seq_unused_cells(struct snd_seq_pool *pool)
index bc1c8488fc2a1508d9572617e9030ba180477fd0..2bc6759e4adcf6a794efc22e4707b8f228d6b362 100644 (file)
@@ -87,7 +87,7 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo)
        if (f->cells > 0) {
                /* drain prioQ */
                while (f->cells > 0)
-                       snd_seq_cell_free(snd_seq_prioq_cell_out(f));
+                       snd_seq_cell_free(snd_seq_prioq_cell_out(f, NULL));
        }
        
        kfree(f);
@@ -214,8 +214,18 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
        return 0;
 }
 
+/* return 1 if the current time >= event timestamp */
+static int event_is_ready(struct snd_seq_event *ev, void *current_time)
+{
+       if ((ev->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK)
+               return snd_seq_compare_tick_time(current_time, &ev->time.tick);
+       else
+               return snd_seq_compare_real_time(current_time, &ev->time.time);
+}
+
 /* dequeue cell from prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
+struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f,
+                                                 void *current_time)
 {
        struct snd_seq_event_cell *cell;
        unsigned long flags;
@@ -227,6 +237,8 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
        spin_lock_irqsave(&f->lock, flags);
 
        cell = f->head;
+       if (cell && current_time && !event_is_ready(&cell->event, current_time))
+               cell = NULL;
        if (cell) {
                f->head = cell->next;
 
@@ -252,18 +264,6 @@ int snd_seq_prioq_avail(struct snd_seq_prioq * f)
        return f->cells;
 }
 
-
-/* peek at cell at the head of the prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
-{
-       if (f == NULL) {
-               pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n");
-               return NULL;
-       }
-       return f->head;
-}
-
-
 static inline int prioq_match(struct snd_seq_event_cell *cell,
                              int client, int timestamp)
 {
index d38bb78d934545b56e87f248ac1b6b46f34be8e7..2c315ca10fc4c1a8ef5eddd20e3731705fa8097c 100644 (file)
@@ -44,14 +44,12 @@ void snd_seq_prioq_delete(struct snd_seq_prioq **fifo);
 int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell);
 
 /* dequeue cell from prioq */ 
-struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f);
+struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f,
+                                                 void *current_time);
 
 /* return number of events available in prioq */
 int snd_seq_prioq_avail(struct snd_seq_prioq *f);
 
-/* peek at cell at the head of the prioq */
-struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq *f);
-
 /* client left queue */
 void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp);        
 
index 0428e9061b47c63d9c4d414d98b6f633515f79ef..b377f50483529e969dbd65cdea65f0ab80e01863 100644 (file)
@@ -277,30 +277,20 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
 
       __again:
        /* Process tick queue... */
-       while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) {
-               if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick,
-                                             &cell->event.time.tick)) {
-                       cell = snd_seq_prioq_cell_out(q->tickq);
-                       if (cell)
-                               snd_seq_dispatch_event(cell, atomic, hop);
-               } else {
-                       /* event remains in the queue */
+       for (;;) {
+               cell = snd_seq_prioq_cell_out(q->tickq,
+                                             &q->timer->tick.cur_tick);
+               if (!cell)
                        break;
-               }
+               snd_seq_dispatch_event(cell, atomic, hop);
        }
 
-
        /* Process time queue... */
-       while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) {
-               if (snd_seq_compare_real_time(&q->timer->cur_time,
-                                             &cell->event.time.time)) {
-                       cell = snd_seq_prioq_cell_out(q->timeq);
-                       if (cell)
-                               snd_seq_dispatch_event(cell, atomic, hop);
-               } else {
-                       /* event remains in the queue */
+       for (;;) {
+               cell = snd_seq_prioq_cell_out(q->timeq, &q->timer->cur_time);
+               if (!cell)
                        break;
-               }
+               snd_seq_dispatch_event(cell, atomic, hop);
        }
 
        /* free lock */
index 0333143a1fa7ad646c4da4b25eb653b2d3a1a3fb..1063a4377502a8338bfa3237183068eefcf0da0a 100644 (file)
@@ -192,6 +192,11 @@ static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
        dpcm->timer.expires = 0;
 }
 
+static inline void loopback_timer_stop_sync(struct loopback_pcm *dpcm)
+{
+       del_timer_sync(&dpcm->timer);
+}
+
 #define CABLE_VALID_PLAYBACK   (1 << SNDRV_PCM_STREAM_PLAYBACK)
 #define CABLE_VALID_CAPTURE    (1 << SNDRV_PCM_STREAM_CAPTURE)
 #define CABLE_VALID_BOTH       (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
@@ -326,6 +331,8 @@ static int loopback_prepare(struct snd_pcm_substream *substream)
        struct loopback_cable *cable = dpcm->cable;
        int bps, salign;
 
+       loopback_timer_stop_sync(dpcm);
+
        salign = (snd_pcm_format_width(runtime->format) *
                                                runtime->channels) / 8;
        bps = salign * runtime->rate;
@@ -659,7 +666,9 @@ static void free_cable(struct snd_pcm_substream *substream)
                return;
        if (cable->streams[!substream->stream]) {
                /* other stream is still alive */
+               spin_lock_irq(&cable->lock);
                cable->streams[substream->stream] = NULL;
+               spin_unlock_irq(&cable->lock);
        } else {
                /* free the cable */
                loopback->cables[substream->number][dev] = NULL;
@@ -698,7 +707,6 @@ static int loopback_open(struct snd_pcm_substream *substream)
                loopback->cables[substream->number][dev] = cable;
        }
        dpcm->cable = cable;
-       cable->streams[substream->stream] = dpcm;
 
        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 
@@ -730,6 +738,11 @@ static int loopback_open(struct snd_pcm_substream *substream)
                runtime->hw = loopback_pcm_hardware;
        else
                runtime->hw = cable->hw;
+
+       spin_lock_irq(&cable->lock);
+       cable->streams[substream->stream] = dpcm;
+       spin_unlock_irq(&cable->lock);
+
  unlock:
        if (err < 0) {
                free_cable(substream);
@@ -744,7 +757,7 @@ static int loopback_close(struct snd_pcm_substream *substream)
        struct loopback *loopback = substream->private_data;
        struct loopback_pcm *dpcm = substream->runtime->private_data;
 
-       loopback_timer_stop(dpcm);
+       loopback_timer_stop_sync(dpcm);
        mutex_lock(&loopback->cable_lock);
        free_cable(substream);
        mutex_unlock(&loopback->cable_lock);
index 06f845e293cb2dfcdaba0208aea03c69d3ad0ddc..7ba100bb1c3fcb22e0a958e7763a7ee683c45d2d 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac,
        return (state == target_state);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_check_power_state);
+/**
+ * snd_hdac_sync_power_state - wait until actual power state matches
+ * with the target state
+ *
+ * @hdac: the HDAC device
+ * @nid: NID to send the command
+ * @target_state: target state to check for
+ *
+ * Return power state or PS_ERROR if codec rejects GET verb.
+ */
+unsigned int snd_hdac_sync_power_state(struct hdac_device *codec,
+                       hda_nid_t nid, unsigned int power_state)
+{
+       unsigned long end_time = jiffies + msecs_to_jiffies(500);
+       unsigned int state, actual_state, count;
+
+       for (count = 0; count < 500; count++) {
+               state = snd_hdac_codec_read(codec, nid, 0,
+                               AC_VERB_GET_POWER_STATE, 0);
+               if (state & AC_PWRST_ERROR) {
+                       msleep(20);
+                       break;
+               }
+               actual_state = (state >> 4) & 0x0f;
+               if (actual_state == power_state)
+                       break;
+               if (time_after_eq(jiffies, end_time))
+                       break;
+               /* wait until the codec reachs to the target state */
+               msleep(1);
+       }
+       return state;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state);
index e018ecbf78a8f88e801990f1603218faaebba5f4..5bc3a7468e1716bb27113d0b7b1563625e14e134 100644 (file)
@@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
 }
 EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all);
 
-/*
- * wait until the state is reached, returns the current state
- */
-static unsigned int hda_sync_power_state(struct hda_codec *codec,
-                                        hda_nid_t fg,
-                                        unsigned int power_state)
-{
-       unsigned long end_time = jiffies + msecs_to_jiffies(500);
-       unsigned int state, actual_state;
-
-       for (;;) {
-               state = snd_hda_codec_read(codec, fg, 0,
-                                          AC_VERB_GET_POWER_STATE, 0);
-               if (state & AC_PWRST_ERROR)
-                       break;
-               actual_state = (state >> 4) & 0x0f;
-               if (actual_state == power_state)
-                       break;
-               if (time_after_eq(jiffies, end_time))
-                       break;
-               /* wait until the codec reachs to the target state */
-               msleep(1);
-       }
-       return state;
-}
-
 /**
  * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD
  * @codec: the HDA codec
@@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
                                                   state);
                        snd_hda_codec_set_power_to_all(codec, fg, power_state);
                }
-               state = hda_sync_power_state(codec, fg, power_state);
+               state = snd_hda_sync_power_state(codec, fg, power_state);
                if (!(state & AC_PWRST_ERROR))
                        break;
        }
index c71dcacea807bf0e0d11aa147401acd12280686c..c507c69029e31f9fe8715c384dab8f98114db7bb 100644 (file)
@@ -186,6 +186,10 @@ module_param(power_save, xint, 0644);
 MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
                 "(in second, 0 = disable).");
 
+static bool pm_blacklist = true;
+module_param(pm_blacklist, bool, 0644);
+MODULE_PARM_DESC(pm_blacklist, "Enable power-management blacklist");
+
 /* reset the HD-audio controller in power save mode.
  * this may give more power-saving, but will take longer time to
  * wake up.
@@ -371,6 +375,7 @@ enum {
                                        ((pci)->device == 0x160c))
 
 #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
 
 static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
@@ -1740,6 +1745,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        else
                chip->bdl_pos_adj = bdl_pos_adj[dev];
 
+       /* Workaround for a communication error on CFL (bko#199007) */
+       if (IS_CFL(pci))
+               chip->polling_mode = 1;
+
        err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
        if (err < 0) {
                kfree(hda);
@@ -2186,6 +2195,24 @@ out_free:
        return err;
 }
 
+#ifdef CONFIG_PM
+/* On some boards setting power_save to a non 0 value leads to clicking /
+ * popping sounds when ever we enter/leave powersaving mode. Ideally we would
+ * figure out how to avoid these sounds, but that is not always feasible.
+ * So we keep a list of devices where we disable powersaving as its known
+ * to causes problems on these devices.
+ */
+static struct snd_pci_quirk power_save_blacklist[] = {
+       /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
+       SND_PCI_QUIRK(0x1849, 0x0c0c, "Asrock B85M-ITX", 0),
+       /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
+       SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */
+       SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0),
+       {}
+};
+#endif /* CONFIG_PM */
+
 /* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
 static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
        [AZX_DRIVER_NVIDIA] = 8,
@@ -2198,6 +2225,7 @@ static int azx_probe_continue(struct azx *chip)
        struct hdac_bus *bus = azx_bus(chip);
        struct pci_dev *pci = chip->pci;
        int dev = chip->dev_index;
+       int val;
        int err;
 
        hda->probe_continued = 1;
@@ -2278,7 +2306,21 @@ static int azx_probe_continue(struct azx *chip)
 
        chip->running = 1;
        azx_add_card_list(chip);
-       snd_hda_set_power_save(&chip->bus, power_save * 1000);
+
+       val = power_save;
+#ifdef CONFIG_PM
+       if (pm_blacklist) {
+               const struct snd_pci_quirk *q;
+
+               q = snd_pci_quirk_lookup(chip->pci, power_save_blacklist);
+               if (q && val) {
+                       dev_info(chip->card->dev, "device %04x:%04x is on the power_save blacklist, forcing power_save to 0\n",
+                                q->subvendor, q->subdevice);
+                       val = 0;
+               }
+       }
+#endif /* CONFIG_PM */
+       snd_hda_set_power_save(&chip->bus, val * 1000);
        if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
                pm_runtime_put_autosuspend(&pci->dev);
 
index 5b5c324c99b9d9261330f3ad8e160e9036559e21..321e78baa63ca830332f7be3221cf4b999c2a4fe 100644 (file)
@@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
 {
        return snd_hdac_check_power_state(&codec->core, nid, target_state);
 }
-
+static inline bool snd_hda_sync_power_state(struct hda_codec *codec,
+                          hda_nid_t nid, unsigned int target_state)
+{
+       return snd_hdac_sync_power_state(&codec->core, nid, target_state);
+}
 unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
                                             hda_nid_t nid,
                                             unsigned int power_state);
index 37e1cf8218ff0f864de4635d0188ed5b9b91d73c..5b4dbcec6de8dab957f045786d4808b4edfd573f 100644 (file)
@@ -957,6 +957,8 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
        SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
        SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
        SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
+       SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
+       SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
        SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
        SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
        SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
index 23475888192b5b5b0b1657ad1def3c38c57c5e9a..aef1f52db7d9e5264fdcdb382dac477edc098514 100644 (file)
@@ -3130,6 +3130,8 @@ static void alc256_init(struct hda_codec *codec)
 
        alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
        alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
+       alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
+       alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
 }
 
 static void alc256_shutup(struct hda_codec *codec)
@@ -3465,6 +3467,19 @@ static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
                spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
 }
 
+static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
+                                                const struct hda_fixup *fix,
+                                                int action)
+{
+       unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
+       unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
+
+       if (cfg_headphone && cfg_headset_mic == 0x411111f0)
+               snd_hda_codec_set_pincfg(codec, 0x19,
+                       (cfg_headphone & ~AC_DEFCFG_DEVICE) |
+                       (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
+}
+
 static void alc269_fixup_hweq(struct hda_codec *codec,
                               const struct hda_fixup *fix, int action)
 {
@@ -3583,8 +3598,12 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
        pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
        pinval &= ~AC_PINCTL_VREFEN;
        pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
-       if (spec->mute_led_nid)
+       if (spec->mute_led_nid) {
+               /* temporarily power up/down for setting VREF */
+               snd_hda_power_up_pm(codec);
                snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
+               snd_hda_power_down_pm(codec);
+       }
 }
 
 /* Make sure the led works even in runtime suspend */
@@ -4972,6 +4991,29 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec,
        }
 }
 
+static void alc_fixup_tpt470_dock(struct hda_codec *codec,
+                                 const struct hda_fixup *fix, int action)
+{
+       static const struct hda_pintbl pincfgs[] = {
+               { 0x17, 0x21211010 }, /* dock headphone */
+               { 0x19, 0x21a11010 }, /* dock mic */
+               { }
+       };
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
+               snd_hda_apply_pincfgs(codec, pincfgs);
+       } else if (action == HDA_FIXUP_ACT_INIT) {
+               /* Enable DOCK device */
+               snd_hda_codec_write(codec, 0x17, 0,
+                           AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
+               /* Enable DOCK device */
+               snd_hda_codec_write(codec, 0x19, 0,
+                           AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
+       }
+}
+
 static void alc_shutup_dell_xps13(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -5238,6 +5280,16 @@ static void alc298_fixup_speaker_volume(struct hda_codec *codec,
        }
 }
 
+/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
+static void alc295_fixup_disable_dac3(struct hda_codec *codec,
+                                     const struct hda_fixup *fix, int action)
+{
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               hda_nid_t conn[2] = { 0x02, 0x03 };
+               snd_hda_override_conn_list(codec, 0x17, 2, conn);
+       }
+}
+
 /* Hook to update amp GPIO4 for automute */
 static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
                                          struct hda_jack_callback *jack)
@@ -5351,6 +5403,7 @@ enum {
        ALC269_FIXUP_LIFEBOOK_EXTMIC,
        ALC269_FIXUP_LIFEBOOK_HP_PIN,
        ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
+       ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
        ALC269_FIXUP_AMIC,
        ALC269_FIXUP_DMIC,
        ALC269VB_FIXUP_AMIC,
@@ -5429,6 +5482,7 @@ enum {
        ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
        ALC255_FIXUP_DELL_SPK_NOISE,
        ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC295_FIXUP_DISABLE_DAC3,
        ALC280_FIXUP_HP_HEADSET_MIC,
        ALC221_FIXUP_HP_FRONT_MIC,
        ALC292_FIXUP_TPT460,
@@ -5443,9 +5497,13 @@ enum {
        ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
        ALC233_FIXUP_LENOVO_MULTI_CODECS,
        ALC294_FIXUP_LENOVO_MIC_LOCATION,
+       ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
        ALC700_FIXUP_INTEL_REFERENCE,
        ALC274_FIXUP_DELL_BIND_DACS,
        ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
+       ALC298_FIXUP_TPT470_DOCK,
+       ALC255_FIXUP_DUMMY_LINEOUT_VERB,
+       ALC255_FIXUP_DELL_HEADSET_MIC,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -5556,6 +5614,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
        },
+       [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
+       },
        [ALC269_FIXUP_AMIC] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -6156,6 +6218,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
        },
+       [ALC295_FIXUP_DISABLE_DAC3] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc295_fixup_disable_dac3,
+       },
        [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -6241,6 +6307,18 @@ static const struct hda_fixup alc269_fixups[] = {
                        { }
                },
        },
+       [ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x16, 0x0101102f }, /* Rear Headset HP */
+                       { 0x19, 0x02a1913c }, /* use as Front headset mic, without its own jack detect */
+                       { 0x1a, 0x01a19030 }, /* Rear Headset MIC */
+                       { 0x1b, 0x02011020 },
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
+       },
        [ALC700_FIXUP_INTEL_REFERENCE] = {
                .type = HDA_FIXUP_VERBS,
                .v.verbs = (const struct hda_verb[]) {
@@ -6271,6 +6349,28 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC274_FIXUP_DELL_BIND_DACS
        },
+       [ALC298_FIXUP_TPT470_DOCK] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_tpt470_dock,
+               .chained = true,
+               .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
+       },
+       [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x14, 0x0201101f },
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
+       },
+       [ALC255_FIXUP_DELL_HEADSET_MIC] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
+                       { }
+               },
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6319,8 +6419,15 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
        SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
        SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
+       SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
        SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
+       SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+       SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
+       SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
+       SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -6422,6 +6529,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
        SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
        SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
+       SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
        SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
        SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
        SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
@@ -6450,8 +6558,18 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
        SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
+       SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
+       SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
@@ -6472,7 +6590,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
        SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
        SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
+       SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
        SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
@@ -6734,6 +6857,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
                {0x12, 0xb7a60130},
                {0x14, 0x90170110},
                {0x21, 0x02211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+               {0x12, 0x90a60130},
+               {0x14, 0x90170110},
+               {0x14, 0x01011020},
+               {0x21, 0x0221101f}),
        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
                ALC256_STANDARD_PINS),
        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
@@ -6803,6 +6931,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
                {0x12, 0x90a60120},
                {0x14, 0x90170110},
                {0x21, 0x0321101f}),
+       SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
+               {0x12, 0xb7a60130},
+               {0x14, 0x90170110},
+               {0x21, 0x04211020}),
        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
                ALC290_STANDARD_PINS,
                {0x15, 0x04211040},
@@ -7038,6 +7170,8 @@ static int patch_alc269(struct hda_codec *codec)
                break;
        case 0x10ec0257:
                spec->codec_variant = ALC269_TYPE_ALC257;
+               spec->shutup = alc256_shutup;
+               spec->init_hook = alc256_init;
                spec->gen.mixer_nid = 0;
                break;
        case 0x10ec0215:
index 84c3582f3982785c1408fae5435f4c779dea2359..41af6b9cc3500bead51340637e24f4288e135100 100644 (file)
@@ -45,7 +45,6 @@ source "sound/soc/amd/Kconfig"
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/bcm/Kconfig"
-source "sound/soc/blackfin/Kconfig"
 source "sound/soc/cirrus/Kconfig"
 source "sound/soc/davinci/Kconfig"
 source "sound/soc/dwc/Kconfig"
index 74cd1858d38b4c28b53d21b4ba8e1aed9728f9a4..8d92492183d28ca4cafd2021a0edf885853112ce 100644 (file)
@@ -29,7 +29,6 @@ obj-$(CONFIG_SND_SOC) += amd/
 obj-$(CONFIG_SND_SOC)  += atmel/
 obj-$(CONFIG_SND_SOC)  += au1x/
 obj-$(CONFIG_SND_SOC)  += bcm/
-obj-$(CONFIG_SND_SOC)  += blackfin/
 obj-$(CONFIG_SND_SOC)  += cirrus/
 obj-$(CONFIG_SND_SOC)  += davinci/
 obj-$(CONFIG_SND_SOC)  += dwc/
index d5838402f667b39622c4ee01276df1eb75d0413b..6cbf9cf4d1a4c2e451a5d0f434b806dfbc414a87 100644 (file)
@@ -3,6 +3,15 @@ config SND_SOC_AMD_ACP
        help
         This option enables ACP DMA support on AMD platform.
 
+config SND_SOC_AMD_CZ_DA7219MX98357_MACH
+       tristate "AMD CZ support for DA7219 and MAX9835"
+       select SND_SOC_DA7219
+       select SND_SOC_MAX98357A
+       select SND_SOC_ADAU7002
+       depends on SND_SOC_AMD_ACP && I2C
+       help
+        This option enables machine driver for DA7219 and MAX9835.
+
 config SND_SOC_AMD_CZ_RT5645_MACH
        tristate "AMD CZ support for RT5645"
        select SND_SOC_RT5645
index f07fd2e2870ace0aef7e277f80f006f81405e99e..79b0622fa5d3aa0dcf6fd2a08fa390b3dbf80aea 100644 (file)
@@ -1,5 +1,7 @@
 acp_audio_dma-objs := acp-pcm-dma.o
+snd-soc-acp-da7219mx98357-mach-objs := acp-da7219-max98357a.o
 snd-soc-acp-rt5645-mach-objs := acp-rt5645.o
 
 obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o
+obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o
 obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
new file mode 100644 (file)
index 0000000..b205c78
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * Machine driver for AMD ACP Audio engine using DA7219 & MAX98357 codec
+ *
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+
+#include "../codecs/da7219.h"
+#include "../codecs/da7219-aad.h"
+
+#define CZ_PLAT_CLK 24000000
+#define MCLK_RATE 24576000
+#define DUAL_CHANNEL           2
+
+static struct snd_soc_jack cz_jack;
+struct clk *da7219_dai_clk;
+
+static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
+{
+       int ret;
+       struct snd_soc_card *card = rtd->card;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_component *component = codec_dai->component;
+
+       dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK,
+                                    CZ_PLAT_CLK, SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL,
+                                 CZ_PLAT_CLK, MCLK_RATE);
+       if (ret < 0) {
+               dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+               return ret;
+       }
+
+       da7219_dai_clk = clk_get(component->dev, "da7219-dai-clks");
+
+       ret = snd_soc_card_jack_new(card, "Headset Jack",
+                               SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
+                               SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+                               SND_JACK_BTN_2 | SND_JACK_BTN_3,
+                               &cz_jack, NULL, 0);
+       if (ret) {
+               dev_err(card->dev, "HP jack creation failed %d\n", ret);
+               return ret;
+       }
+
+       da7219_aad_jack_det(component, &cz_jack);
+
+       return 0;
+}
+
+static int cz_da7219_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params)
+{
+       int ret = 0;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+       ret = clk_prepare_enable(da7219_dai_clk);
+       if (ret < 0) {
+               dev_err(rtd->dev, "can't enable master clock %d\n", ret);
+               return ret;
+       }
+
+       return ret;
+}
+
+static int cz_da7219_hw_free(struct snd_pcm_substream *substream)
+{
+       clk_disable_unprepare(da7219_dai_clk);
+
+       return 0;
+}
+
+static const unsigned int channels[] = {
+       DUAL_CHANNEL,
+};
+
+static const unsigned int rates[] = {
+       48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+       .count = ARRAY_SIZE(rates),
+       .list  = rates,
+       .mask = 0,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+       .count = ARRAY_SIZE(channels),
+       .list = channels,
+       .mask = 0,
+};
+
+static int cz_fe_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       /*
+        * On this platform for PCM device we support stereo
+        */
+
+       runtime->hw.channels_max = DUAL_CHANNEL;
+       snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                  &constraints_channels);
+       snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                  &constraints_rates);
+
+       return 0;
+}
+
+static struct snd_soc_ops cz_da7219_cap_ops = {
+       .hw_params = cz_da7219_hw_params,
+       .hw_free = cz_da7219_hw_free,
+       .startup = cz_fe_startup,
+};
+
+static struct snd_soc_ops cz_max_play_ops = {
+       .hw_params = cz_da7219_hw_params,
+       .hw_free = cz_da7219_hw_free,
+};
+
+static struct snd_soc_ops cz_dmic_cap_ops = {
+       .hw_params = cz_da7219_hw_params,
+       .hw_free = cz_da7219_hw_free,
+};
+
+static struct snd_soc_dai_link cz_dai_7219_98357[] = {
+       {
+               .name = "amd-da7219-play-cap",
+               .stream_name = "Playback and Capture",
+               .platform_name = "acp_audio_dma.0.auto",
+               .cpu_dai_name = "designware-i2s.3.auto",
+               .codec_dai_name = "da7219-hifi",
+               .codec_name = "i2c-DLGS7219:00",
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+                               | SND_SOC_DAIFMT_CBM_CFM,
+               .init = cz_da7219_init,
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .ops = &cz_da7219_cap_ops,
+       },
+       {
+               .name = "amd-max98357-play",
+               .stream_name = "HiFi Playback",
+               .platform_name = "acp_audio_dma.0.auto",
+               .cpu_dai_name = "designware-i2s.1.auto",
+               .codec_dai_name = "HiFi",
+               .codec_name = "MX98357A:00",
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+                               | SND_SOC_DAIFMT_CBM_CFM,
+               .dpcm_playback = 1,
+               .ops = &cz_max_play_ops,
+       },
+       {
+               .name = "dmic",
+               .stream_name = "DMIC Capture",
+               .platform_name = "acp_audio_dma.0.auto",
+               .cpu_dai_name = "designware-i2s.2.auto",
+               .codec_dai_name = "adau7002-hifi",
+               .codec_name = "ADAU7002:00",
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+                               | SND_SOC_DAIFMT_CBM_CFM,
+               .dpcm_capture = 1,
+               .ops = &cz_dmic_cap_ops,
+       },
+};
+
+static const struct snd_soc_dapm_widget cz_widgets[] = {
+       SND_SOC_DAPM_HP("Headphones", NULL),
+       SND_SOC_DAPM_SPK("Speakers", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+       SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route cz_audio_route[] = {
+       {"Headphones", NULL, "HPL"},
+       {"Headphones", NULL, "HPR"},
+       {"MIC", NULL, "Headset Mic"},
+       {"Speakers", NULL, "Speaker"},
+       {"PDM_DAT", NULL, "Int Mic"},
+};
+
+static const struct snd_kcontrol_new cz_mc_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Headphones"),
+       SOC_DAPM_PIN_SWITCH("Speakers"),
+       SOC_DAPM_PIN_SWITCH("Headset Mic"),
+       SOC_DAPM_PIN_SWITCH("Int Mic"),
+};
+
+static struct snd_soc_card cz_card = {
+       .name = "acpd7219m98357",
+       .owner = THIS_MODULE,
+       .dai_link = cz_dai_7219_98357,
+       .num_links = ARRAY_SIZE(cz_dai_7219_98357),
+       .dapm_widgets = cz_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(cz_widgets),
+       .dapm_routes = cz_audio_route,
+       .num_dapm_routes = ARRAY_SIZE(cz_audio_route),
+       .controls = cz_mc_controls,
+       .num_controls = ARRAY_SIZE(cz_mc_controls),
+};
+
+static int cz_probe(struct platform_device *pdev)
+{
+       int ret;
+       struct snd_soc_card *card;
+
+       card = &cz_card;
+       cz_card.dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+       ret = devm_snd_soc_register_card(&pdev->dev, &cz_card);
+       if (ret) {
+               dev_err(&pdev->dev,
+                               "devm_snd_soc_register_card(%s) failed: %d\n",
+                               cz_card.name, ret);
+               return ret;
+       }
+       return 0;
+}
+
+static const struct acpi_device_id cz_audio_acpi_match[] = {
+       { "AMD7219", 0 },
+       {},
+};
+MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
+
+static struct platform_driver cz_pcm_driver = {
+       .driver = {
+               .name = "cz-da7219-max98357a",
+               .acpi_match_table = ACPI_PTR(cz_audio_acpi_match),
+               .pm = &snd_soc_pm_ops,
+       },
+       .probe = cz_probe,
+};
+
+module_platform_driver(cz_pcm_driver);
+
+MODULE_AUTHOR("akshu.agrawal@amd.com");
+MODULE_DESCRIPTION("DA7219 & MAX98357A audio support");
+MODULE_LICENSE("GPL v2");
index c33a512283a48fecfe52a7ca3086dc7b30376e29..540088d317f2e0fe55d8a7ae4f6f4c1a12a04432 100644 (file)
@@ -23,6 +23,8 @@
 #include <drm/amd_asic_type.h>
 #include "acp.h"
 
+#define DRV_NAME "acp_audio_dma"
+
 #define PLAYBACK_MIN_NUM_PERIODS    2
 #define PLAYBACK_MAX_NUM_PERIODS    2
 #define PLAYBACK_MAX_PERIOD_SIZE    16384
@@ -182,19 +184,18 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
  * system memory <-> ACP SRAM
  */
 static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
-                                       u32 size, int direction,
-                                       u32 pte_offset, u32 asic_type)
+                                       u32 size, int direction, u32 pte_offset,
+                                       u16 ch, u32 sram_bank,
+                                       u16 dma_dscr_idx, u32 asic_type)
 {
        u16 i;
-       u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
        acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
 
        for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
                dmadscr[i].xfer_val = 0;
                if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
-                       dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12 + i;
-                       dmadscr[i].dest = ACP_SHARED_RAM_BANK_1_ADDRESS
-                                       + (i * (size/2));
+                       dma_dscr_idx = dma_dscr_idx + i;
+                       dmadscr[i].dest = sram_bank + (i * (size/2));
                        dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
                                + (pte_offset * SZ_4K) + (i * (size/2));
                        switch (asic_type) {
@@ -209,25 +210,19 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
                                (size / 2);
                        }
                } else {
-                       dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14 + i;
+                       dma_dscr_idx = dma_dscr_idx + i;
+                       dmadscr[i].src = sram_bank + (i * (size/2));
+                       dmadscr[i].dest =
+                       ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
+                       (pte_offset * SZ_4K) + (i * (size/2));
                        switch (asic_type) {
                        case CHIP_STONEY:
-                               dmadscr[i].src = ACP_SHARED_RAM_BANK_3_ADDRESS +
-                               (i * (size/2));
-                               dmadscr[i].dest =
-                               ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
-                               (pte_offset * SZ_4K) + (i * (size/2));
                                dmadscr[i].xfer_val |=
                                BIT(22) |
                                (ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC << 16) |
                                (size / 2);
                                break;
                        default:
-                               dmadscr[i].src = ACP_SHARED_RAM_BANK_5_ADDRESS +
-                               (i * (size/2));
-                               dmadscr[i].dest =
-                               ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
-                               (pte_offset * SZ_4K) + (i * (size/2));
                                dmadscr[i].xfer_val |=
                                BIT(22) |
                                (ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) |
@@ -237,72 +232,49 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
                config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
                                                &dmadscr[i]);
        }
-       if (direction == SNDRV_PCM_STREAM_PLAYBACK)
-               config_acp_dma_channel(acp_mmio, SYSRAM_TO_ACP_CH_NUM,
-                                       PLAYBACK_START_DMA_DESCR_CH12,
-                                       NUM_DSCRS_PER_CHANNEL,
-                                       ACP_DMA_PRIORITY_LEVEL_NORMAL);
-       else
-               config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_CH_NUM,
-                                       CAPTURE_START_DMA_DESCR_CH14,
-                                       NUM_DSCRS_PER_CHANNEL,
-                                       ACP_DMA_PRIORITY_LEVEL_NORMAL);
+       config_acp_dma_channel(acp_mmio, ch,
+                               dma_dscr_idx - 1,
+                               NUM_DSCRS_PER_CHANNEL,
+                               ACP_DMA_PRIORITY_LEVEL_NORMAL);
 }
 
 /* Initialize the DMA descriptor information for transfer between
  * ACP SRAM <-> I2S
  */
-static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio,
-                                       u32 size, int direction,
-                                       u32 asic_type)
+static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
+                                               int direction, u32 sram_bank,
+                                               u16 destination, u16 ch,
+                                               u16 dma_dscr_idx, u32 asic_type)
 {
 
        u16 i;
-       u16 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
        acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
 
        for (i = 0; i < NUM_DSCRS_PER_CHANNEL; i++) {
                dmadscr[i].xfer_val = 0;
                if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
-                       dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13 + i;
-                       dmadscr[i].src = ACP_SHARED_RAM_BANK_1_ADDRESS +
-                                        (i * (size/2));
+                       dma_dscr_idx = dma_dscr_idx + i;
+                       dmadscr[i].src = sram_bank  + (i * (size/2));
                        /* dmadscr[i].dest is unused by hardware. */
                        dmadscr[i].dest = 0;
-                       dmadscr[i].xfer_val |= BIT(22) | (TO_ACP_I2S_1 << 16) |
+                       dmadscr[i].xfer_val |= BIT(22) | (destination << 16) |
                                                (size / 2);
                } else {
-                       dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15 + i;
+                       dma_dscr_idx = dma_dscr_idx + i;
                        /* dmadscr[i].src is unused by hardware. */
                        dmadscr[i].src = 0;
-                       switch (asic_type) {
-                       case CHIP_STONEY:
-                               dmadscr[i].dest =
-                                        ACP_SHARED_RAM_BANK_3_ADDRESS +
-                                       (i * (size / 2));
-                               break;
-                       default:
-                               dmadscr[i].dest =
-                                        ACP_SHARED_RAM_BANK_5_ADDRESS +
-                                       (i * (size / 2));
-                       }
+                       dmadscr[i].dest =
+                                sram_bank + (i * (size / 2));
                        dmadscr[i].xfer_val |= BIT(22) |
-                                       (FROM_ACP_I2S_1 << 16) | (size / 2);
+                               (destination << 16) | (size / 2);
                }
                config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
                                                &dmadscr[i]);
        }
        /* Configure the DMA channel with the above descriptore */
-       if (direction == SNDRV_PCM_STREAM_PLAYBACK)
-               config_acp_dma_channel(acp_mmio, ACP_TO_I2S_DMA_CH_NUM,
-                                       PLAYBACK_START_DMA_DESCR_CH13,
-                                       NUM_DSCRS_PER_CHANNEL,
-                                       ACP_DMA_PRIORITY_LEVEL_NORMAL);
-       else
-               config_acp_dma_channel(acp_mmio, I2S_TO_ACP_DMA_CH_NUM,
-                                       CAPTURE_START_DMA_DESCR_CH15,
-                                       NUM_DSCRS_PER_CHANNEL,
-                                       ACP_DMA_PRIORITY_LEVEL_NORMAL);
+       config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
+                               NUM_DSCRS_PER_CHANNEL,
+                               ACP_DMA_PRIORITY_LEVEL_NORMAL);
 }
 
 /* Create page table entries in ACP SRAM for the allocated memory */
@@ -344,23 +316,51 @@ static void config_acp_dma(void __iomem *acp_mmio,
                        struct audio_substream_data *audio_config,
                        u32 asic_type)
 {
-       u32 pte_offset;
+       u32 pte_offset, sram_bank;
+       u16 ch1, ch2, destination, dma_dscr_idx;
 
-       if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
+       if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) {
                pte_offset = ACP_PLAYBACK_PTE_OFFSET;
-       else
+               ch1 = SYSRAM_TO_ACP_CH_NUM;
+               ch2 = ACP_TO_I2S_DMA_CH_NUM;
+               sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS;
+               destination = TO_ACP_I2S_1;
+
+       } else {
                pte_offset = ACP_CAPTURE_PTE_OFFSET;
+               ch1 = SYSRAM_TO_ACP_CH_NUM;
+               ch2 = ACP_TO_I2S_DMA_CH_NUM;
+               switch (asic_type) {
+               case CHIP_STONEY:
+                       sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS;
+                       break;
+               default:
+                       sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS;
+               }
+               destination = FROM_ACP_I2S_1;
+       }
 
        acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages,
                        pte_offset);
+       if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
+               dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
+       else
+               dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14;
 
        /* Configure System memory <-> ACP SRAM DMA descriptors */
        set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size,
-                               audio_config->direction, pte_offset, asic_type);
+                                      audio_config->direction, pte_offset,
+                                       ch1, sram_bank, dma_dscr_idx, asic_type);
 
+       if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
+               dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
+       else
+               dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15;
        /* Configure ACP SRAM <-> I2S DMA descriptors */
        set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size,
-                               audio_config->direction, asic_type);
+                                       audio_config->direction, sram_bank,
+                                       destination, ch2, dma_dscr_idx,
+                                       asic_type);
 }
 
 /* Start a given DMA channel transfer */
@@ -579,13 +579,6 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
                for (bank = 1; bank < 48; bank++)
                        acp_set_sram_bank_state(acp_mmio, bank, false);
        }
-
-       /* Stoney supports 16bit resolution */
-       if (asic_type == CHIP_STONEY) {
-               val = acp_reg_read(acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN);
-               val |= 0x03;
-               acp_reg_write(val, acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN);
-       }
        return 0;
 }
 
@@ -662,7 +655,7 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
                                       1, 0);
                acp_dma_start(acp_mmio, SYSRAM_TO_ACP_CH_NUM, false);
 
-               snd_pcm_period_elapsed(irq_data->play_stream);
+               snd_pcm_period_elapsed(irq_data->play_i2ssp_stream);
 
                acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) << 16,
                                acp_mmio, mmACP_EXTERNAL_INTR_STAT);
@@ -685,7 +678,7 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
 
        if ((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) != 0) {
                valid_irq = true;
-               snd_pcm_period_elapsed(irq_data->capture_stream);
+               snd_pcm_period_elapsed(irq_data->capture_i2ssp_stream);
                acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) << 16,
                                acp_mmio, mmACP_EXTERNAL_INTR_STAT);
        }
@@ -702,8 +695,8 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
        int ret = 0;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *prtd = substream->private_data;
-       struct audio_drv_data *intr_data = dev_get_drvdata(prtd->platform->dev);
-
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+       struct audio_drv_data *intr_data = dev_get_drvdata(component->dev);
        struct audio_substream_data *adata =
                kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL);
        if (adata == NULL)
@@ -730,7 +723,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
        ret = snd_pcm_hw_constraint_integer(runtime,
                                            SNDRV_PCM_HW_PARAM_PERIODS);
        if (ret < 0) {
-               dev_err(prtd->platform->dev, "set integer constraint failed\n");
+               dev_err(component->dev, "set integer constraint failed\n");
                kfree(adata);
                return ret;
        }
@@ -743,11 +736,11 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
         * This enablement is not required for another stream, if current
         * stream is not closed
        */
-       if (!intr_data->play_stream && !intr_data->capture_stream)
+       if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream)
                acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               intr_data->play_stream = substream;
+               intr_data->play_i2ssp_stream = substream;
                /* For Stoney, Memory gating is disabled,i.e SRAM Banks
                 * won't be turned off. The default state for SRAM banks is ON.
                 * Setting SRAM bank state code skipped for STONEY platform.
@@ -758,7 +751,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
                                                        bank, true);
                }
        } else {
-               intr_data->capture_stream = substream;
+               intr_data->capture_i2ssp_stream = substream;
                if (intr_data->asic_type != CHIP_STONEY) {
                        for (bank = 5; bank <= 8; bank++)
                                acp_set_sram_bank_state(intr_data->acp_mmio,
@@ -774,11 +767,13 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
 {
        int status;
        uint64_t size;
+       u32 val = 0;
        struct page *pg;
        struct snd_pcm_runtime *runtime;
        struct audio_substream_data *rtd;
        struct snd_soc_pcm_runtime *prtd = substream->private_data;
-       struct audio_drv_data *adata = dev_get_drvdata(prtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+       struct audio_drv_data *adata = dev_get_drvdata(component->dev);
 
        runtime = substream->runtime;
        rtd = runtime->private_data;
@@ -786,6 +781,14 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
        if (WARN_ON(!rtd))
                return -EINVAL;
 
+       if (adata->asic_type == CHIP_STONEY) {
+               val = acp_reg_read(adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       val |= ACP_I2S_SP_16BIT_RESOLUTION_EN;
+               else
+                       val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN;
+               acp_reg_write(val, adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN);
+       }
        size = params_buffer_bytes(params);
        status = snd_pcm_lib_malloc_pages(substream, size);
        if (status < 0)
@@ -857,11 +860,11 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
        bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (bytescount > rtd->renderbytescount)
-                       bytescount = bytescount - rtd->renderbytescount;
+               if (bytescount > rtd->i2ssp_renderbytescount)
+                       bytescount = bytescount - rtd->i2ssp_renderbytescount;
        } else {
-               if (bytescount > rtd->capturebytescount)
-                       bytescount = bytescount - rtd->capturebytescount;
+               if (bytescount > rtd->i2ssp_capturebytescount)
+                       bytescount = bytescount - rtd->i2ssp_capturebytescount;
        }
        pos = do_div(bytescount, buffersize);
        return bytes_to_frames(runtime, pos);
@@ -907,6 +910,7 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *prtd = substream->private_data;
        struct audio_substream_data *rtd = runtime->private_data;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
 
        if (!rtd)
                return -EINVAL;
@@ -917,14 +921,14 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
                bytescount = acp_get_byte_count(rtd->acp_mmio,
                                                substream->stream);
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-                       if (rtd->renderbytescount == 0)
-                               rtd->renderbytescount = bytescount;
+                       if (rtd->i2ssp_renderbytescount == 0)
+                               rtd->i2ssp_renderbytescount = bytescount;
                        acp_dma_start(rtd->acp_mmio,
                                                SYSRAM_TO_ACP_CH_NUM, false);
                        while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) &
                                                BIT(SYSRAM_TO_ACP_CH_NUM)) {
                                if (!loops--) {
-                                       dev_err(prtd->platform->dev,
+                                       dev_err(component->dev,
                                                "acp dma start timeout\n");
                                        return -ETIMEDOUT;
                                }
@@ -935,8 +939,8 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
                                        ACP_TO_I2S_DMA_CH_NUM, true);
 
                } else {
-                       if (rtd->capturebytescount == 0)
-                               rtd->capturebytescount = bytescount;
+                       if (rtd->i2ssp_capturebytescount == 0)
+                               rtd->i2ssp_capturebytescount = bytescount;
                        acp_dma_start(rtd->acp_mmio,
                                            I2S_TO_ACP_DMA_CH_NUM, true);
                }
@@ -951,13 +955,17 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
                 * completes : SYSRAM_TO_ACP_CH_NUM / ACP_TO_SYSRAM_CH_NUM
                 */
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       ret = acp_dma_stop(rtd->acp_mmio,
+                                               SYSRAM_TO_ACP_CH_NUM);
                        ret = acp_dma_stop(rtd->acp_mmio,
                                        ACP_TO_I2S_DMA_CH_NUM);
-                       rtd->renderbytescount = 0;
+                       rtd->i2ssp_renderbytescount = 0;
                } else {
                        ret = acp_dma_stop(rtd->acp_mmio,
                                        I2S_TO_ACP_DMA_CH_NUM);
-                       rtd->capturebytescount = 0;
+                       ret = acp_dma_stop(rtd->acp_mmio,
+                                               ACP_TO_SYSRAM_CH_NUM);
+                       rtd->i2ssp_capturebytescount = 0;
                }
                break;
        default:
@@ -970,7 +978,8 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
 static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
-       struct audio_drv_data *adata = dev_get_drvdata(rtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct audio_drv_data *adata = dev_get_drvdata(component->dev);
 
        switch (adata->asic_type) {
        case CHIP_STONEY:
@@ -987,7 +996,7 @@ static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
                break;
        }
        if (ret < 0)
-               dev_err(rtd->platform->dev,
+               dev_err(component->dev,
                                "buffer preallocation failer error:%d\n", ret);
        return ret;
 }
@@ -998,12 +1007,13 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct audio_substream_data *rtd = runtime->private_data;
        struct snd_soc_pcm_runtime *prtd = substream->private_data;
-       struct audio_drv_data *adata = dev_get_drvdata(prtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
+       struct audio_drv_data *adata = dev_get_drvdata(component->dev);
 
        kfree(rtd);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               adata->play_stream = NULL;
+               adata->play_i2ssp_stream = NULL;
                /* For Stoney, Memory gating is disabled,i.e SRAM Banks
                 * won't be turned off. The default state for SRAM banks is ON.
                 * Setting SRAM bank state code skipped for STONEY platform.
@@ -1015,7 +1025,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
                                false);
                }
        } else  {
-               adata->capture_stream = NULL;
+               adata->capture_i2ssp_stream = NULL;
                if (adata->asic_type != CHIP_STONEY) {
                        for (bank = 5; bank <= 8; bank++)
                                acp_set_sram_bank_state(adata->acp_mmio, bank,
@@ -1026,7 +1036,7 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
        /* Disable ACP irq, when the current stream is being closed and
         * another stream is also not active.
        */
-       if (!adata->play_stream && !adata->capture_stream)
+       if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream)
                acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
 
        return 0;
@@ -1044,7 +1054,8 @@ static const struct snd_pcm_ops acp_dma_ops = {
        .prepare = acp_dma_prepare,
 };
 
-static struct snd_soc_platform_driver acp_asoc_platform = {
+static struct snd_soc_component_driver acp_asoc_platform = {
+       .name = DRV_NAME,
        .ops = &acp_dma_ops,
        .pcm_new = acp_dma_new,
 };
@@ -1076,8 +1087,9 @@ static int acp_audio_probe(struct platform_device *pdev)
         * and device doesn't generate any interrupts.
         */
 
-       audio_drv_data->play_stream = NULL;
-       audio_drv_data->capture_stream = NULL;
+       audio_drv_data->play_i2ssp_stream = NULL;
+       audio_drv_data->capture_i2ssp_stream = NULL;
+
        audio_drv_data->asic_type =  *pdata;
 
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -1102,7 +1114,8 @@ static int acp_audio_probe(struct platform_device *pdev)
                return status;
        }
 
-       status = snd_soc_register_platform(&pdev->dev, &acp_asoc_platform);
+       status = devm_snd_soc_register_component(&pdev->dev,
+                                               &acp_asoc_platform, NULL, 0);
        if (status != 0) {
                dev_err(&pdev->dev, "Fail to register ALSA platform device\n");
                return status;
@@ -1123,7 +1136,6 @@ static int acp_audio_remove(struct platform_device *pdev)
        status = acp_deinit(adata->acp_mmio);
        if (status)
                dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);
-       snd_soc_unregister_platform(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        return 0;
@@ -1141,7 +1153,7 @@ static int acp_pcm_resume(struct device *dev)
                return status;
        }
 
-       if (adata->play_stream && adata->play_stream->runtime) {
+       if (adata->play_i2ssp_stream && adata->play_i2ssp_stream->runtime) {
                /* For Stoney, Memory gating is disabled,i.e SRAM Banks
                 * won't be turned off. The default state for SRAM banks is ON.
                 * Setting SRAM bank state code skipped for STONEY platform.
@@ -1152,17 +1164,17 @@ static int acp_pcm_resume(struct device *dev)
                                                true);
                }
                config_acp_dma(adata->acp_mmio,
-                       adata->play_stream->runtime->private_data,
+                       adata->play_i2ssp_stream->runtime->private_data,
                        adata->asic_type);
        }
-       if (adata->capture_stream && adata->capture_stream->runtime) {
+       if (adata->capture_i2ssp_stream && adata->capture_i2ssp_stream->runtime) {
                if (adata->asic_type != CHIP_STONEY) {
                        for (bank = 5; bank <= 8; bank++)
                                acp_set_sram_bank_state(adata->acp_mmio, bank,
                                                true);
                }
                config_acp_dma(adata->acp_mmio,
-                       adata->capture_stream->runtime->private_data,
+                       adata->capture_i2ssp_stream->runtime->private_data,
                        adata->asic_type);
        }
        acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
index 941aed6bb364ff122d9f64a6f536a47b60f290cb..b79b922b08a00600e926f77637009ab1924989df 100644 (file)
@@ -71,9 +71,9 @@ static int cz_init(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
        struct snd_soc_card *card;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *codec;
 
-       codec = rtd->codec;
+       codec = rtd->codec_dai->component;
        card = rtd->card;
 
        ret = snd_soc_card_jack_new(card, "Headset Jack",
index ecb458935d1e82607f907c9105ccaac20411f8ce..ba01510eb818b7079fc633d575199daf436fb449 100644 (file)
@@ -70,6 +70,8 @@
 #define CAPTURE_END_DMA_DESCR_CH15 7
 
 #define mmACP_I2S_16BIT_RESOLUTION_EN       0x5209
+#define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01
+#define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02
 enum acp_dma_priority_level {
        /* 0x0 Specifies the DMA channel is given normal priority */
        ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
@@ -84,14 +86,14 @@ struct audio_substream_data {
        u16 num_of_pages;
        u16 direction;
        uint64_t size;
-       u64 renderbytescount;
-       u64 capturebytescount;
+       u64 i2ssp_renderbytescount;
+       u64 i2ssp_capturebytescount;
        void __iomem *acp_mmio;
 };
 
 struct audio_drv_data {
-       struct snd_pcm_substream *play_stream;
-       struct snd_pcm_substream *capture_stream;
+       struct snd_pcm_substream *play_i2ssp_stream;
+       struct snd_pcm_substream *capture_i2ssp_stream;
        void __iomem *acp_mmio;
        u32 asic_type;
 };
index ebabed69f0e67d3c74bffdfee4726acb8044c51f..3d70061901a0795018ce4bc8dcf9a85dae7e0c2b 100644 (file)
@@ -32,6 +32,7 @@ struct atmel_classd {
        struct regmap *regmap;
        struct clk *pclk;
        struct clk *gclk;
+       struct device *dev;
        int irq;
        const struct atmel_classd_pdata *pdata;
 };
@@ -165,7 +166,7 @@ atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream,
        struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
 
        if (params_physical_width(params) != 16) {
-               dev_err(rtd->platform->dev,
+               dev_err(dd->dev,
                        "only supports 16-bit audio data\n");
                return -EINVAL;
        }
@@ -247,9 +248,9 @@ static const char * const pwm_type[] = {
        "Single ended", "Differential"
 };
 
-static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
+static int atmel_classd_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
        struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
        const struct atmel_classd_pdata *pdata = dd->pdata;
        u32 mask, val;
@@ -283,16 +284,16 @@ static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
                default:
                        val |= (CLASSD_MR_NOVR_VAL_10NS
                                << CLASSD_MR_NOVR_VAL_SHIFT);
-                       dev_warn(codec->dev,
+                       dev_warn(component->dev,
                                "non-overlapping value %d is invalid, the default value 10 is specified\n",
                                pdata->non_overlap_time);
                        break;
                }
        }
 
-       snd_soc_update_bits(codec, CLASSD_MR, mask, val);
+       snd_soc_component_update_bits(component, CLASSD_MR, mask, val);
 
-       dev_info(codec->dev,
+       dev_info(component->dev,
                "PWM modulation type is %s, non-overlapping is %s\n",
                pwm_type[pdata->pwm_type],
                pdata->non_overlap_enable?"enabled":"disabled");
@@ -300,21 +301,23 @@ static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int atmel_classd_codec_resume(struct snd_soc_codec *codec)
+static int atmel_classd_component_resume(struct snd_soc_component *component)
 {
-       struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
        struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
 
        return regcache_sync(dd->regmap);
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_classd = {
-       .probe          = atmel_classd_codec_probe,
-       .resume         = atmel_classd_codec_resume,
-       .component_driver = {
-               .controls               = atmel_classd_snd_controls,
-               .num_controls           = ARRAY_SIZE(atmel_classd_snd_controls),
-       },
+static struct snd_soc_component_driver soc_component_dev_classd = {
+       .probe                  = atmel_classd_component_probe,
+       .resume                 = atmel_classd_component_resume,
+       .controls               = atmel_classd_snd_controls,
+       .num_controls           = ARRAY_SIZE(atmel_classd_snd_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /* codec dai component */
@@ -330,7 +333,7 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream,
 static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
        int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u32 mask, val;
 
        mask = CLASSD_MR_LMUTE_MASK | CLASSD_MR_RMUTE_MASK;
@@ -340,7 +343,7 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
        else
                val = 0;
 
-       snd_soc_update_bits(codec, CLASSD_MR, mask, val);
+       snd_soc_component_update_bits(component, CLASSD_MR, mask, val);
 
        return 0;
 }
@@ -379,7 +382,7 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int fs;
        int i, best, best_val, cur_val, ret;
        u32 mask, val;
@@ -397,7 +400,7 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
                }
        }
 
-       dev_dbg(codec->dev,
+       dev_dbg(component->dev,
                "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n",
                sample_rates[best].rate, sample_rates[best].gclk_rate);
 
@@ -411,7 +414,7 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
        val = (sample_rates[best].dsp_clk << CLASSD_INTPMR_DSP_CLK_FREQ_SHIFT)
        | (sample_rates[best].sample_rate << CLASSD_INTPMR_FRAME_SHIFT);
 
-       snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val);
+       snd_soc_component_update_bits(component, CLASSD_INTPMR, mask, val);
 
        return clk_prepare_enable(dd->gclk);
 }
@@ -429,9 +432,9 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream,
 static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
                                        struct snd_soc_dai *codec_dai)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
-       snd_soc_update_bits(codec, CLASSD_MR,
+       snd_soc_component_update_bits(component, CLASSD_MR,
                                CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK,
                                (CLASSD_MR_LEN_DIS << CLASSD_MR_LEN_SHIFT)
                                |(CLASSD_MR_REN_DIS << CLASSD_MR_REN_SHIFT));
@@ -442,7 +445,7 @@ static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
 static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream,
                                        int cmd, struct snd_soc_dai *codec_dai)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u32 mask, val;
 
        mask = CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK;
@@ -463,7 +466,7 @@ static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, CLASSD_MR, mask, val);
+       snd_soc_component_update_bits(component, CLASSD_MR, mask, val);
 
        return 0;
 }
@@ -580,13 +583,11 @@ static int atmel_classd_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        io_base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(io_base)) {
-               ret =  PTR_ERR(io_base);
-               dev_err(dev, "failed to remap register memory: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(io_base))
+               return PTR_ERR(io_base);
 
        dd->phy_base = res->start;
+       dd->dev = dev;
 
        dd->regmap = devm_regmap_init_mmio(dev, io_base,
                                        &atmel_classd_regmap_config);
@@ -612,10 +613,10 @@ static int atmel_classd_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret = snd_soc_register_codec(dev, &soc_codec_dev_classd,
+       ret = devm_snd_soc_register_component(dev, &soc_component_dev_classd,
                                        &atmel_classd_codec_dai, 1);
        if (ret) {
-               dev_err(dev, "could not register codec: %d\n", ret);
+               dev_err(dev, "could not register component: %d\n", ret);
                return ret;
        }
 
@@ -643,13 +644,11 @@ static int atmel_classd_probe(struct platform_device *pdev)
        return 0;
 
 unregister_codec:
-       snd_soc_unregister_codec(dev);
        return ret;
 }
 
 static int atmel_classd_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
index 91b7069c34994b8248d44218066e0ff20124a1bb..99ca23d527c9ead39bf8564a9dc57b8769548ec9 100644 (file)
@@ -393,7 +393,7 @@ static const struct snd_pcm_ops atmel_pcm_ops = {
        .mmap           = atmel_pcm_mmap,
 };
 
-static struct snd_soc_platform_driver atmel_soc_platform = {
+static struct snd_soc_component_driver atmel_soc_platform = {
        .ops            = &atmel_pcm_ops,
        .pcm_new        = atmel_pcm_new,
        .pcm_free       = atmel_pcm_free,
@@ -401,13 +401,13 @@ static struct snd_soc_platform_driver atmel_soc_platform = {
 
 int atmel_pcm_pdc_platform_register(struct device *dev)
 {
-       return snd_soc_register_platform(dev, &atmel_soc_platform);
+       return devm_snd_soc_register_component(dev, &atmel_soc_platform,
+                                              NULL, 0);
 }
 EXPORT_SYMBOL(atmel_pcm_pdc_platform_register);
 
 void atmel_pcm_pdc_platform_unregister(struct device *dev)
 {
-       snd_soc_unregister_platform(dev);
 }
 EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister);
 
index 8e3d34be9e690878be8c084ed9dfb1ff79a7b087..915c2b064de1fcfca0fab6a8acabe648848422bc 100644 (file)
@@ -32,6 +32,7 @@ struct atmel_pdmic {
        struct regmap *regmap;
        struct clk *pclk;
        struct clk *gclk;
+       struct device *dev;
        int irq;
        struct snd_pcm_substream *substream;
        const struct atmel_pdmic_pdata *pdata;
@@ -206,7 +207,7 @@ atmel_pdmic_platform_configure_dma(struct snd_pcm_substream *substream,
        ret = snd_hwparams_to_dma_slave_config(substream, params,
                                               slave_config);
        if (ret) {
-               dev_err(rtd->platform->dev,
+               dev_err(dd->dev,
                        "hw params to dma slave configure failed\n");
                return ret;
        }
@@ -288,14 +289,14 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
 static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int dgain_val, scale_val;
        int i;
 
-       dgain_val = (snd_soc_read(codec, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
+       dgain_val = (snd_soc_component_read32(component, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
                    >> PDMIC_DSPR1_DGAIN_SHIFT;
 
-       scale_val = (snd_soc_read(codec, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
+       scale_val = (snd_soc_component_read32(component, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
                    >> PDMIC_DSPR0_SCALE_SHIFT;
 
        for (i = 0; i < ARRAY_SIZE(mic_gain_table); i++) {
@@ -312,7 +313,7 @@ static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int max = mc->max;
        unsigned int val;
        int ret;
@@ -322,12 +323,12 @@ static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
        if (val > max)
                return -EINVAL;
 
-       ret = snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
+       ret = snd_soc_component_update_bits(component, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
                         mic_gain_table[val].dgain << PDMIC_DSPR1_DGAIN_SHIFT);
        if (ret < 0)
                return ret;
 
-       ret = snd_soc_update_bits(codec, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
+       ret = snd_soc_component_update_bits(component, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
                         mic_gain_table[val].scale << PDMIC_DSPR0_SCALE_SHIFT);
        if (ret < 0)
                return ret;
@@ -346,23 +347,25 @@ SOC_SINGLE("High Pass Filter Switch", PDMIC_DSPR0,
 SOC_SINGLE("SINCC Filter Switch", PDMIC_DSPR0, PDMIC_DSPR0_SINBYP_SHIFT, 1, 1),
 };
 
-static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec)
+static int atmel_pdmic_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
        struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
 
-       snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
+       snd_soc_component_update_bits(component, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
                     (u32)(dd->pdata->mic_offset << PDMIC_DSPR1_OFFSET_SHIFT));
 
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_pdmic = {
-       .probe          = atmel_pdmic_codec_probe,
-       .component_driver = {
-               .controls               = atmel_pdmic_snd_controls,
-               .num_controls           = ARRAY_SIZE(atmel_pdmic_snd_controls),
-       },
+static struct snd_soc_component_driver soc_component_dev_pdmic = {
+       .probe                  = atmel_pdmic_component_probe,
+       .controls               = atmel_pdmic_snd_controls,
+       .num_controls           = ARRAY_SIZE(atmel_pdmic_snd_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /* codec dai component */
@@ -375,7 +378,7 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        unsigned int rate_min = substream->runtime->hw.rate_min;
        unsigned int rate_max = substream->runtime->hw.rate_max;
        int fs = params_rate(params);
@@ -385,13 +388,13 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
        u32 mr_val, dspr0_val, pclk_prescal, gclk_prescal;
 
        if (params_channels(params) != 1) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "only supports one channel\n");
                return -EINVAL;
        }
 
        if ((fs < rate_min) || (fs > rate_max)) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "sample rate is %dHz, min rate is %dHz, max rate is %dHz\n",
                        fs, rate_min, rate_max);
 
@@ -436,10 +439,10 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
                mr_val |= PDMIC_MR_CLKS_PCK << PDMIC_MR_CLKS_SHIFT;
        }
 
-       snd_soc_update_bits(codec, PDMIC_MR,
+       snd_soc_component_update_bits(component, PDMIC_MR,
                PDMIC_MR_PRESCAL_MASK | PDMIC_MR_CLKS_MASK, mr_val);
 
-       snd_soc_update_bits(codec, PDMIC_DSPR0,
+       snd_soc_component_update_bits(component, PDMIC_DSPR0,
                PDMIC_DSPR0_OSR_MASK | PDMIC_DSPR0_SIZE_MASK, dspr0_val);
 
        return 0;
@@ -448,9 +451,9 @@ atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
 static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream,
                                        struct snd_soc_dai *codec_dai)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
-       snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
+       snd_soc_component_update_bits(component, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
                            PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);
 
        return 0;
@@ -459,7 +462,7 @@ static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream,
 static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream,
                                        int cmd, struct snd_soc_dai *codec_dai)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u32 val;
 
        switch (cmd) {
@@ -477,7 +480,7 @@ static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);
+       snd_soc_component_update_bits(component, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);
 
        return 0;
 }
@@ -596,6 +599,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        dd->pdata = pdata;
+       dd->dev = dev;
 
        dd->irq = platform_get_irq(pdev, 0);
        if (dd->irq < 0) {
@@ -629,11 +633,8 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        io_base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(io_base)) {
-               ret = PTR_ERR(io_base);
-               dev_err(dev, "failed to remap register memory: %d\n", ret);
-               return ret;
-       }
+       if (IS_ERR(io_base))
+               return PTR_ERR(io_base);
 
        dd->phy_base = res->start;
 
@@ -679,10 +680,10 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
        /* register codec and codec dai */
        atmel_pdmic_codec_dai.capture.rate_min = rate_min;
        atmel_pdmic_codec_dai.capture.rate_max = rate_max;
-       ret = snd_soc_register_codec(dev, &soc_codec_dev_pdmic,
+       ret = devm_snd_soc_register_component(dev, &soc_component_dev_pdmic,
                                     &atmel_pdmic_codec_dai, 1);
        if (ret) {
-               dev_err(dev, "could not register codec: %d\n", ret);
+               dev_err(dev, "could not register component: %d\n", ret);
                return ret;
        }
 
@@ -710,13 +711,11 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
        return 0;
 
 unregister_codec:
-       snd_soc_unregister_codec(dev);
        return ret;
 }
 
 static int atmel_pdmic_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
index 6a035ca0f521f71a17710dc6934d0a836338b372..fb650659c3a3ef229ca03b9b51744834b8a34500 100644 (file)
@@ -32,6 +32,8 @@
 
 /*#define PCM_DEBUG*/
 
+#define DRV_NAME "dbdma2"
+
 #define MSG(x...)      printk(KERN_INFO "au1xpsc_pcm: " x)
 #ifdef PCM_DEBUG
 #define DBG            MSG
@@ -187,8 +189,8 @@ out:
 static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss)
 {
        struct snd_soc_pcm_runtime *rtd = ss->private_data;
-       struct au1xpsc_audio_dmadata *pcd =
-                               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct au1xpsc_audio_dmadata *pcd = snd_soc_component_get_drvdata(component);
        return &pcd[ss->stream];
 }
 
@@ -327,7 +329,8 @@ static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
 }
 
 /* au1xpsc audio platform */
-static struct snd_soc_platform_driver au1xpsc_soc_platform = {
+static struct snd_soc_component_driver au1xpsc_soc_component = {
+       .name           = DRV_NAME,
        .ops            = &au1xpsc_pcm_ops,
        .pcm_new        = au1xpsc_pcm_new,
 };
@@ -344,8 +347,8 @@ static int au1xpsc_pcm_drvprobe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dmadata);
 
-       return devm_snd_soc_register_platform(&pdev->dev,
-                                             &au1xpsc_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev,
+                                       &au1xpsc_soc_component, NULL, 0);
 }
 
 static struct platform_driver au1xpsc_pcm_driver = {
index 19457e2b351ec158433497f6ca4d65c7e11c5db3..efff1e293a1b279b3e39835c75ee323ed2349ea2 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "psc.h"
 
+#define DRV_NAME "au1x_dma"
+
 struct pcm_period {
        u32 start;
        u32 relative_end;       /* relative to start of buffer */
@@ -174,7 +176,8 @@ static const struct snd_pcm_hardware alchemy_pcm_hardware = {
 static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss)
 {
        struct snd_soc_pcm_runtime *rtd = ss->private_data;
-       return snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       return snd_soc_component_get_drvdata(component);
 }
 
 static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss)
@@ -297,7 +300,8 @@ static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
-static struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
+static struct snd_soc_component_driver alchemy_pcm_soc_component = {
+       .name           = DRV_NAME,
        .ops            = &alchemy_pcm_ops,
        .pcm_new        = alchemy_pcm_new,
 };
@@ -312,8 +316,8 @@ static int alchemy_pcm_drvprobe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, ctx);
 
-       return devm_snd_soc_register_platform(&pdev->dev,
-                                             &alchemy_pcm_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev,
+                                       &alchemy_pcm_soc_component, NULL, 0);
 }
 
 static struct platform_driver alchemy_pcmdma_driver = {
index d616e096462e7dac67843023e7951eff1084afa3..123ecf5479d7a71aed47b80228461882a5c1c68d 100644 (file)
@@ -820,7 +820,7 @@ static int cygnus_dma_new(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
-static struct snd_soc_platform_driver cygnus_soc_platform = {
+static struct snd_soc_component_driver cygnus_soc_platform = {
        .ops            = &cygnus_pcm_ops,
        .pcm_new        = cygnus_dma_new,
        .pcm_free       = cygnus_dma_free_dma_buffers,
@@ -840,7 +840,8 @@ int cygnus_soc_platform_register(struct device *dev,
                return rc;
        }
 
-       rc = snd_soc_register_platform(dev, &cygnus_soc_platform);
+       rc = devm_snd_soc_register_component(dev, &cygnus_soc_platform,
+                                            NULL, 0);
        if (rc) {
                dev_err(dev, "%s failed\n", __func__);
                return rc;
@@ -851,8 +852,6 @@ int cygnus_soc_platform_register(struct device *dev,
 
 int cygnus_soc_platform_unregister(struct device *dev)
 {
-       snd_soc_unregister_platform(dev);
-
        return 0;
 }
 
index abafadc0b534b4fe7d87a02af3d92e5762227d21..b733f144635308a0e87b78e2ab3774b1d4b828f0 100644 (file)
@@ -1281,7 +1281,7 @@ static int cygnus_ssp_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *child_node;
-       struct resource *res = pdev->resource;
+       struct resource *res;
        struct cygnus_audio *cygaud;
        int err = -EINVAL;
        int node_count;
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
deleted file mode 100644 (file)
index 6410aa2..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-config SND_BF5XX_I2S
-       tristate "SoC I2S Audio for the ADI Blackfin chip"
-       depends on BLACKFIN
-       select SND_BF5XX_SOC_SPORT if !BF60x
-       select SND_BF6XX_SOC_SPORT if BF60x
-       help
-         Say Y or M if you want to add support for codecs attached to
-         the Blackfin SPORT (synchronous serial ports) interface in I2S
-         mode (supports single stereo In/Out).
-         You will also need to select the audio interfaces to support below.
-
-config SND_BF5XX_SOC_SSM2602
-       tristate "SoC SSM2602 Audio Codec Add-On Card support"
-       depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
-       select SND_BF5XX_SOC_I2S if !BF60x
-       select SND_BF6XX_SOC_I2S if BF60x
-       select SND_SOC_SSM2602_SPI if SPI_MASTER
-       select SND_SOC_SSM2602_I2C if I2C
-       help
-         Say Y if you want to add support for the Analog Devices
-         SSM2602 Audio Codec Add-On Card.
-
-config SND_SOC_BFIN_EVAL_ADAU1701
-       tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
-       depends on SND_BF5XX_I2S && I2C
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_ADAU1701
-       help
-         Say Y if you want to add support for the Analog Devices EVAL-ADAU1701MINIZ
-         board connected to one of the Blackfin evaluation boards like the
-         BF5XX-STAMP or BF5XX-EZKIT.
-
-config SND_SOC_BFIN_EVAL_ADAU1373
-       tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards"
-       depends on SND_BF5XX_I2S && I2C
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_ADAU1373
-       help
-         Say Y if you want to add support for the Analog Devices EVAL-ADAU1373
-         board connected to one of the Blackfin evaluation boards like the
-         BF5XX-STAMP or BF5XX-EZKIT.
-
-         Note: This driver assumes that first ADAU1373 DAI is connected to the
-         first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAU1X61
-       tristate "Support for the EVAL-ADAU1X61 board on Blackfin eval boards"
-       depends on SND_BF5XX_I2S && I2C
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_ADAU1761_I2C
-       help
-         Say Y if you want to add support for the Analog Devices EVAL-ADAU1X61
-         board connected to one of the Blackfin evaluation boards like the
-         BF5XX-STAMP or BF5XX-EZKIT.
-
-         Note: This driver assumes that the ADAU1X61 is connected to the
-         first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAU1X81
-       tristate "Support for the EVAL-ADAU1X81 boards on Blackfin eval boards"
-       depends on SND_BF5XX_I2S && I2C
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_ADAU1781_I2C
-       help
-         Say Y if you want to add support for the Analog Devices EVAL-ADAU1X81
-         board connected to one of the Blackfin evaluation boards like the
-         BF5XX-STAMP or BF5XX-EZKIT.
-
-         Note: This driver assumes that the ADAU1X81 is connected to the
-         first SPORT port on the BF5XX board.
-
-config SND_SOC_BFIN_EVAL_ADAV80X
-       tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards"
-       depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_ADAV801 if SPI_MASTER
-       select SND_SOC_ADAV803 if I2C
-       help
-         Say Y if you want to add support for the Analog Devices EVAL-ADAV801 or
-         EVAL-ADAV803 board connected to one of the Blackfin evaluation boards
-         like the BF5XX-STAMP or BF5XX-EZKIT.
-
-         Note: This driver assumes that the ADAV80X digital record and playback
-         interfaces are connected to the first SPORT port on the BF5XX board.
-
-config SND_BF5XX_SOC_AD1836
-       tristate "SoC AD1836 Audio support for BF5xx"
-       depends on SND_BF5XX_I2S && SPI_MASTER
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_AD1836
-       help
-         Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD193X
-       tristate "SoC AD193X Audio support for Blackfin"
-       depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_AD193X_I2C if I2C
-       select SND_SOC_AD193X_SPI if SPI_MASTER
-       help
-         Say Y if you want to add support for AD193X codec on Blackfin.
-         This driver supports AD1936, AD1937, AD1938 and AD1939.
-
-config SND_BF5XX_SOC_AD73311
-       tristate "SoC AD73311 Audio support for Blackfin"
-       depends on SND_BF5XX_I2S
-       select SND_BF5XX_SOC_I2S
-       select SND_SOC_AD73311
-       help
-         Say Y if you want to add support for AD73311 codec on Blackfin.
-
-config SND_BFIN_AD73311_SE
-       int "PF pin for AD73311L Chip Select"
-       depends on SND_BF5XX_SOC_AD73311
-       default 4
-       help
-         Enter the GPIO used to control AD73311's SE pin. Acceptable
-         values are 0 to 7
-
-config SND_BF5XX_AC97
-       tristate "SoC AC97 Audio for the ADI BF5xx chip"
-       depends on BLACKFIN
-       select AC97_BUS
-       select SND_SOC_AC97_BUS
-       select SND_BF5XX_SOC_SPORT
-       select SND_BF5XX_SOC_AC97
-       help
-         Say Y or M if you want to add support for codecs attached to
-         the Blackfin SPORT (synchronous serial ports) interface in slot 16
-         mode (pseudo AC97 interface).
-         You will also need to select the audio interfaces to support below.
-
-         Note:
-         AC97 codecs which do not implement the slot-16 mode will not function
-         properly with this driver. This driver is known to work with the
-         Analog Devices line of AC97 codecs.
-
-config SND_BF5XX_MMAP_SUPPORT
-       bool "Enable MMAP Support"
-       depends on SND_BF5XX_AC97
-       default y
-       help
-         Say y if you want AC97 driver to support mmap mode.
-         We introduce an intermediate buffer to simulate mmap.
-
-config SND_BF5XX_MULTICHAN_SUPPORT
-       bool "Enable Multichannel Support"
-       depends on SND_BF5XX_AC97
-       default n
-       help
-         Say y if you want AC97 driver to support up to 5.1 channel audio.
-         this mode will consume much more memory for DMA.
-
-config SND_BF5XX_HAVE_COLD_RESET
-       bool "BOARD has COLD Reset GPIO"
-       depends on SND_BF5XX_AC97
-       default y if BFIN548_EZKIT
-       default n if !BFIN548_EZKIT
-
-config SND_BF5XX_RESET_GPIO_NUM
-       int "Set a GPIO for cold reset"
-       depends on SND_BF5XX_HAVE_COLD_RESET
-       range 0 159
-       default 19 if BFIN548_EZKIT
-       default 5 if BFIN537_STAMP
-       default 0
-       help
-         Set the correct GPIO for RESET the sound chip.
-
-config SND_BF5XX_SOC_AD1980
-       tristate "SoC AD1980/1 Audio support for BF5xx (Obsolete)"
-       depends on SND_BF5XX_AC97
-       select SND_BF5XX_SOC_AC97
-       select SND_SOC_AD1980
-       help
-         Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-         Warning:
-         Because Analog Devices Inc. discontinued the ad1980 sound chip since
-         Sep. 2009, this ad1980 driver is not maintained, tested and supported
-         by ADI now.
-
-config SND_BF5XX_SOC_SPORT
-       tristate
-
-config SND_BF6XX_SOC_SPORT
-       tristate
-
-config SND_BF5XX_SOC_I2S
-       tristate
-
-config SND_BF6XX_SOC_I2S
-       tristate
-
-config SND_BF5XX_SOC_AC97
-       tristate
-
-config SND_BF5XX_SPORT_NUM
-       int "Set a SPORT for Sound chip"
-       depends on (SND_BF5XX_SOC_SPORT || SND_BF6XX_SOC_SPORT)
-       range 0 3 if BF54x
-       range 0 1 if !BF54x
-       default 0
-       help
-         Set the correct SPORT for sound chip.
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
deleted file mode 100644 (file)
index ebeb6a9..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Blackfin Platform Support
-snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
-snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
-snd-soc-bf5xx-sport-objs := bf5xx-sport.o
-snd-soc-bf6xx-sport-objs := bf6xx-sport.o
-snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
-snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
-snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o
-
-obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
-obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
-obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o
-obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
-obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o
-
-# Blackfin Machine Support
-snd-ad1836-objs := bf5xx-ad1836.o
-snd-ad1980-objs := bf5xx-ad1980.o
-snd-ssm2602-objs := bf5xx-ssm2602.o
-snd-ad73311-objs := bf5xx-ad73311.o
-snd-ad193x-objs := bf5xx-ad193x.o
-snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o
-snd-soc-bfin-eval-adau1x61-objs := bfin-eval-adau1x61.o
-snd-soc-bfin-eval-adau1x81-objs := bfin-eval-adau1x81.o
-snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o
-snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o
-
-obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
-obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
-obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) += snd-soc-bfin-eval-adau1x61.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X81) += snd-soc-bfin-eval-adau1x81.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o
-obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
deleted file mode 100644 (file)
index 8c1d198..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ac97-pcm.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  DMA Driver for AC97 sound chip
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-ac97.h"
-#include "bf5xx-sport.h"
-
-static unsigned int ac97_chan_mask[] = {
-       SP_FL, /* Mono */
-       SP_STEREO, /* Stereo */
-       SP_2DOT1, /* 2.1*/
-       SP_QUAD,/*Quadraquic*/
-       SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
-       SP_5DOT1, /* 5.1 */
-};
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
-        snd_pcm_uframes_t count)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
-               sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
-               runtime->channels, count, chan_mask);
-               sport->tx_pos += runtime->period_size;
-               if (sport->tx_pos >= runtime->buffer_size)
-                       sport->tx_pos %= runtime->buffer_size;
-               sport->tx_delay_pos = sport->tx_pos;
-       } else {
-               bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
-               sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
-               runtime->channels, count);
-               sport->rx_pos += runtime->period_size;
-               if (sport->rx_pos >= runtime->buffer_size)
-                       sport->rx_pos %= runtime->buffer_size;
-       }
-}
-#endif
-
-static void bf5xx_dma_irq(void *data)
-{
-       struct snd_pcm_substream *pcm = data;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       struct snd_pcm_runtime *runtime = pcm->runtime;
-       struct sport_device *sport = runtime->private_data;
-       bf5xx_mmap_copy(pcm, runtime->period_size);
-       if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (sport->once == 0) {
-                       snd_pcm_period_elapsed(pcm);
-                       bf5xx_mmap_copy(pcm, runtime->period_size);
-                       sport->once = 1;
-               }
-       }
-#endif
-       snd_pcm_period_elapsed(pcm);
-}
-
-/* The memory size for pure pcm data is 128*1024 = 0x20000 bytes.
- * The total rx/tx buffer is for ac97 frame to hold all pcm data
- * is  0x20000 * sizeof(struct ac97_frame) / 4.
- */
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
-       .info                   = SNDRV_PCM_INFO_INTERLEAVED |
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-                                  SNDRV_PCM_INFO_MMAP |
-                                  SNDRV_PCM_INFO_MMAP_VALID |
-#endif
-                                  SNDRV_PCM_INFO_BLOCK_TRANSFER,
-
-       .period_bytes_min       = 32,
-       .period_bytes_max       = 0x10000,
-       .periods_min            = 1,
-       .periods_max            = PAGE_SIZE/32,
-       .buffer_bytes_max       = 0x20000, /* 128 kbytes */
-       .fifo_size              = 16,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       size_t size = bf5xx_pcm_hardware.buffer_bytes_max
-                       * sizeof(struct ac97_frame) / 4;
-
-       snd_pcm_lib_malloc_pages(substream, size);
-
-       return 0;
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               sport->once = 0;
-               if (runtime->dma_area)
-                       memset(runtime->dma_area, 0, runtime->buffer_size);
-               memset(sport->tx_dma_buf, 0, runtime->buffer_size *
-                       sizeof(struct ac97_frame));
-       } else
-               memset(sport->rx_dma_buf, 0, runtime->buffer_size *
-                       sizeof(struct ac97_frame));
-#endif
-       snd_pcm_lib_free_pages(substream);
-       return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-
-       /* An intermediate buffer is introduced for implementing mmap for
-        * SPORT working in TMD mode(include AC97).
-        */
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
-                       runtime->period_size * sizeof(struct ac97_frame));
-       } else {
-               sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
-                       runtime->period_size * sizeof(struct ac97_frame));
-       }
-#else
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_tx_dma(sport, runtime->dma_area, runtime->periods,
-                       runtime->period_size * sizeof(struct ac97_frame));
-       } else {
-               sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_rx_dma(sport, runtime->dma_area, runtime->periods,
-                       runtime->period_size * sizeof(struct ac97_frame));
-       }
-#endif
-       return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       int ret = 0;
-
-       pr_debug("%s enter\n", __func__);
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-                       bf5xx_mmap_copy(substream, runtime->period_size);
-                       sport->tx_delay_pos = 0;
-#endif
-                       sport_tx_start(sport);
-               } else
-                       sport_rx_start(sport);
-               break;
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-                       sport->tx_pos = 0;
-#endif
-                       sport_tx_stop(sport);
-               } else {
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-                       sport->rx_pos = 0;
-#endif
-                       sport_rx_stop(sport);
-               }
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       unsigned int curr;
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               curr = sport->tx_delay_pos;
-       else
-               curr = sport->rx_pos;
-#else
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               curr = sport_curr_offset_tx(sport) / sizeof(struct ac97_frame);
-       else
-               curr = sport_curr_offset_rx(sport) / sizeof(struct ac97_frame);
-
-#endif
-       return curr;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       int ret;
-
-       pr_debug("%s enter\n", __func__);
-       snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-
-       ret = snd_pcm_hw_constraint_integer(runtime,
-                                           SNDRV_PCM_HW_PARAM_PERIODS);
-       if (ret < 0)
-               goto out;
-
-       if (sport_handle != NULL)
-               runtime->private_data = sport_handle;
-       else {
-               pr_err("sport_handle is NULL\n");
-               return -1;
-       }
-       return 0;
-
- out:
-       return ret;
-}
-
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
-       struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       size_t size = vma->vm_end - vma->vm_start;
-       vma->vm_start = (unsigned long)runtime->dma_area;
-       vma->vm_end = vma->vm_start + size;
-       vma->vm_flags |=  VM_SHARED;
-       return 0 ;
-}
-#else
-static int bf5xx_pcm_copy(struct snd_pcm_substream *substream,
-                          int channel, unsigned long pos,
-                          void *buf, unsigned long count)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
-       struct ac97_frame *dst;
-
-       pr_debug("%s copy pos:0x%lx count:0x%lx\n",
-                       substream->stream ? "Capture" : "Playback", pos, count);
-       dst = (struct ac97_frame *)runtime->dma_area +
-               bytes_to_frames(runtime, pos);
-       count = bytes_to_frames(runtime, count);
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               bf5xx_pcm_to_ac97(dst, buf, count, chan_mask);
-       else
-               bf5xx_ac97_to_pcm(dst, buf, count);
-       return 0;
-}
-
-static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream,
-                               int channel, unsigned long pos,
-                               void __user *buf, unsigned long count)
-{
-       return bf5xx_pcm_copy(substream, channel, pos, (void *)buf, count);
-}
-#endif
-
-static const struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
-       .open           = bf5xx_pcm_open,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = bf5xx_pcm_hw_params,
-       .hw_free        = bf5xx_pcm_hw_free,
-       .prepare        = bf5xx_pcm_prepare,
-       .trigger        = bf5xx_pcm_trigger,
-       .pointer        = bf5xx_pcm_pointer,
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       .mmap           = bf5xx_pcm_mmap,
-#else
-       .copy_user      = bf5xx_pcm_copy_user,
-       .copy_kernel    = bf5xx_pcm_copy,
-#endif
-};
-
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       struct snd_soc_pcm_runtime *rtd = pcm->private_data;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-       size_t size = bf5xx_pcm_hardware.buffer_bytes_max
-                       * sizeof(struct ac97_frame) / 4;
-
-       buf->dev.type = SNDRV_DMA_TYPE_DEV;
-       buf->dev.dev = pcm->card->dev;
-       buf->private_data = NULL;
-       buf->area = dma_alloc_coherent(pcm->card->dev, size,
-                       &buf->addr, GFP_KERNEL);
-       if (!buf->area) {
-               pr_err("Failed to allocate dma memory\n");
-               pr_err("Please increase uncached DMA memory region\n");
-               return -ENOMEM;
-       }
-       buf->bytes = size;
-
-       pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
-                       buf->area, buf->bytes);
-
-       if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-               sport_handle->tx_buf = buf->area;
-       else
-               sport_handle->rx_buf = buf->area;
-
-/*
- * Need to allocate local buffer when enable
- * MMAP for SPORT working in TMD mode (include AC97).
- */
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (!sport_handle->tx_dma_buf) {
-                       sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
-                               size, &sport_handle->tx_dma_phy, GFP_KERNEL);
-                       if (!sport_handle->tx_dma_buf) {
-                               pr_err("Failed to allocate memory for tx dma buf - Please increase uncached DMA memory region\n");
-                               return -ENOMEM;
-                       } else
-                               memset(sport_handle->tx_dma_buf, 0, size);
-               } else
-                       memset(sport_handle->tx_dma_buf, 0, size);
-       } else {
-               if (!sport_handle->rx_dma_buf) {
-                       sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
-                               size, &sport_handle->rx_dma_phy, GFP_KERNEL);
-                       if (!sport_handle->rx_dma_buf) {
-                               pr_err("Failed to allocate memory for rx dma buf - Please increase uncached DMA memory region\n");
-                               return -ENOMEM;
-                       } else
-                               memset(sport_handle->rx_dma_buf, 0, size);
-               } else
-                       memset(sport_handle->rx_dma_buf, 0, size);
-       }
-#endif
-       return 0;
-}
-
-static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       struct snd_soc_pcm_runtime *rtd = pcm->private_data;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-       size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
-               sizeof(struct ac97_frame) / 4;
-#endif
-       for (stream = 0; stream < 2; stream++) {
-               substream = pcm->streams[stream].substream;
-               if (!substream)
-                       continue;
-
-               buf = &substream->dma_buffer;
-               if (!buf->area)
-                       continue;
-               dma_free_coherent(NULL, buf->bytes, buf->area, 0);
-               buf->area = NULL;
-#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (sport_handle->tx_dma_buf)
-                       dma_free_coherent(NULL, size, \
-                               sport_handle->tx_dma_buf, 0);
-               sport_handle->tx_dma_buf = NULL;
-       } else {
-
-               if (sport_handle->rx_dma_buf)
-                       dma_free_coherent(NULL, size, \
-                               sport_handle->rx_dma_buf, 0);
-               sport_handle->rx_dma_buf = NULL;
-       }
-#endif
-       }
-}
-
-static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       struct snd_pcm *pcm = rtd->pcm;
-       int ret;
-
-       pr_debug("%s enter\n", __func__);
-       ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
-       if (ret)
-               return ret;
-
-       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
-               ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_PLAYBACK);
-               if (ret)
-                       goto out;
-       }
-
-       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-               ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_CAPTURE);
-               if (ret)
-                       goto out;
-       }
- out:
-       return ret;
-}
-
-static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = {
-       .ops                    = &bf5xx_pcm_ac97_ops,
-       .pcm_new        = bf5xx_pcm_ac97_new,
-       .pcm_free       = bf5xx_pcm_free_dma_buffers,
-};
-
-static int bf5xx_soc_platform_probe(struct platform_device *pdev)
-{
-       return devm_snd_soc_register_platform(&pdev->dev,
-                                             &bf5xx_ac97_soc_platform);
-}
-
-static struct platform_driver bf5xx_pcm_driver = {
-       .driver = {
-                       .name = "bfin-ac97-pcm-audio",
-       },
-
-       .probe = bf5xx_soc_platform_probe,
-};
-
-module_platform_driver(bf5xx_pcm_driver);
-
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
deleted file mode 100644 (file)
index a040cfe..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * bf5xx-ac97.c -- AC97 support for the ADI blackfin chip.
- *
- * Author:     Roy Huang
- * Created:    11th. June 2007
- * Copyright:  Analog Device 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/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-ac97.h"
-
-/* Anomaly notes:
- *  05000250 - AD1980 is running in TDM mode and RFS/TFS are generated by SPORT
- *             contrtoller. But, RFSDIV and TFSDIV are always set to 16*16-1,
- *             while the max AC97 data size is 13*16. The DIV is always larger
- *             than data size. AD73311 and ad2602 are not running in TDM mode.
- *             AD1836 and AD73322 depend on external RFS/TFS only. So, this
- *             anomaly does not affect blackfin sound drivers.
-*/
-
-static struct sport_device *ac97_sport_handle;
-
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
-               size_t count, unsigned int chan_mask)
-{
-       while (count--) {
-               dst->ac97_tag = TAG_VALID;
-               if (chan_mask & SP_FL) {
-                       dst->ac97_pcm_r = *src++;
-                       dst->ac97_tag |= TAG_PCM_RIGHT;
-               }
-               if (chan_mask & SP_FR) {
-                       dst->ac97_pcm_l = *src++;
-                       dst->ac97_tag |= TAG_PCM_LEFT;
-
-               }
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-               if (chan_mask & SP_SR) {
-                       dst->ac97_sl = *src++;
-                       dst->ac97_tag |= TAG_PCM_SL;
-               }
-               if (chan_mask & SP_SL) {
-                       dst->ac97_sr = *src++;
-                       dst->ac97_tag |= TAG_PCM_SR;
-               }
-               if (chan_mask & SP_LFE) {
-                       dst->ac97_lfe = *src++;
-                       dst->ac97_tag |= TAG_PCM_LFE;
-               }
-               if (chan_mask & SP_FC) {
-                       dst->ac97_center = *src++;
-                       dst->ac97_tag |= TAG_PCM_CENTER;
-               }
-#endif
-               dst++;
-       }
-}
-EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
-
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
-               size_t count)
-{
-       while (count--) {
-               *(dst++) = src->ac97_pcm_l;
-               *(dst++) = src->ac97_pcm_r;
-               src++;
-       }
-}
-EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
-
-static unsigned int sport_tx_curr_frag(struct sport_device *sport)
-{
-       return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
-                       sport->tx_fragsize;
-}
-
-static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
-{
-       struct sport_device *sport = ac97_sport_handle;
-       int *cmd_count = sport->private_data;
-       int nextfrag = sport_tx_curr_frag(sport);
-       struct ac97_frame *nextwrite;
-
-       sport_incfrag(sport, &nextfrag, 1);
-
-       nextwrite = (struct ac97_frame *)(sport->tx_buf +
-                       nextfrag * sport->tx_fragsize);
-       pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
-               sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
-       nextwrite[cmd_count[nextfrag]].ac97_tag |= TAG_CMD;
-       nextwrite[cmd_count[nextfrag]].ac97_addr = addr;
-       nextwrite[cmd_count[nextfrag]].ac97_data = data;
-       ++cmd_count[nextfrag];
-       pr_debug("ac97_sport: Inserting %02x/%04x into fragment %d\n",
-                       addr >> 8, data, nextfrag);
-}
-
-static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
-       unsigned short reg)
-{
-       struct sport_device *sport_handle = ac97_sport_handle;
-       struct ac97_frame out_frame[2], in_frame[2];
-
-       pr_debug("%s enter 0x%x\n", __func__, reg);
-
-       /* When dma descriptor is enabled, the register should not be read */
-       if (sport_handle->tx_run || sport_handle->rx_run) {
-               pr_err("Could you send a mail to cliff.cai@analog.com "
-                               "to report this?\n");
-               return -EFAULT;
-       }
-
-       memset(&out_frame, 0, 2 * sizeof(struct ac97_frame));
-       memset(&in_frame, 0, 2 * sizeof(struct ac97_frame));
-       out_frame[0].ac97_tag = TAG_VALID | TAG_CMD;
-       out_frame[0].ac97_addr = ((reg << 8) | 0x8000);
-       sport_send_and_recv(sport_handle, (unsigned char *)&out_frame,
-                       (unsigned char *)&in_frame,
-                       2 * sizeof(struct ac97_frame));
-       return in_frame[1].ac97_data;
-}
-
-void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
-       unsigned short val)
-{
-       struct sport_device *sport_handle = ac97_sport_handle;
-
-       pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
-
-       if (sport_handle->tx_run) {
-               enqueue_cmd(ac97, (reg << 8), val); /* write */
-               enqueue_cmd(ac97, (reg << 8) | 0x8000, 0); /* read back */
-       } else {
-               struct ac97_frame frame;
-               memset(&frame, 0, sizeof(struct ac97_frame));
-               frame.ac97_tag = TAG_VALID | TAG_CMD;
-               frame.ac97_addr = (reg << 8);
-               frame.ac97_data = val;
-               sport_send_and_recv(sport_handle, (unsigned char *)&frame, \
-                               NULL, sizeof(struct ac97_frame));
-       }
-}
-
-static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
-{
-       struct sport_device *sport_handle = ac97_sport_handle;
-       u16 gpio = P_IDENT(sport_handle->pin_req[3]);
-
-       pr_debug("%s enter\n", __func__);
-
-       peripheral_free_list(sport_handle->pin_req);
-       gpio_request(gpio, "bf5xx-ac97");
-       gpio_direction_output(gpio, 1);
-       udelay(2);
-       gpio_set_value(gpio, 0);
-       udelay(1);
-       gpio_free(gpio);
-       peripheral_request_list(sport_handle->pin_req, "soc-audio");
-}
-
-static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
-{
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-       pr_debug("%s enter\n", __func__);
-
-       /* It is specified for bf548-ezkit */
-       gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 0);
-       /* Keep reset pin low for 1 ms */
-       mdelay(1);
-       gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
-       /* Wait for bit clock recover */
-       mdelay(1);
-#else
-       pr_info("%s: Not implemented\n", __func__);
-#endif
-}
-
-static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
-       .read   = bf5xx_ac97_read,
-       .write  = bf5xx_ac97_write,
-       .warm_reset     = bf5xx_ac97_warm_reset,
-       .reset  = bf5xx_ac97_cold_reset,
-};
-
-#ifdef CONFIG_PM
-static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-       pr_debug("%s : sport %d\n", __func__, dai->id);
-       if (!dai->active)
-               return 0;
-       if (dai->capture_active)
-               sport_rx_stop(sport);
-       if (dai->playback_active)
-               sport_tx_stop(sport);
-       return 0;
-}
-
-static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
-{
-       int ret;
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-       pr_debug("%s : sport %d\n", __func__, dai->id);
-       if (!dai->active)
-               return 0;
-
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-       ret = sport_set_multichannel(sport, 16, 0x3FF, 0x3FF, 1);
-#else
-       ret = sport_set_multichannel(sport, 16, 0x1F, 0x1F, 1);
-#endif
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               return -EBUSY;
-       }
-
-       ret = sport_config_rx(sport, IRFS, 0xF, 0, (16*16-1));
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               return -EBUSY;
-       }
-
-       ret = sport_config_tx(sport, ITFS, 0xF, 0, (16*16-1));
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-#else
-#define bf5xx_ac97_suspend     NULL
-#define bf5xx_ac97_resume      NULL
-#endif
-
-static struct snd_soc_dai_driver bfin_ac97_dai = {
-       .bus_control = true,
-       .suspend = bf5xx_ac97_suspend,
-       .resume = bf5xx_ac97_resume,
-       .playback = {
-               .stream_name = "AC97 Playback",
-               .channels_min = 2,
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-               .channels_max = 6,
-#else
-               .channels_max = 2,
-#endif
-               .rates = SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE, },
-       .capture = {
-               .stream_name = "AC97 Capture",
-               .channels_min = 2,
-               .channels_max = 2,
-               .rates = SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE, },
-};
-
-static const struct snd_soc_component_driver bfin_ac97_component = {
-       .name           = "bfin-ac97",
-};
-
-static int asoc_bfin_ac97_probe(struct platform_device *pdev)
-{
-       struct sport_device *sport_handle;
-       int ret;
-
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-       /* Request PB3 as reset pin */
-       ret = devm_gpio_request_one(&pdev->dev,
-                                   CONFIG_SND_BF5XX_RESET_GPIO_NUM,
-                                   GPIOF_OUT_INIT_HIGH, "SND_AD198x RESET");
-       if (ret) {
-               dev_err(&pdev->dev,
-                       "Failed to request GPIO_%d for reset: %d\n",
-                       CONFIG_SND_BF5XX_RESET_GPIO_NUM, ret);
-               return ret;
-       }
-#endif
-
-       sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
-               PAGE_SIZE);
-       if (!sport_handle) {
-               ret = -ENODEV;
-               goto sport_err;
-       }
-
-       /*SPORT works in TDM mode to simulate AC97 transfers*/
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-       ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 0x3FF, 1);
-#else
-       ret = sport_set_multichannel(sport_handle, 16, 0x1F, 0x1F, 1);
-#endif
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-               goto sport_config_err;
-       }
-
-       ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-               goto sport_config_err;
-       }
-
-       ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-               goto sport_config_err;
-       }
-
-       ret = snd_soc_set_ac97_ops(&bf5xx_ac97_ops);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
-               goto sport_config_err;
-       }
-
-       ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
-                                        &bfin_ac97_dai, 1);
-       if (ret) {
-               pr_err("Failed to register DAI: %d\n", ret);
-               goto sport_config_err;
-       }
-
-       ac97_sport_handle = sport_handle;
-
-       return 0;
-
-sport_config_err:
-       sport_done(sport_handle);
-sport_err:
-       snd_soc_set_ac97_ops(NULL);
-
-       return ret;
-}
-
-static int asoc_bfin_ac97_remove(struct platform_device *pdev)
-{
-       struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
-       snd_soc_unregister_component(&pdev->dev);
-       sport_done(sport_handle);
-       snd_soc_set_ac97_ops(NULL);
-
-       return 0;
-}
-
-static struct platform_driver asoc_bfin_ac97_driver = {
-       .driver = {
-                       .name = "bfin-ac97",
-       },
-
-       .probe = asoc_bfin_ac97_probe,
-       .remove = asoc_bfin_ac97_remove,
-};
-
-module_platform_driver(asoc_bfin_ac97_driver);
-
-MODULE_AUTHOR("Roy Huang");
-MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
deleted file mode 100644 (file)
index a680fdc..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-ac97.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_AC97_H
-#define _BF5XX_AC97_H
-
-/* Frame format in memory, only support stereo currently */
-struct ac97_frame {
-       u16 ac97_tag;           /* slot 0 */
-       u16 ac97_addr;          /* slot 1 */
-       u16 ac97_data;          /* slot 2 */
-       u16 ac97_pcm_l;         /*slot 3:front left*/
-       u16 ac97_pcm_r;         /*slot 4:front left*/
-#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-       u16 ac97_mdm_l1;
-       u16 ac97_center;        /*slot 6:center*/
-       u16 ac97_sl;            /*slot 7:surround left*/
-       u16 ac97_sr;            /*slot 8:surround right*/
-       u16 ac97_lfe;           /*slot 9:lfe*/
-#endif
-} __attribute__ ((packed));
-
-/* Speaker location */
-#define SP_FL          0x0001
-#define SP_FR          0x0010
-#define SP_FC          0x0002
-#define SP_LFE         0x0020
-#define SP_SL          0x0004
-#define SP_SR          0x0040
-
-#define SP_STEREO      (SP_FL | SP_FR)
-#define SP_2DOT1       (SP_FL | SP_FR | SP_LFE)
-#define SP_QUAD                (SP_FL | SP_FR | SP_SL | SP_SR)
-#define SP_5DOT1       (SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
-
-#define TAG_VALID              0x8000
-#define TAG_CMD                        0x6000
-#define TAG_PCM_LEFT           0x1000
-#define TAG_PCM_RIGHT          0x0800
-#define TAG_PCM_MDM_L1         0x0400
-#define TAG_PCM_CENTER         0x0200
-#define TAG_PCM_SL             0x0100
-#define TAG_PCM_SR             0x0080
-#define TAG_PCM_LFE            0x0040
-
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
-               size_t count, unsigned int chan_mask);
-
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
-               size_t count);
-
-#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
deleted file mode 100644 (file)
index 864df26..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad1836.c
- * Author:       Barry Song <Barry.Song@analog.com>
- *
- * Created:      Aug 4 2009
- * Description:  Board driver for ad1836 sound chip
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.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/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad1836.h"
-
-static struct snd_soc_card bf5xx_ad1836;
-
-static int bf5xx_ad1836_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
-       int ret = 0;
-
-       /* set cpu DAI channel mapping */
-       ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
-               channel_map, ARRAY_SIZE(channel_map), channel_map);
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
-                               SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad1836_dai = {
-       .name = "ad1836",
-       .stream_name = "AD1836",
-       .codec_dai_name = "ad1836-hifi",
-       .platform_name = "bfin-i2s-pcm-audio",
-       .dai_fmt = BF5XX_AD1836_DAIFMT,
-       .init = bf5xx_ad1836_init,
-};
-
-static struct snd_soc_card bf5xx_ad1836 = {
-       .name = "bfin-ad1836",
-       .owner = THIS_MODULE,
-       .dai_link = &bf5xx_ad1836_dai,
-       .num_links = 1,
-};
-
-static int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = &bf5xx_ad1836;
-       const char **link_name;
-       int ret;
-
-       link_name = pdev->dev.platform_data;
-       if (!link_name) {
-               dev_err(&pdev->dev, "No platform data supplied\n");
-               return -EINVAL;
-       }
-       bf5xx_ad1836_dai.cpu_dai_name = link_name[0];
-       bf5xx_ad1836_dai.codec_name = link_name[1];
-
-       card->dev = &pdev->dev;
-       platform_set_drvdata(pdev, card);
-
-       ret = devm_snd_soc_register_card(&pdev->dev, card);
-       if (ret)
-               dev_err(&pdev->dev, "Failed to register card\n");
-       return ret;
-}
-
-static struct platform_driver bf5xx_ad1836_driver = {
-       .driver = {
-               .name = "bfin-snd-ad1836",
-               .pm = &snd_soc_pm_ops,
-       },
-       .probe = bf5xx_ad1836_driver_probe,
-};
-module_platform_driver(bf5xx_ad1836_driver);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ALSA SoC AD1836 board driver");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
deleted file mode 100644 (file)
index 603ad1f..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad193x.c
- * Author:       Barry Song <Barry.Song@analog.com>
- *
- * Created:      Thur June 4 2009
- * Description:  Board driver for ad193x sound chip
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad193x.h"
-
-static struct snd_soc_card bf5xx_ad193x;
-
-static int bf5xx_ad193x_link_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int ret;
-
-       /* set the codec system clock for DAC and ADC */
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 24576000, SND_SOC_CLOCK_IN);
-       if (ret < 0)
-               return ret;
-
-       /* set codec DAI slots, 8 channels, all channels are enabled */
-       ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
-                               SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
-       {
-               .name = "ad193x",
-               .stream_name = "AD193X",
-               .cpu_dai_name = "bfin-i2s.0",
-               .codec_dai_name ="ad193x-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "spi0.5",
-               .dai_fmt = BF5XX_AD193X_DAIFMT,
-               .init = bf5xx_ad193x_link_init,
-       },
-       {
-               .name = "ad193x",
-               .stream_name = "AD193X",
-               .cpu_dai_name = "bfin-i2s.1",
-               .codec_dai_name ="ad193x-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "spi0.5",
-               .dai_fmt = BF5XX_AD193X_DAIFMT,
-               .init = bf5xx_ad193x_link_init,
-       },
-};
-
-static struct snd_soc_card bf5xx_ad193x = {
-       .name = "bfin-ad193x",
-       .owner = THIS_MODULE,
-       .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-       .num_links = 1,
-};
-
-static struct platform_device *bfxx_ad193x_snd_device;
-
-static int __init bf5xx_ad193x_init(void)
-{
-       int ret;
-
-       bfxx_ad193x_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!bfxx_ad193x_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x);
-       ret = platform_device_add(bfxx_ad193x_snd_device);
-
-       if (ret)
-               platform_device_put(bfxx_ad193x_snd_device);
-
-       return ret;
-}
-
-static void __exit bf5xx_ad193x_exit(void)
-{
-       platform_device_unregister(bfxx_ad193x_snd_device);
-}
-
-module_init(bf5xx_ad193x_init);
-module_exit(bf5xx_ad193x_exit);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ALSA SoC AD193X board driver");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
deleted file mode 100644 (file)
index 0fa81a5..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad1980.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  Board driver for AD1980/1 audio codec
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-/*
- * WARNING:
- *
- * Because Analog Devices Inc. discontinued the ad1980 sound chip since
- * Sep. 2009, this ad1980 driver is not maintained, tested and supported
- * by ADI now.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <asm/dma.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <linux/gpio.h>
-#include <asm/portmux.h>
-
-#include "bf5xx-ac97.h"
-
-static struct snd_soc_card bf5xx_board;
-
-static struct snd_soc_dai_link bf5xx_board_dai[] = {
-       {
-               .name = "AC97",
-               .stream_name = "AC97 HiFi",
-               .cpu_dai_name = "bfin-ac97.0",
-               .codec_dai_name = "ad1980-hifi",
-               .platform_name = "bfin-ac97-pcm-audio",
-               .codec_name = "ad1980",
-       },
-       {
-               .name = "AC97",
-               .stream_name = "AC97 HiFi",
-               .cpu_dai_name = "bfin-ac97.1",
-               .codec_dai_name = "ad1980-hifi",
-               .platform_name = "bfin-ac97-pcm-audio",
-               .codec_name = "ad1980",
-       },
-};
-
-static struct snd_soc_card bf5xx_board = {
-       .name = "bfin-ad1980",
-       .owner = THIS_MODULE,
-       .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-       .num_links = 1,
-};
-
-static struct platform_device *bf5xx_board_snd_device;
-
-static int __init bf5xx_board_init(void)
-{
-       int ret;
-
-       bf5xx_board_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!bf5xx_board_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board);
-       ret = platform_device_add(bf5xx_board_snd_device);
-
-       if (ret)
-               platform_device_put(bf5xx_board_snd_device);
-
-       return ret;
-}
-
-static void __exit bf5xx_board_exit(void)
-{
-       platform_device_unregister(bf5xx_board_snd_device);
-}
-
-module_init(bf5xx_board_init);
-module_exit(bf5xx_board_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board (Obsolete)");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
deleted file mode 100644 (file)
index 786bbdd..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ad73311.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Thur Sep 25 2008
- * Description:  Board driver for ad73311 sound chip
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "../codecs/ad73311.h"
-#include "bf5xx-sport.h"
-
-#if CONFIG_SND_BF5XX_SPORT_NUM == 0
-#define bfin_write_SPORT_TCR1  bfin_write_SPORT0_TCR1
-#define bfin_read_SPORT_TCR1   bfin_read_SPORT0_TCR1
-#define bfin_write_SPORT_TCR2  bfin_write_SPORT0_TCR2
-#define bfin_write_SPORT_TX16  bfin_write_SPORT0_TX16
-#define bfin_read_SPORT_STAT   bfin_read_SPORT0_STAT
-#else
-#define bfin_write_SPORT_TCR1  bfin_write_SPORT1_TCR1
-#define bfin_read_SPORT_TCR1   bfin_read_SPORT1_TCR1
-#define bfin_write_SPORT_TCR2  bfin_write_SPORT1_TCR2
-#define bfin_write_SPORT_TX16  bfin_write_SPORT1_TX16
-#define bfin_read_SPORT_STAT   bfin_read_SPORT1_STAT
-#endif
-
-#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
-
-static struct snd_soc_card bf5xx_ad73311;
-
-static int snd_ad73311_startup(void)
-{
-       pr_debug("%s enter\n", __func__);
-
-       /* Pull up SE pin on AD73311L */
-       gpio_set_value(GPIO_SE, 1);
-       return 0;
-}
-
-static int snd_ad73311_configure(void)
-{
-       unsigned short ctrl_regs[6];
-       unsigned short status = 0;
-       int count = 0;
-
-       /* DMCLK = MCLK = 16.384 MHz
-        * SCLK = DMCLK/8 = 2.048 MHz
-        * Sample Rate = DMCLK/2048  = 8 KHz
-        */
-       ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
-                       REGB_SCDIV(0) | REGB_DIRATE(0);
-       ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
-                       REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
-       ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
-                       REGD_IGS(2);
-       ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
-       ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
-       ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
-
-       local_irq_disable();
-       snd_ad73311_startup();
-       udelay(1);
-
-       bfin_write_SPORT_TCR1(TFSR);
-       bfin_write_SPORT_TCR2(0xF);
-       SSYNC();
-
-       /* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to
-        * FIFO before enable SPORT to transfer the data
-        */
-       for (count = 0; count < 6; count++)
-               bfin_write_SPORT_TX16(ctrl_regs[count]);
-       SSYNC();
-       bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);
-       SSYNC();
-
-       /* When TUVF is set, the data is already send out */
-       while (!(status & TUVF) && ++count < 10000) {
-               udelay(1);
-               status = bfin_read_SPORT_STAT();
-               SSYNC();
-       }
-       bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);
-       SSYNC();
-       local_irq_enable();
-
-       if (count >= 10000) {
-               printk(KERN_ERR "ad73311: failed to configure codec\n");
-               return -1;
-       }
-       return 0;
-}
-
-static int bf5xx_probe(struct snd_soc_card *card)
-{
-       int err;
-       if (gpio_request(GPIO_SE, "AD73311_SE")) {
-               printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
-               return -EBUSY;
-       }
-
-       gpio_direction_output(GPIO_SE, 0);
-
-       err = snd_ad73311_configure();
-       if (err < 0)
-               return -EFAULT;
-
-       return 0;
-}
-
-#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
-                               SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
-       {
-               .name = "ad73311",
-               .stream_name = "AD73311",
-               .cpu_dai_name = "bfin-i2s.0",
-               .codec_dai_name = "ad73311-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "ad73311",
-               .dai_fmt = BF5XX_AD7311_DAI_FMT,
-       },
-       {
-               .name = "ad73311",
-               .stream_name = "AD73311",
-               .cpu_dai_name = "bfin-i2s.1",
-               .codec_dai_name = "ad73311-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "ad73311",
-               .dai_fmt = BF5XX_AD7311_DAI_FMT,
-       },
-};
-
-static struct snd_soc_card bf5xx_ad73311 = {
-       .name = "bfin-ad73311",
-       .owner = THIS_MODULE,
-       .probe = bf5xx_probe,
-       .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-       .num_links = 1,
-};
-
-static struct platform_device *bf5xx_ad73311_snd_device;
-
-static int __init bf5xx_ad73311_init(void)
-{
-       int ret;
-
-       pr_debug("%s enter\n", __func__);
-       bf5xx_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!bf5xx_ad73311_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311);
-       ret = platform_device_add(bf5xx_ad73311_snd_device);
-
-       if (ret)
-               platform_device_put(bf5xx_ad73311_snd_device);
-
-       return ret;
-}
-
-static void __exit bf5xx_ad73311_exit(void)
-{
-       pr_debug("%s enter\n", __func__);
-       platform_device_unregister(bf5xx_ad73311_snd_device);
-}
-
-module_init(bf5xx_ad73311_init);
-module_exit(bf5xx_ad73311_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
deleted file mode 100644 (file)
index 51cae76..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-i2s-pcm.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  DMA driver for i2s codec
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gfp.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
-
-static void bf5xx_dma_irq(void *data)
-{
-       struct snd_pcm_substream *pcm = data;
-       snd_pcm_period_elapsed(pcm);
-}
-
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
-       .info                   = SNDRV_PCM_INFO_INTERLEAVED |
-                                  SNDRV_PCM_INFO_MMAP_VALID |
-                                  SNDRV_PCM_INFO_BLOCK_TRANSFER,
-       .period_bytes_min       = 32,
-       .period_bytes_max       = 0x10000,
-       .periods_min            = 1,
-       .periods_max            = PAGE_SIZE/32,
-       .buffer_bytes_max       = 0x20000, /* 128 kbytes */
-       .fifo_size              = 16,
-};
-
-static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       unsigned int buffer_size = params_buffer_bytes(params);
-       struct bf5xx_i2s_pcm_data *dma_data;
-
-       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       if (dma_data->tdm_mode)
-               buffer_size = buffer_size / params_channels(params) * 8;
-
-       return snd_pcm_lib_malloc_pages(substream, buffer_size);
-}
-
-static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-       snd_pcm_lib_free_pages(substream);
-
-       return 0;
-}
-
-static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       int period_bytes = frames_to_bytes(runtime, runtime->period_size);
-       struct bf5xx_i2s_pcm_data *dma_data;
-
-       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       if (dma_data->tdm_mode)
-               period_bytes = period_bytes / runtime->channels * 8;
-
-       pr_debug("%s enter\n", __func__);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_tx_dma(sport, runtime->dma_area,
-                       runtime->periods, period_bytes);
-       } else {
-               sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_rx_dma(sport, runtime->dma_area,
-                       runtime->periods, period_bytes);
-       }
-
-       return 0;
-}
-
-static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       int ret = 0;
-
-       pr_debug("%s enter\n", __func__);
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       sport_tx_start(sport);
-               else
-                       sport_rx_start(sport);
-               break;
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       sport_tx_stop(sport);
-               else
-                       sport_rx_stop(sport);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       unsigned int diff;
-       snd_pcm_uframes_t frames;
-       struct bf5xx_i2s_pcm_data *dma_data;
-
-       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       pr_debug("%s enter\n", __func__);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               diff = sport_curr_offset_tx(sport);
-       } else {
-               diff = sport_curr_offset_rx(sport);
-       }
-
-       /*
-        * TX at least can report one frame beyond the end of the
-        * buffer if we hit the wraparound case - clamp to within the
-        * buffer as the ALSA APIs require.
-        */
-       if (diff == snd_pcm_lib_buffer_bytes(substream))
-               diff = 0;
-
-       frames = bytes_to_frames(substream->runtime, diff);
-       if (dma_data->tdm_mode)
-               frames = frames * runtime->channels / 8;
-
-       return frames;
-}
-
-static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-       struct bf5xx_i2s_pcm_data *dma_data;
-       int ret;
-
-       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       pr_debug("%s enter\n", __func__);
-
-       snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
-       if (dma_data->tdm_mode)
-               runtime->hw.buffer_bytes_max /= 4;
-       else
-               runtime->hw.info |= SNDRV_PCM_INFO_MMAP;
-
-       ret = snd_pcm_hw_constraint_integer(runtime,
-                       SNDRV_PCM_HW_PARAM_PERIODS);
-       if (ret < 0)
-               goto out;
-
-       if (sport_handle != NULL) {
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       sport_handle->tx_buf = buf->area;
-               else
-                       sport_handle->rx_buf = buf->area;
-
-               runtime->private_data = sport_handle;
-       } else {
-               pr_err("sport_handle is NULL\n");
-               return -1;
-       }
-       return 0;
-
- out:
-       return ret;
-}
-
-static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
-       struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       size_t size = vma->vm_end - vma->vm_start;
-       vma->vm_start = (unsigned long)runtime->dma_area;
-       vma->vm_end = vma->vm_start + size;
-       vma->vm_flags |=  VM_SHARED;
-
-       return 0 ;
-}
-
-static int bf5xx_pcm_copy(struct snd_pcm_substream *substream,
-                         int channel, unsigned long pos,
-                         void *buf, unsigned long count)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       unsigned int sample_size = runtime->sample_bits / 8;
-       struct bf5xx_i2s_pcm_data *dma_data;
-       unsigned int i;
-       void *src, *dst;
-
-       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       if (dma_data->tdm_mode) {
-               pos = bytes_to_frames(runtime, pos);
-               count = bytes_to_frames(runtime, count);
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-                       src = buf;
-                       dst = runtime->dma_area;
-                       dst += pos * sample_size * 8;
-
-                       while (count--) {
-                               for (i = 0; i < runtime->channels; i++) {
-                                       memcpy(dst + dma_data->map[i] *
-                                               sample_size, src, sample_size);
-                                       src += sample_size;
-                               }
-                               dst += 8 * sample_size;
-                       }
-               } else {
-                       src = runtime->dma_area;
-                       src += pos * sample_size * 8;
-                       dst = buf;
-
-                       while (count--) {
-                               for (i = 0; i < runtime->channels; i++) {
-                                       memcpy(dst, src + dma_data->map[i] *
-                                               sample_size, sample_size);
-                                       dst += sample_size;
-                               }
-                               src += 8 * sample_size;
-                       }
-               }
-       } else {
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-                       src = buf;
-                       dst = runtime->dma_area;
-                       dst += pos;
-               } else {
-                       src = runtime->dma_area;
-                       src += pos;
-                       dst = buf;
-               }
-
-               memcpy(dst, src, count);
-       }
-
-       return 0;
-}
-
-static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream,
-                              int channel, unsigned long pos,
-                              void __user *buf, unsigned long count)
-{
-       return bf5xx_pcm_copy(substream, channel, pos, (void *)buf, count);
-}
-
-static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
-                            int channel, unsigned long pos,
-                            unsigned long count)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       unsigned int sample_size = runtime->sample_bits / 8;
-       void *buf = runtime->dma_area;
-       struct bf5xx_i2s_pcm_data *dma_data;
-       unsigned int offset, samples;
-
-       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-       if (dma_data->tdm_mode) {
-               offset = bytes_to_frames(runtime, pos) * 8 * sample_size;
-               samples = bytes_to_frames(runtime, count) * 8;
-       } else {
-               offset = pos;
-               samples = bytes_to_samples(runtime, count);
-       }
-
-       snd_pcm_format_set_silence(runtime->format, buf + offset, samples);
-
-       return 0;
-}
-
-static const struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
-       .open           = bf5xx_pcm_open,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = bf5xx_pcm_hw_params,
-       .hw_free        = bf5xx_pcm_hw_free,
-       .prepare        = bf5xx_pcm_prepare,
-       .trigger        = bf5xx_pcm_trigger,
-       .pointer        = bf5xx_pcm_pointer,
-       .mmap           = bf5xx_pcm_mmap,
-       .copy_user      = bf5xx_pcm_copy_user,
-       .copy_kernel    = bf5xx_pcm_copy,
-       .fill_silence   = bf5xx_pcm_silence,
-};
-
-static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
-       int ret;
-
-       pr_debug("%s enter\n", __func__);
-       ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
-       if (ret)
-               return ret;
-
-       return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
-                               SNDRV_DMA_TYPE_DEV, card->dev, size, size);
-}
-
-static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
-       .ops            = &bf5xx_pcm_i2s_ops,
-       .pcm_new        = bf5xx_pcm_i2s_new,
-};
-
-static int bfin_i2s_soc_platform_probe(struct platform_device *pdev)
-{
-       return devm_snd_soc_register_platform(&pdev->dev,
-                                             &bf5xx_i2s_soc_platform);
-}
-
-static struct platform_driver bfin_i2s_pcm_driver = {
-       .driver = {
-               .name = "bfin-i2s-pcm-audio",
-       },
-
-       .probe = bfin_i2s_soc_platform_probe,
-};
-
-module_platform_driver(bfin_i2s_pcm_driver);
-
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.h b/sound/soc/blackfin/bf5xx-i2s-pcm.h
deleted file mode 100644 (file)
index 1f04352..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _BF5XX_TDM_PCM_H
-#define _BF5XX_TDM_PCM_H
-
-#define BFIN_TDM_DAI_MAX_SLOTS 8
-
-struct bf5xx_i2s_pcm_data {
-       unsigned int map[BFIN_TDM_DAI_MAX_SLOTS];
-       bool tdm_mode;
-};
-
-#endif
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
deleted file mode 100644 (file)
index b69aeef..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-i2s.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  Blackfin I2S CPU DAI driver
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/irq.h>
-#include <asm/portmux.h>
-#include <linux/mutex.h>
-#include <linux/gpio.h>
-
-#include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
-
-struct bf5xx_i2s_port {
-       u16 tcr1;
-       u16 rcr1;
-       u16 tcr2;
-       u16 rcr2;
-       int configured;
-
-       unsigned int slots;
-       unsigned int tx_mask;
-       unsigned int rx_mask;
-
-       struct bf5xx_i2s_pcm_data tx_dma_data;
-       struct bf5xx_i2s_pcm_data rx_dma_data;
-};
-
-static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-               unsigned int fmt)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-       int ret = 0;
-
-       /* interface format:support I2S,slave mode */
-       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-       case SND_SOC_DAIFMT_I2S:
-               bf5xx_i2s->tcr1 |= TFSR | TCKFE;
-               bf5xx_i2s->rcr1 |= RFSR | RCKFE;
-               bf5xx_i2s->tcr2 |= TSFSE;
-               bf5xx_i2s->rcr2 |= RSFSE;
-               break;
-       case SND_SOC_DAIFMT_DSP_A:
-               bf5xx_i2s->tcr1 |= TFSR;
-               bf5xx_i2s->rcr1 |= RFSR;
-               break;
-       case SND_SOC_DAIFMT_LEFT_J:
-               ret = -EINVAL;
-               break;
-       default:
-               dev_err(cpu_dai->dev, "%s: Unknown DAI format type\n",
-                       __func__);
-               ret = -EINVAL;
-               break;
-       }
-
-       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-       case SND_SOC_DAIFMT_CBM_CFM:
-               break;
-       case SND_SOC_DAIFMT_CBS_CFS:
-       case SND_SOC_DAIFMT_CBM_CFS:
-       case SND_SOC_DAIFMT_CBS_CFM:
-               ret = -EINVAL;
-               break;
-       default:
-               dev_err(cpu_dai->dev, "%s: Unknown DAI master type\n",
-                       __func__);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params,
-                               struct snd_soc_dai *dai)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-       int ret = 0;
-
-       bf5xx_i2s->tcr2 &= ~0x1f;
-       bf5xx_i2s->rcr2 &= ~0x1f;
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S8:
-               bf5xx_i2s->tcr2 |= 7;
-               bf5xx_i2s->rcr2 |= 7;
-               sport_handle->wdsize = 1;
-               break;
-       case SNDRV_PCM_FORMAT_S16_LE:
-               bf5xx_i2s->tcr2 |= 15;
-               bf5xx_i2s->rcr2 |= 15;
-               sport_handle->wdsize = 2;
-               break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               bf5xx_i2s->tcr2 |= 23;
-               bf5xx_i2s->rcr2 |= 23;
-               sport_handle->wdsize = 3;
-               break;
-       case SNDRV_PCM_FORMAT_S32_LE:
-               bf5xx_i2s->tcr2 |= 31;
-               bf5xx_i2s->rcr2 |= 31;
-               sport_handle->wdsize = 4;
-               break;
-       }
-
-       if (!bf5xx_i2s->configured) {
-               /*
-                * TX and RX are not independent,they are enabled at the
-                * same time, even if only one side is running. So, we
-                * need to configure both of them at the time when the first
-                * stream is opened.
-                *
-                * CPU DAI:slave mode.
-                */
-               bf5xx_i2s->configured = 1;
-               ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
-                                     bf5xx_i2s->rcr2, 0, 0);
-               if (ret) {
-                       dev_err(dai->dev, "SPORT is busy!\n");
-                       return -EBUSY;
-               }
-
-               ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
-                                     bf5xx_i2s->tcr2, 0, 0);
-               if (ret) {
-                       dev_err(dai->dev, "SPORT is busy!\n");
-                       return -EBUSY;
-               }
-       }
-
-       return 0;
-}
-
-static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
-                              struct snd_soc_dai *dai)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-
-       dev_dbg(dai->dev, "%s enter\n", __func__);
-       /* No active stream, SPORT is allowed to be configured again. */
-       if (!dai->active)
-               bf5xx_i2s->configured = 0;
-}
-
-static int bf5xx_i2s_set_channel_map(struct snd_soc_dai *dai,
-               unsigned int tx_num, unsigned int *tx_slot,
-               unsigned int rx_num, unsigned int *rx_slot)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-       unsigned int tx_mapped = 0, rx_mapped = 0;
-       unsigned int slot;
-       int i;
-
-       if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
-                       (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
-               return -EINVAL;
-
-       for (i = 0; i < tx_num; i++) {
-               slot = tx_slot[i];
-               if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
-                               (!(tx_mapped & (1 << slot)))) {
-                       bf5xx_i2s->tx_dma_data.map[i] = slot;
-                       tx_mapped |= 1 << slot;
-               } else
-                       return -EINVAL;
-       }
-       for (i = 0; i < rx_num; i++) {
-               slot = rx_slot[i];
-               if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
-                               (!(rx_mapped & (1 << slot)))) {
-                       bf5xx_i2s->rx_dma_data.map[i] = slot;
-                       rx_mapped |= 1 << slot;
-               } else
-                       return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int bf5xx_i2s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
-       unsigned int rx_mask, int slots, int width)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-
-       if (slots % 8 != 0 || slots > 8)
-               return -EINVAL;
-
-       if (width != 32)
-               return -EINVAL;
-
-       bf5xx_i2s->slots = slots;
-       bf5xx_i2s->tx_mask = tx_mask;
-       bf5xx_i2s->rx_mask = rx_mask;
-
-       bf5xx_i2s->tx_dma_data.tdm_mode = slots != 0;
-       bf5xx_i2s->rx_dma_data.tdm_mode = slots != 0;
-
-       return sport_set_multichannel(sport_handle, slots, tx_mask, rx_mask, 0);
-}
-
-#ifdef CONFIG_PM
-static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-
-       dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
-
-       if (dai->capture_active)
-               sport_rx_stop(sport_handle);
-       if (dai->playback_active)
-               sport_tx_stop(sport_handle);
-       return 0;
-}
-
-static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-       int ret;
-
-       dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
-
-       ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
-                                     bf5xx_i2s->rcr2, 0, 0);
-       if (ret) {
-               dev_err(dai->dev, "SPORT is busy!\n");
-               return -EBUSY;
-       }
-
-       ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
-                                     bf5xx_i2s->tcr2, 0, 0);
-       if (ret) {
-               dev_err(dai->dev, "SPORT is busy!\n");
-               return -EBUSY;
-       }
-
-       return sport_set_multichannel(sport_handle, bf5xx_i2s->slots,
-                       bf5xx_i2s->tx_mask, bf5xx_i2s->rx_mask, 0);
-}
-
-#else
-#define bf5xx_i2s_suspend      NULL
-#define bf5xx_i2s_resume       NULL
-#endif
-
-static int bf5xx_i2s_dai_probe(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
-       unsigned int i;
-
-       for (i = 0; i < BFIN_TDM_DAI_MAX_SLOTS; i++) {
-               bf5xx_i2s->tx_dma_data.map[i] = i;
-               bf5xx_i2s->rx_dma_data.map[i] = i;
-       }
-
-       dai->playback_dma_data = &bf5xx_i2s->tx_dma_data;
-       dai->capture_dma_data = &bf5xx_i2s->rx_dma_data;
-
-       return 0;
-}
-
-#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
-               SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
-               SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
-               SNDRV_PCM_RATE_96000)
-
-#define BF5XX_I2S_FORMATS \
-       (SNDRV_PCM_FMTBIT_S8 | \
-        SNDRV_PCM_FMTBIT_S16_LE | \
-        SNDRV_PCM_FMTBIT_S24_LE | \
-        SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
-       .shutdown        = bf5xx_i2s_shutdown,
-       .hw_params       = bf5xx_i2s_hw_params,
-       .set_fmt         = bf5xx_i2s_set_dai_fmt,
-       .set_tdm_slot    = bf5xx_i2s_set_tdm_slot,
-       .set_channel_map = bf5xx_i2s_set_channel_map,
-};
-
-static struct snd_soc_dai_driver bf5xx_i2s_dai = {
-       .probe = bf5xx_i2s_dai_probe,
-       .suspend = bf5xx_i2s_suspend,
-       .resume = bf5xx_i2s_resume,
-       .playback = {
-               .channels_min = 2,
-               .channels_max = 8,
-               .rates = BF5XX_I2S_RATES,
-               .formats = BF5XX_I2S_FORMATS,},
-       .capture = {
-               .channels_min = 2,
-               .channels_max = 8,
-               .rates = BF5XX_I2S_RATES,
-               .formats = BF5XX_I2S_FORMATS,},
-       .ops = &bf5xx_i2s_dai_ops,
-};
-
-static const struct snd_soc_component_driver bf5xx_i2s_component = {
-       .name           = "bf5xx-i2s",
-};
-
-static int bf5xx_i2s_probe(struct platform_device *pdev)
-{
-       struct sport_device *sport_handle;
-       int ret;
-
-       /* configure SPORT for I2S */
-       sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
-               sizeof(struct bf5xx_i2s_port));
-       if (!sport_handle)
-               return -ENODEV;
-
-       /* register with the ASoC layers */
-       ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component,
-                                        &bf5xx_i2s_dai, 1);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
-               sport_done(sport_handle);
-               return ret;
-       }
-
-       return 0;
-}
-
-static int bf5xx_i2s_remove(struct platform_device *pdev)
-{
-       struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
-       dev_dbg(&pdev->dev, "%s enter\n", __func__);
-
-       snd_soc_unregister_component(&pdev->dev);
-       sport_done(sport_handle);
-
-       return 0;
-}
-
-static struct platform_driver bfin_i2s_driver = {
-       .probe  = bf5xx_i2s_probe,
-       .remove = bf5xx_i2s_remove,
-       .driver = {
-               .name = "bfin-i2s",
-       },
-};
-
-module_platform_driver(bfin_i2s_driver);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
deleted file mode 100644 (file)
index 9dfa124..0000000
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * File:         bf5xx_sport.c
- * Based on:
- * Author:       Roy Huang <roy.huang@analog.com>
- *
- * Created:      Tue Sep 21 10:52:42 CEST 2004
- * Description:
- *               Blackfin SPORT Driver
- *
- *               Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/bug.h>
-#include <linux/module.h>
-#include <asm/portmux.h>
-#include <asm/dma.h>
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-
-#include "bf5xx-sport.h"
-/* delay between frame sync pulse and first data bit in multichannel mode */
-#define FRAME_DELAY (1<<12)
-
-/* note: multichannel is in units of 8 channels,
- * tdm_count is # channels NOT / 8 ! */
-int sport_set_multichannel(struct sport_device *sport,
-               int tdm_count, u32 tx_mask, u32 rx_mask, int packed)
-{
-       pr_debug("%s tdm_count=%d tx_mask:0x%08x rx_mask:0x%08x packed=%d\n",
-                       __func__, tdm_count, tx_mask, rx_mask, packed);
-
-       if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
-               return -EBUSY;
-
-       if (tdm_count & 0x7)
-               return -EINVAL;
-
-       if (tdm_count > 32)
-               return -EINVAL; /* Only support less than 32 channels now */
-
-       if (tdm_count) {
-               sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
-               sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
-                               (packed ? (MCDTXPE|MCDRXPE) : 0);
-
-               sport->regs->mtcs0 = tx_mask;
-               sport->regs->mrcs0 = rx_mask;
-               sport->regs->mtcs1 = 0;
-               sport->regs->mrcs1 = 0;
-               sport->regs->mtcs2 = 0;
-               sport->regs->mrcs2 = 0;
-               sport->regs->mtcs3 = 0;
-               sport->regs->mrcs3 = 0;
-       } else {
-               sport->regs->mcmc1 = 0;
-               sport->regs->mcmc2 = 0;
-
-               sport->regs->mtcs0 = 0;
-               sport->regs->mrcs0 = 0;
-       }
-
-       sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
-       sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;
-
-       SSYNC();
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_set_multichannel);
-
-int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
-               unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
-{
-       if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
-               return -EBUSY;
-
-       sport->regs->rcr1 = rcr1;
-       sport->regs->rcr2 = rcr2;
-       sport->regs->rclkdiv = clkdiv;
-       sport->regs->rfsdiv = fsdiv;
-
-       SSYNC();
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_config_rx);
-
-int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
-               unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
-{
-       if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
-               return -EBUSY;
-
-       sport->regs->tcr1 = tcr1;
-       sport->regs->tcr2 = tcr2;
-       sport->regs->tclkdiv = clkdiv;
-       sport->regs->tfsdiv = fsdiv;
-
-       SSYNC();
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_config_tx);
-
-static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
-               size_t fragsize, unsigned int cfg,
-               unsigned int x_count, unsigned int ycount, size_t wdsize)
-{
-
-       int i;
-
-       for (i = 0; i < fragcount; ++i) {
-               desc[i].next_desc_addr  = &(desc[i + 1]);
-               desc[i].start_addr = (unsigned long)buf + i*fragsize;
-               desc[i].cfg = cfg;
-               desc[i].x_count = x_count;
-               desc[i].x_modify = wdsize;
-               desc[i].y_count = ycount;
-               desc[i].y_modify = wdsize;
-       }
-
-       /* make circular */
-       desc[fragcount-1].next_desc_addr = desc;
-
-       pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p,"
-               "next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
-               desc, desc[0].next_desc_addr,
-               desc+1, desc[1].next_desc_addr,
-               desc[0].x_count, desc[0].y_count,
-               desc[0].start_addr, desc[0].cfg);
-}
-
-static int sport_start(struct sport_device *sport)
-{
-       enable_dma(sport->dma_rx_chan);
-       enable_dma(sport->dma_tx_chan);
-       sport->regs->rcr1 |= RSPEN;
-       sport->regs->tcr1 |= TSPEN;
-       SSYNC();
-
-       return 0;
-}
-
-static int sport_stop(struct sport_device *sport)
-{
-       sport->regs->tcr1 &= ~TSPEN;
-       sport->regs->rcr1 &= ~RSPEN;
-       SSYNC();
-
-       disable_dma(sport->dma_rx_chan);
-       disable_dma(sport->dma_tx_chan);
-       return 0;
-}
-
-static inline int sport_hook_rx_dummy(struct sport_device *sport)
-{
-       struct dmasg *desc, temp_desc;
-       unsigned long flags;
-
-       if (WARN_ON(!sport->dummy_rx_desc) ||
-           WARN_ON(sport->curr_rx_desc == sport->dummy_rx_desc))
-               return -EINVAL;
-
-       /* Maybe the dummy buffer descriptor ring is damaged */
-       sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1;
-
-       local_irq_save(flags);
-       desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
-       /* Copy the descriptor which will be damaged to backup */
-       temp_desc = *desc;
-       desc->x_count = sport->dummy_count / 2;
-       desc->y_count = 0;
-       desc->next_desc_addr = sport->dummy_rx_desc;
-       local_irq_restore(flags);
-       /* Waiting for dummy buffer descriptor is already hooked*/
-       while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
-                       sizeof(struct dmasg)) != sport->dummy_rx_desc)
-               continue;
-       sport->curr_rx_desc = sport->dummy_rx_desc;
-       /* Restore the damaged descriptor */
-       *desc = temp_desc;
-
-       return 0;
-}
-
-static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
-{
-       if (dummy) {
-               sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc;
-               sport->curr_rx_desc = sport->dummy_rx_desc;
-       } else
-               sport->curr_rx_desc = sport->dma_rx_desc;
-
-       set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc);
-       set_dma_x_count(sport->dma_rx_chan, 0);
-       set_dma_x_modify(sport->dma_rx_chan, 0);
-       set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
-                               WDSIZE_32 | WNR));
-       set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
-       SSYNC();
-
-       return 0;
-}
-
-static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
-{
-       if (dummy) {
-               sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc;
-               sport->curr_tx_desc = sport->dummy_tx_desc;
-       } else
-               sport->curr_tx_desc = sport->dma_tx_desc;
-
-       set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc);
-       set_dma_x_count(sport->dma_tx_chan, 0);
-       set_dma_x_modify(sport->dma_tx_chan, 0);
-       set_dma_config(sport->dma_tx_chan,
-                       (DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
-       set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
-       SSYNC();
-
-       return 0;
-}
-
-int sport_rx_start(struct sport_device *sport)
-{
-       unsigned long flags;
-       pr_debug("%s enter\n", __func__);
-       if (sport->rx_run)
-               return -EBUSY;
-       if (sport->tx_run) {
-               /* tx is running, rx is not running */
-               if (WARN_ON(!sport->dma_rx_desc) ||
-                   WARN_ON(sport->curr_rx_desc != sport->dummy_rx_desc))
-                       return -EINVAL;
-               local_irq_save(flags);
-               while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
-                       sizeof(struct dmasg)) != sport->dummy_rx_desc)
-                       continue;
-               sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc;
-               local_irq_restore(flags);
-               sport->curr_rx_desc = sport->dma_rx_desc;
-       } else {
-               sport_tx_dma_start(sport, 1);
-               sport_rx_dma_start(sport, 0);
-               sport_start(sport);
-       }
-
-       sport->rx_run = 1;
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_rx_start);
-
-int sport_rx_stop(struct sport_device *sport)
-{
-       pr_debug("%s enter\n", __func__);
-
-       if (!sport->rx_run)
-               return 0;
-       if (sport->tx_run) {
-               /* TX dma is still running, hook the dummy buffer */
-               sport_hook_rx_dummy(sport);
-       } else {
-               /* Both rx and tx dma will be stopped */
-               sport_stop(sport);
-               sport->curr_rx_desc = NULL;
-               sport->curr_tx_desc = NULL;
-       }
-
-       sport->rx_run = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_rx_stop);
-
-static inline int sport_hook_tx_dummy(struct sport_device *sport)
-{
-       struct dmasg *desc, temp_desc;
-       unsigned long flags;
-
-       if (WARN_ON(!sport->dummy_tx_desc) ||
-           WARN_ON(sport->curr_tx_desc == sport->dummy_tx_desc))
-               return -EINVAL;
-
-       sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1;
-
-       /* Shorten the time on last normal descriptor */
-       local_irq_save(flags);
-       desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
-       /* Store the descriptor which will be damaged */
-       temp_desc = *desc;
-       desc->x_count = sport->dummy_count / 2;
-       desc->y_count = 0;
-       desc->next_desc_addr = sport->dummy_tx_desc;
-       local_irq_restore(flags);
-       /* Waiting for dummy buffer descriptor is already hooked*/
-       while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
-                       sizeof(struct dmasg)) != sport->dummy_tx_desc)
-               continue;
-       sport->curr_tx_desc = sport->dummy_tx_desc;
-       /* Restore the damaged descriptor */
-       *desc = temp_desc;
-
-       return 0;
-}
-
-int sport_tx_start(struct sport_device *sport)
-{
-       unsigned long flags;
-       pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
-                       sport->tx_run, sport->rx_run);
-       if (sport->tx_run)
-               return -EBUSY;
-       if (sport->rx_run) {
-               if (WARN_ON(!sport->dma_tx_desc) ||
-                   WARN_ON(sport->curr_tx_desc != sport->dummy_tx_desc))
-                       return -EINVAL;
-               /* Hook the normal buffer descriptor */
-               local_irq_save(flags);
-               while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
-                       sizeof(struct dmasg)) != sport->dummy_tx_desc)
-                       continue;
-               sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc;
-               local_irq_restore(flags);
-               sport->curr_tx_desc = sport->dma_tx_desc;
-       } else {
-
-               sport_tx_dma_start(sport, 0);
-               /* Let rx dma run the dummy buffer */
-               sport_rx_dma_start(sport, 1);
-               sport_start(sport);
-       }
-       sport->tx_run = 1;
-       return 0;
-}
-EXPORT_SYMBOL(sport_tx_start);
-
-int sport_tx_stop(struct sport_device *sport)
-{
-       if (!sport->tx_run)
-               return 0;
-       if (sport->rx_run) {
-               /* RX is still running, hook the dummy buffer */
-               sport_hook_tx_dummy(sport);
-       } else {
-               /* Both rx and tx dma stopped */
-               sport_stop(sport);
-               sport->curr_rx_desc = NULL;
-               sport->curr_tx_desc = NULL;
-       }
-
-       sport->tx_run = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_tx_stop);
-
-static inline int compute_wdsize(size_t wdsize)
-{
-       switch (wdsize) {
-       case 1:
-               return WDSIZE_8;
-       case 2:
-               return WDSIZE_16;
-       case 4:
-       default:
-               return WDSIZE_32;
-       }
-}
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-               int fragcount, size_t fragsize)
-{
-       unsigned int x_count;
-       unsigned int y_count;
-       unsigned int cfg;
-       dma_addr_t addr;
-
-       pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
-                       buf, fragcount, fragsize);
-
-       x_count = fragsize / sport->wdsize;
-       y_count = 0;
-
-       /* for fragments larger than 64k words we use 2d dma,
-        * denote fragecount as two numbers' mutliply and both of them
-        * are less than 64k.*/
-       if (x_count >= 0x10000) {
-               int i, count = x_count;
-
-               for (i = 16; i > 0; i--) {
-                       x_count = 1 << i;
-                       if ((count & (x_count - 1)) == 0) {
-                               y_count = count >> i;
-                               if (y_count < 0x10000)
-                                       break;
-                       }
-               }
-               if (i == 0)
-                       return -EINVAL;
-       }
-       pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
-                       x_count, y_count);
-
-       if (sport->dma_rx_desc)
-               dma_free_coherent(NULL, sport->rx_desc_bytes,
-                                       sport->dma_rx_desc, 0);
-
-       /* Allocate a new descritor ring as current one. */
-       sport->dma_rx_desc = dma_alloc_coherent(NULL, \
-                       fragcount * sizeof(struct dmasg), &addr, 0);
-       sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);
-
-       if (!sport->dma_rx_desc) {
-               pr_err("Failed to allocate memory for rx desc\n");
-               return -ENOMEM;
-       }
-
-       sport->rx_buf = buf;
-       sport->rx_fragsize = fragsize;
-       sport->rx_frags = fragcount;
-
-       cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
-                 (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
-
-       if (y_count != 0)
-               cfg |= DMA2D;
-
-       setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
-                       cfg|DMAEN, x_count, y_count, sport->wdsize);
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_config_rx_dma);
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf, \
-               int fragcount, size_t fragsize)
-{
-       unsigned int x_count;
-       unsigned int y_count;
-       unsigned int cfg;
-       dma_addr_t addr;
-
-       pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
-                       __func__, buf, fragcount, fragsize);
-
-       x_count = fragsize/sport->wdsize;
-       y_count = 0;
-
-       /* for fragments larger than 64k words we use 2d dma,
-        * denote fragecount as two numbers' mutliply and both of them
-        * are less than 64k.*/
-       if (x_count >= 0x10000) {
-               int i, count = x_count;
-
-               for (i = 16; i > 0; i--) {
-                       x_count = 1 << i;
-                       if ((count & (x_count - 1)) == 0) {
-                               y_count = count >> i;
-                               if (y_count < 0x10000)
-                                       break;
-                       }
-               }
-               if (i == 0)
-                       return -EINVAL;
-       }
-       pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
-                       x_count, y_count);
-
-
-       if (sport->dma_tx_desc) {
-               dma_free_coherent(NULL, sport->tx_desc_bytes, \
-                               sport->dma_tx_desc, 0);
-       }
-
-       sport->dma_tx_desc = dma_alloc_coherent(NULL, \
-                       fragcount * sizeof(struct dmasg), &addr, 0);
-       sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
-       if (!sport->dma_tx_desc) {
-               pr_err("Failed to allocate memory for tx desc\n");
-               return -ENOMEM;
-       }
-
-       sport->tx_buf = buf;
-       sport->tx_fragsize = fragsize;
-       sport->tx_frags = fragcount;
-       cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
-                 (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
-
-       if (y_count != 0)
-               cfg |= DMA2D;
-
-       setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
-                       cfg|DMAEN, x_count, y_count, sport->wdsize);
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_config_tx_dma);
-
-/* setup dummy dma descriptor ring, which don't generate interrupts,
- * the x_modify is set to 0 */
-static int sport_config_rx_dummy(struct sport_device *sport)
-{
-       struct dmasg *desc;
-       unsigned config;
-
-       pr_debug("%s entered\n", __func__);
-       if (L1_DATA_A_LENGTH)
-               desc = l1_data_sram_zalloc(2 * sizeof(*desc));
-       else {
-               dma_addr_t addr;
-               desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
-               memset(desc, 0, 2 * sizeof(*desc));
-       }
-       if (desc == NULL) {
-               pr_err("Failed to allocate memory for dummy rx desc\n");
-               return -ENOMEM;
-       }
-       sport->dummy_rx_desc = desc;
-       desc->start_addr = (unsigned long)sport->dummy_buf;
-       config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
-                | WNR | DMAEN;
-       desc->cfg = config;
-       desc->x_count = sport->dummy_count/sport->wdsize;
-       desc->x_modify = sport->wdsize;
-       desc->y_count = 0;
-       desc->y_modify = 0;
-       memcpy(desc+1, desc, sizeof(*desc));
-       desc->next_desc_addr = desc + 1;
-       desc[1].next_desc_addr = desc;
-       return 0;
-}
-
-static int sport_config_tx_dummy(struct sport_device *sport)
-{
-       struct dmasg *desc;
-       unsigned int config;
-
-       pr_debug("%s entered\n", __func__);
-
-       if (L1_DATA_A_LENGTH)
-               desc = l1_data_sram_zalloc(2 * sizeof(*desc));
-       else {
-               dma_addr_t addr;
-               desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
-               memset(desc, 0, 2 * sizeof(*desc));
-       }
-       if (!desc) {
-               pr_err("Failed to allocate memory for dummy tx desc\n");
-               return -ENOMEM;
-       }
-       sport->dummy_tx_desc = desc;
-       desc->start_addr = (unsigned long)sport->dummy_buf + \
-               sport->dummy_count;
-       config = DMAFLOW_LARGE | NDSIZE_9 |
-                compute_wdsize(sport->wdsize) | DMAEN;
-       desc->cfg = config;
-       desc->x_count = sport->dummy_count/sport->wdsize;
-       desc->x_modify = sport->wdsize;
-       desc->y_count = 0;
-       desc->y_modify = 0;
-       memcpy(desc+1, desc, sizeof(*desc));
-       desc->next_desc_addr = desc + 1;
-       desc[1].next_desc_addr = desc;
-       return 0;
-}
-
-unsigned long sport_curr_offset_rx(struct sport_device *sport)
-{
-       unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);
-
-       return (unsigned char *)curr - sport->rx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_rx);
-
-unsigned long sport_curr_offset_tx(struct sport_device *sport)
-{
-       unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);
-
-       return (unsigned char *)curr - sport->tx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_tx);
-
-void sport_incfrag(struct sport_device *sport, int *frag, int tx)
-{
-       ++(*frag);
-       if (tx == 1 && *frag == sport->tx_frags)
-               *frag = 0;
-
-       if (tx == 0 && *frag == sport->rx_frags)
-               *frag = 0;
-}
-EXPORT_SYMBOL(sport_incfrag);
-
-void sport_decfrag(struct sport_device *sport, int *frag, int tx)
-{
-       --(*frag);
-       if (tx == 1 && *frag == 0)
-               *frag = sport->tx_frags;
-
-       if (tx == 0 && *frag == 0)
-               *frag = sport->rx_frags;
-}
-EXPORT_SYMBOL(sport_decfrag);
-
-static int sport_check_status(struct sport_device *sport,
-               unsigned int *sport_stat,
-               unsigned int *rx_stat,
-               unsigned int *tx_stat)
-{
-       int status = 0;
-
-       if (sport_stat) {
-               SSYNC();
-               status = sport->regs->stat;
-               if (status & (TOVF|TUVF|ROVF|RUVF))
-                       sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
-               SSYNC();
-               *sport_stat = status;
-       }
-
-       if (rx_stat) {
-               SSYNC();
-               status = get_dma_curr_irqstat(sport->dma_rx_chan);
-               if (status & (DMA_DONE|DMA_ERR))
-                       clear_dma_irqstat(sport->dma_rx_chan);
-               SSYNC();
-               *rx_stat = status;
-       }
-
-       if (tx_stat) {
-               SSYNC();
-               status = get_dma_curr_irqstat(sport->dma_tx_chan);
-               if (status & (DMA_DONE|DMA_ERR))
-                       clear_dma_irqstat(sport->dma_tx_chan);
-               SSYNC();
-               *tx_stat = status;
-       }
-
-       return 0;
-}
-
-int  sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
-{
-       int ret;
-
-       ret = snprintf(buf, len,
-                       "sts: 0x%04x\n"
-                       "rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
-                       sport->regs->stat,
-                       sport->dma_rx_chan,
-                       get_dma_curr_irqstat(sport->dma_rx_chan),
-                       sport->dma_tx_chan,
-                       get_dma_curr_irqstat(sport->dma_tx_chan));
-       buf += ret;
-       len -= ret;
-
-       ret += snprintf(buf, len,
-                       "curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
-                       "dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
-                       "dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
-                       sport->curr_rx_desc, sport->curr_tx_desc,
-                       sport->dma_rx_desc, sport->dma_tx_desc,
-                       sport->dummy_rx_desc, sport->dummy_tx_desc);
-
-       return ret;
-}
-
-static irqreturn_t rx_handler(int irq, void *dev_id)
-{
-       unsigned int rx_stat;
-       struct sport_device *sport = dev_id;
-
-       pr_debug("%s enter\n", __func__);
-       sport_check_status(sport, NULL, &rx_stat, NULL);
-       if (!(rx_stat & DMA_DONE))
-               pr_err("rx dma is already stopped\n");
-
-       if (sport->rx_callback) {
-               sport->rx_callback(sport->rx_data);
-               return IRQ_HANDLED;
-       }
-
-       return IRQ_NONE;
-}
-
-static irqreturn_t tx_handler(int irq, void *dev_id)
-{
-       unsigned int tx_stat;
-       struct sport_device *sport = dev_id;
-       pr_debug("%s enter\n", __func__);
-       sport_check_status(sport, NULL, NULL, &tx_stat);
-       if (!(tx_stat & DMA_DONE)) {
-               pr_err("tx dma is already stopped\n");
-               return IRQ_HANDLED;
-       }
-       if (sport->tx_callback) {
-               sport->tx_callback(sport->tx_data);
-               return IRQ_HANDLED;
-       }
-
-       return IRQ_NONE;
-}
-
-static irqreturn_t err_handler(int irq, void *dev_id)
-{
-       unsigned int status = 0;
-       struct sport_device *sport = dev_id;
-
-       pr_debug("%s\n", __func__);
-       if (sport_check_status(sport, &status, NULL, NULL)) {
-               pr_err("error checking status ??");
-               return IRQ_NONE;
-       }
-
-       if (status & (TOVF|TUVF|ROVF|RUVF)) {
-               pr_info("sport status error:%s%s%s%s\n",
-                               status & TOVF ? " TOVF" : "",
-                               status & TUVF ? " TUVF" : "",
-                               status & ROVF ? " ROVF" : "",
-                               status & RUVF ? " RUVF" : "");
-               if (status & TOVF || status & TUVF) {
-                       disable_dma(sport->dma_tx_chan);
-                       if (sport->tx_run)
-                               sport_tx_dma_start(sport, 0);
-                       else
-                               sport_tx_dma_start(sport, 1);
-                       enable_dma(sport->dma_tx_chan);
-               } else {
-                       disable_dma(sport->dma_rx_chan);
-                       if (sport->rx_run)
-                               sport_rx_dma_start(sport, 0);
-                       else
-                               sport_rx_dma_start(sport, 1);
-                       enable_dma(sport->dma_rx_chan);
-               }
-       }
-       status = sport->regs->stat;
-       if (status & (TOVF|TUVF|ROVF|RUVF))
-               sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
-       SSYNC();
-
-       if (sport->err_callback)
-               sport->err_callback(sport->err_data);
-
-       return IRQ_HANDLED;
-}
-
-int sport_set_rx_callback(struct sport_device *sport,
-                      void (*rx_callback)(void *), void *rx_data)
-{
-       if (WARN_ON(!rx_callback))
-               return -EINVAL;
-       sport->rx_callback = rx_callback;
-       sport->rx_data = rx_data;
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_set_rx_callback);
-
-int sport_set_tx_callback(struct sport_device *sport,
-               void (*tx_callback)(void *), void *tx_data)
-{
-       if (WARN_ON(!tx_callback))
-               return -EINVAL;
-       sport->tx_callback = tx_callback;
-       sport->tx_data = tx_data;
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_set_tx_callback);
-
-int sport_set_err_callback(struct sport_device *sport,
-               void (*err_callback)(void *), void *err_data)
-{
-       if (WARN_ON(!err_callback))
-               return -EINVAL;
-       sport->err_callback = err_callback;
-       sport->err_data = err_data;
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_set_err_callback);
-
-static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
-{
-       /* Extract settings from platform data */
-       struct device *dev = &pdev->dev;
-       struct bfin_snd_platform_data *pdata = dev->platform_data;
-       struct resource *res;
-
-       param->num = pdev->id;
-
-       if (!pdata) {
-               dev_err(dev, "no platform_data\n");
-               return -ENODEV;
-       }
-       param->pin_req = pdata->pin_req;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "no MEM resource\n");
-               return -ENODEV;
-       }
-       param->regs = (struct sport_register *)res->start;
-
-       /* first RX, then TX */
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!res) {
-               dev_err(dev, "no rx DMA resource\n");
-               return -ENODEV;
-       }
-       param->dma_rx_chan = res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (!res) {
-               dev_err(dev, "no tx DMA resource\n");
-               return -ENODEV;
-       }
-       param->dma_tx_chan = res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res) {
-               dev_err(dev, "no irq resource\n");
-               return -ENODEV;
-       }
-       param->err_irq = res->start;
-
-       return 0;
-}
-
-struct sport_device *sport_init(struct platform_device *pdev,
-       unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
-{
-       struct device *dev = &pdev->dev;
-       struct sport_param param;
-       struct sport_device *sport;
-       int ret;
-
-       dev_dbg(dev, "%s enter\n", __func__);
-
-       param.wdsize = wdsize;
-       param.dummy_count = dummy_count;
-       if (WARN_ON(param.wdsize == 0 || param.dummy_count == 0))
-               return NULL;
-
-       ret = sport_config_pdev(pdev, &param);
-       if (ret)
-               return NULL;
-
-       if (peripheral_request_list(param.pin_req, "soc-audio")) {
-               dev_err(dev, "requesting Peripherals failed\n");
-               return NULL;
-       }
-
-       sport = kzalloc(sizeof(*sport), GFP_KERNEL);
-       if (!sport) {
-               dev_err(dev, "failed to allocate for sport device\n");
-               goto __init_err0;
-       }
-
-       sport->num = param.num;
-       sport->dma_rx_chan = param.dma_rx_chan;
-       sport->dma_tx_chan = param.dma_tx_chan;
-       sport->err_irq = param.err_irq;
-       sport->regs = param.regs;
-       sport->pin_req = param.pin_req;
-
-       if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
-               dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
-               goto __init_err1;
-       }
-       if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
-               dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
-               goto __init_err2;
-       }
-
-       if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
-               dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
-               goto __init_err2;
-       }
-
-       if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
-               dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
-               goto __init_err3;
-       }
-
-       if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
-                       sport) < 0) {
-               dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
-               goto __init_err3;
-       }
-
-       dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
-                       sport->dma_rx_chan, sport->dma_tx_chan,
-                       sport->err_irq, sport->regs);
-
-       sport->wdsize = param.wdsize;
-       sport->dummy_count = param.dummy_count;
-
-       sport->private_data = kzalloc(priv_size, GFP_KERNEL);
-       if (!sport->private_data) {
-               dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
-               goto __init_err4;
-       }
-
-       if (L1_DATA_A_LENGTH)
-               sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
-       else
-               sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
-       if (sport->dummy_buf == NULL) {
-               dev_err(dev, "failed to allocate dummy buffer\n");
-               goto __error1;
-       }
-
-       ret = sport_config_rx_dummy(sport);
-       if (ret) {
-               dev_err(dev, "failed to config rx dummy ring\n");
-               goto __error2;
-       }
-       ret = sport_config_tx_dummy(sport);
-       if (ret) {
-               dev_err(dev, "failed to config tx dummy ring\n");
-               goto __error3;
-       }
-
-       platform_set_drvdata(pdev, sport);
-
-       return sport;
-__error3:
-       if (L1_DATA_A_LENGTH)
-               l1_data_sram_free(sport->dummy_rx_desc);
-       else
-               dma_free_coherent(NULL, 2*sizeof(struct dmasg),
-                               sport->dummy_rx_desc, 0);
-__error2:
-       if (L1_DATA_A_LENGTH)
-               l1_data_sram_free(sport->dummy_buf);
-       else
-               kfree(sport->dummy_buf);
-__error1:
-       kfree(sport->private_data);
-__init_err4:
-       free_irq(sport->err_irq, sport);
-__init_err3:
-       free_dma(sport->dma_tx_chan);
-__init_err2:
-       free_dma(sport->dma_rx_chan);
-__init_err1:
-       kfree(sport);
-__init_err0:
-       peripheral_free_list(param.pin_req);
-       return NULL;
-}
-EXPORT_SYMBOL(sport_init);
-
-void sport_done(struct sport_device *sport)
-{
-       if (sport == NULL)
-               return;
-
-       sport_stop(sport);
-       if (sport->dma_rx_desc)
-               dma_free_coherent(NULL, sport->rx_desc_bytes,
-                       sport->dma_rx_desc, 0);
-       if (sport->dma_tx_desc)
-               dma_free_coherent(NULL, sport->tx_desc_bytes,
-                       sport->dma_tx_desc, 0);
-
-#if L1_DATA_A_LENGTH != 0
-       l1_data_sram_free(sport->dummy_rx_desc);
-       l1_data_sram_free(sport->dummy_tx_desc);
-       l1_data_sram_free(sport->dummy_buf);
-#else
-       dma_free_coherent(NULL, 2*sizeof(struct dmasg),
-               sport->dummy_rx_desc, 0);
-       dma_free_coherent(NULL, 2*sizeof(struct dmasg),
-               sport->dummy_tx_desc, 0);
-       kfree(sport->dummy_buf);
-#endif
-       free_dma(sport->dma_rx_chan);
-       free_dma(sport->dma_tx_chan);
-       free_irq(sport->err_irq, sport);
-
-       kfree(sport->private_data);
-       peripheral_free_list(sport->pin_req);
-       kfree(sport);
-}
-EXPORT_SYMBOL(sport_done);
-
-/*
-* It is only used to send several bytes when dma is not enabled
- * sport controller is configured but not enabled.
- * Multichannel cannot works with pio mode */
-/* Used by ac97 to write and read codec register */
-int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
-               u8 *in_data, int len)
-{
-       unsigned short dma_config;
-       unsigned short status;
-       unsigned long flags;
-       unsigned long wait = 0;
-
-       pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
-                       __func__, out_data, in_data, len);
-       pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
-                       "mcmc1:0x%04x, mcmc2:0x%04x\n",
-                       sport->regs->tcr1, sport->regs->tcr2,
-                       sport->regs->tclkdiv, sport->regs->tfsdiv,
-                       sport->regs->mcmc1, sport->regs->mcmc2);
-       flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));
-
-       /* Enable tx dma */
-       dma_config = (RESTART | WDSIZE_16 | DI_EN);
-       set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
-       set_dma_x_count(sport->dma_tx_chan, len/2);
-       set_dma_x_modify(sport->dma_tx_chan, 2);
-       set_dma_config(sport->dma_tx_chan, dma_config);
-       enable_dma(sport->dma_tx_chan);
-
-       if (in_data != NULL) {
-               invalidate_dcache_range((unsigned)in_data, \
-                               (unsigned)(in_data + len));
-               /* Enable rx dma */
-               dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
-               set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
-               set_dma_x_count(sport->dma_rx_chan, len/2);
-               set_dma_x_modify(sport->dma_rx_chan, 2);
-               set_dma_config(sport->dma_rx_chan, dma_config);
-               enable_dma(sport->dma_rx_chan);
-       }
-
-       local_irq_save(flags);
-       sport->regs->tcr1 |= TSPEN;
-       sport->regs->rcr1 |= RSPEN;
-       SSYNC();
-
-       status = get_dma_curr_irqstat(sport->dma_tx_chan);
-       while (status & DMA_RUN) {
-               udelay(1);
-               status = get_dma_curr_irqstat(sport->dma_tx_chan);
-               pr_debug("DMA status:0x%04x\n", status);
-               if (wait++ > 100)
-                       goto __over;
-       }
-       status = sport->regs->stat;
-       wait = 0;
-
-       while (!(status & TXHRE)) {
-               pr_debug("sport status:0x%04x\n", status);
-               udelay(1);
-               status = *(unsigned short *)&sport->regs->stat;
-               if (wait++ > 1000)
-                       goto __over;
-       }
-       /* Wait for the last byte sent out */
-       udelay(20);
-       pr_debug("sport status:0x%04x\n", status);
-
-__over:
-       sport->regs->tcr1 &= ~TSPEN;
-       sport->regs->rcr1 &= ~RSPEN;
-       SSYNC();
-       disable_dma(sport->dma_tx_chan);
-       /* Clear the status */
-       clear_dma_irqstat(sport->dma_tx_chan);
-       if (in_data != NULL) {
-               disable_dma(sport->dma_rx_chan);
-               clear_dma_irqstat(sport->dma_rx_chan);
-       }
-       SSYNC();
-       local_irq_restore(flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(sport_send_and_recv);
-
-MODULE_AUTHOR("Roy Huang");
-MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
deleted file mode 100644 (file)
index 9fc2192..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * File:         bf5xx_sport.h
- * Based on:
- * Author:       Roy Huang <roy.huang@analog.com>
- *
- * Created:
- * Description:
- *
- *               Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-
-#ifndef __BF5XX_SPORT_H__
-#define __BF5XX_SPORT_H__
-
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <asm/dma.h>
-#include <asm/bfin_sport.h>
-
-#define DESC_ELEMENT_COUNT 9
-
-struct sport_device {
-       int num;
-       int dma_rx_chan;
-       int dma_tx_chan;
-       int err_irq;
-       const unsigned short *pin_req;
-       struct sport_register *regs;
-
-       unsigned char *rx_buf;
-       unsigned char *tx_buf;
-       unsigned int rx_fragsize;
-       unsigned int tx_fragsize;
-       unsigned int rx_frags;
-       unsigned int tx_frags;
-       unsigned int wdsize;
-
-       /* for dummy dma transfer */
-       void *dummy_buf;
-       unsigned int dummy_count;
-
-       /* DMA descriptor ring head of current audio stream*/
-       struct dmasg *dma_rx_desc;
-       struct dmasg *dma_tx_desc;
-       unsigned int rx_desc_bytes;
-       unsigned int tx_desc_bytes;
-
-       unsigned int rx_run:1; /* rx is running */
-       unsigned int tx_run:1; /* tx is running */
-
-       struct dmasg *dummy_rx_desc;
-       struct dmasg *dummy_tx_desc;
-
-       struct dmasg *curr_rx_desc;
-       struct dmasg *curr_tx_desc;
-
-       int rx_curr_frag;
-       int tx_curr_frag;
-
-       unsigned int rcr1;
-       unsigned int rcr2;
-       int rx_tdm_count;
-
-       unsigned int tcr1;
-       unsigned int tcr2;
-       int tx_tdm_count;
-
-       void (*rx_callback)(void *data);
-       void *rx_data;
-       void (*tx_callback)(void *data);
-       void *tx_data;
-       void (*err_callback)(void *data);
-       void *err_data;
-       unsigned char *tx_dma_buf;
-       unsigned char *rx_dma_buf;
-#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
-       dma_addr_t tx_dma_phy;
-       dma_addr_t rx_dma_phy;
-       int tx_pos;/*pcm sample count*/
-       int rx_pos;
-       unsigned int tx_buffer_size;
-       unsigned int rx_buffer_size;
-       int tx_delay_pos;
-       int once;
-#endif
-       void *private_data;
-};
-
-struct sport_param {
-       int num;
-       int dma_rx_chan;
-       int dma_tx_chan;
-       int err_irq;
-       const unsigned short *pin_req;
-       struct sport_register *regs;
-       unsigned int wdsize;
-       unsigned int dummy_count;
-       void *private_data;
-};
-
-struct sport_device *sport_init(struct platform_device *pdev,
-       unsigned int wdsize, unsigned int dummy_count, size_t priv_size);
-
-void sport_done(struct sport_device *sport);
-
-/* first use these ...*/
-
-/* note: multichannel is in units of 8 channels, tdm_count is number of channels
- *  NOT / 8 ! all channels are enabled by default */
-int sport_set_multichannel(struct sport_device *sport, int tdm_count,
-               u32 tx_mask, u32 rx_mask, int packed);
-
-int sport_config_rx(struct sport_device *sport,
-               unsigned int rcr1, unsigned int rcr2,
-               unsigned int clkdiv, unsigned int fsdiv);
-
-int sport_config_tx(struct sport_device *sport,
-               unsigned int tcr1, unsigned int tcr2,
-               unsigned int clkdiv, unsigned int fsdiv);
-
-/* ... then these: */
-
-/* buffer size (in bytes) == fragcount * fragsize_bytes */
-
-/* this is not a very general api, it sets the dma to 2d autobuffer mode */
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-               int fragcount, size_t fragsize_bytes);
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
-               int fragcount, size_t fragsize_bytes);
-
-int sport_tx_start(struct sport_device *sport);
-int sport_tx_stop(struct sport_device *sport);
-int sport_rx_start(struct sport_device *sport);
-int sport_rx_stop(struct sport_device *sport);
-
-/* for use in interrupt handler */
-unsigned long sport_curr_offset_rx(struct sport_device *sport);
-unsigned long sport_curr_offset_tx(struct sport_device *sport);
-
-void sport_incfrag(struct sport_device *sport, int *frag, int tx);
-void sport_decfrag(struct sport_device *sport, int *frag, int tx);
-
-int sport_set_rx_callback(struct sport_device *sport,
-                      void (*rx_callback)(void *), void *rx_data);
-int sport_set_tx_callback(struct sport_device *sport,
-                      void (*tx_callback)(void *), void *tx_data);
-int sport_set_err_callback(struct sport_device *sport,
-                      void (*err_callback)(void *), void *err_data);
-
-int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
-               u8 *in_data, int len);
-#endif /* BF53X_SPORT_H */
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
deleted file mode 100644 (file)
index 9c19ccc..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-ssm2602.c
- * Author:       Cliff Cai <Cliff.Cai@analog.com>
- *
- * Created:      Tue June 06 2008
- * Description:  board driver for SSM2602 sound chip
- *
- * Modified:
- *               Copyright 2008 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-#include <linux/gpio.h>
-#include "../codecs/ssm2602.h"
-#include "bf5xx-sport.h"
-
-static struct snd_soc_card bf5xx_ssm2602;
-
-static int bf5xx_ssm2602_dai_init(struct snd_soc_pcm_runtime *rtd)
-{
-       /*
-        * If you are using a crystal source which frequency is not 12MHz
-        * then modify the below case statement with frequency of the crystal.
-        *
-        * If you are using the SPORT to generate clocking then this is
-        * where to do it.
-        */
-       return snd_soc_dai_set_sysclk(rtd->codec_dai, SSM2602_SYSCLK, 12000000,
-               SND_SOC_CLOCK_IN);
-}
-
-/* CODEC is master for BCLK and LRC in this configuration. */
-#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
-                               SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
-       {
-               .name = "ssm2602",
-               .stream_name = "SSM2602",
-               .cpu_dai_name = "bfin-i2s.0",
-               .codec_dai_name = "ssm2602-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "ssm2602.0-001b",
-               .init = bf5xx_ssm2602_dai_init,
-               .dai_fmt = BF5XX_SSM2602_DAIFMT,
-       },
-       {
-               .name = "ssm2602",
-               .stream_name = "SSM2602",
-               .cpu_dai_name = "bfin-i2s.1",
-               .codec_dai_name = "ssm2602-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "ssm2602.0-001b",
-               .init = bf5xx_ssm2602_dai_init,
-               .dai_fmt = BF5XX_SSM2602_DAIFMT,
-       },
-};
-
-static struct snd_soc_card bf5xx_ssm2602 = {
-       .name = "bfin-ssm2602",
-       .owner = THIS_MODULE,
-       .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-       .num_links = 1,
-};
-
-static struct platform_device *bf5xx_ssm2602_snd_device;
-
-static int __init bf5xx_ssm2602_init(void)
-{
-       int ret;
-
-       pr_debug("%s enter\n", __func__);
-       bf5xx_ssm2602_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!bf5xx_ssm2602_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(bf5xx_ssm2602_snd_device, &bf5xx_ssm2602);
-       ret = platform_device_add(bf5xx_ssm2602_snd_device);
-
-       if (ret)
-               platform_device_put(bf5xx_ssm2602_snd_device);
-
-       return ret;
-}
-
-static void __exit bf5xx_ssm2602_exit(void)
-{
-       pr_debug("%s enter\n", __func__);
-       platform_device_unregister(bf5xx_ssm2602_snd_device);
-}
-
-module_init(bf5xx_ssm2602_init);
-module_exit(bf5xx_ssm2602_exit);
-
-/* Module information */
-MODULE_AUTHOR("Cliff Cai");
-MODULE_DESCRIPTION("ALSA SoC SSM2602 BF527-EZKIT");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
deleted file mode 100644 (file)
index 819cff1..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * bf6xx-i2s.c - Analog Devices BF6XX i2s interface driver
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dai.h>
-
-#include "bf6xx-sport.h"
-
-struct sport_params param;
-
-static int bfin_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-               unsigned int fmt)
-{
-       struct sport_device *sport = snd_soc_dai_get_drvdata(cpu_dai);
-       struct device *dev = &sport->pdev->dev;
-       int ret = 0;
-
-       param.spctl &= ~(SPORT_CTL_OPMODE | SPORT_CTL_CKRE | SPORT_CTL_FSR
-                       | SPORT_CTL_LFS | SPORT_CTL_LAFS);
-       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-       case SND_SOC_DAIFMT_I2S:
-               param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_CKRE
-                       | SPORT_CTL_LFS;
-               break;
-       case SND_SOC_DAIFMT_DSP_A:
-               param.spctl |= SPORT_CTL_FSR;
-               break;
-       case SND_SOC_DAIFMT_LEFT_J:
-               param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_LFS
-                       | SPORT_CTL_LAFS;
-               break;
-       default:
-               dev_err(dev, "%s: Unknown DAI format type\n", __func__);
-               ret = -EINVAL;
-               break;
-       }
-
-       param.spctl &= ~(SPORT_CTL_ICLK | SPORT_CTL_IFS);
-       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-       case SND_SOC_DAIFMT_CBM_CFM:
-               break;
-       case SND_SOC_DAIFMT_CBS_CFS:
-       case SND_SOC_DAIFMT_CBM_CFS:
-       case SND_SOC_DAIFMT_CBS_CFM:
-               ret = -EINVAL;
-               break;
-       default:
-               dev_err(dev, "%s: Unknown DAI master type\n", __func__);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-static int bfin_i2s_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params,
-                               struct snd_soc_dai *dai)
-{
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-       struct device *dev = &sport->pdev->dev;
-       int ret = 0;
-
-       param.spctl &= ~SPORT_CTL_SLEN;
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S8:
-               param.spctl |= 0x70;
-               sport->wdsize = 1;
-               break;
-       case SNDRV_PCM_FORMAT_S16_LE:
-               param.spctl |= 0xf0;
-               sport->wdsize = 2;
-               break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               param.spctl |= 0x170;
-               sport->wdsize = 3;
-               break;
-       case SNDRV_PCM_FORMAT_S32_LE:
-               param.spctl |= 0x1f0;
-               sport->wdsize = 4;
-               break;
-       }
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               ret = sport_set_tx_params(sport, &param);
-               if (ret) {
-                       dev_err(dev, "SPORT tx is busy!\n");
-                       return ret;
-               }
-       } else {
-               ret = sport_set_rx_params(sport, &param);
-               if (ret) {
-                       dev_err(dev, "SPORT rx is busy!\n");
-                       return ret;
-               }
-       }
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int bfin_i2s_suspend(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-       if (dai->capture_active)
-               sport_rx_stop(sport);
-       if (dai->playback_active)
-               sport_tx_stop(sport);
-       return 0;
-}
-
-static int bfin_i2s_resume(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-       struct device *dev = &sport->pdev->dev;
-       int ret;
-
-       ret = sport_set_tx_params(sport, &param);
-       if (ret) {
-               dev_err(dev, "SPORT tx is busy!\n");
-               return ret;
-       }
-       ret = sport_set_rx_params(sport, &param);
-       if (ret) {
-               dev_err(dev, "SPORT rx is busy!\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-#else
-#define bfin_i2s_suspend NULL
-#define bfin_i2s_resume NULL
-#endif
-
-#define BFIN_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
-               SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
-               SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
-               SNDRV_PCM_RATE_96000)
-
-#define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
-               SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-static const struct snd_soc_dai_ops bfin_i2s_dai_ops = {
-       .hw_params      = bfin_i2s_hw_params,
-       .set_fmt        = bfin_i2s_set_dai_fmt,
-};
-
-static struct snd_soc_dai_driver bfin_i2s_dai = {
-       .suspend = bfin_i2s_suspend,
-       .resume = bfin_i2s_resume,
-       .playback = {
-               .channels_min = 1,
-               .channels_max = 2,
-               .rates = BFIN_I2S_RATES,
-               .formats = BFIN_I2S_FORMATS,
-       },
-       .capture = {
-               .channels_min = 1,
-               .channels_max = 2,
-               .rates = BFIN_I2S_RATES,
-               .formats = BFIN_I2S_FORMATS,
-       },
-       .ops = &bfin_i2s_dai_ops,
-};
-
-static const struct snd_soc_component_driver bfin_i2s_component = {
-       .name           = "bfin-i2s",
-};
-
-static int bfin_i2s_probe(struct platform_device *pdev)
-{
-       struct sport_device *sport;
-       struct device *dev = &pdev->dev;
-       int ret;
-
-       sport = sport_create(pdev);
-       if (!sport)
-               return -ENODEV;
-
-       /* register with the ASoC layers */
-       ret = snd_soc_register_component(dev, &bfin_i2s_component,
-                                        &bfin_i2s_dai, 1);
-       if (ret) {
-               dev_err(dev, "Failed to register DAI: %d\n", ret);
-               sport_delete(sport);
-               return ret;
-       }
-       platform_set_drvdata(pdev, sport);
-
-       return 0;
-}
-
-static int bfin_i2s_remove(struct platform_device *pdev)
-{
-       struct sport_device *sport = platform_get_drvdata(pdev);
-
-       snd_soc_unregister_component(&pdev->dev);
-       sport_delete(sport);
-
-       return 0;
-}
-
-static struct platform_driver bfin_i2s_driver = {
-       .probe  = bfin_i2s_probe,
-       .remove = bfin_i2s_remove,
-       .driver = {
-               .name = "bfin-i2s",
-       },
-};
-
-module_platform_driver(bfin_i2s_driver);
-
-MODULE_DESCRIPTION("Analog Devices BF6XX i2s interface driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c
deleted file mode 100644 (file)
index d2caadf..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * bf6xx_sport.c Analog Devices BF6XX SPORT driver
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <asm/blackfin.h>
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#include "bf6xx-sport.h"
-
-int sport_set_tx_params(struct sport_device *sport,
-                       struct sport_params *params)
-{
-       if (sport->tx_regs->spctl & SPORT_CTL_SPENPRI)
-               return -EBUSY;
-       sport->tx_regs->spctl = params->spctl | SPORT_CTL_SPTRAN;
-       sport->tx_regs->div = params->div;
-       SSYNC();
-       return 0;
-}
-EXPORT_SYMBOL(sport_set_tx_params);
-
-int sport_set_rx_params(struct sport_device *sport,
-                       struct sport_params *params)
-{
-       if (sport->rx_regs->spctl & SPORT_CTL_SPENPRI)
-               return -EBUSY;
-       sport->rx_regs->spctl = params->spctl & ~SPORT_CTL_SPTRAN;
-       sport->rx_regs->div = params->div;
-       SSYNC();
-       return 0;
-}
-EXPORT_SYMBOL(sport_set_rx_params);
-
-static int compute_wdsize(size_t wdsize)
-{
-       switch (wdsize) {
-       case 1:
-               return WDSIZE_8 | PSIZE_8;
-       case 2:
-               return WDSIZE_16 | PSIZE_16;
-       default:
-               return WDSIZE_32 | PSIZE_32;
-       }
-}
-
-void sport_tx_start(struct sport_device *sport)
-{
-       set_dma_next_desc_addr(sport->tx_dma_chan, sport->tx_desc);
-       set_dma_config(sport->tx_dma_chan, DMAFLOW_LIST | DI_EN
-                       | compute_wdsize(sport->wdsize) | NDSIZE_6);
-       enable_dma(sport->tx_dma_chan);
-       sport->tx_regs->spctl |= SPORT_CTL_SPENPRI;
-       SSYNC();
-}
-EXPORT_SYMBOL(sport_tx_start);
-
-void sport_rx_start(struct sport_device *sport)
-{
-       set_dma_next_desc_addr(sport->rx_dma_chan, sport->rx_desc);
-       set_dma_config(sport->rx_dma_chan, DMAFLOW_LIST | DI_EN | WNR
-                       | compute_wdsize(sport->wdsize) | NDSIZE_6);
-       enable_dma(sport->rx_dma_chan);
-       sport->rx_regs->spctl |= SPORT_CTL_SPENPRI;
-       SSYNC();
-}
-EXPORT_SYMBOL(sport_rx_start);
-
-void sport_tx_stop(struct sport_device *sport)
-{
-       sport->tx_regs->spctl &= ~SPORT_CTL_SPENPRI;
-       SSYNC();
-       disable_dma(sport->tx_dma_chan);
-}
-EXPORT_SYMBOL(sport_tx_stop);
-
-void sport_rx_stop(struct sport_device *sport)
-{
-       sport->rx_regs->spctl &= ~SPORT_CTL_SPENPRI;
-       SSYNC();
-       disable_dma(sport->rx_dma_chan);
-}
-EXPORT_SYMBOL(sport_rx_stop);
-
-void sport_set_tx_callback(struct sport_device *sport,
-               void (*tx_callback)(void *), void *tx_data)
-{
-       sport->tx_callback = tx_callback;
-       sport->tx_data = tx_data;
-}
-EXPORT_SYMBOL(sport_set_tx_callback);
-
-void sport_set_rx_callback(struct sport_device *sport,
-               void (*rx_callback)(void *), void *rx_data)
-{
-       sport->rx_callback = rx_callback;
-       sport->rx_data = rx_data;
-}
-EXPORT_SYMBOL(sport_set_rx_callback);
-
-static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
-               size_t fragsize, unsigned int cfg,
-               unsigned int count, size_t wdsize)
-{
-
-       int i;
-
-       for (i = 0; i < fragcount; ++i) {
-               desc[i].next_desc_addr  = &(desc[i + 1]);
-               desc[i].start_addr = (unsigned long)buf + i * fragsize;
-               desc[i].cfg = cfg;
-               desc[i].x_count = count;
-               desc[i].x_modify = wdsize;
-               desc[i].y_count = 0;
-               desc[i].y_modify = 0;
-       }
-
-       /* make circular */
-       desc[fragcount - 1].next_desc_addr = desc;
-}
-
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
-               int fragcount, size_t fragsize)
-{
-       unsigned int count;
-       unsigned int cfg;
-       dma_addr_t addr;
-
-       count = fragsize / sport->wdsize;
-
-       if (sport->tx_desc)
-               dma_free_coherent(NULL, sport->tx_desc_size,
-                               sport->tx_desc, 0);
-
-       sport->tx_desc = dma_alloc_coherent(NULL,
-                       fragcount * sizeof(struct dmasg), &addr, 0);
-       sport->tx_desc_size = fragcount * sizeof(struct dmasg);
-       if (!sport->tx_desc)
-               return -ENOMEM;
-
-       sport->tx_buf = buf;
-       sport->tx_fragsize = fragsize;
-       sport->tx_frags = fragcount;
-       cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6;
-
-       setup_desc(sport->tx_desc, buf, fragcount, fragsize,
-                  cfg | DMAEN, count, sport->wdsize);
-       return 0;
-}
-EXPORT_SYMBOL(sport_config_tx_dma);
-
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-               int fragcount, size_t fragsize)
-{
-       unsigned int count;
-       unsigned int cfg;
-       dma_addr_t addr;
-
-       count = fragsize / sport->wdsize;
-
-       if (sport->rx_desc)
-               dma_free_coherent(NULL, sport->rx_desc_size,
-                               sport->rx_desc, 0);
-
-       sport->rx_desc = dma_alloc_coherent(NULL,
-                       fragcount * sizeof(struct dmasg), &addr, 0);
-       sport->rx_desc_size = fragcount * sizeof(struct dmasg);
-       if (!sport->rx_desc)
-               return -ENOMEM;
-
-       sport->rx_buf = buf;
-       sport->rx_fragsize = fragsize;
-       sport->rx_frags = fragcount;
-       cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize)
-               | WNR | NDSIZE_6;
-
-       setup_desc(sport->rx_desc, buf, fragcount, fragsize,
-                  cfg | DMAEN, count, sport->wdsize);
-       return 0;
-}
-EXPORT_SYMBOL(sport_config_rx_dma);
-
-unsigned long sport_curr_offset_tx(struct sport_device *sport)
-{
-       unsigned long curr = get_dma_curr_addr(sport->tx_dma_chan);
-
-       return (unsigned char *)curr - sport->tx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_tx);
-
-unsigned long sport_curr_offset_rx(struct sport_device *sport)
-{
-       unsigned long curr = get_dma_curr_addr(sport->rx_dma_chan);
-
-       return (unsigned char *)curr - sport->rx_buf;
-}
-EXPORT_SYMBOL(sport_curr_offset_rx);
-
-static irqreturn_t sport_tx_irq(int irq, void *dev_id)
-{
-       struct sport_device *sport = dev_id;
-       static unsigned long status;
-
-       status = get_dma_curr_irqstat(sport->tx_dma_chan);
-       if (status & (DMA_DONE | DMA_ERR)) {
-               clear_dma_irqstat(sport->tx_dma_chan);
-               SSYNC();
-       }
-       if (sport->tx_callback)
-               sport->tx_callback(sport->tx_data);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t sport_rx_irq(int irq, void *dev_id)
-{
-       struct sport_device *sport = dev_id;
-       unsigned long status;
-
-       status = get_dma_curr_irqstat(sport->rx_dma_chan);
-       if (status & (DMA_DONE | DMA_ERR)) {
-               clear_dma_irqstat(sport->rx_dma_chan);
-               SSYNC();
-       }
-       if (sport->rx_callback)
-               sport->rx_callback(sport->rx_data);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t sport_err_irq(int irq, void *dev_id)
-{
-       struct sport_device *sport = dev_id;
-       struct device *dev = &sport->pdev->dev;
-
-       if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI)
-               dev_err(dev, "sport error: TUVF\n");
-       if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI)
-               dev_err(dev, "sport error: ROVF\n");
-
-       return IRQ_HANDLED;
-}
-
-static int sport_get_resource(struct sport_device *sport)
-{
-       struct platform_device *pdev = sport->pdev;
-       struct device *dev = &pdev->dev;
-       struct bfin_snd_platform_data *pdata = dev->platform_data;
-       struct resource *res;
-
-       if (!pdata) {
-               dev_err(dev, "No platform data\n");
-               return -ENODEV;
-       }
-       sport->pin_req = pdata->pin_req;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               dev_err(dev, "No tx MEM resource\n");
-               return -ENODEV;
-       }
-       sport->tx_regs = (struct sport_register *)res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!res) {
-               dev_err(dev, "No rx MEM resource\n");
-               return -ENODEV;
-       }
-       sport->rx_regs = (struct sport_register *)res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!res) {
-               dev_err(dev, "No tx DMA resource\n");
-               return -ENODEV;
-       }
-       sport->tx_dma_chan = res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (!res) {
-               dev_err(dev, "No rx DMA resource\n");
-               return -ENODEV;
-       }
-       sport->rx_dma_chan = res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!res) {
-               dev_err(dev, "No tx error irq resource\n");
-               return -ENODEV;
-       }
-       sport->tx_err_irq = res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-       if (!res) {
-               dev_err(dev, "No rx error irq resource\n");
-               return -ENODEV;
-       }
-       sport->rx_err_irq = res->start;
-
-       return 0;
-}
-
-static int sport_request_resource(struct sport_device *sport)
-{
-       struct device *dev = &sport->pdev->dev;
-       int ret;
-
-       ret = peripheral_request_list(sport->pin_req, "soc-audio");
-       if (ret) {
-               dev_err(dev, "Unable to request sport pin\n");
-               return ret;
-       }
-
-       ret = request_dma(sport->tx_dma_chan, "SPORT TX Data");
-       if (ret) {
-               dev_err(dev, "Unable to allocate DMA channel for sport tx\n");
-               goto err_tx_dma;
-       }
-       set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport);
-
-       ret = request_dma(sport->rx_dma_chan, "SPORT RX Data");
-       if (ret) {
-               dev_err(dev, "Unable to allocate DMA channel for sport rx\n");
-               goto err_rx_dma;
-       }
-       set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport);
-
-       ret = request_irq(sport->tx_err_irq, sport_err_irq,
-                       0, "SPORT TX ERROR", sport);
-       if (ret) {
-               dev_err(dev, "Unable to allocate tx error IRQ for sport\n");
-               goto err_tx_irq;
-       }
-
-       ret = request_irq(sport->rx_err_irq, sport_err_irq,
-                       0, "SPORT RX ERROR", sport);
-       if (ret) {
-               dev_err(dev, "Unable to allocate rx error IRQ for sport\n");
-               goto err_rx_irq;
-       }
-
-       return 0;
-err_rx_irq:
-       free_irq(sport->tx_err_irq, sport);
-err_tx_irq:
-       free_dma(sport->rx_dma_chan);
-err_rx_dma:
-       free_dma(sport->tx_dma_chan);
-err_tx_dma:
-       peripheral_free_list(sport->pin_req);
-       return ret;
-}
-
-static void sport_free_resource(struct sport_device *sport)
-{
-       free_irq(sport->rx_err_irq, sport);
-       free_irq(sport->tx_err_irq, sport);
-       free_dma(sport->rx_dma_chan);
-       free_dma(sport->tx_dma_chan);
-       peripheral_free_list(sport->pin_req);
-}
-
-struct sport_device *sport_create(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct sport_device *sport;
-       int ret;
-
-       sport = kzalloc(sizeof(*sport), GFP_KERNEL);
-       if (!sport)
-               return NULL;
-
-       sport->pdev = pdev;
-
-       ret = sport_get_resource(sport);
-       if (ret)
-               goto free_data;
-
-       ret = sport_request_resource(sport);
-       if (ret)
-               goto free_data;
-
-       dev_dbg(dev, "SPORT create success\n");
-       return sport;
-free_data:
-       kfree(sport);
-       return NULL;
-}
-EXPORT_SYMBOL(sport_create);
-
-void sport_delete(struct sport_device *sport)
-{
-       if (sport->tx_desc)
-               dma_free_coherent(NULL, sport->tx_desc_size,
-                               sport->tx_desc, 0);
-       if (sport->rx_desc)
-               dma_free_coherent(NULL, sport->rx_desc_size,
-                               sport->rx_desc, 0);
-       sport_free_resource(sport);
-       kfree(sport);
-}
-EXPORT_SYMBOL(sport_delete);
-
-MODULE_DESCRIPTION("Analog Devices BF6XX SPORT driver");
-MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.h b/sound/soc/blackfin/bf6xx-sport.h
deleted file mode 100644 (file)
index 307d193..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * bf6xx_sport - Analog Devices BF6XX SPORT driver
- *
- * Copyright (c) 2012 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _BF6XX_SPORT_H_
-#define _BF6XX_SPORT_H_
-
-#include <linux/platform_device.h>
-#include <asm/bfin_sport3.h>
-
-struct sport_device {
-       struct platform_device *pdev;
-       const unsigned short *pin_req;
-       struct sport_register *tx_regs;
-       struct sport_register *rx_regs;
-       int tx_dma_chan;
-       int rx_dma_chan;
-       int tx_err_irq;
-       int rx_err_irq;
-
-       void (*tx_callback)(void *data);
-       void *tx_data;
-       void (*rx_callback)(void *data);
-       void *rx_data;
-
-       struct dmasg *tx_desc;
-       struct dmasg *rx_desc;
-       unsigned int tx_desc_size;
-       unsigned int rx_desc_size;
-       unsigned char *tx_buf;
-       unsigned char *rx_buf;
-       unsigned int tx_fragsize;
-       unsigned int rx_fragsize;
-       unsigned int tx_frags;
-       unsigned int rx_frags;
-       unsigned int wdsize;
-};
-
-struct sport_params {
-       u32 spctl;
-       u32 div;
-};
-
-struct sport_device *sport_create(struct platform_device *pdev);
-void sport_delete(struct sport_device *sport);
-int sport_set_tx_params(struct sport_device *sport,
-               struct sport_params *params);
-int sport_set_rx_params(struct sport_device *sport,
-               struct sport_params *params);
-void sport_tx_start(struct sport_device *sport);
-void sport_rx_start(struct sport_device *sport);
-void sport_tx_stop(struct sport_device *sport);
-void sport_rx_stop(struct sport_device *sport);
-void sport_set_tx_callback(struct sport_device *sport,
-       void (*tx_callback)(void *), void *tx_data);
-void sport_set_rx_callback(struct sport_device *sport,
-       void (*rx_callback)(void *), void *rx_data);
-int sport_config_tx_dma(struct sport_device *sport, void *buf,
-       int fragcount, size_t fragsize);
-int sport_config_rx_dma(struct sport_device *sport, void *buf,
-       int fragcount, size_t fragsize);
-unsigned long sport_curr_offset_tx(struct sport_device *sport);
-unsigned long sport_curr_offset_rx(struct sport_device *sport);
-
-
-
-#endif
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
deleted file mode 100644 (file)
index 64b88fd..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1373 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau1373.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = {
-       SND_SOC_DAPM_LINE("Line In1", NULL),
-       SND_SOC_DAPM_LINE("Line In2", NULL),
-       SND_SOC_DAPM_LINE("Line In3", NULL),
-       SND_SOC_DAPM_LINE("Line In4", NULL),
-
-       SND_SOC_DAPM_LINE("Line Out1", NULL),
-       SND_SOC_DAPM_LINE("Line Out2", NULL),
-       SND_SOC_DAPM_LINE("Stereo Out", NULL),
-       SND_SOC_DAPM_HP("Headphone", NULL),
-       SND_SOC_DAPM_HP("Earpiece", NULL),
-       SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = {
-       { "AIN1L", NULL, "Line In1" },
-       { "AIN1R", NULL, "Line In1" },
-       { "AIN2L", NULL, "Line In2" },
-       { "AIN2R", NULL, "Line In2" },
-       { "AIN3L", NULL, "Line In3" },
-       { "AIN3R", NULL, "Line In3" },
-       { "AIN4L", NULL, "Line In4" },
-       { "AIN4R", NULL, "Line In4" },
-
-       /* MICBIAS can be connected via a jumper to the line-in jack, since w
-          don't know which one is going to be used, just power both. */
-       { "Line In1", NULL, "MICBIAS1" },
-       { "Line In2", NULL, "MICBIAS1" },
-       { "Line In3", NULL, "MICBIAS1" },
-       { "Line In4", NULL, "MICBIAS1" },
-       { "Line In1", NULL, "MICBIAS2" },
-       { "Line In2", NULL, "MICBIAS2" },
-       { "Line In3", NULL, "MICBIAS2" },
-       { "Line In4", NULL, "MICBIAS2" },
-
-       { "Line Out1", NULL, "LOUT1L" },
-       { "Line Out1", NULL, "LOUT1R" },
-       { "Line Out2", NULL, "LOUT2L" },
-       { "Line Out2", NULL, "LOUT2R" },
-       { "Headphone", NULL, "HPL" },
-       { "Headphone", NULL, "HPR" },
-       { "Earpiece", NULL, "EP" },
-       { "Speaker", NULL, "SPKL" },
-       { "Stereo Out", NULL, "SPKR" },
-};
-
-static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int ret;
-       int pll_rate;
-
-       switch (params_rate(params)) {
-       case 48000:
-       case 8000:
-       case 12000:
-       case 16000:
-       case 24000:
-       case 32000:
-               pll_rate = 48000 * 1024;
-               break;
-       case 44100:
-       case 7350:
-       case 11025:
-       case 14700:
-       case 22050:
-       case 29400:
-               pll_rate = 44100 * 1024;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
-                       ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
-       if (ret)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
-                       SND_SOC_CLOCK_IN);
-
-       return ret;
-}
-
-static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       unsigned int pll_rate = 48000 * 1024;
-       int ret;
-
-       ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1,
-                       ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate);
-       if (ret)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate,
-                       SND_SOC_CLOCK_IN);
-
-       return ret;
-}
-static const struct snd_soc_ops bfin_eval_adau1373_ops = {
-       .hw_params = bfin_eval_adau1373_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
-       .name = "adau1373",
-       .stream_name = "adau1373",
-       .cpu_dai_name = "bfin-i2s.0",
-       .codec_dai_name = "adau1373-aif1",
-       .platform_name = "bfin-i2s-pcm-audio",
-       .codec_name = "adau1373.0-001a",
-       .ops = &bfin_eval_adau1373_ops,
-       .init = bfin_eval_adau1373_codec_init,
-       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-                       SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1373 = {
-       .name = "bfin-eval-adau1373",
-       .owner = THIS_MODULE,
-       .dai_link = &bfin_eval_adau1373_dai,
-       .num_links = 1,
-
-       .dapm_widgets           = bfin_eval_adau1373_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets),
-       .dapm_routes            = bfin_eval_adau1373_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes),
-};
-
-static int bfin_eval_adau1373_probe(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = &bfin_eval_adau1373;
-
-       card->dev = &pdev->dev;
-
-       return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1373);
-}
-
-static struct platform_driver bfin_eval_adau1373_driver = {
-       .driver = {
-               .name = "bfin-eval-adau1373",
-               .pm = &snd_soc_pm_ops,
-       },
-       .probe = bfin_eval_adau1373_probe,
-};
-
-module_platform_driver(bfin_eval_adau1373_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1373");
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
deleted file mode 100644 (file)
index 5c67f72..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1701MINIZ on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau1701.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1701_dapm_widgets[] = {
-       SND_SOC_DAPM_SPK("Speaker", NULL),
-       SND_SOC_DAPM_LINE("Line Out", NULL),
-       SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1701_dapm_routes[] = {
-       { "Speaker", NULL, "OUT0" },
-       { "Speaker", NULL, "OUT1" },
-       { "Line Out", NULL, "OUT2" },
-       { "Line Out", NULL, "OUT3" },
-
-       { "IN0", NULL, "Line In" },
-       { "IN1", NULL, "Line In" },
-};
-
-static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
-                       SND_SOC_CLOCK_IN);
-
-       return ret;
-}
-
-static struct snd_soc_ops bfin_eval_adau1701_ops = {
-       .hw_params = bfin_eval_adau1701_hw_params,
-};
-
-#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
-                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
-
-static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
-       {
-               .name = "adau1701",
-               .stream_name = "adau1701",
-               .cpu_dai_name = "bfin-i2s.0",
-               .codec_dai_name = "adau1701",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "adau1701.0-0034",
-               .ops = &bfin_eval_adau1701_ops,
-               .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
-       },
-       {
-               .name = "adau1701",
-               .stream_name = "adau1701",
-               .cpu_dai_name = "bfin-i2s.1",
-               .codec_dai_name = "adau1701",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .codec_name = "adau1701.0-0034",
-               .ops = &bfin_eval_adau1701_ops,
-               .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
-       },
-};
-
-static struct snd_soc_card bfin_eval_adau1701 = {
-       .name = "bfin-eval-adau1701",
-       .owner = THIS_MODULE,
-       .dai_link = &bfin_eval_adau1701_dai[CONFIG_SND_BF5XX_SPORT_NUM],
-       .num_links = 1,
-
-       .dapm_widgets           = bfin_eval_adau1701_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(bfin_eval_adau1701_dapm_widgets),
-       .dapm_routes            = bfin_eval_adau1701_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(bfin_eval_adau1701_dapm_routes),
-};
-
-static int bfin_eval_adau1701_probe(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = &bfin_eval_adau1701;
-
-       card->dev = &pdev->dev;
-
-       return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1701);
-}
-
-static struct platform_driver bfin_eval_adau1701_driver = {
-       .driver = {
-               .name = "bfin-eval-adau1701",
-               .pm = &snd_soc_pm_ops,
-       },
-       .probe = bfin_eval_adau1701_probe,
-};
-
-module_platform_driver(bfin_eval_adau1701_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1701");
diff --git a/sound/soc/blackfin/bfin-eval-adau1x61.c b/sound/soc/blackfin/bfin-eval-adau1x61.c
deleted file mode 100644 (file)
index fddfe00..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1x61MINIZ on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011-2014 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau17x1.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1x61_dapm_widgets[] = {
-       SND_SOC_DAPM_LINE("In 1", NULL),
-       SND_SOC_DAPM_LINE("In 2", NULL),
-       SND_SOC_DAPM_LINE("In 3-4", NULL),
-
-       SND_SOC_DAPM_LINE("Diff Out L", NULL),
-       SND_SOC_DAPM_LINE("Diff Out R", NULL),
-       SND_SOC_DAPM_LINE("Stereo Out", NULL),
-       SND_SOC_DAPM_HP("Capless HP Out", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1x61_dapm_routes[] = {
-       { "LAUX", NULL, "In 3-4" },
-       { "RAUX", NULL, "In 3-4" },
-       { "LINP", NULL, "In 1" },
-       { "LINN", NULL, "In 1"},
-       { "RINP", NULL, "In 2" },
-       { "RINN", NULL, "In 2" },
-
-       { "In 1", NULL, "MICBIAS" },
-       { "In 2", NULL, "MICBIAS" },
-
-       { "Capless HP Out", NULL, "LHP" },
-       { "Capless HP Out", NULL, "RHP" },
-       { "Diff Out L", NULL, "LOUT" },
-       { "Diff Out R", NULL, "ROUT" },
-       { "Stereo Out", NULL, "LOUT" },
-       { "Stereo Out", NULL, "ROUT" },
-};
-
-static int bfin_eval_adau1x61_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int pll_rate;
-       int ret;
-
-       switch (params_rate(params)) {
-       case 48000:
-       case 8000:
-       case 12000:
-       case 16000:
-       case 24000:
-       case 32000:
-       case 96000:
-               pll_rate = 48000 * 1024;
-               break;
-       case 44100:
-       case 7350:
-       case 11025:
-       case 14700:
-       case 22050:
-       case 29400:
-       case 88200:
-               pll_rate = 44100 * 1024;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = snd_soc_dai_set_pll(codec_dai, ADAU17X1_PLL,
-                       ADAU17X1_PLL_SRC_MCLK, 12288000, pll_rate);
-       if (ret)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU17X1_CLK_SRC_PLL, pll_rate,
-                       SND_SOC_CLOCK_IN);
-
-       return ret;
-}
-
-static const struct snd_soc_ops bfin_eval_adau1x61_ops = {
-       .hw_params = bfin_eval_adau1x61_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1x61_dai = {
-       .name = "adau1x61",
-       .stream_name = "adau1x61",
-       .cpu_dai_name = "bfin-i2s.0",
-       .codec_dai_name = "adau-hifi",
-       .platform_name = "bfin-i2s-pcm-audio",
-       .codec_name = "adau1761.0-0038",
-       .ops = &bfin_eval_adau1x61_ops,
-       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-               SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1x61 = {
-       .name = "bfin-eval-adau1x61",
-       .owner = THIS_MODULE,
-       .driver_name = "eval-adau1x61",
-       .dai_link = &bfin_eval_adau1x61_dai,
-       .num_links = 1,
-
-       .dapm_widgets = bfin_eval_adau1x61_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1x61_dapm_widgets),
-       .dapm_routes = bfin_eval_adau1x61_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1x61_dapm_routes),
-       .fully_routed = true,
-};
-
-static int bfin_eval_adau1x61_probe(struct platform_device *pdev)
-{
-       bfin_eval_adau1x61.dev = &pdev->dev;
-
-       return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1x61);
-}
-
-static struct platform_driver bfin_eval_adau1x61_driver = {
-       .driver = {
-               .name = "bfin-eval-adau1x61",
-               .pm = &snd_soc_pm_ops,
-       },
-       .probe = bfin_eval_adau1x61_probe,
-};
-module_platform_driver(bfin_eval_adau1x61_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1x61 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1x61");
diff --git a/sound/soc/blackfin/bfin-eval-adau1x81.c b/sound/soc/blackfin/bfin-eval-adau1x81.c
deleted file mode 100644 (file)
index 3e01cbe..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Machine driver for EVAL-ADAU1x81 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011-2014 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-
-#include "../codecs/adau17x1.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adau1x81_dapm_widgets[] = {
-       SND_SOC_DAPM_LINE("Stereo In", NULL),
-       SND_SOC_DAPM_LINE("Beep", NULL),
-
-       SND_SOC_DAPM_SPK("Speaker", NULL),
-       SND_SOC_DAPM_HP("Headphone", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adau1x81_dapm_routes[] = {
-       { "BEEP", NULL, "Beep" },
-       { "LMIC", NULL, "Stereo In" },
-       { "LMIC", NULL, "Stereo In" },
-
-       { "Headphone", NULL, "AOUTL" },
-       { "Headphone", NULL, "AOUTR" },
-       { "Speaker", NULL, "SP" },
-};
-
-static int bfin_eval_adau1x81_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int pll_rate;
-       int ret;
-
-       switch (params_rate(params)) {
-       case 48000:
-       case 8000:
-       case 12000:
-       case 16000:
-       case 24000:
-       case 32000:
-       case 96000:
-               pll_rate = 48000 * 1024;
-               break;
-       case 44100:
-       case 7350:
-       case 11025:
-       case 14700:
-       case 22050:
-       case 29400:
-       case 88200:
-               pll_rate = 44100 * 1024;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = snd_soc_dai_set_pll(codec_dai, ADAU17X1_PLL,
-                       ADAU17X1_PLL_SRC_MCLK, 12288000, pll_rate);
-       if (ret)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, ADAU17X1_CLK_SRC_PLL, pll_rate,
-                       SND_SOC_CLOCK_IN);
-
-       return ret;
-}
-
-static const struct snd_soc_ops bfin_eval_adau1x81_ops = {
-       .hw_params = bfin_eval_adau1x81_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adau1x81_dai = {
-       .name = "adau1x81",
-       .stream_name = "adau1x81",
-       .cpu_dai_name = "bfin-i2s.0",
-       .codec_dai_name = "adau-hifi",
-       .platform_name = "bfin-i2s-pcm-audio",
-       .codec_name = "adau1781.0-0038",
-       .ops = &bfin_eval_adau1x81_ops,
-       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-               SND_SOC_DAIFMT_CBM_CFM,
-};
-
-static struct snd_soc_card bfin_eval_adau1x81 = {
-       .name = "bfin-eval-adau1x81",
-       .driver_name = "eval-adau1x81",
-       .dai_link = &bfin_eval_adau1x81_dai,
-       .num_links = 1,
-
-       .dapm_widgets = bfin_eval_adau1x81_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1x81_dapm_widgets),
-       .dapm_routes = bfin_eval_adau1x81_dapm_routes,
-       .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1x81_dapm_routes),
-       .fully_routed = true,
-};
-
-static int bfin_eval_adau1x81_probe(struct platform_device *pdev)
-{
-       bfin_eval_adau1x81.dev = &pdev->dev;
-
-       return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1x81);
-}
-
-static struct platform_driver bfin_eval_adau1x81_driver = {
-       .driver = {
-               .name = "bfin-eval-adau1x81",
-               .pm = &snd_soc_pm_ops,
-       },
-       .probe = bfin_eval_adau1x81_probe,
-};
-module_platform_driver(bfin_eval_adau1x81_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adau1x81 driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:bfin-eval-adau1x81");
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
deleted file mode 100644 (file)
index 99e5eca..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Machine driver for EVAL-ADAV801 and EVAL-ADAV803 on Analog Devices bfin
- * evaluation boards.
- *
- * Copyright 2011 Analog Devices Inc.
- * Author: Lars-Peter Clausen <lars@metafoo.de>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include "../codecs/adav80x.h"
-
-static const struct snd_soc_dapm_widget bfin_eval_adav80x_dapm_widgets[] = {
-       SND_SOC_DAPM_LINE("Line Out", NULL),
-       SND_SOC_DAPM_LINE("Line In", NULL),
-};
-
-static const struct snd_soc_dapm_route bfin_eval_adav80x_dapm_routes[] = {
-       { "Line Out", NULL, "VOUTL" },
-       { "Line Out", NULL, "VOUTR" },
-
-       { "VINL", NULL, "Line In" },
-       { "VINR", NULL, "Line In" },
-};
-
-static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int ret;
-
-       ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
-                       27000000, params_rate(params) * 256);
-       if (ret)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_PLL1,
-                       params_rate(params) * 256, SND_SOC_CLOCK_IN);
-
-       return ret;
-}
-
-static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-
-       snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK1, 0,
-           SND_SOC_CLOCK_OUT);
-       snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK2, 0,
-           SND_SOC_CLOCK_OUT);
-       snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_SYSCLK3, 0,
-           SND_SOC_CLOCK_OUT);
-
-       snd_soc_dai_set_sysclk(codec_dai, ADAV80X_CLK_XTAL, 2700000, 0);
-
-       return 0;
-}
-
-static const struct snd_soc_ops bfin_eval_adav80x_ops = {
-       .hw_params = bfin_eval_adav80x_hw_params,
-};
-
-static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
-       {
-               .name = "adav80x",
-               .stream_name = "ADAV80x HiFi",
-               .cpu_dai_name = "bfin-i2s.0",
-               .codec_dai_name = "adav80x-hifi",
-               .platform_name = "bfin-i2s-pcm-audio",
-               .init = bfin_eval_adav80x_codec_init,
-               .ops = &bfin_eval_adav80x_ops,
-               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-                               SND_SOC_DAIFMT_CBM_CFM,
-       },
-};
-
-static struct snd_soc_card bfin_eval_adav80x = {
-       .name = "bfin-eval-adav80x",
-       .owner = THIS_MODULE,
-       .dai_link = bfin_eval_adav80x_dais,
-       .num_links = ARRAY_SIZE(bfin_eval_adav80x_dais),
-
-       .dapm_widgets           = bfin_eval_adav80x_dapm_widgets,
-       .num_dapm_widgets       = ARRAY_SIZE(bfin_eval_adav80x_dapm_widgets),
-       .dapm_routes            = bfin_eval_adav80x_dapm_routes,
-       .num_dapm_routes        = ARRAY_SIZE(bfin_eval_adav80x_dapm_routes),
-};
-
-enum bfin_eval_adav80x_type {
-       BFIN_EVAL_ADAV801,
-       BFIN_EVAL_ADAV803,
-};
-
-static int bfin_eval_adav80x_probe(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = &bfin_eval_adav80x;
-       const char *codec_name;
-
-       switch (platform_get_device_id(pdev)->driver_data) {
-       case BFIN_EVAL_ADAV801:
-               codec_name = "spi0.1";
-               break;
-       case BFIN_EVAL_ADAV803:
-               codec_name = "adav803.0-0034";
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       bfin_eval_adav80x_dais[0].codec_name = codec_name;
-
-       card->dev = &pdev->dev;
-
-       return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adav80x);
-}
-
-static const struct platform_device_id bfin_eval_adav80x_ids[] = {
-       { "bfin-eval-adav801", BFIN_EVAL_ADAV801 },
-       { "bfin-eval-adav803", BFIN_EVAL_ADAV803 },
-       { },
-};
-MODULE_DEVICE_TABLE(platform, bfin_eval_adav80x_ids);
-
-static struct platform_driver bfin_eval_adav80x_driver = {
-       .driver = {
-               .name = "bfin-eval-adav80x",
-               .pm = &snd_soc_pm_ops,
-       },
-       .probe = bfin_eval_adav80x_probe,
-       .id_table = bfin_eval_adav80x_ids,
-};
-
-module_platform_driver(bfin_eval_adav80x_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver");
-MODULE_LICENSE("GPL");
index be8ea723dff9bf75ee071ec12766dacb0368c957..3c3ef422853d439ea574b6684acc41dd97f9f893 100644 (file)
@@ -139,7 +139,7 @@ struct pm860x_priv {
        unsigned int            pcmclk;
        unsigned int            dir;
        unsigned int            filter;
-       struct snd_soc_codec    *codec;
+       struct snd_soc_component *component;
        struct i2c_client       *i2c;
        struct regmap           *regmap;
        struct pm860x_chip      *chip;
@@ -272,15 +272,15 @@ static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        int val[2], val2[2], i;
 
-       val[0] = snd_soc_read(codec, reg) & 0x3f;
-       val[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT) >> 4) & 0xf;
-       val2[0] = snd_soc_read(codec, reg2) & 0x3f;
-       val2[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT)) & 0xf;
+       val[0] = snd_soc_component_read32(component, reg) & 0x3f;
+       val[1] = (snd_soc_component_read32(component, PM860X_SIDETONE_SHIFT) >> 4) & 0xf;
+       val2[0] = snd_soc_component_read32(component, reg2) & 0x3f;
+       val2[1] = (snd_soc_component_read32(component, PM860X_SIDETONE_SHIFT)) & 0xf;
 
        for (i = 0; i < ARRAY_SIZE(st_table); i++) {
                if ((st_table[i].m == val[0]) && (st_table[i].n == val[1]))
@@ -296,7 +296,7 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        int err;
@@ -308,18 +308,18 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
        if (val >= ARRAY_SIZE(st_table) || val2 >= ARRAY_SIZE(st_table))
                return -EINVAL;
 
-       err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m);
+       err = snd_soc_component_update_bits(component, reg, 0x3f, st_table[val].m);
        if (err < 0)
                return err;
-       err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0xf0,
+       err = snd_soc_component_update_bits(component, PM860X_SIDETONE_SHIFT, 0xf0,
                                  st_table[val].n << 4);
        if (err < 0)
                return err;
 
-       err = snd_soc_update_bits(codec, reg2, 0x3f, st_table[val2].m);
+       err = snd_soc_component_update_bits(component, reg2, 0x3f, st_table[val2].m);
        if (err < 0)
                return err;
-       err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0x0f,
+       err = snd_soc_component_update_bits(component, PM860X_SIDETONE_SHIFT, 0x0f,
                                  st_table[val2].n);
        return err;
 }
@@ -329,15 +329,15 @@ static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        unsigned int shift = mc->shift;
        int max = mc->max, val, val2;
        unsigned int mask = (1 << fls(max)) - 1;
 
-       val = snd_soc_read(codec, reg) >> shift;
-       val2 = snd_soc_read(codec, reg2) >> shift;
+       val = snd_soc_component_read32(component, reg) >> shift;
+       val2 = snd_soc_component_read32(component, reg2) >> shift;
        ucontrol->value.integer.value[0] = (max - val) & mask;
        ucontrol->value.integer.value[1] = (max - val2) & mask;
 
@@ -349,7 +349,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        unsigned int shift = mc->shift;
@@ -365,11 +365,11 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
        val = val << shift;
        val2 = val2 << shift;
 
-       err = snd_soc_update_bits(codec, reg, val_mask, val);
+       err = snd_soc_component_update_bits(component, reg, val_mask, val);
        if (err < 0)
                return err;
 
-       err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+       err = snd_soc_component_update_bits(component, reg2, val_mask, val2);
        return err;
 }
 
@@ -382,7 +382,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
 static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
                              struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        /*
         * In order to avoid current on the load, mute power-on and power-off
@@ -390,8 +390,8 @@ static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
         * Unmute by DAC_MUTE. It should be unmuted when DAPM sequence is
         * finished.
         */
-       snd_soc_update_bits(codec, PM860X_DAC_OFFSET, DAC_MUTE, 0);
-       snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+       snd_soc_component_update_bits(component, PM860X_DAC_OFFSET, DAC_MUTE, 0);
+       snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
                            RSYNC_CHANGE, RSYNC_CHANGE);
        return 0;
 }
@@ -399,7 +399,7 @@ static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
 static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int dac = 0;
        int data;
 
@@ -412,28 +412,28 @@ static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
                if (dac) {
                        /* Auto mute in power-on sequence. */
                        dac |= MODULATOR;
-                       snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
+                       snd_soc_component_update_bits(component, PM860X_DAC_OFFSET,
                                            DAC_MUTE, DAC_MUTE);
-                       snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+                       snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
                                            RSYNC_CHANGE, RSYNC_CHANGE);
                        /* update dac */
-                       snd_soc_update_bits(codec, PM860X_DAC_EN_2,
+                       snd_soc_component_update_bits(component, PM860X_DAC_EN_2,
                                            dac, dac);
                }
                break;
        case SND_SOC_DAPM_PRE_PMD:
                if (dac) {
                        /* Auto mute in power-off sequence. */
-                       snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
+                       snd_soc_component_update_bits(component, PM860X_DAC_OFFSET,
                                            DAC_MUTE, DAC_MUTE);
-                       snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+                       snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
                                            RSYNC_CHANGE, RSYNC_CHANGE);
                        /* update dac */
-                       data = snd_soc_read(codec, PM860X_DAC_EN_2);
+                       data = snd_soc_component_read32(component, PM860X_DAC_EN_2);
                        data &= ~dac;
                        if (!(data & (DAC_LEFT | DAC_RIGHT)))
                                data &= ~MODULATOR;
-                       snd_soc_write(codec, PM860X_DAC_EN_2, data);
+                       snd_soc_component_write(component, PM860X_DAC_EN_2, data);
                }
                break;
        }
@@ -922,13 +922,13 @@ static const struct snd_soc_dapm_route pm860x_dapm_routes[] = {
  */
 static int pm860x_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int data = 0, mask = MUTE_LEFT | MUTE_RIGHT;
 
        if (mute)
                data = mask;
-       snd_soc_update_bits(codec, PM860X_DAC_OFFSET, mask, data);
-       snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
+       snd_soc_component_update_bits(component, PM860X_DAC_OFFSET, mask, data);
+       snd_soc_component_update_bits(component, PM860X_EAR_CTRL_2,
                            RSYNC_CHANGE, RSYNC_CHANGE);
        return 0;
 }
@@ -937,7 +937,7 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned char inf = 0, mask = 0;
 
        /* bit size */
@@ -952,7 +952,7 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
        mask |= PCM_INF2_18WL;
-       snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
+       snd_soc_component_update_bits(component, PM860X_PCM_IFACE_2, mask, inf);
 
        /* sample rate */
        switch (params_rate(params)) {
@@ -971,7 +971,7 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, PM860X_PCM_RATE, 0x0f, inf);
+       snd_soc_component_update_bits(component, PM860X_PCM_RATE, 0x0f, inf);
 
        return 0;
 }
@@ -979,8 +979,8 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
 static int pm860x_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
                                  unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
        unsigned char inf = 0, mask = 0;
        int ret = -EINVAL;
 
@@ -1012,15 +1012,15 @@ static int pm860x_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
        mask |= PCM_MODE_MASK;
        if (ret)
                return ret;
-       snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
+       snd_soc_component_update_bits(component, PM860X_PCM_IFACE_2, mask, inf);
        return 0;
 }
 
 static int pm860x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 
        if (dir == PM860X_CLK_DIR_OUT)
                pm860x->dir = PM860X_CLK_DIR_OUT;
@@ -1034,7 +1034,7 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned char inf;
 
        /* bit size */
@@ -1048,7 +1048,7 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, PCM_INF2_18WL, inf);
+       snd_soc_component_update_bits(component, PM860X_I2S_IFACE_2, PCM_INF2_18WL, inf);
 
        /* sample rate */
        switch (params_rate(params)) {
@@ -1076,7 +1076,7 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, PM860X_I2S_IFACE_4, 0xf, inf);
+       snd_soc_component_update_bits(component, PM860X_I2S_IFACE_4, 0xf, inf);
 
        return 0;
 }
@@ -1084,8 +1084,8 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
 static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
                                  unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
        unsigned char inf = 0, mask = 0;
 
        mask |= PCM_INF2_BCLK | PCM_INF2_FS | PCM_INF2_MASTER;
@@ -1116,14 +1116,14 @@ static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
        mask |= PCM_MODE_MASK;
-       snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, mask, inf);
+       snd_soc_component_update_bits(component, PM860X_I2S_IFACE_2, mask, inf);
        return 0;
 }
 
-static int pm860x_set_bias_level(struct snd_soc_codec *codec,
+static int pm860x_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
        int data;
 
        switch (level) {
@@ -1134,7 +1134,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Enable Audio PLL & Audio section */
                        data = AUDIO_PLL | AUDIO_SECTION_ON;
                        pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
@@ -1216,7 +1216,7 @@ static struct snd_soc_dai_driver pm860x_dai[] = {
        },
 };
 
-static irqreturn_t pm860x_codec_handler(int irq, void *data)
+static irqreturn_t pm860x_component_handler(int irq, void *data)
 {
        struct pm860x_priv *pm860x = data;
        int status, shrt, report = 0, mic_report = 0;
@@ -1230,7 +1230,7 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data)
 #ifndef CONFIG_SND_SOC_88PM860X_MODULE
        if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
                      SHORT_LO1 | SHORT_LO2))
-               trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
+               trace_snd_soc_jack_irq(dev_name(pm860x->component->dev));
 #endif
 
        if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
@@ -1256,17 +1256,17 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data)
                snd_soc_jack_report(pm860x->det.mic_jack, SND_JACK_MICROPHONE,
                                    SND_JACK_MICROPHONE);
 
-       dev_dbg(pm860x->codec->dev, "headphone report:0x%x, mask:%x\n",
+       dev_dbg(pm860x->component->dev, "headphone report:0x%x, mask:%x\n",
                report, mask);
-       dev_dbg(pm860x->codec->dev, "microphone report:0x%x\n", mic_report);
+       dev_dbg(pm860x->component->dev, "microphone report:0x%x\n", mic_report);
        return IRQ_HANDLED;
 }
 
-int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
+int pm860x_hs_jack_detect(struct snd_soc_component *component,
                          struct snd_soc_jack *jack,
                          int det, int hook, int hs_shrt, int lo_shrt)
 {
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
        int data;
 
        pm860x->det.hp_jack = jack;
@@ -1290,15 +1290,15 @@ int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
        }
 
        /* sync status */
-       pm860x_codec_handler(0, pm860x);
+       pm860x_component_handler(0, pm860x);
        return 0;
 }
 EXPORT_SYMBOL_GPL(pm860x_hs_jack_detect);
 
-int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
+int pm860x_mic_jack_detect(struct snd_soc_component *component,
                           struct snd_soc_jack *jack, int det)
 {
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
 
        pm860x->det.mic_jack = jack;
        pm860x->det.mic_det = det;
@@ -1308,25 +1308,25 @@ int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
                                MICDET_MASK, MICDET_MASK);
 
        /* sync status */
-       pm860x_codec_handler(0, pm860x);
+       pm860x_component_handler(0, pm860x);
        return 0;
 }
 EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
 
-static int pm860x_probe(struct snd_soc_codec *codec)
+static int pm860x_probe(struct snd_soc_component *component)
 {
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
        int i, ret;
 
-       pm860x->codec = codec;
-       snd_soc_codec_init_regmap(codec,  pm860x->regmap);
+       pm860x->component = component;
+       snd_soc_component_init_regmap(component,  pm860x->regmap);
 
        for (i = 0; i < 4; i++) {
                ret = request_threaded_irq(pm860x->irq[i], NULL,
-                                          pm860x_codec_handler, IRQF_ONESHOT,
+                                          pm860x_component_handler, IRQF_ONESHOT,
                                           pm860x->name[i], pm860x);
                if (ret < 0) {
-                       dev_err(codec->dev, "Failed to request IRQ!\n");
+                       dev_err(component->dev, "Failed to request IRQ!\n");
                        goto out;
                }
        }
@@ -1339,29 +1339,29 @@ out:
        return ret;
 }
 
-static int pm860x_remove(struct snd_soc_codec *codec)
+static void pm860x_remove(struct snd_soc_component *component)
 {
-       struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
+       struct pm860x_priv *pm860x = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 3; i >= 0; i--)
                free_irq(pm860x->irq[i], pm860x);
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_pm860x = {
-       .probe          = pm860x_probe,
-       .remove         = pm860x_remove,
-       .set_bias_level = pm860x_set_bias_level,
-
-       .component_driver = {
-               .controls               = pm860x_snd_controls,
-               .num_controls           = ARRAY_SIZE(pm860x_snd_controls),
-               .dapm_widgets           = pm860x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pm860x_dapm_widgets),
-               .dapm_routes            = pm860x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pm860x_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_pm860x = {
+       .probe                  = pm860x_probe,
+       .remove                 = pm860x_remove,
+       .set_bias_level         = pm860x_set_bias_level,
+       .controls               = pm860x_snd_controls,
+       .num_controls           = ARRAY_SIZE(pm860x_snd_controls),
+       .dapm_widgets           = pm860x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pm860x_dapm_widgets),
+       .dapm_routes            = pm860x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pm860x_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int pm860x_codec_probe(struct platform_device *pdev)
@@ -1393,10 +1393,11 @@ static int pm860x_codec_probe(struct platform_device *pdev)
                strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);
        }
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pm860x,
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                    &soc_component_dev_pm860x,
                                     pm860x_dai, ARRAY_SIZE(pm860x_dai));
        if (ret) {
-               dev_err(&pdev->dev, "Failed to register codec\n");
+               dev_err(&pdev->dev, "Failed to register component\n");
                return -EINVAL;
        }
        return ret;
@@ -1404,7 +1405,6 @@ static int pm860x_codec_probe(struct platform_device *pdev)
 
 static int pm860x_codec_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
index f7282f4f4a7909e3a35e4af6f74d735d90c2f167..33aa9ff3463f5eaeb5e0dceb8949842a0441b2ec 100644 (file)
@@ -88,9 +88,9 @@
 #define PM860X_SHORT_LINEOUT           (1 << 4)
 #define PM860X_DET_MASK                        0x1F
 
-extern int pm860x_hs_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
+extern int pm860x_hs_jack_detect(struct snd_soc_component *, struct snd_soc_jack *,
                                 int, int, int, int);
-extern int pm860x_mic_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
+extern int pm860x_mic_jack_detect(struct snd_soc_component *, struct snd_soc_jack *,
                                  int);
 
 #endif /* __88PM860X_H */
index 2b331f7266abed6c73ed27dfa1f3f7dbd058c961..9548f63ca531c89ec682819e22d5b34584df7f0b 100644 (file)
@@ -35,6 +35,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_ADAU7002
        select SND_SOC_ADS117X
        select SND_SOC_AK4104 if SPI_MASTER
+       select SND_SOC_AK4458 if I2C
        select SND_SOC_AK4535 if I2C
        select SND_SOC_AK4554
        select SND_SOC_AK4613 if I2C
@@ -42,9 +43,11 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_AK4642 if I2C
        select SND_SOC_AK4671 if I2C
        select SND_SOC_AK5386
+       select SND_SOC_AK5558 if I2C
        select SND_SOC_ALC5623 if I2C
        select SND_SOC_ALC5632 if I2C
        select SND_SOC_BT_SCO
+       select SND_SOC_BD28623
        select SND_SOC_CQ0093VC
        select SND_SOC_CS35L32 if I2C
        select SND_SOC_CS35L33 if I2C
@@ -98,6 +101,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_MAX98373 if I2C
        select SND_SOC_MAX9850 if I2C
        select SND_SOC_MAX9860 if I2C
+       select SND_SOC_MAX9759
        select SND_SOC_MAX9768 if I2C
        select SND_SOC_MAX9877 if I2C
        select SND_SOC_MC13783 if MFD_MC13XXX
@@ -108,6 +112,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_NAU8825 if I2C
        select SND_SOC_HDMI_CODEC
        select SND_SOC_PCM1681 if I2C
+       select SND_SOC_PCM1789_I2C if I2C
        select SND_SOC_PCM179X_I2C if I2C
        select SND_SOC_PCM179X_SPI if SPI_MASTER
        select SND_SOC_PCM186X_I2C if I2C
@@ -151,6 +156,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_TAS571X if I2C
        select SND_SOC_TAS5720 if I2C
        select SND_SOC_TAS6424 if I2C
+       select SND_SOC_TDA7419 if I2C
        select SND_SOC_TFA9879 if I2C
        select SND_SOC_TLV320AIC23_I2C if I2C
        select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
@@ -375,6 +381,11 @@ config SND_SOC_AK4104
        tristate "AKM AK4104 CODEC"
        depends on SPI_MASTER
 
+config SND_SOC_AK4458
+       tristate "AKM AK4458 CODEC"
+       depends on I2C
+       select REGMAP_I2C
+
 config SND_SOC_AK4535
        tristate
 
@@ -398,6 +409,11 @@ config SND_SOC_AK4671
 config SND_SOC_AK5386
        tristate "AKM AK5638 CODEC"
 
+config SND_SOC_AK5558
+       tristate "AKM AK5558 CODEC"
+       depends on I2C
+       select REGMAP_I2C
+
 config SND_SOC_ALC5623
        tristate "Realtek ALC5623 CODEC"
        depends on I2C
@@ -405,9 +421,20 @@ config SND_SOC_ALC5623
 config SND_SOC_ALC5632
        tristate
 
+config SND_SOC_BD28623
+       tristate "ROHM BD28623 CODEC"
+       help
+         Enable support for ROHM BD28623MUV Class D speaker amplifier.
+         This codec does not have any control buses such as I2C, it
+         detect format of I2S automatically.
+
 config SND_SOC_BT_SCO
        tristate "Dummy BT SCO codec driver"
 
+config SND_SOC_CPCAP
+       tristate "Motorola CPCAP codec"
+       depends on MFD_CPCAP
+
 config SND_SOC_CQ0093VC
        tristate
 
@@ -615,7 +642,8 @@ config SND_SOC_MAX98504
        depends on I2C
 
 config SND_SOC_MAX9867
-       tristate
+       tristate "Maxim MAX9867 CODEC"
+       depends on I2C
 
 config SND_SOC_MAX98925
        tristate
@@ -650,6 +678,17 @@ config SND_SOC_PCM1681
        tristate "Texas Instruments PCM1681 CODEC"
        depends on I2C
 
+config SND_SOC_PCM1789
+       tristate
+
+config SND_SOC_PCM1789_I2C
+       tristate "Texas Instruments PCM1789 CODEC (I2C)"
+       depends on I2C
+       select SND_SOC_PCM1789
+       help
+         Enable support for Texas Instruments PCM1789 CODEC.
+         Select this if your PCM1789 is connected via an I2C bus.
+
 config SND_SOC_PCM179X
        tristate
 
@@ -910,6 +949,11 @@ config SND_SOC_TAS6424
          Enable support for Texas Instruments TAS6424 high-efficiency
          digital input quad-channel Class-D audio power amplifiers.
 
+config SND_SOC_TDA7419
+       tristate "ST TDA7419 audio processor"
+       depends on I2C
+       select REGMAP_I2C
+
 config SND_SOC_TFA9879
        tristate "NXP Semiconductors TFA9879 amplifier"
        depends on I2C
@@ -1187,6 +1231,10 @@ config SND_SOC_ZX_AUD96P22
 config SND_SOC_LM4857
        tristate
 
+config SND_SOC_MAX9759
+       tristate "Maxim MAX9759 speaker Amplifier"
+       select GPIOLIB
+
 config SND_SOC_MAX9768
        tristate
 
index da1571336f1e83a431c5a301b7c22e4ce12758a2..e849d1495308f96acc49417a5b0fbfcba1975b93 100644 (file)
@@ -27,6 +27,7 @@ snd-soc-adav801-objs := adav801.o
 snd-soc-adav803-objs := adav803.o
 snd-soc-ads117x-objs := ads117x.o
 snd-soc-ak4104-objs := ak4104.o
+snd-soc-ak4458-objs := ak4458.o
 snd-soc-ak4535-objs := ak4535.o
 snd-soc-ak4554-objs := ak4554.o
 snd-soc-ak4613-objs := ak4613.o
@@ -34,8 +35,11 @@ snd-soc-ak4641-objs := ak4641.o
 snd-soc-ak4642-objs := ak4642.o
 snd-soc-ak4671-objs := ak4671.o
 snd-soc-ak5386-objs := ak5386.o
+snd-soc-ak5558-objs := ak5558.o
 snd-soc-arizona-objs := arizona.o
+snd-soc-bd28623-objs := bd28623.o
 snd-soc-bt-sco-objs := bt-sco.o
+snd-soc-cpcap-objs := cpcap.o
 snd-soc-cq93vc-objs := cq93vc.o
 snd-soc-cs35l32-objs := cs35l32.o
 snd-soc-cs35l33-objs := cs35l33.o
@@ -80,6 +84,7 @@ snd-soc-jz4740-codec-objs := jz4740.o
 snd-soc-l3-objs := l3.o
 snd-soc-lm4857-objs := lm4857.o
 snd-soc-lm49453-objs := lm49453.o
+snd-soc-max9759-objs := max9759.o
 snd-soc-max9768-objs := max9768.o
 snd-soc-max98088-objs := max98088.o
 snd-soc-max98090-objs := max98090.o
@@ -103,6 +108,8 @@ snd-soc-nau8824-objs := nau8824.o
 snd-soc-nau8825-objs := nau8825.o
 snd-soc-hdmi-codec-objs := hdmi-codec.o
 snd-soc-pcm1681-objs := pcm1681.o
+snd-soc-pcm1789-codec-objs := pcm1789.o
+snd-soc-pcm1789-i2c-objs := pcm1789-i2c.o
 snd-soc-pcm179x-codec-objs := pcm179x.o
 snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o
 snd-soc-pcm179x-spi-objs := pcm179x-spi.o
@@ -160,6 +167,7 @@ snd-soc-tas5086-objs := tas5086.o
 snd-soc-tas571x-objs := tas571x.o
 snd-soc-tas5720-objs := tas5720.o
 snd-soc-tas6424-objs := tas6424.o
+snd-soc-tda7419-objs := tda7419.o
 snd-soc-tfa9879-objs := tfa9879.o
 snd-soc-tlv320aic23-objs := tlv320aic23.o
 snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
@@ -270,6 +278,7 @@ obj-$(CONFIG_SND_SOC_ADAV801)  += snd-soc-adav801.o
 obj-$(CONFIG_SND_SOC_ADAV803)  += snd-soc-adav803.o
 obj-$(CONFIG_SND_SOC_ADS117X)  += snd-soc-ads117x.o
 obj-$(CONFIG_SND_SOC_AK4104)   += snd-soc-ak4104.o
+obj-$(CONFIG_SND_SOC_AK4458)   += snd-soc-ak4458.o
 obj-$(CONFIG_SND_SOC_AK4535)   += snd-soc-ak4535.o
 obj-$(CONFIG_SND_SOC_AK4554)   += snd-soc-ak4554.o
 obj-$(CONFIG_SND_SOC_AK4613)   += snd-soc-ak4613.o
@@ -277,11 +286,14 @@ obj-$(CONFIG_SND_SOC_AK4641)      += snd-soc-ak4641.o
 obj-$(CONFIG_SND_SOC_AK4642)   += snd-soc-ak4642.o
 obj-$(CONFIG_SND_SOC_AK4671)   += snd-soc-ak4671.o
 obj-$(CONFIG_SND_SOC_AK5386)   += snd-soc-ak5386.o
+obj-$(CONFIG_SND_SOC_AK5558)   += snd-soc-ak5558.o
 obj-$(CONFIG_SND_SOC_ALC5623)    += snd-soc-alc5623.o
 obj-$(CONFIG_SND_SOC_ALC5632)  += snd-soc-alc5632.o
 obj-$(CONFIG_SND_SOC_ARIZONA)  += snd-soc-arizona.o
+obj-$(CONFIG_SND_SOC_BD28623)  += snd-soc-bd28623.o
 obj-$(CONFIG_SND_SOC_BT_SCO)   += snd-soc-bt-sco.o
 obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
+obj-$(CONFIG_SND_SOC_CPCAP)    += snd-soc-cpcap.o
 obj-$(CONFIG_SND_SOC_CS35L32)  += snd-soc-cs35l32.o
 obj-$(CONFIG_SND_SOC_CS35L33)  += snd-soc-cs35l33.o
 obj-$(CONFIG_SND_SOC_CS35L34)  += snd-soc-cs35l34.o
@@ -325,6 +337,7 @@ obj-$(CONFIG_SND_SOC_JZ4740_CODEC)  += snd-soc-jz4740-codec.o
 obj-$(CONFIG_SND_SOC_L3)       += snd-soc-l3.o
 obj-$(CONFIG_SND_SOC_LM4857)   += snd-soc-lm4857.o
 obj-$(CONFIG_SND_SOC_LM49453)   += snd-soc-lm49453.o
+obj-$(CONFIG_SND_SOC_MAX9759)  += snd-soc-max9759.o
 obj-$(CONFIG_SND_SOC_MAX9768)  += snd-soc-max9768.o
 obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
 obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
@@ -349,6 +362,8 @@ obj-$(CONFIG_SND_SOC_NAU8825)   += snd-soc-nau8825.o
 obj-$(CONFIG_SND_SOC_HDMI_CODEC)       += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM1681)  += snd-soc-pcm1681.o
 obj-$(CONFIG_SND_SOC_PCM179X)  += snd-soc-pcm179x-codec.o
+obj-$(CONFIG_SND_SOC_PCM1789_I2C)      += snd-soc-pcm1789-i2c.o
+obj-$(CONFIG_SND_SOC_PCM1789)  += snd-soc-pcm1789-codec.o
 obj-$(CONFIG_SND_SOC_PCM179X_I2C)      += snd-soc-pcm179x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM179X_SPI)      += snd-soc-pcm179x-spi.o
 obj-$(CONFIG_SND_SOC_PCM186X)  += snd-soc-pcm186x.o
@@ -387,7 +402,6 @@ obj-$(CONFIG_SND_SOC_SIGMADSP)      += snd-soc-sigmadsp.o
 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C)     += snd-soc-sigmadsp-i2c.o
 obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP)  += snd-soc-sigmadsp-regmap.o
 obj-$(CONFIG_SND_SOC_SI476X)   += snd-soc-si476x.o
-obj-$(CONFIG_SND_SOC_SN95031)  +=snd-soc-sn95031.o
 obj-$(CONFIG_SND_SOC_SPDIF)    += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
 obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
 obj-$(CONFIG_SND_SOC_SSM2518)  += snd-soc-ssm2518.o
@@ -405,6 +419,7 @@ obj-$(CONFIG_SND_SOC_TAS5086)       += snd-soc-tas5086.o
 obj-$(CONFIG_SND_SOC_TAS571X)  += snd-soc-tas571x.o
 obj-$(CONFIG_SND_SOC_TAS5720)  += snd-soc-tas5720.o
 obj-$(CONFIG_SND_SOC_TAS6424)  += snd-soc-tas6424.o
+obj-$(CONFIG_SND_SOC_TDA7419)  += snd-soc-tda7419.o
 obj-$(CONFIG_SND_SOC_TFA9879)  += snd-soc-tfa9879.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23)      += snd-soc-tlv320aic23.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C)  += snd-soc-tlv320aic23-i2c.o
index 006627b8c3a840d7823b74de64053dc281385435..03bbbcd3b6c115254a75f367c40447f012edc8c4 100644 (file)
@@ -1037,86 +1037,86 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
 };
 
 /* ANC FIR-coefficients configuration sequence */
-static void anc_fir(struct snd_soc_codec *codec,
+static void anc_fir(struct snd_soc_component *component,
                unsigned int bnk, unsigned int par, unsigned int val)
 {
        if (par == 0 && bnk == 0)
-               snd_soc_update_bits(codec, AB8500_ANCCONF1,
+               snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                        BIT(AB8500_ANCCONF1_ANCFIRUPDATE),
                        BIT(AB8500_ANCCONF1_ANCFIRUPDATE));
 
-       snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff);
-       snd_soc_write(codec, AB8500_ANCCONF6, val &  0xff);
+       snd_soc_component_write(component, AB8500_ANCCONF5, val >> 8 & 0xff);
+       snd_soc_component_write(component, AB8500_ANCCONF6, val &  0xff);
 
        if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1)
-               snd_soc_update_bits(codec, AB8500_ANCCONF1,
+               snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                        BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0);
 }
 
 /* ANC IIR-coefficients configuration sequence */
-static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk,
+static void anc_iir(struct snd_soc_component *component, unsigned int bnk,
                unsigned int par, unsigned int val)
 {
        if (par == 0) {
                if (bnk == 0) {
-                       snd_soc_update_bits(codec, AB8500_ANCCONF1,
+                       snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                                        BIT(AB8500_ANCCONF1_ANCIIRINIT),
                                        BIT(AB8500_ANCCONF1_ANCIIRINIT));
                        usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
-                       snd_soc_update_bits(codec, AB8500_ANCCONF1,
+                       snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                                        BIT(AB8500_ANCCONF1_ANCIIRINIT), 0);
                        usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
                } else {
-                       snd_soc_update_bits(codec, AB8500_ANCCONF1,
+                       snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                                        BIT(AB8500_ANCCONF1_ANCIIRUPDATE),
                                        BIT(AB8500_ANCCONF1_ANCIIRUPDATE));
                }
        } else if (par > 3) {
-               snd_soc_write(codec, AB8500_ANCCONF7, 0);
-               snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff);
+               snd_soc_component_write(component, AB8500_ANCCONF7, 0);
+               snd_soc_component_write(component, AB8500_ANCCONF8, val >> 16 & 0xff);
        }
 
-       snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff);
-       snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff);
+       snd_soc_component_write(component, AB8500_ANCCONF7, val >> 8 & 0xff);
+       snd_soc_component_write(component, AB8500_ANCCONF8, val & 0xff);
 
        if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1)
-               snd_soc_update_bits(codec, AB8500_ANCCONF1,
+               snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                        BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0);
 }
 
 /* ANC IIR-/FIR-coefficients configuration sequence */
-static void anc_configure(struct snd_soc_codec *codec,
+static void anc_configure(struct snd_soc_component *component,
                        bool apply_fir, bool apply_iir)
 {
-       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
        unsigned int bnk, par, val;
 
-       dev_dbg(codec->dev, "%s: Enter.\n", __func__);
+       dev_dbg(component->dev, "%s: Enter.\n", __func__);
 
        if (apply_fir)
-               snd_soc_update_bits(codec, AB8500_ANCCONF1,
+               snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                        BIT(AB8500_ANCCONF1_ENANC), 0);
 
-       snd_soc_update_bits(codec, AB8500_ANCCONF1,
+       snd_soc_component_update_bits(component, AB8500_ANCCONF1,
                BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC));
 
        if (apply_fir)
                for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
                        for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) {
-                               val = snd_soc_read(codec,
+                               val = snd_soc_component_read32(component,
                                                drvdata->anc_fir_values[par]);
-                               anc_fir(codec, bnk, par, val);
+                               anc_fir(component, bnk, par, val);
                        }
 
        if (apply_iir)
                for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
                        for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) {
-                               val = snd_soc_read(codec,
+                               val = snd_soc_component_read32(component,
                                                drvdata->anc_iir_values[par]);
-                               anc_iir(codec, bnk, par, val);
+                               anc_iir(component, bnk, par, val);
                        }
 
-       dev_dbg(codec->dev, "%s: Exit.\n", __func__);
+       dev_dbg(component->dev, "%s: Exit.\n", __func__);
 }
 
 /*
@@ -1126,8 +1126,8 @@ static void anc_configure(struct snd_soc_codec *codec,
 static int sid_status_control_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
 
        mutex_lock(&drvdata->ctrl_lock);
        ucontrol->value.enumerated.item[0] = drvdata->sid_status;
@@ -1140,15 +1140,15 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol,
 static int sid_status_control_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
        unsigned int param, sidconf, val;
        int status = 1;
 
-       dev_dbg(codec->dev, "%s: Enter\n", __func__);
+       dev_dbg(component->dev, "%s: Enter\n", __func__);
 
        if (ucontrol->value.enumerated.item[0] != SID_APPLY_FIR) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: ERROR: This control supports '%s' only!\n",
                        __func__, enum_sid_state[SID_APPLY_FIR]);
                return -EIO;
@@ -1156,10 +1156,10 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 
        mutex_lock(&drvdata->ctrl_lock);
 
-       sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF);
+       sidconf = snd_soc_component_read32(component, AB8500_SIDFIRCONF);
        if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
                if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) {
-                       dev_err(codec->dev, "%s: Sidetone busy while off!\n",
+                       dev_err(component->dev, "%s: Sidetone busy while off!\n",
                                __func__);
                        status = -EPERM;
                } else {
@@ -1168,18 +1168,18 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
                goto out;
        }
 
-       snd_soc_write(codec, AB8500_SIDFIRADR, 0);
+       snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
 
        for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
-               val = snd_soc_read(codec, drvdata->sid_fir_values[param]);
-               snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
-               snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff);
+               val = snd_soc_component_read32(component, drvdata->sid_fir_values[param]);
+               snd_soc_component_write(component, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
+               snd_soc_component_write(component, AB8500_SIDFIRCOEF2, val & 0xff);
        }
 
-       snd_soc_update_bits(codec, AB8500_SIDFIRADR,
+       snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
                BIT(AB8500_SIDFIRADR_FIRSIDSET),
                BIT(AB8500_SIDFIRADR_FIRSIDSET));
-       snd_soc_update_bits(codec, AB8500_SIDFIRADR,
+       snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
                BIT(AB8500_SIDFIRADR_FIRSIDSET), 0);
 
        drvdata->sid_status = SID_FIR_CONFIGURED;
@@ -1187,7 +1187,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
 out:
        mutex_unlock(&drvdata->ctrl_lock);
 
-       dev_dbg(codec->dev, "%s: Exit\n", __func__);
+       dev_dbg(component->dev, "%s: Exit\n", __func__);
 
        return status;
 }
@@ -1195,8 +1195,8 @@ out:
 static int anc_status_control_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
 
        mutex_lock(&drvdata->ctrl_lock);
        ucontrol->value.enumerated.item[0] = drvdata->anc_status;
@@ -1208,10 +1208,10 @@ static int anc_status_control_get(struct snd_kcontrol *kcontrol,
 static int anc_status_control_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
-       struct device *dev = codec->dev;
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
+       struct device *dev = component->dev;
        bool apply_fir, apply_iir;
        unsigned int req;
        int status;
@@ -1244,7 +1244,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
        }
        snd_soc_dapm_sync(dapm);
 
-       anc_configure(codec, apply_fir, apply_iir);
+       anc_configure(component, apply_fir, apply_iir);
 
        if (apply_fir) {
                if (drvdata->anc_status == ANC_IIR_CONFIGURED)
@@ -1291,8 +1291,8 @@ static int filter_control_info(struct snd_kcontrol *kcontrol,
 static int filter_control_get(struct snd_kcontrol *kcontrol,
                        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ab8500_codec_drvdata *drvdata = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ab8500_codec_drvdata *drvdata = snd_soc_component_get_drvdata(component);
        struct filter_control *fc =
                        (struct filter_control *)kcontrol->private_value;
        unsigned int i;
@@ -1308,8 +1308,8 @@ static int filter_control_get(struct snd_kcontrol *kcontrol,
 static int filter_control_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ab8500_codec_drvdata *drvdata = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ab8500_codec_drvdata *drvdata = snd_soc_component_get_drvdata(component);
        struct filter_control *fc =
                        (struct filter_control *)kcontrol->private_value;
        unsigned int i;
@@ -1926,11 +1926,11 @@ enum ab8500_filter {
  * Extended interface for codec-driver
  */
 
-static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
+static int ab8500_audio_init_audioblock(struct snd_soc_component *component)
 {
        int status;
 
-       dev_dbg(codec->dev, "%s: Enter.\n", __func__);
+       dev_dbg(component->dev, "%s: Enter.\n", __func__);
 
        /* Reset audio-registers and disable 32kHz-clock output 2 */
        status = ab8500_sysctrl_write(AB8500_STW4500CTRL3,
@@ -1943,26 +1943,26 @@ static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
+static int ab8500_audio_setup_mics(struct snd_soc_component *component,
                        struct amic_settings *amics)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        u8 value8;
        unsigned int value;
        int status;
        const struct snd_soc_dapm_route *route;
 
-       dev_dbg(codec->dev, "%s: Enter.\n", __func__);
+       dev_dbg(component->dev, "%s: Enter.\n", __func__);
 
        /* Set DMic-clocks to outputs */
-       status = abx500_get_register_interruptible(codec->dev, AB8500_MISC,
+       status = abx500_get_register_interruptible(component->dev, AB8500_MISC,
                                                AB8500_GPIO_DIR4_REG,
                                                &value8);
        if (status < 0)
                return status;
        value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
                GPIO31_DIR_OUTPUT;
-       status = abx500_set_register_interruptible(codec->dev,
+       status = abx500_set_register_interruptible(component->dev,
                                                AB8500_MISC,
                                                AB8500_GPIO_DIR4_REG,
                                                value);
@@ -1970,41 +1970,41 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
                return status;
 
        /* Attach regulators to AMic DAPM-paths */
-       dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
+       dev_dbg(component->dev, "%s: Mic 1a regulator: %s\n", __func__,
                amic_micbias_str(amics->mic1a_micbias));
        route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
        status = snd_soc_dapm_add_routes(dapm, route, 1);
-       dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
+       dev_dbg(component->dev, "%s: Mic 1b regulator: %s\n", __func__,
                amic_micbias_str(amics->mic1b_micbias));
        route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
        status |= snd_soc_dapm_add_routes(dapm, route, 1);
-       dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
+       dev_dbg(component->dev, "%s: Mic 2 regulator: %s\n", __func__,
                amic_micbias_str(amics->mic2_micbias));
        route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
        status |= snd_soc_dapm_add_routes(dapm, route, 1);
        if (status < 0) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
                        __func__, status);
                return status;
        }
 
        /* Set AMic-configuration */
-       dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__,
+       dev_dbg(component->dev, "%s: Mic 1 mic-type: %s\n", __func__,
                amic_type_str(amics->mic1_type));
-       snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX,
+       snd_soc_component_update_bits(component, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX,
                        amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ?
                                0 : AB8500_ANAGAINX_ENSEMICX);
-       dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__,
+       dev_dbg(component->dev, "%s: Mic 2 mic-type: %s\n", __func__,
                amic_type_str(amics->mic2_type));
-       snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX,
+       snd_soc_component_update_bits(component, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX,
                        amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ?
                                0 : AB8500_ANAGAINX_ENSEMICX);
 
        return 0;
 }
 
-static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
+static int ab8500_audio_set_ear_cmv(struct snd_soc_component *component,
                                enum ear_cm_voltage ear_cmv)
 {
        char *cmv_str;
@@ -2023,14 +2023,14 @@ static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
                cmv_str = "1.58V";
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: Unknown earpiece CM-voltage (%d)!\n",
                        __func__, (int)ear_cmv);
                return -EINVAL;
        }
-       dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__,
+       dev_dbg(component->dev, "%s: Earpiece CM-voltage: %s\n", __func__,
                cmv_str);
-       snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM,
+       snd_soc_component_update_bits(component, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM,
                        ear_cmv);
 
        return 0;
@@ -2040,7 +2040,7 @@ static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
                                unsigned int delay)
 {
        unsigned int mask, val;
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        mask = BIT(AB8500_DIGIFCONF2_IF0DEL);
        val = 0;
@@ -2052,21 +2052,21 @@ static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
                val |= BIT(AB8500_DIGIFCONF2_IF0DEL);
                break;
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupported bit-delay (0x%x)!\n",
                        __func__, delay);
                return -EINVAL;
        }
 
-       dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n",
+       dev_dbg(dai->component->dev, "%s: IF0 Bit-delay: %d bits.\n",
                __func__, delay);
-       snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
+       snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
 
        return 0;
 }
 
 /* Gates clocking according format mask */
-static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec,
+static int ab8500_codec_set_dai_clock_gate(struct snd_soc_component *component,
                                        unsigned int fmt)
 {
        unsigned int mask;
@@ -2079,22 +2079,22 @@ static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec,
 
        switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
        case SND_SOC_DAIFMT_CONT: /* continuous clock */
-               dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n",
+               dev_dbg(component->dev, "%s: IF0 Clock is continuous.\n",
                        __func__);
                val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
                break;
        case SND_SOC_DAIFMT_GATED: /* clock is gated */
-               dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n",
+               dev_dbg(component->dev, "%s: IF0 Clock is gated.\n",
                        __func__);
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: ERROR: Unsupported clock mask (0x%x)!\n",
                        __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
+       snd_soc_component_update_bits(component, AB8500_DIGIFCONF1, mask, val);
 
        return 0;
 }
@@ -2103,10 +2103,10 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
        unsigned int mask;
        unsigned int val;
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int status;
 
-       dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
+       dev_dbg(component->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
 
        mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) |
                        BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) |
@@ -2116,32 +2116,32 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0 Master-mode: AB8500 master.\n", __func__);
                val |= BIT(AB8500_DIGIFCONF3_IF0MASTER);
                break;
        case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0 Master-mode: AB8500 slave.\n", __func__);
                break;
        case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */
        case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: The device is either a master or a slave.\n",
                        __func__);
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupporter master mask 0x%x\n",
                        __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);
+       snd_soc_component_update_bits(component, AB8500_DIGIFCONF3, mask, val);
 
        /* Set clock gating */
-       status = ab8500_codec_set_dai_clock_gate(codec, fmt);
+       status = ab8500_codec_set_dai_clock_gate(component, fmt);
        if (status) {
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Failed to set clock gate (%d).\n",
                        __func__, status);
                return status;
@@ -2157,27 +2157,27 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S: /* I2S mode */
-               dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__);
+               dev_dbg(dai->component->dev, "%s: IF0 Protocol: I2S\n", __func__);
                val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1);
                ab8500_audio_set_bit_delay(dai, 0);
                break;
 
        case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0 Protocol: DSP A (TDM)\n", __func__);
                val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
                ab8500_audio_set_bit_delay(dai, 1);
                break;
 
        case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0 Protocol: DSP B (TDM)\n", __func__);
                val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
                ab8500_audio_set_bit_delay(dai, 0);
                break;
 
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupported format (0x%x)!\n",
                        __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
                return -EINVAL;
@@ -2185,37 +2185,37 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0: Normal bit clock, normal frame\n",
                        __func__);
                break;
        case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0: Normal bit clock, inverted frame\n",
                        __func__);
                val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
                break;
        case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0: Inverted bit clock, normal frame\n",
                        __func__);
                val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
                break;
        case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: IF0: Inverted bit clock, inverted frame\n",
                        __func__);
                val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
                val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
                break;
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupported INV mask 0x%x\n",
                        __func__, fmt & SND_SOC_DAIFMT_INV_MASK);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
+       snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
 
        return 0;
 }
@@ -2224,7 +2224,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
                unsigned int tx_mask, unsigned int rx_mask,
                int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val, mask, slot, slots_active;
 
        mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
@@ -2245,17 +2245,17 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
                        BIT(AB8500_DIGIFCONF2_IF0WL0);
                break;
        default:
-               dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n",
+               dev_err(dai->component->dev, "%s: Unsupported slot-width 0x%x\n",
                        __func__, slot_width);
                return -EINVAL;
        }
 
-       dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n",
+       dev_dbg(dai->component->dev, "%s: IF0 slot-width: %d bits.\n",
                __func__, slot_width);
-       snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
+       snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
 
        /* Setup TDM clocking according to slot count */
-       dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots);
+       dev_dbg(dai->component->dev, "%s: Slots, total: %d\n", __func__, slots);
        mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
                        BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
        switch (slots) {
@@ -2273,12 +2273,12 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
                        BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
                break;
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupported number of slots (%d)!\n",
                        __func__, slots);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
+       snd_soc_component_update_bits(component, AB8500_DIGIFCONF1, mask, val);
 
        /* Setup TDM DA according to active tx slots */
 
@@ -2289,7 +2289,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
        tx_mask = tx_mask << AB8500_DA_DATA0_OFFSET;
        slots_active = hweight32(tx_mask);
 
-       dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__,
+       dev_dbg(dai->component->dev, "%s: Slots, active, TX: %d\n", __func__,
                slots_active);
 
        switch (slots_active) {
@@ -2297,26 +2297,26 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
                break;
        case 1:
                slot = ffs(tx_mask);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF1, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF3, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF2, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF4, mask, slot);
                break;
        case 2:
                slot = ffs(tx_mask);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF1, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF3, mask, slot);
                slot = fls(tx_mask);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF2, mask, slot);
+               snd_soc_component_update_bits(component, AB8500_DASLOTCONF4, mask, slot);
                break;
        case 8:
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: In 8-channel mode DA-from-slot mapping is set manually.",
                        __func__);
                break;
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: Unsupported number of active TX-slots (%d)!\n",
                        __func__, slots_active);
                return -EINVAL;
@@ -2330,7 +2330,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
        rx_mask = rx_mask << AB8500_AD_DATA0_OFFSET;
        slots_active = hweight32(rx_mask);
 
-       dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__,
+       dev_dbg(dai->component->dev, "%s: Slots, active, RX: %d\n", __func__,
                slots_active);
 
        switch (slots_active) {
@@ -2338,29 +2338,29 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
                break;
        case 1:
                slot = ffs(rx_mask);
-               snd_soc_update_bits(codec, AB8500_ADSLOTSEL(slot),
+               snd_soc_component_update_bits(component, AB8500_ADSLOTSEL(slot),
                                AB8500_MASK_SLOT(slot),
                                AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
                break;
        case 2:
                slot = ffs(rx_mask);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                                AB8500_ADSLOTSEL(slot),
                                AB8500_MASK_SLOT(slot),
                                AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
                slot = fls(rx_mask);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                                AB8500_ADSLOTSEL(slot),
                                AB8500_MASK_SLOT(slot),
                                AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT2, slot));
                break;
        case 8:
-               dev_dbg(dai->codec->dev,
+               dev_dbg(dai->component->dev,
                        "%s: In 8-channel mode AD-to-slot mapping is set manually.",
                        __func__);
                break;
        default:
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: Unsupported number of active RX-slots (%d)!\n",
                        __func__, slots_active);
                return -EINVAL;
@@ -2458,10 +2458,10 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
        }
 }
 
-static int ab8500_codec_probe(struct snd_soc_codec *codec)
+static int ab8500_codec_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct device *dev = codec->dev;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct device *dev = component->dev;
        struct device_node *np = dev->of_node;
        struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
        struct ab8500_codec_platform_data codec_pdata;
@@ -2472,19 +2472,19 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 
        ab8500_codec_of_probe(dev, np, &codec_pdata);
 
-       status = ab8500_audio_setup_mics(codec, &codec_pdata.amics);
+       status = ab8500_audio_setup_mics(component, &codec_pdata.amics);
        if (status < 0) {
                pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
                return status;
        }
-       status = ab8500_audio_set_ear_cmv(codec, codec_pdata.ear_cmv);
+       status = ab8500_audio_set_ear_cmv(component, codec_pdata.ear_cmv);
        if (status < 0) {
                pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n",
                        __func__, status);
                return status;
        }
 
-       status = ab8500_audio_init_audioblock(codec);
+       status = ab8500_audio_init_audioblock(component);
        if (status < 0) {
                dev_err(dev, "%s: failed to init audio-block (%d)!\n",
                        __func__, status);
@@ -2492,13 +2492,13 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
        }
 
        /* Override HW-defaults */
-       snd_soc_write(codec, AB8500_ANACONF5,
+       snd_soc_component_write(component, AB8500_ANACONF5,
                      BIT(AB8500_ANACONF5_HSAUTOEN));
-       snd_soc_write(codec, AB8500_SHORTCIRCONF,
+       snd_soc_component_write(component, AB8500_SHORTCIRCONF,
                      BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
 
        /* Add filter controls */
-       status = snd_soc_add_codec_controls(codec, ab8500_filter_controls,
+       status = snd_soc_add_component_controls(component, ab8500_filter_controls,
                                ARRAY_SIZE(ab8500_filter_controls));
        if (status < 0) {
                dev_err(dev,
@@ -2523,16 +2523,18 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
        return status;
 }
 
-static const struct snd_soc_codec_driver ab8500_codec_driver = {
-       .probe =                ab8500_codec_probe,
-       .component_driver = {
-               .controls =             ab8500_ctrls,
-               .num_controls =         ARRAY_SIZE(ab8500_ctrls),
-               .dapm_widgets =         ab8500_dapm_widgets,
-               .num_dapm_widgets =     ARRAY_SIZE(ab8500_dapm_widgets),
-               .dapm_routes =          ab8500_dapm_routes,
-               .num_dapm_routes =      ARRAY_SIZE(ab8500_dapm_routes),
-       },
+static const struct snd_soc_component_driver ab8500_component_driver = {
+       .probe                  = ab8500_codec_probe,
+       .controls               = ab8500_ctrls,
+       .num_controls           = ARRAY_SIZE(ab8500_ctrls),
+       .dapm_widgets           = ab8500_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ab8500_dapm_widgets),
+       .dapm_routes            = ab8500_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ab8500_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ab8500_codec_driver_probe(struct platform_device *pdev)
@@ -2561,7 +2563,8 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
        }
 
        dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
-       status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
+       status = devm_snd_soc_register_component(&pdev->dev,
+                               &ab8500_component_driver,
                                ab8500_codec_dai,
                                ARRAY_SIZE(ab8500_codec_dai));
        if (status < 0)
@@ -2572,21 +2575,11 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
        return status;
 }
 
-static int ab8500_codec_driver_remove(struct platform_device *pdev)
-{
-       dev_dbg(&pdev->dev, "%s Enter.\n", __func__);
-
-       snd_soc_unregister_codec(&pdev->dev);
-
-       return 0;
-}
-
 static struct platform_driver ab8500_codec_platform_driver = {
        .driver = {
                .name   = "ab8500-codec",
        },
        .probe          = ab8500_codec_driver_probe,
-       .remove         = ab8500_codec_driver_remove,
 };
 module_platform_driver(ab8500_codec_platform_driver);
 
index 440b4ce543764be82f354e42fc45f6a5ad4b3c90..02b4d01adb403807a554d9029bc442cf4b70abc1 100644 (file)
@@ -36,8 +36,8 @@ static const struct snd_soc_dapm_route ac97_routes[] = {
 static int ac97_prepare(struct snd_pcm_substream *substream,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
        int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
                  AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
@@ -65,7 +65,7 @@ static struct snd_soc_dai_driver ac97_dai = {
        .ops = &ac97_dai_ops,
 };
 
-static int ac97_soc_probe(struct snd_soc_codec *codec)
+static int ac97_soc_probe(struct snd_soc_component *component)
 {
        struct snd_ac97 *ac97;
        struct snd_ac97_bus *ac97_bus;
@@ -73,7 +73,7 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
        int ret;
 
        /* add codec as bus device for standard ac97 */
-       ret = snd_ac97_bus(codec->component.card->snd_card, 0, soc_ac97_ops,
+       ret = snd_ac97_bus(component->card->snd_card, 0, soc_ac97_ops,
                           NULL, &ac97_bus);
        if (ret < 0)
                return ret;
@@ -83,25 +83,25 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
        if (ret < 0)
                return ret;
 
-       snd_soc_codec_set_drvdata(codec, ac97);
+       snd_soc_component_set_drvdata(component, ac97);
 
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int ac97_soc_suspend(struct snd_soc_codec *codec)
+static int ac97_soc_suspend(struct snd_soc_component *component)
 {
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
        snd_ac97_suspend(ac97);
 
        return 0;
 }
 
-static int ac97_soc_resume(struct snd_soc_codec *codec)
+static int ac97_soc_resume(struct snd_soc_component *component)
 {
 
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
        snd_ac97_resume(ac97);
 
@@ -112,28 +112,28 @@ static int ac97_soc_resume(struct snd_soc_codec *codec)
 #define ac97_soc_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_ac97 = {
-       .probe =        ac97_soc_probe,
-       .suspend =      ac97_soc_suspend,
-       .resume =       ac97_soc_resume,
-
-       .component_driver = {
-               .dapm_widgets           = ac97_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ac97_widgets),
-               .dapm_routes            = ac97_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ac97_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ac97 = {
+       .probe                  = ac97_soc_probe,
+       .suspend                = ac97_soc_suspend,
+       .resume                 = ac97_soc_resume,
+       .dapm_widgets           = ac97_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ac97_widgets),
+       .dapm_routes            = ac97_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ac97_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ac97_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_ac97, &ac97_dai, 1);
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_ac97, &ac97_dai, 1);
 }
 
 static int ac97_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
index d0361caad09e08e51ba2f6f6e0bebc8905be85c9..ada663bf5648251fbdfafa4a3c2876c5a936388e 100644 (file)
@@ -164,7 +164,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *dai)
 {
-       struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(dai->component);
        int word_len = 0;
 
        /* bit size */
@@ -228,17 +228,17 @@ static struct snd_soc_dai_driver ad183x_dais[] = {
 };
 
 #ifdef CONFIG_PM
-static int ad1836_suspend(struct snd_soc_codec *codec)
+static int ad1836_suspend(struct snd_soc_component *component)
 {
-       struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+       struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
        /* reset clock control mode */
        return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
                AD1836_ADC_SERFMT_MASK, 0);
 }
 
-static int ad1836_resume(struct snd_soc_codec *codec)
+static int ad1836_resume(struct snd_soc_component *component)
 {
-       struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+       struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
        /* restore clock control mode */
        return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
                AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
@@ -248,10 +248,10 @@ static int ad1836_resume(struct snd_soc_codec *codec)
 #define ad1836_resume  NULL
 #endif
 
-static int ad1836_probe(struct snd_soc_codec *codec)
+static int ad1836_probe(struct snd_soc_component *component)
 {
-       struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int num_dacs, num_adcs;
        int ret = 0;
        int i;
@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
        if (ad1836->type == AD1836) {
                /* left/right diff:PGA/MUX */
                regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A);
-               ret = snd_soc_add_codec_controls(codec, ad1836_controls,
+               ret = snd_soc_add_component_controls(component, ad1836_controls,
                                ARRAY_SIZE(ad1836_controls));
                if (ret)
                        return ret;
@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
                regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00);
        }
 
-       ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
+       ret = snd_soc_add_component_controls(component, ad183x_dac_controls, num_dacs * 2);
        if (ret)
                return ret;
 
-       ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
+       ret = snd_soc_add_component_controls(component, ad183x_adc_controls, num_adcs);
        if (ret)
                return ret;
 
@@ -313,28 +313,29 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 }
 
 /* power down chip */
-static int ad1836_remove(struct snd_soc_codec *codec)
+static void ad1836_remove(struct snd_soc_component *component)
 {
-       struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+       struct ad1836_priv *ad1836 = snd_soc_component_get_drvdata(component);
        /* reset clock control mode */
-       return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
+       regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
                AD1836_ADC_SERFMT_MASK, 0);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
-       .probe = ad1836_probe,
-       .remove = ad1836_remove,
-       .suspend = ad1836_suspend,
-       .resume = ad1836_resume,
-
-       .component_driver = {
-               .controls               = ad183x_controls,
-               .num_controls           = ARRAY_SIZE(ad183x_controls),
-               .dapm_widgets           = ad183x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ad183x_dapm_widgets),
-               .dapm_routes            = ad183x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ad183x_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ad1836 = {
+       .probe                  = ad1836_probe,
+       .remove                 = ad1836_remove,
+       .suspend                = ad1836_suspend,
+       .resume                 = ad1836_resume,
+       .controls               = ad183x_controls,
+       .num_controls           = ARRAY_SIZE(ad183x_controls),
+       .dapm_widgets           = ad183x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ad183x_dapm_widgets),
+       .dapm_routes            = ad183x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ad183x_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct reg_default ad1836_reg_defaults[] = {
@@ -382,17 +383,11 @@ static int ad1836_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, ad1836);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_ad1836, &ad183x_dais[ad1836->type], 1);
        return ret;
 }
 
-static int ad1836_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static const struct spi_device_id ad1836_ids[] = {
        { "ad1835", AD1835 },
        { "ad1836", AD1836 },
@@ -408,7 +403,6 @@ static struct spi_driver ad1836_spi_driver = {
                .name   = "ad1836",
        },
        .probe          = ad1836_spi_probe,
-       .remove         = ad1836_spi_remove,
        .id_table       = ad1836_ids,
 };
 
index 171313664bc8dac6472dcf423063882fb4ffd8f2..b9551334f6b4e10066e8af87283888c9300d05e2 100644 (file)
@@ -35,18 +35,11 @@ static int ad193x_i2c_probe(struct i2c_client *client,
                            (enum ad193x_type)id->driver_data);
 }
 
-static int ad193x_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static struct i2c_driver ad193x_i2c_driver = {
        .driver = {
                .name = "ad193x",
        },
        .probe    = ad193x_i2c_probe,
-       .remove   = ad193x_i2c_remove,
        .id_table = ad193x_id,
 };
 module_i2c_driver(ad193x_i2c_driver);
index 23c28573bdb7057356c569cb0d6054cd041611b0..3c1394a803b868d67f530214fc97e03891ea087f 100644 (file)
@@ -29,12 +29,6 @@ static int ad193x_spi_probe(struct spi_device *spi)
                            (enum ad193x_type)id->driver_data);
 }
 
-static int ad193x_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static const struct spi_device_id ad193x_spi_id[] = {
        { "ad193x", AD193X },
        { "ad1933", AD1933 },
@@ -51,7 +45,6 @@ static struct spi_driver ad193x_spi_driver = {
                .name   = "ad193x",
        },
        .probe          = ad193x_spi_probe,
-       .remove         = ad193x_spi_remove,
        .id_table       = ad193x_spi_id,
 };
 module_spi_driver(ad193x_spi_driver);
index d10988eec0c10a236454dc146956d735e2ec98c6..4b60ebee491dce7090e70c20a09bf8601b73d50d 100644 (file)
@@ -130,7 +130,7 @@ static inline bool ad193x_has_adc(const struct ad193x_priv *ad193x)
 
 static int ad193x_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
+       struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
 
        if (mute)
                regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
@@ -146,7 +146,7 @@ static int ad193x_mute(struct snd_soc_dai *dai, int mute)
 static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                               unsigned int rx_mask, int slots, int width)
 {
-       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
+       struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
        unsigned int channels;
 
        switch (slots) {
@@ -179,7 +179,7 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec);
+       struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component);
        unsigned int adc_serfmt = 0;
        unsigned int adc_fmt = 0;
        unsigned int dac_fmt = 0;
@@ -257,8 +257,8 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
        switch (freq) {
        case 12288000:
        case 18432000:
@@ -275,8 +275,8 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
                struct snd_soc_dai *dai)
 {
        int word_len = 0, master_rate = 0;
-       struct snd_soc_codec *codec = dai->codec;
-       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
 
        /* bit size */
        switch (params_width(params)) {
@@ -351,10 +351,10 @@ static struct snd_soc_dai_driver ad193x_dai = {
        .ops = &ad193x_dai_ops,
 };
 
-static int ad193x_codec_probe(struct snd_soc_codec *codec)
+static int ad193x_component_probe(struct snd_soc_component *component)
 {
-       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int num, ret;
 
        /* default setting for ad193x */
@@ -382,7 +382,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
        if (ad193x_has_adc(ad193x)) {
                /* add adc controls */
                num = ARRAY_SIZE(ad193x_adc_snd_controls);
-               ret = snd_soc_add_codec_controls(codec,
+               ret = snd_soc_add_component_controls(component,
                                                 ad193x_adc_snd_controls,
                                                 num);
                if (ret)
@@ -408,16 +408,18 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad193x = {
-       .probe = ad193x_codec_probe,
-       .component_driver = {
-               .controls               = ad193x_snd_controls,
-               .num_controls           = ARRAY_SIZE(ad193x_snd_controls),
-               .dapm_widgets           = ad193x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ad193x_dapm_widgets),
-               .dapm_routes            = audio_paths,
-               .num_dapm_routes        = ARRAY_SIZE(audio_paths),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ad193x = {
+       .probe                  = ad193x_component_probe,
+       .controls               = ad193x_snd_controls,
+       .num_controls           = ARRAY_SIZE(ad193x_snd_controls),
+       .dapm_widgets           = ad193x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ad193x_dapm_widgets),
+       .dapm_routes            = audio_paths,
+       .num_dapm_routes        = ARRAY_SIZE(audio_paths),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 const struct regmap_config ad193x_regmap_config = {
@@ -442,7 +444,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
 
        dev_set_drvdata(dev, ad193x);
 
-       return snd_soc_register_codec(dev, &soc_codec_dev_ad193x,
+       return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
                &ad193x_dai, 1);
 }
 EXPORT_SYMBOL_GPL(ad193x_probe);
index ce89bfb42094b4d678d9992bbd3c76e068914015..16dab3f00a1cb745efa97dbee9ef4787a328cda2 100644 (file)
@@ -205,9 +205,9 @@ static struct snd_soc_dai_driver ad1980_dai = {
 #define AD1980_VENDOR_ID 0x41445300
 #define AD1980_VENDOR_MASK 0xffffff00
 
-static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
+static int ad1980_reset(struct snd_soc_component *component, int try_warm)
 {
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
        unsigned int retry_cnt = 0;
        int ret;
 
@@ -223,16 +223,16 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
                 * case the first nibble of data is eaten by the addr. (Tag is
                 * always 16 bit)
                 */
-               snd_soc_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
+               snd_soc_component_write(component, AC97_AD_SERIAL_CFG, 0x9900);
 
        } while (retry_cnt++ < 10);
 
-       dev_err(codec->dev, "Failed to reset: AC97 link error\n");
+       dev_err(component->dev, "Failed to reset: AC97 link error\n");
 
        return -EIO;
 }
 
-static int ad1980_soc_probe(struct snd_soc_codec *codec)
+static int ad1980_soc_probe(struct snd_soc_component *component)
 {
        struct snd_ac97 *ac97;
        struct regmap *regmap;
@@ -240,10 +240,10 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
        u16 vendor_id2;
        u16 ext_status;
 
-       ac97 = snd_soc_new_ac97_codec(codec, 0, 0);
+       ac97 = snd_soc_new_ac97_component(component, 0, 0);
        if (IS_ERR(ac97)) {
                ret = PTR_ERR(ac97);
-               dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
+               dev_err(component->dev, "Failed to register AC97 component: %d\n", ret);
                return ret;
        }
 
@@ -253,72 +253,66 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
                goto err_free_ac97;
        }
 
-       snd_soc_codec_init_regmap(codec, regmap);
-       snd_soc_codec_set_drvdata(codec, ac97);
+       snd_soc_component_init_regmap(component, regmap);
+       snd_soc_component_set_drvdata(component, ac97);
 
-       ret = ad1980_reset(codec, 0);
+       ret = ad1980_reset(component, 0);
        if (ret < 0)
                goto reset_err;
 
-       vendor_id2 = snd_soc_read(codec, AC97_VENDOR_ID2);
+       vendor_id2 = snd_soc_component_read32(component, AC97_VENDOR_ID2);
        if (vendor_id2 == 0x5374) {
-               dev_warn(codec->dev,
+               dev_warn(component->dev,
                        "Found AD1981 - only 2/2 IN/OUT Channels supported\n");
        }
 
        /* unmute captures and playbacks volume */
-       snd_soc_write(codec, AC97_MASTER, 0x0000);
-       snd_soc_write(codec, AC97_PCM, 0x0000);
-       snd_soc_write(codec, AC97_REC_GAIN, 0x0000);
-       snd_soc_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
-       snd_soc_write(codec, AC97_SURROUND_MASTER, 0x0000);
+       snd_soc_component_write(component, AC97_MASTER, 0x0000);
+       snd_soc_component_write(component, AC97_PCM, 0x0000);
+       snd_soc_component_write(component, AC97_REC_GAIN, 0x0000);
+       snd_soc_component_write(component, AC97_CENTER_LFE_MASTER, 0x0000);
+       snd_soc_component_write(component, AC97_SURROUND_MASTER, 0x0000);
 
        /*power on LFE/CENTER/Surround DACs*/
-       ext_status = snd_soc_read(codec, AC97_EXTENDED_STATUS);
-       snd_soc_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
+       ext_status = snd_soc_component_read32(component, AC97_EXTENDED_STATUS);
+       snd_soc_component_write(component, AC97_EXTENDED_STATUS, ext_status&~0x3800);
 
        return 0;
 
 reset_err:
-       snd_soc_codec_exit_regmap(codec);
+       snd_soc_component_exit_regmap(component);
 err_free_ac97:
-       snd_soc_free_ac97_codec(ac97);
+       snd_soc_free_ac97_component(ac97);
        return ret;
 }
 
-static int ad1980_soc_remove(struct snd_soc_codec *codec)
+static void ad1980_soc_remove(struct snd_soc_component *component)
 {
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
-       snd_soc_codec_exit_regmap(codec);
-       snd_soc_free_ac97_codec(ac97);
-       return 0;
+       snd_soc_component_exit_regmap(component);
+       snd_soc_free_ac97_component(ac97);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
-       .probe =        ad1980_soc_probe,
-       .remove =       ad1980_soc_remove,
-
-       .component_driver = {
-               .controls               = ad1980_snd_ac97_controls,
-               .num_controls           = ARRAY_SIZE(ad1980_snd_ac97_controls),
-               .dapm_widgets           = ad1980_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ad1980_dapm_widgets),
-               .dapm_routes            = ad1980_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ad1980_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ad1980 = {
+       .probe                  = ad1980_soc_probe,
+       .remove                 = ad1980_soc_remove,
+       .controls               = ad1980_snd_ac97_controls,
+       .num_controls           = ARRAY_SIZE(ad1980_snd_ac97_controls),
+       .dapm_widgets           = ad1980_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ad1980_dapm_widgets),
+       .dapm_routes            = ad1980_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ad1980_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ad1980_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_ad1980, &ad1980_dai, 1);
-}
-
-static int ad1980_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_ad1980, &ad1980_dai, 1);
 }
 
 static struct platform_driver ad1980_codec_driver = {
@@ -327,7 +321,6 @@ static struct platform_driver ad1980_codec_driver = {
        },
 
        .probe = ad1980_probe,
-       .remove = ad1980_remove,
 };
 
 module_platform_driver(ad1980_codec_driver);
index d8d86a0fea605941a8f4295d3fd4cff88eec941b..03ee571e1b7a3f5db79b416e349224b6be6761b6 100644 (file)
@@ -54,25 +54,21 @@ static struct snd_soc_dai_driver ad73311_dai = {
                .formats = SNDRV_PCM_FMTBIT_S16_LE, },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
-       .component_driver = {
-               .dapm_widgets           = ad73311_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ad73311_dapm_widgets),
-               .dapm_routes            = ad73311_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ad73311_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ad73311 = {
+       .dapm_widgets           = ad73311_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ad73311_dapm_widgets),
+       .dapm_routes            = ad73311_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ad73311_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ad73311_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_ad73311, &ad73311_dai, 1);
-}
-
-static int ad73311_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_ad73311, &ad73311_dai, 1);
 }
 
 static struct platform_driver ad73311_codec_driver = {
@@ -81,7 +77,6 @@ static struct platform_driver ad73311_codec_driver = {
        },
 
        .probe = ad73311_probe,
-       .remove = ad73311_remove,
 };
 
 module_platform_driver(ad73311_codec_driver);
index a865945d776a4b08f88b0fdd2f1d40ea59c38a1c..f22ff9f6ab47cb08dceab6714c2155c8ca9e1960 100644 (file)
@@ -549,8 +549,8 @@ static const struct snd_kcontrol_new adau1373_drc_controls[] = {
 static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
        unsigned int pll_id = w->name[3] - '1';
        unsigned int val;
 
@@ -821,8 +821,8 @@ static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = {
 static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
        struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
        unsigned int dai;
        const char *clk;
 
@@ -842,8 +842,8 @@ static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source,
 static int adau1373_check_src(struct snd_soc_dapm_widget *source,
        struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
        unsigned int dai;
 
        dai = sink->name[3] - '1';
@@ -1031,8 +1031,8 @@ static const struct snd_soc_dapm_route adau1373_dapm_routes[] = {
 static int adau1373_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
        struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
        unsigned int div;
        unsigned int freq;
@@ -1098,8 +1098,8 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
 
 static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
        struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
        unsigned int ctrl;
 
@@ -1158,7 +1158,7 @@ static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
        int clk_id, unsigned int freq, int dir)
 {
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(dai->component);
        struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id];
 
        switch (clk_id) {
@@ -1250,10 +1250,10 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = {
        },
 };
 
-static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
+static int adau1373_set_pll(struct snd_soc_component *component, int pll_id,
        int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
        unsigned int dpll_div = 0;
        uint8_t pll_regs[5];
        int ret;
@@ -1348,10 +1348,10 @@ static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
        return false;
 }
 
-static int adau1373_probe(struct snd_soc_codec *codec)
+static int adau1373_probe(struct snd_soc_component *component)
 {
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
-       struct adau1373_platform_data *pdata = codec->dev->platform_data;
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
+       struct adau1373_platform_data *pdata = component->dev->platform_data;
        bool lineout_differential = false;
        unsigned int val;
        int i;
@@ -1369,7 +1369,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
                                pdata->drc_setting[i]);
                }
 
-               snd_soc_add_codec_controls(codec, adau1373_drc_controls,
+               snd_soc_add_component_controls(component, adau1373_drc_controls,
                        pdata->num_drc);
 
                val = 0;
@@ -1394,7 +1394,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
        }
 
        if (!lineout_differential) {
-               snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
+               snd_soc_add_component_controls(component, adau1373_lineout2_controls,
                        ARRAY_SIZE(adau1373_lineout2_controls));
        }
 
@@ -1404,10 +1404,10 @@ static int adau1373_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int adau1373_set_bias_level(struct snd_soc_codec *codec,
+static int adau1373_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -1426,9 +1426,9 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adau1373_resume(struct snd_soc_codec *codec)
+static int adau1373_resume(struct snd_soc_component *component)
 {
-       struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
+       struct adau1373 *adau1373 = snd_soc_component_get_drvdata(component);
 
        regcache_sync(adau1373->regmap);
 
@@ -1458,22 +1458,20 @@ static const struct regmap_config adau1373_regmap_config = {
        .num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver adau1373_codec_driver = {
-       .probe =        adau1373_probe,
-       .resume =       adau1373_resume,
-       .set_bias_level = adau1373_set_bias_level,
-       .idle_bias_off = true,
-
-       .set_pll = adau1373_set_pll,
-
-       .component_driver = {
-               .controls               = adau1373_controls,
-               .num_controls           = ARRAY_SIZE(adau1373_controls),
-               .dapm_widgets           = adau1373_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adau1373_dapm_widgets),
-               .dapm_routes            = adau1373_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adau1373_dapm_routes),
-       },
+static const struct snd_soc_component_driver adau1373_component_driver = {
+       .probe                  = adau1373_probe,
+       .resume                 = adau1373_resume,
+       .set_bias_level         = adau1373_set_bias_level,
+       .set_pll                = adau1373_set_pll,
+       .controls               = adau1373_controls,
+       .num_controls           = ARRAY_SIZE(adau1373_controls),
+       .dapm_widgets           = adau1373_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adau1373_dapm_widgets),
+       .dapm_routes            = adau1373_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adau1373_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int adau1373_i2c_probe(struct i2c_client *client,
@@ -1495,17 +1493,12 @@ static int adau1373_i2c_probe(struct i2c_client *client,
 
        dev_set_drvdata(&client->dev, adau1373);
 
-       ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,
+       ret = devm_snd_soc_register_component(&client->dev,
+                       &adau1373_component_driver,
                        adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver));
        return ret;
 }
 
-static int adau1373_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id adau1373_i2c_id[] = {
        { "adau1373", 0 },
        { }
@@ -1517,7 +1510,6 @@ static struct i2c_driver adau1373_i2c_driver = {
                .name = "adau1373",
        },
        .probe = adau1373_i2c_probe,
-       .remove = adau1373_i2c_remove,
        .id_table = adau1373_i2c_id,
 };
 
index 805afac8146bbf52bf059df02f2d17a673aad3ae..b5a61741c800c8cd34360c37b84e5fa44ae132dd 100644 (file)
@@ -298,10 +298,10 @@ static const struct sigmadsp_ops adau1701_sigmadsp_ops = {
        .safeload = adau1701_safeload,
 };
 
-static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
+static int adau1701_reset(struct snd_soc_component *component, unsigned int clkdiv,
        unsigned int rate)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        int ret;
 
        sigmadsp_reset(adau1701->sigmadsp);
@@ -348,7 +348,7 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
        if (clkdiv != ADAU1707_CLKDIV_UNSET) {
                ret = sigmadsp_setup(adau1701->sigmadsp, rate);
                if (ret) {
-                       dev_warn(codec->dev, "Failed to load firmware\n");
+                       dev_warn(component->dev, "Failed to load firmware\n");
                        return ret;
                }
        }
@@ -362,10 +362,10 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv,
        return 0;
 }
 
-static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
+static int adau1701_set_capture_pcm_format(struct snd_soc_component *component,
                                           struct snd_pcm_hw_params *params)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
        unsigned int val;
 
@@ -403,10 +403,10 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
+static int adau1701_set_playback_pcm_format(struct snd_soc_component *component,
                                            struct snd_pcm_hw_params *params)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
@@ -435,8 +435,8 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
 static int adau1701_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        unsigned int clkdiv = adau1701->sysclk / params_rate(params);
        unsigned int val;
        int ret;
@@ -447,7 +447,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
         * firmware upload.
         */
        if (clkdiv != adau1701->pll_clkdiv) {
-               ret = adau1701_reset(codec, clkdiv, params_rate(params));
+               ret = adau1701_reset(component, clkdiv, params_rate(params));
                if (ret < 0)
                        return ret;
        }
@@ -470,16 +470,16 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
                ADAU1701_DSPCTRL_SR_MASK, val);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               return adau1701_set_playback_pcm_format(codec, params);
+               return adau1701_set_playback_pcm_format(component, params);
        else
-               return adau1701_set_capture_pcm_format(codec, params);
+               return adau1701_set_capture_pcm_format(component, params);
 }
 
 static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        unsigned int serictl = 0x00, seroctl = 0x00;
        bool invert_lrclk;
 
@@ -548,11 +548,11 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int adau1701_set_bias_level(struct snd_soc_codec *codec,
+static int adau1701_set_bias_level(struct snd_soc_component *component,
                enum snd_soc_bias_level level)
 {
        unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -576,9 +576,9 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
 
 static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int mask = ADAU1701_DSPCTRL_DAM;
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (mute)
@@ -591,11 +591,11 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
        return 0;
 }
 
-static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int adau1701_set_sysclk(struct snd_soc_component *component, int clk_id,
        int source, unsigned int freq, int dir)
 {
        unsigned int val;
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case ADAU1701_CLK_SRC_OSC:
@@ -618,7 +618,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 static int adau1701_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(dai->component);
 
        return sigmadsp_restrict_params(adau1701->sigmadsp, substream);
 }
@@ -664,20 +664,20 @@ static const struct of_device_id adau1701_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
 #endif
 
-static int adau1701_probe(struct snd_soc_codec *codec)
+static int adau1701_probe(struct snd_soc_component *component)
 {
        int i, ret;
        unsigned int val;
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
-       ret = sigmadsp_attach(adau1701->sigmadsp, &codec->component);
+       ret = sigmadsp_attach(adau1701->sigmadsp, component);
        if (ret)
                return ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
                                    adau1701->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+               dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
                return ret;
        }
 
@@ -690,7 +690,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
        adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
 
        /* initalize with pre-configured pll mode settings */
-       ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
+       ret = adau1701_reset(component, adau1701->pll_clkdiv, 0);
        if (ret < 0)
                goto exit_regulators_disable;
 
@@ -715,22 +715,20 @@ exit_regulators_disable:
        return ret;
 }
 
-static int adau1701_remove(struct snd_soc_codec *codec)
+static void adau1701_remove(struct snd_soc_component *component)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(adau1701->gpio_nreset))
                gpio_set_value_cansleep(adau1701->gpio_nreset, 0);
 
        regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int adau1701_suspend(struct snd_soc_codec *codec)
+static int adau1701_suspend(struct snd_soc_component *component)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
 
        regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies),
                               adau1701->supplies);
@@ -738,42 +736,41 @@ static int adau1701_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int adau1701_resume(struct snd_soc_codec *codec)
+static int adau1701_resume(struct snd_soc_component *component)
 {
-       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+       struct adau1701 *adau1701 = snd_soc_component_get_drvdata(component);
        int ret;
 
         ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
                                    adau1701->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+               dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
                return ret;
        }
 
-       return adau1701_reset(codec, adau1701->pll_clkdiv, 0);
+       return adau1701_reset(component, adau1701->pll_clkdiv, 0);
 }
 #else
 #define adau1701_resume        NULL
 #define adau1701_suspend       NULL
 #endif /* CONFIG_PM */
 
-static const struct snd_soc_codec_driver adau1701_codec_drv = {
+static const struct snd_soc_component_driver adau1701_component_drv = {
        .probe                  = adau1701_probe,
        .remove                 = adau1701_remove,
        .resume                 = adau1701_resume,
        .suspend                = adau1701_suspend,
        .set_bias_level         = adau1701_set_bias_level,
-       .idle_bias_off          = true,
-
-       .component_driver = {
-               .controls               = adau1701_controls,
-               .num_controls           = ARRAY_SIZE(adau1701_controls),
-               .dapm_widgets           = adau1701_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adau1701_dapm_widgets),
-               .dapm_routes            = adau1701_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adau1701_dapm_routes),
-       },
+       .controls               = adau1701_controls,
+       .num_controls           = ARRAY_SIZE(adau1701_controls),
+       .dapm_widgets           = adau1701_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adau1701_dapm_widgets),
+       .dapm_routes            = adau1701_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adau1701_dapm_routes),
        .set_sysclk             = adau1701_set_sysclk,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config adau1701_regmap = {
@@ -889,7 +886,8 @@ static int adau1701_i2c_probe(struct i2c_client *client,
                goto exit_regulators_disable;
        }
 
-       ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
+       ret = devm_snd_soc_register_component(&client->dev,
+                       &adau1701_component_drv,
                        &adau1701_dai, 1);
 
 exit_regulators_disable:
@@ -898,12 +896,6 @@ exit_regulators_disable:
        return ret;
 }
 
-static int adau1701_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id adau1701_i2c_id[] = {
        { "adau1401", 0 },
        { "adau1401a", 0 },
@@ -919,7 +911,6 @@ static struct i2c_driver adau1701_i2c_driver = {
                .of_match_table = of_match_ptr(adau1701_dt_ids),
        },
        .probe          = adau1701_i2c_probe,
-       .remove         = adau1701_i2c_remove,
        .id_table       = adau1701_i2c_id,
 };
 
index 3bc3cc559dde0a1430ff671332bae4ca840bf9a9..be136e9816533fd5da7d66d5a383ac13f5866556 100644 (file)
@@ -255,8 +255,8 @@ static const struct snd_kcontrol_new adau1761_input_mux_control =
 static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        /* After any power changes have been made the dejitter circuit
         * has to be reinitialized. */
@@ -445,10 +445,10 @@ static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
        { "Digital Clock 1", NULL, "SYSCLK" },
 };
 
-static int adau1761_set_bias_level(struct snd_soc_codec *codec,
+static int adau1761_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -460,7 +460,7 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
                regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
                        ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
                        ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        regcache_sync(adau->regmap);
                break;
        case SND_SOC_BIAS_OFF:
@@ -474,9 +474,9 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
 }
 
 static enum adau1761_output_mode adau1761_get_lineout_mode(
-       struct snd_soc_codec *codec)
+       struct snd_soc_component *component)
 {
-       struct adau1761_platform_data *pdata = codec->dev->platform_data;
+       struct adau1761_platform_data *pdata = component->dev->platform_data;
 
        if (pdata)
                return pdata->lineout_mode;
@@ -484,11 +484,11 @@ static enum adau1761_output_mode adau1761_get_lineout_mode(
        return ADAU1761_OUTPUT_MODE_LINE;
 }
 
-static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
+static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau1761_platform_data *pdata = codec->dev->platform_data;
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau1761_platform_data *pdata = component->dev->platform_data;
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        enum adau1761_digmic_jackdet_pin_mode mode;
        unsigned int val = 0;
        int ret;
@@ -513,7 +513,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
                if (pdata->jackdetect_active_low)
                        val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
 
-               ret = snd_soc_add_codec_controls(codec,
+               ret = snd_soc_add_component_controls(component,
                        adau1761_jack_detect_controls,
                        ARRAY_SIZE(adau1761_jack_detect_controls));
                if (ret)
@@ -546,11 +546,11 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
+static int adau1761_setup_headphone_mode(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
-       struct adau1761_platform_data *pdata = codec->dev->platform_data;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
+       struct adau1761_platform_data *pdata = component->dev->platform_data;
        enum adau1761_output_mode mode;
        int ret;
 
@@ -588,7 +588,7 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
                        adau1761_capless_dapm_routes,
                        ARRAY_SIZE(adau1761_capless_dapm_routes));
        } else {
-               ret = snd_soc_add_codec_controls(codec, adau1761_mono_controls,
+               ret = snd_soc_add_component_controls(component, adau1761_mono_controls,
                        ARRAY_SIZE(adau1761_mono_controls));
                if (ret)
                        return ret;
@@ -640,14 +640,14 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg)
        return adau17x1_readable_register(dev, reg);
 }
 
-static int adau1761_codec_probe(struct snd_soc_codec *codec)
+static int adau1761_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau1761_platform_data *pdata = codec->dev->platform_data;
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau1761_platform_data *pdata = component->dev->platform_data;
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        int ret;
 
-       ret = adau17x1_add_widgets(codec);
+       ret = adau17x1_add_widgets(component);
        if (ret < 0)
                return ret;
 
@@ -658,20 +658,20 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
                regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
                        ADAU1761_DIFF_INPUT_VOL_LDEN,
                        ADAU1761_DIFF_INPUT_VOL_LDEN);
-               ret = snd_soc_add_codec_controls(codec,
+               ret = snd_soc_add_component_controls(component,
                        adau1761_differential_mode_controls,
                        ARRAY_SIZE(adau1761_differential_mode_controls));
                if (ret)
                        return ret;
        } else {
-               ret = snd_soc_add_codec_controls(codec,
+               ret = snd_soc_add_component_controls(component,
                        adau1761_single_mode_controls,
                        ARRAY_SIZE(adau1761_single_mode_controls));
                if (ret)
                        return ret;
        }
 
-       switch (adau1761_get_lineout_mode(codec)) {
+       switch (adau1761_get_lineout_mode(component)) {
        case ADAU1761_OUTPUT_MODE_LINE:
                break;
        case ADAU1761_OUTPUT_MODE_HEADPHONE:
@@ -686,11 +686,11 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
                return -EINVAL;
        }
 
-       ret = adau1761_setup_headphone_mode(codec);
+       ret = adau1761_setup_headphone_mode(component);
        if (ret)
                return ret;
 
-       ret = adau1761_setup_digmic_jackdetect(codec);
+       ret = adau1761_setup_digmic_jackdetect(component);
        if (ret)
                return ret;
 
@@ -706,27 +706,28 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
                        return ret;
        }
 
-       ret = adau17x1_add_routes(codec);
+       ret = adau17x1_add_routes(component);
        if (ret < 0)
                return ret;
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver adau1761_codec_driver = {
-       .probe = adau1761_codec_probe,
-       .resume = adau17x1_resume,
-       .set_bias_level = adau1761_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = adau1761_controls,
-               .num_controls           = ARRAY_SIZE(adau1761_controls),
-               .dapm_widgets           = adau1x61_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adau1x61_dapm_widgets),
-               .dapm_routes            = adau1x61_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adau1x61_dapm_routes),
-       },
+static const struct snd_soc_component_driver adau1761_component_driver = {
+       .probe                  = adau1761_component_probe,
+       .resume                 = adau17x1_resume,
+       .set_bias_level         = adau1761_set_bias_level,
+       .controls               = adau1761_controls,
+       .num_controls           = ARRAY_SIZE(adau1761_controls),
+       .dapm_widgets           = adau1x61_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adau1x61_dapm_widgets),
+       .dapm_routes            = adau1x61_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adau1x61_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
@@ -793,7 +794,8 @@ int adau1761_probe(struct device *dev, struct regmap *regmap,
         * reaches standby and the core clock is enabled */
        regcache_cache_only(regmap, true);
 
-       return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
+       return devm_snd_soc_register_component(dev, &adau1761_component_driver,
+                                              dai_drv, 1);
 }
 EXPORT_SYMBOL_GPL(adau1761_probe);
 
index 546071c6c0d09472df2170f514ec277fc6f7293d..6a6655730cd41b90e4e266bd73b35fa937cf8662 100644 (file)
@@ -174,8 +174,8 @@ static const struct snd_kcontrol_new adau1781_mono_mixer_controls[] = {
 static int adau1781_dejitter_fixup(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        /* After any power changes have been made the dejitter circuit
         * has to be reinitialized. */
@@ -314,10 +314,10 @@ static const struct snd_soc_dapm_route adau1781_dmic_dapm_routes[] = {
        { "Right Decimator", NULL, "DMIC Select" },
 };
 
-static int adau1781_set_bias_level(struct snd_soc_codec *codec,
+static int adau1781_set_bias_level(struct snd_soc_component *component,
                enum snd_soc_bias_level level)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -380,14 +380,14 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg,
                ADAU1781_INPUT_DIFFERNTIAL, val);
 }
 
-static int adau1781_codec_probe(struct snd_soc_codec *codec)
+static int adau1781_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau1781_platform_data *pdata = dev_get_platdata(component->dev);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        int ret;
 
-       ret = adau17x1_add_widgets(codec);
+       ret = adau17x1_add_widgets(component);
        if (ret)
                return ret;
 
@@ -419,27 +419,28 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
                        return ret;
        }
 
-       ret = adau17x1_add_routes(codec);
+       ret = adau17x1_add_routes(component);
        if (ret < 0)
                return ret;
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver adau1781_codec_driver = {
-       .probe = adau1781_codec_probe,
-       .resume = adau17x1_resume,
-       .set_bias_level = adau1781_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = adau1781_controls,
-               .num_controls           = ARRAY_SIZE(adau1781_controls),
-               .dapm_widgets           = adau1781_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adau1781_dapm_widgets),
-               .dapm_routes            = adau1781_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adau1781_dapm_routes),
-       },
+static const struct snd_soc_component_driver adau1781_component_driver = {
+       .probe                  = adau1781_component_probe,
+       .resume                 = adau17x1_resume,
+       .set_bias_level         = adau1781_set_bias_level,
+       .controls               = adau1781_controls,
+       .num_controls           = ARRAY_SIZE(adau1781_controls),
+       .dapm_widgets           = adau1781_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adau1781_dapm_widgets),
+       .dapm_routes            = adau1781_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adau1781_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
@@ -498,7 +499,7 @@ int adau1781_probe(struct device *dev, struct regmap *regmap,
        if (ret)
                return ret;
 
-       return snd_soc_register_codec(dev, &adau1781_codec_driver,
+       return devm_snd_soc_register_component(dev, &adau1781_component_driver,
                &adau1781_dai_driver, 1);
 }
 EXPORT_SYMBOL_GPL(adau1781_probe);
index 6758f789b712cd32af6940ef501619a5af6b8502..80c2a06285bbe1f5df619542836bef3a15941c96 100644 (file)
@@ -63,8 +63,8 @@ static const struct snd_kcontrol_new adau17x1_controls[] = {
 static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        if (SND_SOC_DAPM_EVENT_ON(event)) {
                adau->pll_regs[5] = 1;
@@ -93,8 +93,8 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
 static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        /*
         * If we are capturing, toggle the ADOSR bit in Converter Control 0 to
@@ -177,11 +177,11 @@ static const struct snd_soc_dapm_route adau17x1_dapm_pll_route = {
 static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       struct snd_soc_dapm_update update = { 0 };
+       struct snd_soc_dapm_update update = {};
        unsigned int stream = e->shift_l;
        unsigned int val, change;
        int reg;
@@ -205,7 +205,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
        else
                reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;
 
-       change = snd_soc_test_bits(codec, reg, 0xff, val);
+       change = snd_soc_component_test_bits(component, reg, 0xff, val);
        if (change) {
                update.kcontrol = kcontrol;
                update.mask = 0xff;
@@ -222,8 +222,8 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
 static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned int stream = e->shift_l;
        unsigned int reg, val;
@@ -328,8 +328,8 @@ EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
 static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
        int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        int ret;
 
        if (freq_in < 8000000 || freq_in > 27000000)
@@ -353,8 +353,8 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
 static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
-       struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component);
+       struct adau *adau = snd_soc_component_get_drvdata(dai->component);
        bool is_pll;
        bool was_pll;
 
@@ -438,8 +438,8 @@ static int adau17x1_auto_pll(struct snd_soc_dai *dai,
 static int adau17x1_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        unsigned int val, div, dsp_div;
        unsigned int freq;
        int ret;
@@ -531,7 +531,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
 static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
                unsigned int fmt)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau *adau = snd_soc_component_get_drvdata(dai->component);
        unsigned int ctrl0, ctrl1;
        int lrclk_pol;
 
@@ -603,7 +603,7 @@ static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,
 static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau *adau = snd_soc_component_get_drvdata(dai->component);
        unsigned int ser_ctrl0, ser_ctrl1;
        unsigned int conv_ctrl0, conv_ctrl1;
 
@@ -728,7 +728,7 @@ static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,
 static int adau17x1_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau *adau = snd_soc_component_get_drvdata(dai->component);
 
        if (adau->sigmadsp)
                return sigmadsp_restrict_params(adau->sigmadsp, substream);
@@ -746,10 +746,10 @@ const struct snd_soc_dai_ops adau17x1_dai_ops = {
 };
 EXPORT_SYMBOL_GPL(adau17x1_dai_ops);
 
-int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
+int adau17x1_set_micbias_voltage(struct snd_soc_component *component,
        enum adau17x1_micbias_voltage micbias)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        switch (micbias) {
        case ADAU17X1_MICBIAS_0_90_AVDD:
@@ -858,13 +858,13 @@ int adau17x1_setup_firmware(struct adau *adau, unsigned int rate)
 }
 EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
 
-int adau17x1_add_widgets(struct snd_soc_codec *codec)
+int adau17x1_add_widgets(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        int ret;
 
-       ret = snd_soc_add_codec_controls(codec, adau17x1_controls,
+       ret = snd_soc_add_component_controls(component, adau17x1_controls,
                ARRAY_SIZE(adau17x1_controls));
        if (ret)
                return ret;
@@ -882,9 +882,9 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec)
                if (!adau->sigmadsp)
                        return 0;
 
-               ret = sigmadsp_attach(adau->sigmadsp, &codec->component);
+               ret = sigmadsp_attach(adau->sigmadsp, component);
                if (ret) {
-                       dev_err(codec->dev, "Failed to attach firmware: %d\n",
+                       dev_err(component->dev, "Failed to attach firmware: %d\n",
                                ret);
                        return ret;
                }
@@ -894,10 +894,10 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(adau17x1_add_widgets);
 
-int adau17x1_add_routes(struct snd_soc_codec *codec)
+int adau17x1_add_routes(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes,
@@ -920,12 +920,12 @@ int adau17x1_add_routes(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(adau17x1_add_routes);
 
-int adau17x1_resume(struct snd_soc_codec *codec)
+int adau17x1_resume(struct snd_soc_component *component)
 {
-       struct adau *adau = snd_soc_codec_get_drvdata(codec);
+       struct adau *adau = snd_soc_component_get_drvdata(component);
 
        if (adau->switch_mode)
-               adau->switch_mode(codec->dev);
+               adau->switch_mode(component->dev);
 
        regcache_sync(adau->regmap);
 
@@ -998,7 +998,6 @@ void adau17x1_remove(struct device *dev)
 {
        struct adau *adau = dev_get_drvdata(dev);
 
-       snd_soc_unregister_codec(dev);
        if (adau->mclk)
                clk_disable_unprepare(adau->mclk);
 }
index eaf8f933bab8ae60c22475dbaaf6adf771474654..a7b1cb770814624f51465664e2dd3e592a91f1df 100644 (file)
@@ -53,18 +53,18 @@ struct adau {
        struct sigmadsp *sigmadsp;
 };
 
-int adau17x1_add_widgets(struct snd_soc_codec *codec);
-int adau17x1_add_routes(struct snd_soc_codec *codec);
+int adau17x1_add_widgets(struct snd_soc_component *component);
+int adau17x1_add_routes(struct snd_soc_component *component);
 int adau17x1_probe(struct device *dev, struct regmap *regmap,
        enum adau17x1_type type, void (*switch_mode)(struct device *dev),
        const char *firmware_name);
 void adau17x1_remove(struct device *dev);
-int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
+int adau17x1_set_micbias_voltage(struct snd_soc_component *component,
        enum adau17x1_micbias_voltage micbias);
 bool adau17x1_readable_register(struct device *dev, unsigned int reg);
 bool adau17x1_volatile_register(struct device *dev, unsigned int reg);
 bool adau17x1_precious_register(struct device *dev, unsigned int reg);
-int adau17x1_resume(struct snd_soc_codec *codec);
+int adau17x1_resume(struct snd_soc_component *component);
 
 extern const struct snd_soc_dai_ops adau17x1_dai_ops;
 
index 21e7394a972ae2a995e1af61a91a198c6dd5b42a..e7fe1ee5cdeb1b7828ac615d4e11de1b298b9f10 100644 (file)
@@ -29,12 +29,6 @@ static int adau1977_i2c_probe(struct i2c_client *client,
                id->driver_data, NULL);
 }
 
-static int adau1977_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id adau1977_i2c_ids[] = {
        { "adau1977", ADAU1977 },
        { "adau1978", ADAU1978 },
@@ -48,7 +42,6 @@ static struct i2c_driver adau1977_i2c_driver = {
                .name = "adau1977",
        },
        .probe = adau1977_i2c_probe,
-       .remove = adau1977_i2c_remove,
        .id_table = adau1977_i2c_ids,
 };
 module_i2c_driver(adau1977_i2c_driver);
index 0b46d88b481ca7ce90a56b7cb819340071d229d4..84ffbde9583f53b0b5739df1d8bcd059cb6e7856 100644 (file)
@@ -46,12 +46,6 @@ static int adau1977_spi_probe(struct spi_device *spi)
                id->driver_data, adau1977_spi_switch_mode);
 }
 
-static int adau1977_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static const struct spi_device_id adau1977_spi_ids[] = {
        { "adau1977", ADAU1977 },
        { "adau1978", ADAU1978 },
@@ -65,7 +59,6 @@ static struct spi_driver adau1977_spi_driver = {
                .name = "adau1977",
        },
        .probe = adau1977_spi_probe,
-       .remove = adau1977_spi_remove,
        .id_table = adau1977_spi_ids,
 };
 module_spi_driver(adau1977_spi_driver);
index e384f212beb2cc7cd90320952e1dda41c5064d1a..116af6a9ce3b82f665bfd11e50577feb7c000318 100644 (file)
@@ -294,8 +294,8 @@ static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate,
 static int adau1977_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
        unsigned int rate = params_rate(params);
        unsigned int slot_width;
        unsigned int ctrl0, ctrl0_mask;
@@ -471,10 +471,10 @@ err_disable_avdd:
        return ret;
 }
 
-static int adau1977_set_bias_level(struct snd_soc_codec *codec,
+static int adau1977_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (level) {
@@ -483,7 +483,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        ret = adau1977_power_enable(adau1977);
                break;
        case SND_SOC_BIAS_OFF:
@@ -497,7 +497,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
 static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        unsigned int rx_mask, int slots, int width)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
        unsigned int ctrl0, ctrl1, drv;
        unsigned int slot[4];
        unsigned int i;
@@ -603,7 +603,7 @@ static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 
 static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
        unsigned int val;
 
        if (mute)
@@ -617,7 +617,7 @@ static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)
 
 static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
        unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0;
        bool invert_lrclk;
        int ret;
@@ -704,7 +704,7 @@ static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int adau1977_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
        u64 formats = 0;
 
        if (adau1977->slot_width == 16)
@@ -729,7 +729,7 @@ static int adau1977_startup(struct snd_pcm_substream *substream,
 
 static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
        unsigned int val;
 
        if (tristate)
@@ -790,10 +790,10 @@ static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq)
        return true;
 }
 
-static int adau1977_set_sysclk(struct snd_soc_codec *codec,
+static int adau1977_set_sysclk(struct snd_soc_component *component,
        int clk_id, int source, unsigned int freq, int dir)
 {
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
        unsigned int mask = 0;
        unsigned int clk_src;
        unsigned int ret;
@@ -844,10 +844,10 @@ static int adau1977_set_sysclk(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adau1977_codec_probe(struct snd_soc_codec *codec)
+static int adau1977_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (adau1977->type) {
@@ -865,20 +865,19 @@ static int adau1977_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver adau1977_codec_driver = {
-       .probe = adau1977_codec_probe,
-       .set_bias_level = adau1977_set_bias_level,
-       .set_sysclk = adau1977_set_sysclk,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = adau1977_snd_controls,
-               .num_controls           = ARRAY_SIZE(adau1977_snd_controls),
-               .dapm_widgets           = adau1977_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adau1977_dapm_widgets),
-               .dapm_routes            = adau1977_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adau1977_dapm_routes),
-       },
+static const struct snd_soc_component_driver adau1977_component_driver = {
+       .probe                  = adau1977_component_probe,
+       .set_bias_level         = adau1977_set_bias_level,
+       .set_sysclk             = adau1977_set_sysclk,
+       .controls               = adau1977_snd_controls,
+       .num_controls           = ARRAY_SIZE(adau1977_snd_controls),
+       .dapm_widgets           = adau1977_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adau1977_dapm_widgets),
+       .dapm_routes            = adau1977_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adau1977_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int adau1977_setup_micbias(struct adau1977 *adau1977)
@@ -968,7 +967,7 @@ int adau1977_probe(struct device *dev, struct regmap *regmap,
        if (ret)
                return ret;
 
-       return snd_soc_register_codec(dev, &adau1977_codec_driver,
+       return devm_snd_soc_register_component(dev, &adau1977_component_driver,
                        &adau1977_dai, 1);
 
 err_poweroff:
index 6384c5491de8e53d1fb94aa136cb37b0d916f31d..fdff86878287fff64343ea713984377dccce6216 100644 (file)
@@ -7,6 +7,7 @@
  * Licensed under the GPL-2.
  */
 
+#include <linux/acpi.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -38,24 +39,26 @@ static struct snd_soc_dai_driver adau7002_dai = {
        },
 };
 
-static const struct snd_soc_codec_driver adau7002_codec_driver = {
-       .component_driver = {
-               .dapm_widgets           = adau7002_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adau7002_widgets),
-               .dapm_routes            = adau7002_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adau7002_routes),
-       },
+static const struct snd_soc_component_driver adau7002_component_driver = {
+       .dapm_widgets           = adau7002_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adau7002_widgets),
+       .dapm_routes            = adau7002_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adau7002_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int adau7002_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &adau7002_codec_driver,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &adau7002_component_driver,
                        &adau7002_dai, 1);
 }
 
 static int adau7002_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
@@ -67,10 +70,19 @@ static const struct of_device_id adau7002_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, adau7002_dt_ids);
 #endif
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id adau7002_acpi_match[] = {
+       { "ADAU7002", 0 },
+       {},
+};
+MODULE_DEVICE_TABLE(acpi, adau7002_acpi_match);
+#endif
+
 static struct platform_driver adau7002_driver = {
        .driver = {
                .name = "adau7002",
                .of_match_table = of_match_ptr(adau7002_dt_ids),
+               .acpi_match_table = ACPI_PTR(adau7002_acpi_match),
        },
        .probe = adau7002_probe,
        .remove = adau7002_remove,
index 055f1228c2b47676418c12ffb3e3a795ec902d4f..d82f79dd1b38bec258947002abda6f13d96ed454 100644 (file)
@@ -30,18 +30,11 @@ static int adav80x_spi_probe(struct spi_device *spi)
        return adav80x_bus_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
 }
 
-static int adav80x_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver adav80x_spi_driver = {
        .driver = {
                .name   = "adav801",
        },
        .probe          = adav80x_spi_probe,
-       .remove         = adav80x_spi_remove,
        .id_table       = adav80x_spi_id,
 };
 module_spi_driver(adav80x_spi_driver);
index 52881faedcf619a5a441e76b51746a7ce39e6dec..deb14bc0f1f7c5e9cfea3cd98c41dbb105256697 100644 (file)
@@ -27,18 +27,11 @@ static int adav803_probe(struct i2c_client *client,
                devm_regmap_init_i2c(client, &adav80x_regmap_config));
 }
 
-static int adav803_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static struct i2c_driver adav803_driver = {
        .driver = {
                .name = "adav803",
        },
        .probe = adav803_probe,
-       .remove = adav803_remove,
        .id_table = adav803_id,
 };
 module_i2c_driver(adav803_driver);
index da7ca81f47cfb46f0a968cc6fcf908735593d115..db21ecbe07625b5f972797de08ff51694f98c2df 100644 (file)
@@ -212,8 +212,8 @@ static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {
 static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        const char *clk;
 
        switch (adav80x->clk_src) {
@@ -236,8 +236,8 @@ static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
 static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
        return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
 }
@@ -281,9 +281,9 @@ static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {
        { "AIFAUXIN", NULL, "SYSCLK" },
 };
 
-static int adav80x_set_deemph(struct snd_soc_codec *codec)
+static int adav80x_set_deemph(struct snd_soc_component *component)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (adav80x->deemph) {
@@ -315,8 +315,8 @@ static int adav80x_set_deemph(struct snd_soc_codec *codec)
 static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
@@ -324,14 +324,14 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
 
        adav80x->deemph = deemph;
 
-       return adav80x_set_deemph(codec);
+       return adav80x_set_deemph(component);
 }
 
 static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = adav80x->deemph;
        return 0;
@@ -365,8 +365,8 @@ static unsigned int adav80x_port_ctrl_regs[2][2] = {
 
 static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int capture = 0x00;
        unsigned int playback = 0x00;
 
@@ -415,10 +415,10 @@ static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        return 0;
 }
 
-static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
+static int adav80x_set_adc_clock(struct snd_soc_component *component,
                unsigned int sample_rate)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (sample_rate <= 48000)
@@ -432,10 +432,10 @@ static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
+static int adav80x_set_dac_clock(struct snd_soc_component *component,
                unsigned int sample_rate)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (sample_rate <= 48000)
@@ -450,10 +450,10 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
+static int adav80x_set_capture_pcm_format(struct snd_soc_component *component,
                struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        switch (params_width(params)) {
@@ -479,10 +479,10 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
+static int adav80x_set_playback_pcm_format(struct snd_soc_component *component,
                struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
@@ -514,32 +514,32 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
 static int adav80x_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int rate = params_rate(params);
 
        if (rate * 256 != adav80x->sysclk)
                return -EINVAL;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               adav80x_set_playback_pcm_format(codec, dai, params);
-               adav80x_set_dac_clock(codec, rate);
+               adav80x_set_playback_pcm_format(component, dai, params);
+               adav80x_set_dac_clock(component, rate);
        } else {
-               adav80x_set_capture_pcm_format(codec, dai, params);
-               adav80x_set_adc_clock(codec, rate);
+               adav80x_set_capture_pcm_format(component, dai, params);
+               adav80x_set_adc_clock(component, rate);
        }
        adav80x->rate = rate;
-       adav80x_set_deemph(codec);
+       adav80x_set_deemph(component);
 
        return 0;
 }
 
-static int adav80x_set_sysclk(struct snd_soc_codec *codec,
+static int adav80x_set_sysclk(struct snd_soc_component *component,
                              int clk_id, int source,
                              unsigned int freq, int dir)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (dir == SND_SOC_CLOCK_IN) {
                switch (clk_id) {
@@ -619,11 +619,11 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
+static int adav80x_set_pll(struct snd_soc_component *component, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int pll_ctrl1 = 0;
        unsigned int pll_ctrl2 = 0;
        unsigned int pll_src;
@@ -694,10 +694,10 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
        return 0;
 }
 
-static int adav80x_set_bias_level(struct snd_soc_codec *codec,
+static int adav80x_set_bias_level(struct snd_soc_component *component,
                enum snd_soc_bias_level level)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
        unsigned int mask = ADAV80X_DAC_CTRL1_PD;
 
        switch (level) {
@@ -722,10 +722,10 @@ static int adav80x_set_bias_level(struct snd_soc_codec *codec,
 static int adav80x_dai_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
-       if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
+       if (!snd_soc_component_is_active(component) || !adav80x->rate)
                return 0;
 
        return snd_pcm_hw_constraint_single(substream->runtime,
@@ -735,10 +735,10 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
 static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
-       if (!snd_soc_codec_is_active(codec))
+       if (!snd_soc_component_is_active(component))
                adav80x->rate = 0;
 }
 
@@ -799,10 +799,10 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
        },
 };
 
-static int adav80x_probe(struct snd_soc_codec *codec)
+static int adav80x_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
        /* Force PLLs on for SYSCLK output */
        snd_soc_dapm_force_enable_pin(dapm, "PLL1");
@@ -816,32 +816,32 @@ static int adav80x_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int adav80x_resume(struct snd_soc_codec *codec)
+static int adav80x_resume(struct snd_soc_component *component)
 {
-       struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
+       struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
 
        regcache_sync(adav80x->regmap);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver adav80x_codec_driver = {
-       .probe = adav80x_probe,
-       .resume = adav80x_resume,
-       .set_bias_level = adav80x_set_bias_level,
-       .suspend_bias_off = true,
-
-       .set_pll = adav80x_set_pll,
-       .set_sysclk = adav80x_set_sysclk,
-
-       .component_driver = {
-               .controls               = adav80x_controls,
-               .num_controls           = ARRAY_SIZE(adav80x_controls),
-               .dapm_widgets           = adav80x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(adav80x_dapm_widgets),
-               .dapm_routes            = adav80x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(adav80x_dapm_routes),
-       },
+static const struct snd_soc_component_driver adav80x_component_driver = {
+       .probe                  = adav80x_probe,
+       .resume                 = adav80x_resume,
+       .set_bias_level         = adav80x_set_bias_level,
+       .set_pll                = adav80x_set_pll,
+       .set_sysclk             = adav80x_set_sysclk,
+       .controls               = adav80x_controls,
+       .num_controls           = ARRAY_SIZE(adav80x_controls),
+       .dapm_widgets           = adav80x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(adav80x_dapm_widgets),
+       .dapm_routes            = adav80x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(adav80x_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
@@ -858,7 +858,7 @@ int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
        dev_set_drvdata(dev, adav80x);
        adav80x->regmap = regmap;
 
-       return snd_soc_register_codec(dev, &adav80x_codec_driver,
+       return devm_snd_soc_register_component(dev, &adav80x_component_driver,
                adav80x_dais, ARRAY_SIZE(adav80x_dais));
 }
 EXPORT_SYMBOL_GPL(adav80x_bus_probe);
index b7f0057c023951457e3968588f8842ec46cdb491..bcd45ff5db0c272ab0fe5492844e5948b4980526 100644 (file)
@@ -58,25 +58,21 @@ static struct snd_soc_dai_driver ads117x_dai = {
                .formats = ADS117X_FORMATS,},
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ads117x = {
-       .component_driver = {
-               .dapm_widgets           = ads117x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ads117x_dapm_widgets),
-               .dapm_routes            = ads117x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ads117x_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ads117x = {
+       .dapm_widgets           = ads117x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ads117x_dapm_widgets),
+       .dapm_routes            = ads117x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ads117x_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ads117x_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_ads117x, &ads117x_dai, 1);
-}
-
-static int ads117x_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_ads117x, &ads117x_dai, 1);
 }
 
 #if defined(CONFIG_OF)
@@ -95,7 +91,6 @@ static struct platform_driver ads117x_codec_driver = {
        },
 
        .probe = ads117x_probe,
-       .remove = ads117x_remove,
 };
 
 module_platform_driver(ads117x_codec_driver);
index dbb184118f2e47314c91501428cb8b46c97f7fbc..32bc545c19cf73002e08e38606ec69b411b52537 100644 (file)
@@ -65,8 +65,8 @@ static const struct snd_soc_dapm_route ak4104_dapm_routes[] = {
 static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
        int val = 0;
        int ret;
 
@@ -81,7 +81,7 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
                val |= AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1;
                break;
        default:
-               dev_err(codec->dev, "invalid dai format\n");
+               dev_err(component->dev, "invalid dai format\n");
                return -EINVAL;
        }
 
@@ -102,8 +102,8 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
        int ret, val = 0;
 
        /* set the IEC958 bits: consumer mode, no copyright bit */
@@ -141,7 +141,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
                val |= IEC958_AES3_CON_FS_192000;
                break;
        default:
-               dev_err(codec->dev, "unsupported sampling rate\n");
+               dev_err(component->dev, "unsupported sampling rate\n");
                return -EINVAL;
        }
 
@@ -174,14 +174,14 @@ static struct snd_soc_dai_driver ak4104_dai = {
        .ops = &ak4101_dai_ops,
 };
 
-static int ak4104_probe(struct snd_soc_codec *codec)
+static int ak4104_probe(struct snd_soc_component *component)
 {
-       struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+       struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_enable(ak4104->regulator);
        if (ret < 0) {
-               dev_err(codec->dev, "Unable to enable regulator: %d\n", ret);
+               dev_err(component->dev, "Unable to enable regulator: %d\n", ret);
                return ret;
        }
 
@@ -205,30 +205,28 @@ exit_disable_regulator:
        return ret;
 }
 
-static int ak4104_remove(struct snd_soc_codec *codec)
+static void ak4104_remove(struct snd_soc_component *component)
 {
-       struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
+       struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);
 
        regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
                           AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
        regulator_disable(ak4104->regulator);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int ak4104_soc_suspend(struct snd_soc_codec *codec)
+static int ak4104_soc_suspend(struct snd_soc_component *component)
 {
-       struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak4104_private *priv = snd_soc_component_get_drvdata(component);
 
        regulator_disable(priv->regulator);
 
        return 0;
 }
 
-static int ak4104_soc_resume(struct snd_soc_codec *codec)
+static int ak4104_soc_resume(struct snd_soc_component *component)
 {
-       struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak4104_private *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_enable(priv->regulator);
@@ -242,18 +240,19 @@ static int ak4104_soc_resume(struct snd_soc_codec *codec)
 #define ak4104_soc_resume      NULL
 #endif /* CONFIG_PM */
 
-static const struct snd_soc_codec_driver soc_codec_device_ak4104 = {
-       .probe = ak4104_probe,
-       .remove = ak4104_remove,
-       .suspend = ak4104_soc_suspend,
-       .resume = ak4104_soc_resume,
-
-       .component_driver = {
-               .dapm_widgets           = ak4104_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4104_dapm_widgets),
-               .dapm_routes            = ak4104_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ak4104_dapm_routes),
-       }
+static const struct snd_soc_component_driver soc_component_device_ak4104 = {
+       .probe                  = ak4104_probe,
+       .remove                 = ak4104_remove,
+       .suspend                = ak4104_soc_suspend,
+       .resume                 = ak4104_soc_resume,
+       .dapm_widgets           = ak4104_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4104_dapm_widgets),
+       .dapm_routes            = ak4104_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ak4104_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ak4104_regmap = {
@@ -323,17 +322,11 @@ static int ak4104_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, ak4104);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_device_ak4104, &ak4104_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_device_ak4104, &ak4104_dai, 1);
        return ret;
 }
 
-static int ak4104_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static const struct of_device_id ak4104_of_match[] = {
        { .compatible = "asahi-kasei,ak4104", },
        { }
@@ -353,7 +346,6 @@ static struct spi_driver ak4104_spi_driver = {
        },
        .id_table = ak4104_id_table,
        .probe  = ak4104_spi_probe,
-       .remove = ak4104_spi_remove,
 };
 
 module_spi_driver(ak4104_spi_driver);
diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
new file mode 100644 (file)
index 0000000..31ec0ba
--- /dev/null
@@ -0,0 +1,657 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Audio driver for AK4458 DAC
+//
+// Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+// Copyright 2018 NXP
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <sound/initval.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "ak4458.h"
+
+/* AK4458 Codec Private Data */
+struct ak4458_priv {
+       struct device *dev;
+       struct regmap *regmap;
+       struct gpio_desc *reset_gpiod;
+       struct gpio_desc *mute_gpiod;
+       int digfil;     /* SSLOW, SD, SLOW bits */
+       int fs;         /* sampling rate */
+       int fmt;
+       int slots;
+       int slot_width;
+};
+
+static const struct reg_default ak4458_reg_defaults[] = {
+       { 0x00, 0x0C }, /*      0x00    AK4458_00_CONTROL1      */
+       { 0x01, 0x22 }, /*      0x01    AK4458_01_CONTROL2      */
+       { 0x02, 0x00 }, /*      0x02    AK4458_02_CONTROL3      */
+       { 0x03, 0xFF }, /*      0x03    AK4458_03_LCHATT        */
+       { 0x04, 0xFF }, /*      0x04    AK4458_04_RCHATT        */
+       { 0x05, 0x00 }, /*      0x05    AK4458_05_CONTROL4      */
+       { 0x06, 0x00 }, /*      0x06    AK4458_06_DSD1          */
+       { 0x07, 0x03 }, /*      0x07    AK4458_07_CONTROL5      */
+       { 0x08, 0x00 }, /*      0x08    AK4458_08_SOUND_CONTROL */
+       { 0x09, 0x00 }, /*      0x09    AK4458_09_DSD2          */
+       { 0x0A, 0x0D }, /*      0x0A    AK4458_0A_CONTROL6      */
+       { 0x0B, 0x0C }, /*      0x0B    AK4458_0B_CONTROL7      */
+       { 0x0C, 0x00 }, /*      0x0C    AK4458_0C_CONTROL8      */
+       { 0x0D, 0x00 }, /*      0x0D    AK4458_0D_CONTROL9      */
+       { 0x0E, 0x50 }, /*      0x0E    AK4458_0E_CONTROL10     */
+       { 0x0F, 0xFF }, /*      0x0F    AK4458_0F_L2CHATT       */
+       { 0x10, 0xFF }, /*      0x10    AK4458_10_R2CHATT       */
+       { 0x11, 0xFF }, /*      0x11    AK4458_11_L3CHATT       */
+       { 0x12, 0xFF }, /*      0x12    AK4458_12_R3CHATT       */
+       { 0x13, 0xFF }, /*      0x13    AK4458_13_L4CHATT       */
+       { 0x14, 0xFF }, /*      0x14    AK4458_14_R4CHATT       */
+};
+
+/*
+ * Volume control:
+ * from -127 to 0 dB in 0.5 dB steps (mute instead of -127.5 dB)
+ */
+static DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+
+/*
+ * DEM1 bit DEM0 bit Mode
+ * 0 0 44.1kHz
+ * 0 1 OFF (default)
+ * 1 0 48kHz
+ * 1 1 32kHz
+ */
+static const char * const ak4458_dem_select_texts[] = {
+       "44.1kHz", "OFF", "48kHz", "32kHz"
+};
+
+/*
+ * SSLOW, SD, SLOW bits Digital Filter Setting
+ * 0, 0, 0 : Sharp Roll-Off Filter
+ * 0, 0, 1 : Slow Roll-Off Filter
+ * 0, 1, 0 : Short delay Sharp Roll-Off Filter
+ * 0, 1, 1 : Short delay Slow Roll-Off Filter
+ * 1, *, * : Super Slow Roll-Off Filter
+ */
+static const char * const ak4458_digfil_select_texts[] = {
+       "Sharp Roll-Off Filter",
+       "Slow Roll-Off Filter",
+       "Short delay Sharp Roll-Off Filter",
+       "Short delay Slow Roll-Off Filter",
+       "Super Slow Roll-Off Filter"
+};
+
+/*
+ * DZFB: Inverting Enable of DZF
+ * 0: DZF goes H at Zero Detection
+ * 1: DZF goes L at Zero Detection
+ */
+static const char * const ak4458_dzfb_select_texts[] = {"H", "L"};
+
+/*
+ * SC1-0 bits: Sound Mode Setting
+ * 0 0 : Sound Mode 0
+ * 0 1 : Sound Mode 1
+ * 1 0 : Sound Mode 2
+ * 1 1 : Reserved
+ */
+static const char * const ak4458_sc_select_texts[] = {
+       "Sound Mode 0", "Sound Mode 1", "Sound Mode 2"
+};
+
+/* FIR2-0 bits: FIR Filter Mode Setting */
+static const char * const ak4458_fir_select_texts[] = {
+       "Mode 0", "Mode 1", "Mode 2", "Mode 3",
+       "Mode 4", "Mode 5", "Mode 6", "Mode 7",
+};
+
+/* ATS1-0 bits Attenuation Speed */
+static const char * const ak4458_ats_select_texts[] = {
+       "4080/fs", "2040/fs", "510/fs", "255/fs",
+};
+
+/* DIF2 bit Audio Interface Format Setting(BICK fs) */
+static const char * const ak4458_dif_select_texts[] = {"32fs,48fs", "64fs",};
+
+static const struct soc_enum ak4458_dac1_dem_enum =
+       SOC_ENUM_SINGLE(AK4458_01_CONTROL2, 1,
+                       ARRAY_SIZE(ak4458_dem_select_texts),
+                       ak4458_dem_select_texts);
+static const struct soc_enum ak4458_dac2_dem_enum =
+       SOC_ENUM_SINGLE(AK4458_0A_CONTROL6, 0,
+                       ARRAY_SIZE(ak4458_dem_select_texts),
+                       ak4458_dem_select_texts);
+static const struct soc_enum ak4458_dac3_dem_enum =
+       SOC_ENUM_SINGLE(AK4458_0E_CONTROL10, 4,
+                       ARRAY_SIZE(ak4458_dem_select_texts),
+                       ak4458_dem_select_texts);
+static const struct soc_enum ak4458_dac4_dem_enum =
+       SOC_ENUM_SINGLE(AK4458_0E_CONTROL10, 6,
+                       ARRAY_SIZE(ak4458_dem_select_texts),
+                       ak4458_dem_select_texts);
+static const struct soc_enum ak4458_digfil_enum =
+       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ak4458_digfil_select_texts),
+                           ak4458_digfil_select_texts);
+static const struct soc_enum ak4458_dzfb_enum =
+       SOC_ENUM_SINGLE(AK4458_02_CONTROL3, 2,
+                       ARRAY_SIZE(ak4458_dzfb_select_texts),
+                       ak4458_dzfb_select_texts);
+static const struct soc_enum ak4458_sm_enum =
+       SOC_ENUM_SINGLE(AK4458_08_SOUND_CONTROL, 0,
+                       ARRAY_SIZE(ak4458_sc_select_texts),
+                       ak4458_sc_select_texts);
+static const struct soc_enum ak4458_fir_enum =
+       SOC_ENUM_SINGLE(AK4458_0C_CONTROL8, 0,
+                       ARRAY_SIZE(ak4458_fir_select_texts),
+                       ak4458_fir_select_texts);
+static const struct soc_enum ak4458_ats_enum =
+       SOC_ENUM_SINGLE(AK4458_0B_CONTROL7, 6,
+                       ARRAY_SIZE(ak4458_ats_select_texts),
+                       ak4458_ats_select_texts);
+static const struct soc_enum ak4458_dif_enum =
+       SOC_ENUM_SINGLE(AK4458_00_CONTROL1, 3,
+                       ARRAY_SIZE(ak4458_dif_select_texts),
+                       ak4458_dif_select_texts);
+
+static int get_digfil(struct snd_kcontrol *kcontrol,
+                     struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+       ucontrol->value.enumerated.item[0] = ak4458->digfil;
+
+       return 0;
+}
+
+static int set_digfil(struct snd_kcontrol *kcontrol,
+                     struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+       int num;
+
+       num = ucontrol->value.enumerated.item[0];
+       if (num > 4)
+               return -EINVAL;
+
+       ak4458->digfil = num;
+
+       /* write SD bit */
+       snd_soc_component_update_bits(component, AK4458_01_CONTROL2,
+                           AK4458_SD_MASK,
+                           ((ak4458->digfil & 0x02) << 4));
+
+       /* write SLOW bit */
+       snd_soc_component_update_bits(component, AK4458_02_CONTROL3,
+                           AK4458_SLOW_MASK,
+                           (ak4458->digfil & 0x01));
+
+       /* write SSLOW bit */
+       snd_soc_component_update_bits(component, AK4458_05_CONTROL4,
+                           AK4458_SSLOW_MASK,
+                           ((ak4458->digfil & 0x04) >> 2));
+
+       return 0;
+}
+
+static const struct snd_kcontrol_new ak4458_snd_controls[] = {
+       SOC_DOUBLE_R_TLV("DAC1 Playback Volume", AK4458_03_LCHATT,
+                        AK4458_04_RCHATT, 0, 0xFF, 0, dac_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Playback Volume", AK4458_0F_L2CHATT,
+                        AK4458_10_R2CHATT, 0, 0xFF, 0, dac_tlv),
+       SOC_DOUBLE_R_TLV("DAC3 Playback Volume", AK4458_11_L3CHATT,
+                        AK4458_12_R3CHATT, 0, 0xFF, 0, dac_tlv),
+       SOC_DOUBLE_R_TLV("DAC4 Playback Volume", AK4458_13_L4CHATT,
+                        AK4458_14_R4CHATT, 0, 0xFF, 0, dac_tlv),
+       SOC_ENUM("AK4458 De-emphasis Response DAC1", ak4458_dac1_dem_enum),
+       SOC_ENUM("AK4458 De-emphasis Response DAC2", ak4458_dac2_dem_enum),
+       SOC_ENUM("AK4458 De-emphasis Response DAC3", ak4458_dac3_dem_enum),
+       SOC_ENUM("AK4458 De-emphasis Response DAC4", ak4458_dac4_dem_enum),
+       SOC_ENUM_EXT("AK4458 Digital Filter Setting", ak4458_digfil_enum,
+                    get_digfil, set_digfil),
+       SOC_ENUM("AK4458 Inverting Enable of DZFB", ak4458_dzfb_enum),
+       SOC_ENUM("AK4458 Sound Mode", ak4458_sm_enum),
+       SOC_ENUM("AK4458 FIR Filter Mode Setting", ak4458_fir_enum),
+       SOC_ENUM("AK4458 Attenuation transition Time Setting",
+                ak4458_ats_enum),
+       SOC_ENUM("AK4458 BICK fs Setting", ak4458_dif_enum),
+};
+
+/* ak4458 dapm widgets */
+static const struct snd_soc_dapm_widget ak4458_dapm_widgets[] = {
+       SND_SOC_DAPM_DAC("AK4458 DAC1", NULL, AK4458_0A_CONTROL6, 2, 0),/*pw*/
+       SND_SOC_DAPM_AIF_IN("AK4458 SDTI", "Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_OUTPUT("AK4458 AOUTA"),
+
+       SND_SOC_DAPM_DAC("AK4458 DAC2", NULL, AK4458_0A_CONTROL6, 3, 0),/*pw*/
+       SND_SOC_DAPM_OUTPUT("AK4458 AOUTB"),
+
+       SND_SOC_DAPM_DAC("AK4458 DAC3", NULL, AK4458_0B_CONTROL7, 2, 0),/*pw*/
+       SND_SOC_DAPM_OUTPUT("AK4458 AOUTC"),
+
+       SND_SOC_DAPM_DAC("AK4458 DAC4", NULL, AK4458_0B_CONTROL7, 3, 0),/*pw*/
+       SND_SOC_DAPM_OUTPUT("AK4458 AOUTD"),
+};
+
+static const struct snd_soc_dapm_route ak4458_intercon[] = {
+       {"AK4458 DAC1",         NULL,   "AK4458 SDTI"},
+       {"AK4458 AOUTA",        NULL,   "AK4458 DAC1"},
+
+       {"AK4458 DAC2",         NULL,   "AK4458 SDTI"},
+       {"AK4458 AOUTB",        NULL,   "AK4458 DAC2"},
+
+       {"AK4458 DAC3",         NULL,   "AK4458 SDTI"},
+       {"AK4458 AOUTC",        NULL,   "AK4458 DAC3"},
+
+       {"AK4458 DAC4",         NULL,   "AK4458 SDTI"},
+       {"AK4458 AOUTD",        NULL,   "AK4458 DAC4"},
+};
+
+static int ak4458_rstn_control(struct snd_soc_component *component, int bit)
+{
+       int ret;
+
+       if (bit)
+               ret = snd_soc_component_update_bits(component,
+                                         AK4458_00_CONTROL1,
+                                         AK4458_RSTN_MASK,
+                                         0x1);
+       else
+               ret = snd_soc_component_update_bits(component,
+                                         AK4458_00_CONTROL1,
+                                         AK4458_RSTN_MASK,
+                                         0x0);
+       return ret;
+}
+
+static int ak4458_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
+{
+       struct snd_soc_component *component = dai->component;
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+       int pcm_width = max(params_physical_width(params), ak4458->slot_width);
+       int nfs1;
+       u8 format;
+
+       nfs1 = params_rate(params);
+       ak4458->fs = nfs1;
+
+       /* Master Clock Frequency Auto Setting Mode Enable */
+       snd_soc_component_update_bits(component, AK4458_00_CONTROL1, 0x80, 0x80);
+
+       switch (pcm_width) {
+       case 16:
+               if (ak4458->fmt == SND_SOC_DAIFMT_I2S)
+                       format = AK4458_DIF_24BIT_I2S;
+               else
+                       format = AK4458_DIF_16BIT_LSB;
+               break;
+       case 32:
+               switch (ak4458->fmt) {
+               case SND_SOC_DAIFMT_I2S:
+                       format = AK4458_DIF_32BIT_I2S;
+                       break;
+               case SND_SOC_DAIFMT_LEFT_J:
+                       format = AK4458_DIF_32BIT_MSB;
+                       break;
+               case SND_SOC_DAIFMT_RIGHT_J:
+                       format = AK4458_DIF_32BIT_LSB;
+                       break;
+               case SND_SOC_DAIFMT_DSP_B:
+                       format = AK4458_DIF_32BIT_MSB;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+                           AK4458_DIF_MASK, format);
+
+       ak4458_rstn_control(component, 0);
+       ak4458_rstn_control(component, 1);
+
+       return 0;
+}
+
+static int ak4458_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+       struct snd_soc_component *component = dai->component;
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS: /* Slave Mode */
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM: /* Master Mode is not supported */
+       case SND_SOC_DAIFMT_CBS_CFM:
+       case SND_SOC_DAIFMT_CBM_CFS:
+       default:
+               dev_err(component->dev, "Master mode unsupported\n");
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+       case SND_SOC_DAIFMT_LEFT_J:
+       case SND_SOC_DAIFMT_RIGHT_J:
+       case SND_SOC_DAIFMT_DSP_B:
+               ak4458->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+               break;
+       default:
+               dev_err(component->dev, "Audio format 0x%02X unsupported\n",
+                       fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+               return -EINVAL;
+       }
+
+       ak4458_rstn_control(component, 0);
+       ak4458_rstn_control(component, 1);
+
+       return 0;
+}
+
+static const int att_speed[] = { 4080, 2040, 510, 255 };
+
+static int ak4458_set_dai_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_component *component = dai->component;
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+       int nfs, ndt, ret, reg;
+       int ats;
+
+       nfs = ak4458->fs;
+
+       reg = snd_soc_component_read32(component, AK4458_0B_CONTROL7);
+       ats = (reg & AK4458_ATS_MASK) >> AK4458_ATS_SHIFT;
+
+       ndt = att_speed[ats] / (nfs / 1000);
+
+       if (mute) {
+               ret = snd_soc_component_update_bits(component, AK4458_01_CONTROL2,  0x01, 1);
+               mdelay(ndt);
+               if (ak4458->mute_gpiod)
+                       gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
+       } else {
+               if (ak4458->mute_gpiod)
+                       gpiod_set_value_cansleep(ak4458->mute_gpiod, 0);
+               ret = snd_soc_component_update_bits(component, AK4458_01_CONTROL2, 0x01, 0);
+               mdelay(ndt);
+       }
+
+       return 0;
+}
+
+static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+                              unsigned int rx_mask, int slots, int slot_width)
+{
+       struct snd_soc_component *component = dai->component;
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+       int mode;
+
+       ak4458->slots = slots;
+       ak4458->slot_width = slot_width;
+
+       switch (slots * slot_width) {
+       case 128:
+               mode = AK4458_MODE_TDM128;
+               break;
+       case 256:
+               mode = AK4458_MODE_TDM256;
+               break;
+       case 512:
+               mode = AK4458_MODE_TDM512;
+               break;
+       default:
+               mode = AK4458_MODE_NORMAL;
+               break;
+       }
+
+       snd_soc_component_update_bits(component, AK4458_0A_CONTROL6,
+                           AK4458_MODE_MASK,
+                           mode);
+
+       return 0;
+}
+
+#define AK4458_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+                        SNDRV_PCM_FMTBIT_S24_LE |\
+                        SNDRV_PCM_FMTBIT_S32_LE)
+
+static const unsigned int ak4458_rates[] = {
+       8000, 11025,  16000, 22050,
+       32000, 44100, 48000, 88200,
+       96000, 176400, 192000, 352800,
+       384000, 705600, 768000, 1411200,
+       2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak4458_rate_constraints = {
+       .count = ARRAY_SIZE(ak4458_rates),
+       .list = ak4458_rates,
+};
+
+static int ak4458_startup(struct snd_pcm_substream *substream,
+                         struct snd_soc_dai *dai)
+{
+       int ret;
+
+       ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                        SNDRV_PCM_HW_PARAM_RATE,
+                                        &ak4458_rate_constraints);
+
+       return ret;
+}
+
+static struct snd_soc_dai_ops ak4458_dai_ops = {
+       .startup        = ak4458_startup,
+       .hw_params      = ak4458_hw_params,
+       .set_fmt        = ak4458_set_dai_fmt,
+       .digital_mute   = ak4458_set_dai_mute,
+       .set_tdm_slot   = ak4458_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ak4458_dai = {
+       .name = "ak4458-aif",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 1,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_KNOT,
+               .formats = AK4458_FORMATS,
+       },
+       .ops = &ak4458_dai_ops,
+};
+
+static void ak4458_power_off(struct ak4458_priv *ak4458)
+{
+       if (ak4458->reset_gpiod) {
+               gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
+               usleep_range(1000, 2000);
+       }
+}
+
+static void ak4458_power_on(struct ak4458_priv *ak4458)
+{
+       if (ak4458->reset_gpiod) {
+               gpiod_set_value_cansleep(ak4458->reset_gpiod, 1);
+               usleep_range(1000, 2000);
+       }
+}
+
+static void ak4458_init(struct snd_soc_component *component)
+{
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+       /* External Mute ON */
+       if (ak4458->mute_gpiod)
+               gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
+
+       ak4458_power_on(ak4458);
+
+       snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+                           0x80, 0x80);   /* ACKS bit = 1; 10000000 */
+
+       ak4458_rstn_control(component, 1);
+}
+
+static int ak4458_probe(struct snd_soc_component *component)
+{
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+       ak4458_init(component);
+
+       ak4458->fs = 48000;
+
+       return 0;
+}
+
+static void ak4458_remove(struct snd_soc_component *component)
+{
+       struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+
+       ak4458_power_off(ak4458);
+}
+
+#ifdef CONFIG_PM
+static int __maybe_unused ak4458_runtime_suspend(struct device *dev)
+{
+       struct ak4458_priv *ak4458 = dev_get_drvdata(dev);
+
+       regcache_cache_only(ak4458->regmap, true);
+
+       ak4458_power_off(ak4458);
+
+       if (ak4458->mute_gpiod)
+               gpiod_set_value_cansleep(ak4458->mute_gpiod, 0);
+
+       return 0;
+}
+
+static int __maybe_unused ak4458_runtime_resume(struct device *dev)
+{
+       struct ak4458_priv *ak4458 = dev_get_drvdata(dev);
+
+       if (ak4458->mute_gpiod)
+               gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
+
+       ak4458_power_off(ak4458);
+       ak4458_power_on(ak4458);
+
+       regcache_cache_only(ak4458->regmap, false);
+       regcache_mark_dirty(ak4458->regmap);
+
+       return regcache_sync(ak4458->regmap);
+}
+#endif /* CONFIG_PM */
+
+struct snd_soc_component_driver soc_codec_dev_ak4458 = {
+       .probe                  = ak4458_probe,
+       .remove                 = ak4458_remove,
+       .controls               = ak4458_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak4458_snd_controls),
+       .dapm_widgets           = ak4458_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4458_dapm_widgets),
+       .dapm_routes            = ak4458_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak4458_intercon),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
+
+static const struct regmap_config ak4458_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = AK4458_14_R4CHATT,
+       .reg_defaults = ak4458_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(ak4458_reg_defaults),
+       .cache_type = REGCACHE_RBTREE,
+};
+
+static const struct dev_pm_ops ak4458_pm = {
+       SET_RUNTIME_PM_OPS(ak4458_runtime_suspend, ak4458_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                               pm_runtime_force_resume)
+};
+
+static int ak4458_i2c_probe(struct i2c_client *i2c)
+{
+       struct ak4458_priv *ak4458;
+       int ret;
+
+       ak4458 = devm_kzalloc(&i2c->dev, sizeof(*ak4458), GFP_KERNEL);
+       if (!ak4458)
+               return -ENOMEM;
+
+       ak4458->regmap = devm_regmap_init_i2c(i2c, &ak4458_regmap);
+       if (IS_ERR(ak4458->regmap))
+               return PTR_ERR(ak4458->regmap);
+
+       i2c_set_clientdata(i2c, ak4458);
+       ak4458->dev = &i2c->dev;
+
+       ak4458->reset_gpiod = devm_gpiod_get_optional(ak4458->dev, "reset",
+                                                     GPIOD_OUT_LOW);
+       if (IS_ERR(ak4458->reset_gpiod))
+               return PTR_ERR(ak4458->reset_gpiod);
+
+       ak4458->mute_gpiod = devm_gpiod_get_optional(ak4458->dev, "mute",
+                                                    GPIOD_OUT_LOW);
+       if (IS_ERR(ak4458->mute_gpiod))
+               return PTR_ERR(ak4458->mute_gpiod);
+
+       ret = devm_snd_soc_register_component(ak4458->dev, &soc_codec_dev_ak4458,
+                                    &ak4458_dai, 1);
+       if (ret < 0) {
+               dev_err(ak4458->dev, "Failed to register CODEC: %d\n", ret);
+               return ret;
+       }
+
+       pm_runtime_enable(&i2c->dev);
+
+       return 0;
+}
+
+static int ak4458_i2c_remove(struct i2c_client *i2c)
+{
+       pm_runtime_disable(&i2c->dev);
+
+       return 0;
+}
+
+static const struct of_device_id ak4458_of_match[] = {
+       { .compatible = "asahi-kasei,ak4458", },
+       { },
+};
+
+static struct i2c_driver ak4458_i2c_driver = {
+       .driver = {
+               .name = "ak4458",
+               .pm = &ak4458_pm,
+               .of_match_table = ak4458_of_match,
+               },
+       .probe_new = ak4458_i2c_probe,
+       .remove = ak4458_i2c_remove,
+};
+
+module_i2c_driver(ak4458_i2c_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("ASoC AK4458 DAC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak4458.h b/sound/soc/codecs/ak4458.h
new file mode 100644 (file)
index 0000000..f906215
--- /dev/null
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Audio driver for AK4458
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright 2018 NXP
+ */
+
+#ifndef _AK4458_H
+#define _AK4458_H
+
+#include <linux/regmap.h>
+
+/* Settings */
+
+#define AK4458_00_CONTROL1                     0x00
+#define AK4458_01_CONTROL2                     0x01
+#define AK4458_02_CONTROL3                     0x02
+#define AK4458_03_LCHATT                       0x03
+#define AK4458_04_RCHATT                       0x04
+#define AK4458_05_CONTROL4                     0x05
+#define AK4458_06_DSD1                         0x06
+#define AK4458_07_CONTROL5                     0x07
+#define AK4458_08_SOUND_CONTROL                        0x08
+#define AK4458_09_DSD2                         0x09
+#define AK4458_0A_CONTROL6                     0x0A
+#define AK4458_0B_CONTROL7                     0x0B
+#define AK4458_0C_CONTROL8                     0x0C
+#define AK4458_0D_CONTROL9                     0x0D
+#define AK4458_0E_CONTROL10                    0x0E
+#define AK4458_0F_L2CHATT                      0x0F
+#define AK4458_10_R2CHATT                      0x10
+#define AK4458_11_L3CHATT                      0x11
+#define AK4458_12_R3CHATT                      0x12
+#define AK4458_13_L4CHATT                      0x13
+#define AK4458_14_R4CHATT                      0x14
+
+/* Bitfield Definitions */
+
+/* AK4458_00_CONTROL1 (0x00) Fields
+ * Addr Register Name  D7     D6    D5    D4    D3    D2    D1    D0
+ * 00H  Control 1      ACKS   0     0     0     DIF2  DIF1  DIF0  RSTN
+ */
+
+/* Digital Filter (SD, SLOW, SSLOW) */
+#define AK4458_SD_MASK         GENMASK(5, 5)
+#define AK4458_SLOW_MASK       GENMASK(0, 0)
+#define AK4458_SSLOW_MASK      GENMASK(0, 0)
+
+/* DIF2        1 0
+ *  x  1 0 MSB justified  Figure 3 (default)
+ *  x  1 1 I2S Compliment  Figure 4
+ */
+#define AK4458_DIF_SHIFT       1
+#define AK4458_DIF_MASK                GENMASK(3, 1)
+
+#define AK4458_DIF_16BIT_LSB   (0 << 1)
+#define AK4458_DIF_24BIT_I2S   (3 << 1)
+#define AK4458_DIF_32BIT_LSB   (5 << 1)
+#define AK4458_DIF_32BIT_MSB   (6 << 1)
+#define AK4458_DIF_32BIT_I2S   (7 << 1)
+
+/* AK4458_00_CONTROL1 (0x00) D0 bit */
+#define AK4458_RSTN_MASK       GENMASK(0, 0)
+#define AK4458_RSTN            (0x1 << 0)
+
+/* AK4458_0A_CONTROL6 Mode bits */
+#define AK4458_MODE_SHIFT      6
+#define AK4458_MODE_MASK       GENMASK(7, 6)
+#define AK4458_MODE_NORMAL     (0 << AK4458_MODE_SHIFT)
+#define AK4458_MODE_TDM128     (1 << AK4458_MODE_SHIFT)
+#define AK4458_MODE_TDM256     (2 << AK4458_MODE_SHIFT)
+#define AK4458_MODE_TDM512     (3 << AK4458_MODE_SHIFT)
+
+/* DAC Digital attenuator transition time setting
+ * Table 19
+ * Mode        ATS1    ATS2    ATT speed
+ * 0   0       0       4080/fs
+ * 1   0       1       2040/fs
+ * 2   1       0       510/fs
+ * 3   1       1       255/fs
+ * */
+#define AK4458_ATS_SHIFT       6
+#define AK4458_ATS_MASK                GENMASK(7, 6)
+
+#endif /* _AK4458_H */
index e3c157dc88db3c796030159ae2487f1efb8e7a59..31f609910bd659d42d6a1a27f307d8200e37907a 100644 (file)
@@ -251,8 +251,8 @@ static const struct snd_soc_dapm_route ak4535_audio_map[] = {
 static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ak4535_priv *ak4535 = snd_soc_component_get_drvdata(component);
 
        ak4535->sysclk = freq;
        return 0;
@@ -262,9 +262,9 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
-       u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
+       struct snd_soc_component *component = dai->component;
+       struct ak4535_priv *ak4535 = snd_soc_component_get_drvdata(component);
+       u8 mode2 = snd_soc_component_read32(component, AK4535_MODE2) & ~(0x3 << 5);
        int rate = params_rate(params), fs = 256;
 
        if (rate)
@@ -283,14 +283,14 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* set rate */
-       snd_soc_write(codec, AK4535_MODE2, mode2);
+       snd_soc_component_write(component, AK4535_MODE2, mode2);
        return 0;
 }
 
 static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 mode1 = 0;
 
        /* interface format */
@@ -308,37 +308,37 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
        /* use 32 fs for BCLK to save power */
        mode1 |= 0x4;
 
-       snd_soc_write(codec, AK4535_MODE1, mode1);
+       snd_soc_component_write(component, AK4535_MODE1, mode1);
        return 0;
 }
 
 static int ak4535_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, AK4535_DAC);
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, AK4535_DAC);
        if (!mute)
-               snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20);
+               snd_soc_component_write(component, AK4535_DAC, mute_reg & ~0x20);
        else
-               snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20);
+               snd_soc_component_write(component, AK4535_DAC, mute_reg | 0x20);
        return 0;
 }
 
-static int ak4535_set_bias_level(struct snd_soc_codec *codec,
+static int ak4535_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0);
+               snd_soc_component_update_bits(component, AK4535_DAC, 0x20, 0);
                break;
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20);
+               snd_soc_component_update_bits(component, AK4535_DAC, 0x20, 0x20);
                break;
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80);
-               snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0);
+               snd_soc_component_update_bits(component, AK4535_PM1, 0x80, 0x80);
+               snd_soc_component_update_bits(component, AK4535_PM2, 0x80, 0);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
+               snd_soc_component_update_bits(component, AK4535_PM1, 0x80, 0);
                break;
        }
        return 0;
@@ -372,9 +372,9 @@ static struct snd_soc_dai_driver ak4535_dai = {
        .ops = &ak4535_dai_ops,
 };
 
-static int ak4535_resume(struct snd_soc_codec *codec)
+static int ak4535_resume(struct snd_soc_component *component)
 {
-       snd_soc_cache_sync(codec);
+       snd_soc_component_cache_sync(component);
        return 0;
 }
 
@@ -390,19 +390,20 @@ static const struct regmap_config ak4535_regmap = {
        .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
-       .resume =       ak4535_resume,
-       .set_bias_level = ak4535_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = ak4535_snd_controls,
-               .num_controls           = ARRAY_SIZE(ak4535_snd_controls),
-               .dapm_widgets           = ak4535_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4535_dapm_widgets),
-               .dapm_routes            = ak4535_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(ak4535_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ak4535 = {
+       .resume                 = ak4535_resume,
+       .set_bias_level         = ak4535_set_bias_level,
+       .controls               = ak4535_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak4535_snd_controls),
+       .dapm_widgets           = ak4535_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4535_dapm_widgets),
+       .dapm_routes            = ak4535_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(ak4535_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ak4535_i2c_probe(struct i2c_client *i2c,
@@ -425,18 +426,12 @@ static int ak4535_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, ak4535);
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_ak4535, &ak4535_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_ak4535, &ak4535_dai, 1);
 
        return ret;
 }
 
-static int ak4535_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id ak4535_i2c_id[] = {
        { "ak4535", 0 },
        { }
@@ -448,7 +443,6 @@ static struct i2c_driver ak4535_i2c_driver = {
                .name = "ak4535",
        },
        .probe =    ak4535_i2c_probe,
-       .remove =   ak4535_i2c_remove,
        .id_table = ak4535_i2c_id,
 };
 
index 0bb4fe5c122a4b17ac19b88df6e5ef0abeb1a837..b7ee13406d93b0a6b4967a920dc02a6f1f3d399b 100644 (file)
@@ -64,28 +64,24 @@ static struct snd_soc_dai_driver ak4554_dai = {
        .symmetric_rates = 1,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
-       .component_driver = {
-               .dapm_widgets           = ak4554_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4554_dapm_widgets),
-               .dapm_routes            = ak4554_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ak4554_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ak4554 = {
+       .dapm_widgets           = ak4554_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4554_dapm_widgets),
+       .dapm_routes            = ak4554_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ak4554_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ak4554_soc_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                                     &soc_codec_dev_ak4554,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &soc_component_dev_ak4554,
                                      &ak4554_dai, 1);
 }
 
-static int ak4554_soc_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static const struct of_device_id ak4554_of_match[] = {
        { .compatible = "asahi-kasei,ak4554" },
        {},
@@ -98,7 +94,6 @@ static struct platform_driver ak4554_driver = {
                .of_match_table = ak4554_of_match,
        },
        .probe  = ak4554_soc_probe,
-       .remove = ak4554_soc_remove,
 };
 module_platform_driver(ak4554_driver);
 
index 3d1cf4784e87cd463039c7f32d13c22f8052301c..8523ff9351cf59a61bcf48517fc7cc08484fdbec 100644 (file)
@@ -243,9 +243,9 @@ static const struct snd_soc_dapm_route ak4613_intercon[] = {
 static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
-       struct device *dev = codec->dev;
+       struct snd_soc_component *component = dai->component;
+       struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
+       struct device *dev = component->dev;
 
        mutex_lock(&priv->lock);
        priv->cnt--;
@@ -305,8 +305,8 @@ static void ak4613_hw_constraints(struct ak4613_priv *priv,
 static int ak4613_dai_startup(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
        priv->cnt++;
 
@@ -318,8 +318,8 @@ static int ak4613_dai_startup(struct snd_pcm_substream *substream,
 static int ak4613_dai_set_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
        priv->sysclk = freq;
 
@@ -328,8 +328,8 @@ static int ak4613_dai_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
        fmt &= SND_SOC_DAIFMT_FORMAT_MASK;
 
@@ -366,10 +366,10 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
        const struct ak4613_interface *iface;
-       struct device *dev = codec->dev;
+       struct device *dev = component->dev;
        unsigned int width = params_width(params);
        unsigned int fmt = priv->fmt;
        unsigned int rate;
@@ -434,11 +434,11 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
 
        fmt_ctrl = AUDIO_IFACE_TO_VAL(iface);
 
-       snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
-       snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2);
+       snd_soc_component_update_bits(component, CTRL1, FMT_MASK, fmt_ctrl);
+       snd_soc_component_update_bits(component, CTRL2, DFS_MASK, ctrl2);
 
-       snd_soc_update_bits(codec, ICTRL, ICTRL_MASK, priv->ic);
-       snd_soc_update_bits(codec, OCTRL, OCTRL_MASK, priv->oc);
+       snd_soc_component_update_bits(component, ICTRL, ICTRL_MASK, priv->ic);
+       snd_soc_component_update_bits(component, OCTRL, OCTRL_MASK, priv->oc);
 
 hw_params_end:
        if (ret < 0)
@@ -447,7 +447,7 @@ hw_params_end:
        return ret;
 }
 
-static int ak4613_set_bias_level(struct snd_soc_codec *codec,
+static int ak4613_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        u8 mgmt1 = 0;
@@ -467,7 +467,7 @@ static int ak4613_set_bias_level(struct snd_soc_codec *codec,
                break;
        }
 
-       snd_soc_write(codec, PW_MGMT1, mgmt1);
+       snd_soc_component_write(component, PW_MGMT1, mgmt1);
 
        return 0;
 }
@@ -504,8 +504,8 @@ static void ak4613_dummy_write(struct work_struct *work)
 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);
+       struct snd_soc_component *component = dai->component;
+       struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
 
        /*
         * FIXME
@@ -537,7 +537,7 @@ static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd,
        if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
                return  0;
 
-       priv->component = &codec->component;
+       priv->component = component;
        schedule_work(&priv->dummy_write_work);
 
        return 0;
@@ -582,35 +582,36 @@ static struct snd_soc_dai_driver ak4613_dai = {
        .symmetric_rates = 1,
 };
 
-static int ak4613_suspend(struct snd_soc_codec *codec)
+static int ak4613_suspend(struct snd_soc_component *component)
 {
-       struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+       struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
        regcache_cache_only(regmap, true);
        regcache_mark_dirty(regmap);
        return 0;
 }
 
-static int ak4613_resume(struct snd_soc_codec *codec)
+static int ak4613_resume(struct snd_soc_component *component)
 {
-       struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+       struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
        regcache_cache_only(regmap, false);
        return regcache_sync(regmap);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
+static const struct snd_soc_component_driver soc_component_dev_ak4613 = {
        .suspend                = ak4613_suspend,
        .resume                 = ak4613_resume,
        .set_bias_level         = ak4613_set_bias_level,
-       .component_driver = {
-               .controls               = ak4613_snd_controls,
-               .num_controls           = ARRAY_SIZE(ak4613_snd_controls),
-               .dapm_widgets           = ak4613_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4613_dapm_widgets),
-               .dapm_routes            = ak4613_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(ak4613_intercon),
-       },
+       .controls               = ak4613_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak4613_snd_controls),
+       .dapm_widgets           = ak4613_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4613_dapm_widgets),
+       .dapm_routes            = ak4613_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak4613_intercon),
+       .idle_bias_on           = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static void ak4613_parse_of(struct ak4613_priv *priv,
@@ -677,13 +678,12 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
-       return snd_soc_register_codec(dev, &soc_codec_dev_ak4613,
+       return devm_snd_soc_register_component(dev, &soc_component_dev_ak4613,
                                      &ak4613_dai, 1);
 }
 
 static int ak4613_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index 60142ff32d4f28139bbddc585befed1c0e17532b..05869beff26e02a906b797a5af790025b35d4e6f 100644 (file)
@@ -70,9 +70,9 @@ static const struct reg_default ak4641_reg_defaults[] = {
 
 static const int deemph_settings[] = {44100, 0, 48000, 32000};
 
-static int ak4641_set_deemph(struct snd_soc_codec *codec)
+static int ak4641_set_deemph(struct snd_soc_component *component)
 {
-       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+       struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
        int i, best = 0;
 
        for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) {
@@ -86,16 +86,16 @@ static int ak4641_set_deemph(struct snd_soc_codec *codec)
                        best = i;
        }
 
-       dev_dbg(codec->dev, "Set deemphasis %d\n", best);
+       dev_dbg(component->dev, "Set deemphasis %d\n", best);
 
-       return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best);
+       return snd_soc_component_update_bits(component, AK4641_DAC, 0x3, best);
 }
 
 static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
        int deemph = ucontrol->value.integer.value[0];
 
        if (deemph > 1)
@@ -103,14 +103,14 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
 
        ak4641->deemph = deemph;
 
-       return ak4641_set_deemph(codec);
+       return ak4641_set_deemph(component);
 }
 
 static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = ak4641->deemph;
        return 0;
@@ -307,8 +307,8 @@ static const struct snd_soc_dapm_route ak4641_audio_map[] = {
 static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
 
        ak4641->sysclk = freq;
        return 0;
@@ -318,8 +318,8 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
        int rate = params_rate(params), fs = 256;
        u8 mode2;
 
@@ -340,16 +340,16 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
                mode2 = (0x0 << 5);
                break;
        default:
-               dev_err(codec->dev, "Error: unsupported fs=%d\n", fs);
+               dev_err(component->dev, "Error: unsupported fs=%d\n", fs);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2);
+       snd_soc_component_update_bits(component, AK4641_MODE2, (0x3 << 5), mode2);
 
        /* Update de-emphasis filter for the new rate */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                ak4641->playback_fs = rate;
-               ak4641_set_deemph(codec);
+               ak4641_set_deemph(component);
        }
 
        return 0;
@@ -358,7 +358,7 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
 static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
                                  unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 btif;
        int ret;
 
@@ -380,7 +380,7 @@ static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       ret = snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
+       ret = snd_soc_component_update_bits(component, AK4641_BTIF, (0x3 << 5), btif);
        if (ret < 0)
                return ret;
 
@@ -390,7 +390,7 @@ static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 mode1 = 0;
 
        /* interface format */
@@ -405,34 +405,34 @@ static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       return snd_soc_write(codec, AK4641_MODE1, mode1);
+       return snd_soc_component_write(component, AK4641_MODE1, mode1);
 }
 
 static int ak4641_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0);
+       return snd_soc_component_update_bits(component, AK4641_DAC, 0x20, mute ? 0x20 : 0);
 }
 
-static int ak4641_set_bias_level(struct snd_soc_codec *codec,
+static int ak4641_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
-       struct ak4641_platform_data *pdata = codec->dev->platform_data;
+       struct ak4641_priv *ak4641 = snd_soc_component_get_drvdata(component);
+       struct ak4641_platform_data *pdata = component->dev->platform_data;
        int ret;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                /* unmute */
-               snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0);
+               snd_soc_component_update_bits(component, AK4641_DAC, 0x20, 0);
                break;
        case SND_SOC_BIAS_PREPARE:
                /* mute */
-               snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
+               snd_soc_component_update_bits(component, AK4641_DAC, 0x20, 0x20);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        if (pdata && gpio_is_valid(pdata->gpio_power))
                                gpio_set_value(pdata->gpio_power, 1);
                        mdelay(1);
@@ -442,16 +442,16 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
 
                        ret = regcache_sync(ak4641->regmap);
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to sync cache: %d\n", ret);
                                return ret;
                        }
                }
-               snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80);
-               snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0);
+               snd_soc_component_update_bits(component, AK4641_PM1, 0x80, 0x80);
+               snd_soc_component_update_bits(component, AK4641_PM2, 0x80, 0);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0);
+               snd_soc_component_update_bits(component, AK4641_PM1, 0x80, 0);
                if (pdata && gpio_is_valid(pdata->gpio_npdn))
                        gpio_set_value(pdata->gpio_npdn, 0);
                if (pdata && gpio_is_valid(pdata->gpio_power))
@@ -524,17 +524,19 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
 },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
-       .component_driver = {
-               .controls               = ak4641_snd_controls,
-               .num_controls           = ARRAY_SIZE(ak4641_snd_controls),
-               .dapm_widgets           = ak4641_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4641_dapm_widgets),
-               .dapm_routes            = ak4641_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(ak4641_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ak4641 = {
+       .controls               = ak4641_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak4641_snd_controls),
+       .dapm_widgets           = ak4641_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4641_dapm_widgets),
+       .dapm_routes            = ak4641_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(ak4641_audio_map),
        .set_bias_level         = ak4641_set_bias_level,
-       .suspend_bias_off       = true,
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ak4641_regmap = {
@@ -583,7 +585,8 @@ static int ak4641_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, ak4641);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                               &soc_component_dev_ak4641,
                                ak4641_dai, ARRAY_SIZE(ak4641_dai));
        if (ret != 0)
                goto err_gpio2;
@@ -608,8 +611,6 @@ static int ak4641_i2c_remove(struct i2c_client *i2c)
 {
        struct ak4641_platform_data *pdata = i2c->dev.platform_data;
 
-       snd_soc_unregister_codec(&i2c->dev);
-
        if (pdata) {
                if (gpio_is_valid(pdata->gpio_power)) {
                        gpio_set_value(pdata->gpio_power, 0);
index 29530c567bd9dd41d09220966618931b7612142f..605055964529880b9c8589c49837460bcc5bb681 100644 (file)
@@ -178,19 +178,19 @@ static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
 static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMD:
        case SND_SOC_DAPM_PRE_PMU:
                /* Power save mode ON */
-               snd_soc_update_bits(codec, SG_SL2, LOPS, LOPS);
+               snd_soc_component_update_bits(component, SG_SL2, LOPS, LOPS);
                break;
        case SND_SOC_DAPM_POST_PMU:
        case SND_SOC_DAPM_POST_PMD:
                /* Power save mode OFF */
                msleep(300);
-               snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
+               snd_soc_component_update_bits(component, SG_SL2, LOPS, 0);
                break;
        }
 
@@ -282,7 +282,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (is_play) {
                /*
@@ -295,8 +295,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                 * This operation came from example code of
                 * "ASAHI KASEI AK4642" (japanese) manual p97.
                 */
-               snd_soc_write(codec, L_IVC, 0x91); /* volume */
-               snd_soc_write(codec, R_IVC, 0x91); /* volume */
+               snd_soc_component_write(component, L_IVC, 0x91); /* volume */
+               snd_soc_component_write(component, R_IVC, 0x91); /* volume */
        } else {
                /*
                 * start stereo input
@@ -311,11 +311,11 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                 * This operation came from example code of
                 * "ASAHI KASEI AK4642" (japanese) manual p94.
                 */
-               snd_soc_update_bits(codec, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0);
-               snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
-               snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
-               snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL);
-               snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
+               snd_soc_component_update_bits(component, SG_SL1, PMMP | MGAIN0, PMMP | MGAIN0);
+               snd_soc_component_write(component, TIMER, ZTM(0x3) | WTM(0x3));
+               snd_soc_component_write(component, ALC_CTL1, ALC | LMTH0);
+               snd_soc_component_update_bits(component, PW_MGMT1, PMADL, PMADL);
+               snd_soc_component_update_bits(component, PW_MGMT3, PMADR, PMADR);
        }
 
        return 0;
@@ -325,22 +325,22 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (is_play) {
        } else {
                /* stop stereo input */
-               snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
-               snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0);
-               snd_soc_update_bits(codec, ALC_CTL1, ALC, 0);
+               snd_soc_component_update_bits(component, PW_MGMT1, PMADL, 0);
+               snd_soc_component_update_bits(component, PW_MGMT3, PMADR, 0);
+               snd_soc_component_update_bits(component, ALC_CTL1, ALC, 0);
        }
 }
 
 static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ak4642_priv *priv = snd_soc_component_get_drvdata(component);
        u8 pll;
        int extended_freq = 0;
 
@@ -382,14 +382,14 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
        if (extended_freq && !priv->drvdata->extended_frequencies)
                return -EINVAL;
 
-       snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
+       snd_soc_component_update_bits(component, MD_CTL1, PLL_MASK, pll);
 
        return 0;
 }
 
 static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 data;
        u8 bcko;
 
@@ -407,8 +407,8 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
-       snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
+       snd_soc_component_update_bits(component, PW_MGMT2, MS | MCKO | PMPLL, data);
+       snd_soc_component_update_bits(component, MD_CTL1, BCKO_MASK, bcko);
 
        /* format type */
        data = 0;
@@ -425,12 +425,12 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
+       snd_soc_component_update_bits(component, MD_CTL1, DIF_MASK, data);
 
        return 0;
 }
 
-static int ak4642_set_mcko(struct snd_soc_codec *codec,
+static int ak4642_set_mcko(struct snd_soc_component *component,
                           u32 frequency)
 {
        static const u32 fs_list[] = {
@@ -458,7 +458,7 @@ static int ak4642_set_mcko(struct snd_soc_codec *codec,
        for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
                for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
                        if (frequency == ps_list[ps] * fs_list[fs]) {
-                               snd_soc_write(codec, MD_CTL2,
+                               snd_soc_component_write(component, MD_CTL2,
                                              PSs(ps) | FSs(fs));
                                return 0;
                        }
@@ -472,25 +472,25 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak4642_priv *priv = snd_soc_component_get_drvdata(component);
        u32 rate = clk_get_rate(priv->mcko);
 
        if (!rate)
                rate = params_rate(params) * 256;
 
-       return ak4642_set_mcko(codec, rate);
+       return ak4642_set_mcko(component, rate);
 }
 
-static int ak4642_set_bias_level(struct snd_soc_codec *codec,
+static int ak4642_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, PW_MGMT1, 0x00);
+               snd_soc_component_write(component, PW_MGMT1, 0x00);
                break;
        default:
-               snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
+               snd_soc_component_update_bits(component, PW_MGMT1, PMVCM, PMVCM);
                break;
        }
 
@@ -523,46 +523,47 @@ static struct snd_soc_dai_driver ak4642_dai = {
        .symmetric_rates = 1,
 };
 
-static int ak4642_suspend(struct snd_soc_codec *codec)
+static int ak4642_suspend(struct snd_soc_component *component)
 {
-       struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+       struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
        regcache_cache_only(regmap, true);
        regcache_mark_dirty(regmap);
        return 0;
 }
 
-static int ak4642_resume(struct snd_soc_codec *codec)
+static int ak4642_resume(struct snd_soc_component *component)
 {
-       struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+       struct regmap *regmap = dev_get_regmap(component->dev, NULL);
 
        regcache_cache_only(regmap, false);
        regcache_sync(regmap);
        return 0;
 }
-static int ak4642_probe(struct snd_soc_codec *codec)
+static int ak4642_probe(struct snd_soc_component *component)
 {
-       struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak4642_priv *priv = snd_soc_component_get_drvdata(component);
 
        if (priv->mcko)
-               ak4642_set_mcko(codec, clk_get_rate(priv->mcko));
+               ak4642_set_mcko(component, clk_get_rate(priv->mcko));
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+static const struct snd_soc_component_driver soc_component_dev_ak4642 = {
        .probe                  = ak4642_probe,
        .suspend                = ak4642_suspend,
        .resume                 = ak4642_resume,
        .set_bias_level         = ak4642_set_bias_level,
-       .component_driver = {
-               .controls               = ak4642_snd_controls,
-               .num_controls           = ARRAY_SIZE(ak4642_snd_controls),
-               .dapm_widgets           = ak4642_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4642_dapm_widgets),
-               .dapm_routes            = ak4642_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
-       },
+       .controls               = ak4642_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak4642_snd_controls),
+       .dapm_widgets           = ak4642_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4642_dapm_widgets),
+       .dapm_routes            = ak4642_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
+       .idle_bias_on           = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ak4642_regmap = {
@@ -675,14 +676,8 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
-       return snd_soc_register_codec(dev,
-                                     &soc_codec_dev_ak4642, &ak4642_dai, 1);
-}
-
-static int ak4642_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
+       return devm_snd_soc_register_component(dev,
+                               &soc_component_dev_ak4642, &ak4642_dai, 1);
 }
 
 static const struct of_device_id ak4642_of_match[] = {
@@ -707,7 +702,6 @@ static struct i2c_driver ak4642_i2c_driver = {
                .of_match_table = ak4642_of_match,
        },
        .probe          = ak4642_i2c_probe,
-       .remove         = ak4642_i2c_remove,
        .id_table       = ak4642_i2c_id,
 };
 
index dcfdff56fc5a1efefaee683251b069285408ba07..7133fd69c64177915fa5c2a150da01e43c8559c5 100644 (file)
@@ -163,15 +163,15 @@ static const struct snd_kcontrol_new ak4671_snd_controls[] = {
 static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
+               snd_soc_component_update_bits(component, AK4671_LOUT2_POWER_MANAGERMENT,
                                    AK4671_MUTEN, AK4671_MUTEN);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT,
+               snd_soc_component_update_bits(component, AK4671_LOUT2_POWER_MANAGERMENT,
                                    AK4671_MUTEN, 0);
                break;
        }
@@ -427,10 +427,10 @@ static int ak4671_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 fs;
 
-       fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
+       fs = snd_soc_component_read32(component, AK4671_PLL_MODE_SELECT0);
        fs &= ~AK4671_FS;
 
        switch (params_rate(params)) {
@@ -465,7 +465,7 @@ static int ak4671_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
+       snd_soc_component_write(component, AK4671_PLL_MODE_SELECT0, fs);
 
        return 0;
 }
@@ -473,10 +473,10 @@ static int ak4671_hw_params(struct snd_pcm_substream *substream,
 static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 pll;
 
-       pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
+       pll = snd_soc_component_read32(component, AK4671_PLL_MODE_SELECT0);
        pll &= ~AK4671_PLL;
 
        switch (freq) {
@@ -511,19 +511,19 @@ static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
+       snd_soc_component_write(component, AK4671_PLL_MODE_SELECT0, pll);
 
        return 0;
 }
 
 static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 mode;
        u8 format;
 
        /* set master/slave audio interface */
-       mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
+       mode = snd_soc_component_read32(component, AK4671_PLL_MODE_SELECT1);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -537,7 +537,7 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
 
        /* interface format */
-       format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
+       format = snd_soc_component_read32(component, AK4671_FORMAT_SELECT);
        format &= ~AK4671_DIF;
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -557,24 +557,24 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
 
        /* set mode and format */
-       snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
-       snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
+       snd_soc_component_write(component, AK4671_PLL_MODE_SELECT1, mode);
+       snd_soc_component_write(component, AK4671_FORMAT_SELECT, format);
 
        return 0;
 }
 
-static int ak4671_set_bias_level(struct snd_soc_codec *codec,
+static int ak4671_set_bias_level(struct snd_soc_component *component,
                enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, AK4671_AD_DA_POWER_MANAGEMENT,
+               snd_soc_component_update_bits(component, AK4671_AD_DA_POWER_MANAGEMENT,
                                    AK4671_PMVCM, AK4671_PMVCM);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
+               snd_soc_component_write(component, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
                break;
        }
        return 0;
@@ -610,16 +610,18 @@ static struct snd_soc_dai_driver ak4671_dai = {
        .ops = &ak4671_dai_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
-       .set_bias_level = ak4671_set_bias_level,
-       .component_driver = {
-               .controls               = ak4671_snd_controls,
-               .num_controls           = ARRAY_SIZE(ak4671_snd_controls),
-               .dapm_widgets           = ak4671_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak4671_dapm_widgets),
-               .dapm_routes            = ak4671_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(ak4671_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ak4671 = {
+       .set_bias_level         = ak4671_set_bias_level,
+       .controls               = ak4671_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak4671_snd_controls),
+       .dapm_widgets           = ak4671_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4671_dapm_widgets),
+       .dapm_routes            = ak4671_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak4671_intercon),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ak4671_regmap = {
@@ -645,17 +647,11 @@ static int ak4671_i2c_probe(struct i2c_client *client,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&client->dev,
-                       &soc_codec_dev_ak4671, &ak4671_dai, 1);
+       ret = devm_snd_soc_register_component(&client->dev,
+                       &soc_component_dev_ak4671, &ak4671_dai, 1);
        return ret;
 }
 
-static int ak4671_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id ak4671_i2c_id[] = {
        { "ak4671", 0 },
        { }
@@ -667,7 +663,6 @@ static struct i2c_driver ak4671_i2c_driver = {
                .name = "ak4671-codec",
        },
        .probe = ak4671_i2c_probe,
-       .remove = ak4671_i2c_remove,
        .id_table = ak4671_i2c_id,
 };
 
index d0e16c03815cc89228a50f74284cddbf9dfa69cd..d212960b4ddaa07f9f266848f48741192604e453 100644 (file)
@@ -38,30 +38,29 @@ static const struct snd_soc_dapm_route ak5386_dapm_routes[] = {
        { "Capture", NULL, "AINR" },
 };
 
-static int ak5386_soc_probe(struct snd_soc_codec *codec)
+static int ak5386_soc_probe(struct snd_soc_component *component)
 {
-       struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
        return regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 }
 
-static int ak5386_soc_remove(struct snd_soc_codec *codec)
+static void ak5386_soc_remove(struct snd_soc_component *component)
 {
-       struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
        regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int ak5386_soc_suspend(struct snd_soc_codec *codec)
+static int ak5386_soc_suspend(struct snd_soc_component *component)
 {
-       struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
        regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
        return 0;
 }
 
-static int ak5386_soc_resume(struct snd_soc_codec *codec)
+static int ak5386_soc_resume(struct snd_soc_component *component)
 {
-       struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
        return regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 }
 #else
@@ -69,28 +68,30 @@ static int ak5386_soc_resume(struct snd_soc_codec *codec)
 #define ak5386_soc_resume      NULL
 #endif /* CONFIG_PM */
 
-static const struct snd_soc_codec_driver soc_codec_ak5386 = {
-       .probe = ak5386_soc_probe,
-       .remove = ak5386_soc_remove,
-       .suspend = ak5386_soc_suspend,
-       .resume = ak5386_soc_resume,
-       .component_driver = {
-               .dapm_widgets           = ak5386_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ak5386_dapm_widgets),
-               .dapm_routes            = ak5386_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ak5386_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_ak5386 = {
+       .probe                  = ak5386_soc_probe,
+       .remove                 = ak5386_soc_remove,
+       .suspend                = ak5386_soc_suspend,
+       .resume                 = ak5386_soc_resume,
+       .dapm_widgets           = ak5386_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak5386_dapm_widgets),
+       .dapm_routes            = ak5386_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ak5386_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        format &= SND_SOC_DAIFMT_FORMAT_MASK;
        if (format != SND_SOC_DAIFMT_LEFT_J &&
            format != SND_SOC_DAIFMT_I2S) {
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -101,8 +102,8 @@ static int ak5386_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 
        /*
         * From the datasheet:
@@ -123,8 +124,8 @@ static int ak5386_hw_params(struct snd_pcm_substream *substream,
 static int ak5386_hw_free(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ak5386_priv *priv = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(priv->reset_gpio))
                gpio_set_value(priv->reset_gpio, 0);
@@ -192,19 +193,12 @@ static int ak5386_probe(struct platform_device *pdev)
                                          "AK5386 Reset"))
                        priv->reset_gpio = -EINVAL;
 
-       return snd_soc_register_codec(dev, &soc_codec_ak5386,
+       return devm_snd_soc_register_component(dev, &soc_component_ak5386,
                                      &ak5386_dai, 1);
 }
 
-static int ak5386_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static struct platform_driver ak5386_driver = {
        .probe          = ak5386_probe,
-       .remove         = ak5386_remove,
        .driver         = {
                .name   = "ak5386",
                .of_match_table = of_match_ptr(ak5386_dt_ids),
diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c
new file mode 100644 (file)
index 0000000..f4ed5cc
--- /dev/null
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Audio driver for AK5558 ADC
+//
+// Copyright (C) 2015 Asahi Kasei Microdevices Corporation
+// Copyright 2018 NXP
+
+#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 <linux/slab.h>
+
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#include "ak5558.h"
+
+/* AK5558 Codec Private Data */
+struct ak5558_priv {
+       struct snd_soc_component component;
+       struct regmap *regmap;
+       struct i2c_client *i2c;
+       struct gpio_desc *reset_gpiod; /* Reset & Power down GPIO */
+       int slots;
+       int slot_width;
+};
+
+/* ak5558 register cache & default register settings */
+static const struct reg_default ak5558_reg[] = {
+       { 0x0, 0xFF },  /*      0x00    AK5558_00_POWER_MANAGEMENT1     */
+       { 0x1, 0x01 },  /*      0x01    AK5558_01_POWER_MANAGEMENT2     */
+       { 0x2, 0x01 },  /*      0x02    AK5558_02_CONTROL1              */
+       { 0x3, 0x00 },  /*      0x03    AK5558_03_CONTROL2              */
+       { 0x4, 0x00 },  /*      0x04    AK5558_04_CONTROL3              */
+       { 0x5, 0x00 }   /*      0x05    AK5558_05_DSD                   */
+};
+
+static const char * const mono_texts[] = {
+       "8 Slot", "2 Slot", "4 Slot", "1 Slot",
+};
+
+static const struct soc_enum ak5558_mono_enum[] = {
+       SOC_ENUM_SINGLE(AK5558_01_POWER_MANAGEMENT2, 1,
+                       ARRAY_SIZE(mono_texts), mono_texts),
+};
+
+static const char * const digfil_texts[] = {
+       "Sharp Roll-Off", "Show Roll-Off",
+       "Short Delay Sharp Roll-Off", "Short Delay Show Roll-Off",
+};
+
+static const struct soc_enum ak5558_adcset_enum[] = {
+       SOC_ENUM_SINGLE(AK5558_04_CONTROL3, 0,
+                       ARRAY_SIZE(digfil_texts), digfil_texts),
+};
+
+static const struct snd_kcontrol_new ak5558_snd_controls[] = {
+       SOC_ENUM("AK5558 Monaural Mode", ak5558_mono_enum[0]),
+       SOC_ENUM("AK5558 Digital Filter", ak5558_adcset_enum[0]),
+};
+
+static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = {
+       /* Analog Input */
+       SND_SOC_DAPM_INPUT("AIN1"),
+       SND_SOC_DAPM_INPUT("AIN2"),
+       SND_SOC_DAPM_INPUT("AIN3"),
+       SND_SOC_DAPM_INPUT("AIN4"),
+       SND_SOC_DAPM_INPUT("AIN5"),
+       SND_SOC_DAPM_INPUT("AIN6"),
+       SND_SOC_DAPM_INPUT("AIN7"),
+       SND_SOC_DAPM_INPUT("AIN8"),
+
+       SND_SOC_DAPM_ADC("ADC Ch1", NULL, AK5558_00_POWER_MANAGEMENT1, 0, 0),
+       SND_SOC_DAPM_ADC("ADC Ch2", NULL, AK5558_00_POWER_MANAGEMENT1, 1, 0),
+       SND_SOC_DAPM_ADC("ADC Ch3", NULL, AK5558_00_POWER_MANAGEMENT1, 2, 0),
+       SND_SOC_DAPM_ADC("ADC Ch4", NULL, AK5558_00_POWER_MANAGEMENT1, 3, 0),
+       SND_SOC_DAPM_ADC("ADC Ch5", NULL, AK5558_00_POWER_MANAGEMENT1, 4, 0),
+       SND_SOC_DAPM_ADC("ADC Ch6", NULL, AK5558_00_POWER_MANAGEMENT1, 5, 0),
+       SND_SOC_DAPM_ADC("ADC Ch7", NULL, AK5558_00_POWER_MANAGEMENT1, 6, 0),
+       SND_SOC_DAPM_ADC("ADC Ch8", NULL, AK5558_00_POWER_MANAGEMENT1, 7, 0),
+
+       SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
+};
+
+static const struct snd_soc_dapm_route ak5558_intercon[] = {
+       {"ADC Ch1", NULL, "AIN1"},
+       {"SDTO", NULL, "ADC Ch1"},
+
+       {"ADC Ch2", NULL, "AIN2"},
+       {"SDTO", NULL, "ADC Ch2"},
+
+       {"ADC Ch3", NULL, "AIN3"},
+       {"SDTO", NULL, "ADC Ch3"},
+
+       {"ADC Ch4", NULL, "AIN4"},
+       {"SDTO", NULL, "ADC Ch4"},
+
+       {"ADC Ch5", NULL, "AIN5"},
+       {"SDTO", NULL, "ADC Ch5"},
+
+       {"ADC Ch6", NULL, "AIN6"},
+       {"SDTO", NULL, "ADC Ch6"},
+
+       {"ADC Ch7", NULL, "AIN7"},
+       {"SDTO", NULL, "ADC Ch7"},
+
+       {"ADC Ch8", NULL, "AIN8"},
+       {"SDTO", NULL, "ADC Ch8"},
+};
+
+static int ak5558_set_mcki(struct snd_soc_component *component)
+{
+       return snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_CKS,
+                                  AK5558_CKS_AUTO);
+}
+
+static int ak5558_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
+{
+       struct snd_soc_component *component = dai->component;
+       struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+       u8 bits;
+       int pcm_width = max(params_physical_width(params), ak5558->slot_width);
+
+       /* set master/slave audio interface */
+       bits = snd_soc_component_read32(component, AK5558_02_CONTROL1);
+       bits &= ~AK5558_BITS;
+
+       switch (pcm_width) {
+       case 16:
+               bits |= AK5558_DIF_24BIT_MODE;
+               break;
+       case 32:
+               bits |= AK5558_DIF_32BIT_MODE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_BITS, bits);
+
+       return 0;
+}
+
+static int ak5558_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+       struct snd_soc_component *component = dai->component;
+       u8 format;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               break;
+       case SND_SOC_DAIFMT_CBS_CFM:
+       case SND_SOC_DAIFMT_CBM_CFS:
+       default:
+               dev_err(dai->dev, "Clock mode unsupported");
+               return -EINVAL;
+       }
+
+       /* set master/slave audio interface */
+       format = snd_soc_component_read32(component, AK5558_02_CONTROL1);
+       format &= ~AK5558_DIF;
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               format |= AK5558_DIF_I2S_MODE;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               format |= AK5558_DIF_MSB_MODE;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               format |= AK5558_DIF_MSB_MODE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_DIF, format);
+
+       return 0;
+}
+
+static int ak5558_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+                              unsigned int rx_mask, int slots,
+                              int slot_width)
+{
+       struct snd_soc_component *component = dai->component;
+       struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+       int tdm_mode;
+
+       ak5558->slots = slots;
+       ak5558->slot_width = slot_width;
+
+       switch (slots * slot_width) {
+       case 128:
+               tdm_mode = AK5558_MODE_TDM128;
+               break;
+       case 256:
+               tdm_mode = AK5558_MODE_TDM256;
+               break;
+       case 512:
+               tdm_mode = AK5558_MODE_TDM512;
+               break;
+       default:
+               tdm_mode = AK5558_MODE_NORMAL;
+               break;
+       }
+
+       snd_soc_component_update_bits(component, AK5558_03_CONTROL2, AK5558_MODE_BITS,
+                           tdm_mode);
+       return 0;
+}
+
+#define AK5558_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+                        SNDRV_PCM_FMTBIT_S24_LE |\
+                        SNDRV_PCM_FMTBIT_S32_LE)
+
+static const unsigned int ak5558_rates[] = {
+       8000, 11025,  16000, 22050,
+       32000, 44100, 48000, 88200,
+       96000, 176400, 192000, 352800,
+       384000, 705600, 768000, 1411200,
+       2822400,
+};
+
+static const struct snd_pcm_hw_constraint_list ak5558_rate_constraints = {
+       .count = ARRAY_SIZE(ak5558_rates),
+       .list = ak5558_rates,
+};
+
+static int ak5558_startup(struct snd_pcm_substream *substream,
+                         struct snd_soc_dai *dai)
+{
+       return snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                         SNDRV_PCM_HW_PARAM_RATE,
+                                         &ak5558_rate_constraints);
+}
+
+static struct snd_soc_dai_ops ak5558_dai_ops = {
+       .startup        = ak5558_startup,
+       .hw_params      = ak5558_hw_params,
+
+       .set_fmt        = ak5558_set_dai_fmt,
+       .set_tdm_slot   = ak5558_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ak5558_dai = {
+       .name = "ak5558-aif",
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_KNOT,
+               .formats = AK5558_FORMATS,
+       },
+       .ops = &ak5558_dai_ops,
+};
+
+static void ak5558_power_off(struct ak5558_priv *ak5558)
+{
+       if (!ak5558->reset_gpiod)
+               return;
+
+       gpiod_set_value_cansleep(ak5558->reset_gpiod, 0);
+       usleep_range(1000, 2000);
+}
+
+static void ak5558_power_on(struct ak5558_priv *ak5558)
+{
+       if (!ak5558->reset_gpiod)
+               return;
+
+       gpiod_set_value_cansleep(ak5558->reset_gpiod, 1);
+       usleep_range(1000, 2000);
+}
+
+static int ak5558_probe(struct snd_soc_component *component)
+{
+       struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+
+       ak5558_power_on(ak5558);
+       return ak5558_set_mcki(component);
+}
+
+static void ak5558_remove(struct snd_soc_component *component)
+{
+       struct ak5558_priv *ak5558 = snd_soc_component_get_drvdata(component);
+
+       ak5558_power_off(ak5558);
+}
+
+static int __maybe_unused ak5558_runtime_suspend(struct device *dev)
+{
+       struct ak5558_priv *ak5558 = dev_get_drvdata(dev);
+
+       regcache_cache_only(ak5558->regmap, true);
+       ak5558_power_off(ak5558);
+
+       return 0;
+}
+
+static int __maybe_unused ak5558_runtime_resume(struct device *dev)
+{
+       struct ak5558_priv *ak5558 = dev_get_drvdata(dev);
+
+       ak5558_power_off(ak5558);
+       ak5558_power_on(ak5558);
+
+       regcache_cache_only(ak5558->regmap, false);
+       regcache_mark_dirty(ak5558->regmap);
+
+       return regcache_sync(ak5558->regmap);
+}
+
+const struct dev_pm_ops ak5558_pm = {
+       SET_RUNTIME_PM_OPS(ak5558_runtime_suspend, ak5558_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                               pm_runtime_force_resume)
+};
+
+struct snd_soc_component_driver soc_codec_dev_ak5558 = {
+       .probe                  = ak5558_probe,
+       .remove                 = ak5558_remove,
+       .controls               = ak5558_snd_controls,
+       .num_controls           = ARRAY_SIZE(ak5558_snd_controls),
+       .dapm_widgets           = ak5558_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak5558_dapm_widgets),
+       .dapm_routes            = ak5558_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak5558_intercon),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
+
+static const struct regmap_config ak5558_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = AK5558_05_DSD,
+       .reg_defaults = ak5558_reg,
+       .num_reg_defaults = ARRAY_SIZE(ak5558_reg),
+       .cache_type = REGCACHE_RBTREE,
+};
+
+static int ak5558_i2c_probe(struct i2c_client *i2c)
+{
+       struct ak5558_priv *ak5558;
+       int ret = 0;
+
+       ak5558 = devm_kzalloc(&i2c->dev, sizeof(*ak5558), GFP_KERNEL);
+       if (!ak5558)
+               return -ENOMEM;
+
+       ak5558->regmap = devm_regmap_init_i2c(i2c, &ak5558_regmap);
+       if (IS_ERR(ak5558->regmap))
+               return PTR_ERR(ak5558->regmap);
+
+       i2c_set_clientdata(i2c, ak5558);
+       ak5558->i2c = i2c;
+
+       ak5558->reset_gpiod = devm_gpiod_get_optional(&i2c->dev, "reset",
+                                                     GPIOD_OUT_LOW);
+       if (IS_ERR(ak5558->reset_gpiod))
+               return PTR_ERR(ak5558->reset_gpiod);
+
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_codec_dev_ak5558,
+                                    &ak5558_dai, 1);
+       if (ret)
+               return ret;
+
+       pm_runtime_enable(&i2c->dev);
+
+       return 0;
+}
+
+static int ak5558_i2c_remove(struct i2c_client *i2c)
+{
+       pm_runtime_disable(&i2c->dev);
+
+       return 0;
+}
+
+static const struct of_device_id ak5558_i2c_dt_ids[] = {
+       { .compatible = "asahi-kasei,ak5558"},
+       { }
+};
+
+static struct i2c_driver ak5558_i2c_driver = {
+       .driver = {
+               .name = "ak5558",
+               .of_match_table = of_match_ptr(ak5558_i2c_dt_ids),
+               .pm = &ak5558_pm,
+       },
+       .probe_new = ak5558_i2c_probe,
+       .remove = ak5558_i2c_remove,
+};
+
+module_i2c_driver(ak5558_i2c_driver);
+
+MODULE_AUTHOR("Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>");
+MODULE_AUTHOR("Mihai Serban <mihai.serban@nxp.com>");
+MODULE_DESCRIPTION("ASoC AK5558 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak5558.h b/sound/soc/codecs/ak5558.h
new file mode 100644 (file)
index 0000000..6105908
--- /dev/null
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Audio driver header for AK5558
+ *
+ * Copyright (C) 2016 Asahi Kasei Microdevices Corporation
+ * Copyright 2018 NXP
+ */
+
+#ifndef _AK5558_H
+#define _AK5558_H
+
+#define AK5558_00_POWER_MANAGEMENT1    0x00
+#define AK5558_01_POWER_MANAGEMENT2    0x01
+#define AK5558_02_CONTROL1             0x02
+#define AK5558_03_CONTROL2             0x03
+#define AK5558_04_CONTROL3             0x04
+#define AK5558_05_DSD                  0x05
+
+/* AK5558_02_CONTROL1 fields */
+#define AK5558_DIF                     GENMASK(1, 1)
+#define AK5558_DIF_MSB_MODE            (0 << 1)
+#define AK5558_DIF_I2S_MODE            (1 << 1)
+
+#define AK5558_BITS                    GENMASK(2, 2)
+#define AK5558_DIF_24BIT_MODE          (0 << 2)
+#define AK5558_DIF_32BIT_MODE          (1 << 2)
+
+#define AK5558_CKS                     GENMASK(6, 3)
+#define AK5558_CKS_128FS_192KHZ                (0 << 3)
+#define AK5558_CKS_192FS_192KHZ                (1 << 3)
+#define AK5558_CKS_256FS_48KHZ         (2 << 3)
+#define AK5558_CKS_256FS_96KHZ         (3 << 3)
+#define AK5558_CKS_384FS_96KHZ         (4 << 3)
+#define AK5558_CKS_384FS_48KHZ         (5 << 3)
+#define AK5558_CKS_512FS_48KHZ         (6 << 3)
+#define AK5558_CKS_768FS_48KHZ         (7 << 3)
+#define AK5558_CKS_64FS_384KHZ         (8 << 3)
+#define AK5558_CKS_32FS_768KHZ         (9 << 3)
+#define AK5558_CKS_96FS_384KHZ         (10 << 3)
+#define AK5558_CKS_48FS_768KHZ         (11 << 3)
+#define AK5558_CKS_64FS_768KHZ         (12 << 3)
+#define AK5558_CKS_1024FS_16KHZ                (13 << 3)
+#define AK5558_CKS_AUTO                        (15 << 3)
+
+/* AK5558_03_CONTROL2 fields */
+#define AK5558_MODE_BITS       GENMASK(6, 5)
+#define AK5558_MODE_NORMAL     (0 << 5)
+#define AK5558_MODE_TDM128     (1 << 5)
+#define AK5558_MODE_TDM256     (2 << 5)
+#define AK5558_MODE_TDM512     (3 << 5)
+
+#endif
index 1db965a93632d8a52835ecf37d55c5963ee9bd4d..981a32973c081cf964460d1c4cf3b441ca8707ef 100644 (file)
@@ -47,28 +47,28 @@ struct alc5623_priv {
        unsigned int jack_det_ctrl;
 };
 
-static inline int alc5623_reset(struct snd_soc_codec *codec)
+static inline int alc5623_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, ALC5623_RESET, 0);
+       return snd_soc_component_write(component, ALC5623_RESET, 0);
 }
 
 static int amp_mixer_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        /* to power-on/off class-d amp generators/speaker */
        /* need to write to 'index-46h' register :        */
        /* so write index num (here 0x46) to reg 0x6a     */
        /* and then 0xffff/0 to reg 0x6c                  */
-       snd_soc_write(codec, ALC5623_HID_CTRL_INDEX, 0x46);
+       snd_soc_component_write(component, ALC5623_HID_CTRL_INDEX, 0x46);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
+               snd_soc_component_write(component, ALC5623_HID_CTRL_DATA, 0xFFFF);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0);
+               snd_soc_component_write(component, ALC5623_HID_CTRL_DATA, 0);
                break;
        }
 
@@ -526,7 +526,7 @@ static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
        int i;
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int gbl_clk = 0, pll_div = 0;
        u16 reg;
 
@@ -534,12 +534,12 @@ static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                return -ENODEV;
 
        /* Disable PLL power */
-       snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+       snd_soc_component_update_bits(component, ALC5623_PWR_MANAG_ADD2,
                                ALC5623_PWR_ADD2_PLL,
                                0);
 
        /* pll is not used in slave mode */
-       reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+       reg = snd_soc_component_read32(component, ALC5623_DAI_CONTROL);
        if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
                return 0;
 
@@ -575,13 +575,13 @@ static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        if (!pll_div)
                return -EINVAL;
 
-       snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
-       snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
-       snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
+       snd_soc_component_write(component, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+       snd_soc_component_write(component, ALC5623_PLL_CTRL, pll_div);
+       snd_soc_component_update_bits(component, ALC5623_PWR_MANAG_ADD2,
                                ALC5623_PWR_ADD2_PLL,
                                ALC5623_PWR_ADD2_PLL);
        gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
-       snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
+       snd_soc_component_write(component, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
 
        return 0;
 }
@@ -604,9 +604,9 @@ static const struct _coeff_div coeff_div[] = {
        {384*1, 0x0c6b},
 };
 
-static int get_coeff(struct snd_soc_codec *codec, int rate)
+static int get_coeff(struct snd_soc_component *component, int rate)
 {
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
@@ -622,8 +622,8 @@ static int get_coeff(struct snd_soc_codec *codec, int rate)
 static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case  8192000:
@@ -643,7 +643,7 @@ static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 iface = 0;
 
        /* set master/slave audio interface */
@@ -695,18 +695,18 @@ static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+       return snd_soc_component_write(component, ALC5623_DAI_CONTROL, iface);
 }
 
 static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
        int coeff, rate;
        u16 iface;
 
-       iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
+       iface = snd_soc_component_read32(component, ALC5623_DAI_CONTROL);
        iface &= ~ALC5623_DAI_I2S_DL_MASK;
 
        /* bit size */
@@ -728,30 +728,30 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* set iface & srate */
-       snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
+       snd_soc_component_write(component, ALC5623_DAI_CONTROL, iface);
        rate = params_rate(params);
-       coeff = get_coeff(codec, rate);
+       coeff = get_coeff(component, rate);
        if (coeff < 0)
                return -EINVAL;
 
        coeff = coeff_div[coeff].regvalue;
-       dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
+       dev_dbg(component->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
                __func__, alc5623->sysclk, rate, coeff);
-       snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
+       snd_soc_component_write(component, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
 
        return 0;
 }
 
 static int alc5623_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
-       u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
+       u16 mute_reg = snd_soc_component_read32(component, ALC5623_MISC_CTRL) & ~hp_mute;
 
        if (mute)
                mute_reg |= hp_mute;
 
-       return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
+       return snd_soc_component_write(component, ALC5623_MISC_CTRL, mute_reg);
 }
 
 #define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
@@ -769,60 +769,60 @@ static int alc5623_mute(struct snd_soc_dai *dai, int mute)
        (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
        | ALC5623_PWR_ADD1_HP_OUT_AMP)
 
-static void enable_power_depop(struct snd_soc_codec *codec)
+static void enable_power_depop(struct snd_soc_component *component)
 {
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 
-       snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
+       snd_soc_component_update_bits(component, ALC5623_PWR_MANAG_ADD1,
                                ALC5623_PWR_ADD1_SOFTGEN_EN,
                                ALC5623_PWR_ADD1_SOFTGEN_EN);
 
-       snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
+       snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
 
-       snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+       snd_soc_component_update_bits(component, ALC5623_MISC_CTRL,
                                ALC5623_MISC_HP_DEPOP_MODE2_EN,
                                ALC5623_MISC_HP_DEPOP_MODE2_EN);
 
        msleep(500);
 
-       snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
+       snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
 
        /* avoid writing '1' into 5622 reserved bits */
        if (alc5623->id == 0x22)
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD1,
                        ALC5623_ADD1_POWER_EN_5622);
        else
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD1,
                        ALC5623_ADD1_POWER_EN);
 
        /* disable HP Depop2 */
-       snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
+       snd_soc_component_update_bits(component, ALC5623_MISC_CTRL,
                                ALC5623_MISC_HP_DEPOP_MODE2_EN,
                                0);
 
 }
 
-static int alc5623_set_bias_level(struct snd_soc_codec *codec,
+static int alc5623_set_bias_level(struct snd_soc_component *component,
                                      enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
-               enable_power_depop(codec);
+               enable_power_depop(component);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
                /* everything off except vref/vmid, */
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD2,
                                ALC5623_PWR_ADD2_VREF);
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD3,
                                ALC5623_PWR_ADD3_MAIN_BIAS);
                break;
        case SND_SOC_BIAS_OFF:
                /* everything off, dac mute, inactive */
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
-               snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD2, 0);
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD3, 0);
+               snd_soc_component_write(component, ALC5623_PWR_MANAG_ADD1, 0);
                break;
        }
        return 0;
@@ -862,25 +862,25 @@ static struct snd_soc_dai_driver alc5623_dai = {
        .ops = &alc5623_dai_ops,
 };
 
-static int alc5623_suspend(struct snd_soc_codec *codec)
+static int alc5623_suspend(struct snd_soc_component *component)
 {
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(alc5623->regmap, true);
 
        return 0;
 }
 
-static int alc5623_resume(struct snd_soc_codec *codec)
+static int alc5623_resume(struct snd_soc_component *component)
 {
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
        int ret;
 
        /* Sync reg_cache with the hardware */
        regcache_cache_only(alc5623->regmap, false);
        ret = regcache_sync(alc5623->regmap);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to sync register cache: %d\n",
+               dev_err(component->dev, "Failed to sync register cache: %d\n",
                        ret);
                regcache_cache_only(alc5623->regmap, true);
                return ret;
@@ -889,41 +889,41 @@ static int alc5623_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int alc5623_probe(struct snd_soc_codec *codec)
+static int alc5623_probe(struct snd_soc_component *component)
 {
-       struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct alc5623_priv *alc5623 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-       alc5623_reset(codec);
+       alc5623_reset(component);
 
        if (alc5623->add_ctrl) {
-               snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
+               snd_soc_component_write(component, ALC5623_ADD_CTRL_REG,
                                alc5623->add_ctrl);
        }
 
        if (alc5623->jack_det_ctrl) {
-               snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
+               snd_soc_component_write(component, ALC5623_JACK_DET_CTRL,
                                alc5623->jack_det_ctrl);
        }
 
        switch (alc5623->id) {
        case 0x21:
-               snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
+               snd_soc_add_component_controls(component, alc5621_vol_snd_controls,
                        ARRAY_SIZE(alc5621_vol_snd_controls));
                break;
        case 0x22:
-               snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
+               snd_soc_add_component_controls(component, alc5622_vol_snd_controls,
                        ARRAY_SIZE(alc5622_vol_snd_controls));
                break;
        case 0x23:
-               snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
+               snd_soc_add_component_controls(component, alc5623_vol_snd_controls,
                        ARRAY_SIZE(alc5623_vol_snd_controls));
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_add_codec_controls(codec, alc5623_snd_controls,
+       snd_soc_add_component_controls(component, alc5623_snd_controls,
                        ARRAY_SIZE(alc5623_snd_controls));
 
        snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
@@ -951,12 +951,16 @@ static int alc5623_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_alc5623 = {
-       .probe = alc5623_probe,
-       .suspend = alc5623_suspend,
-       .resume = alc5623_resume,
-       .set_bias_level = alc5623_set_bias_level,
-       .suspend_bias_off = true,
+static const struct snd_soc_component_driver soc_component_device_alc5623 = {
+       .probe                  = alc5623_probe,
+       .suspend                = alc5623_suspend,
+       .resume                 = alc5623_resume,
+       .set_bias_level         = alc5623_set_bias_level,
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config alc5623_regmap = {
@@ -1052,20 +1056,14 @@ static int alc5623_i2c_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, alc5623);
 
-       ret =  snd_soc_register_codec(&client->dev,
-               &soc_codec_device_alc5623, &alc5623_dai, 1);
+       ret =  devm_snd_soc_register_component(&client->dev,
+               &soc_component_device_alc5623, &alc5623_dai, 1);
        if (ret != 0)
                dev_err(&client->dev, "Failed to register codec: %d\n", ret);
 
        return ret;
 }
 
-static int alc5623_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id alc5623_i2c_table[] = {
        {"alc5621", 0x21},
        {"alc5622", 0x22},
@@ -1087,7 +1085,6 @@ static struct i2c_driver alc5623_i2c_driver = {
                .of_match_table = of_match_ptr(alc5623_of_match),
        },
        .probe = alc5623_i2c_probe,
-       .remove =  alc5623_i2c_remove,
        .id_table = alc5623_i2c_table,
 };
 
index adb80d8719bdd813ec850583ee10ce68880a153b..08034a6d4c5a52a0426812f61dac327f603376ef 100644 (file)
@@ -116,20 +116,20 @@ static inline int alc5632_reset(struct regmap *map)
 static int amp_mixer_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        /* to power-on/off class-d amp generators/speaker */
        /* need to write to 'index-46h' register :        */
        /* so write index num (here 0x46) to reg 0x6a     */
        /* and then 0xffff/0 to reg 0x6c                  */
-       snd_soc_write(codec, ALC5632_HID_CTRL_INDEX, 0x46);
+       snd_soc_component_write(component, ALC5632_HID_CTRL_INDEX, 0x46);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
+               snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0xFFFF);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0);
+               snd_soc_component_write(component, ALC5632_HID_CTRL_DATA, 0);
                break;
        }
 
@@ -681,7 +681,7 @@ static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
        int i;
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int gbl_clk = 0, pll_div = 0;
        u16 reg;
 
@@ -689,15 +689,15 @@ static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                return -EINVAL;
 
        /* Disable PLL power */
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_PWR_ADD2_PLL1,
                                0);
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_PWR_ADD2_PLL2,
                                0);
 
        /* pll is not used in slave mode */
-       reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+       reg = snd_soc_component_read32(component, ALC5632_DAI_CONTROL);
        if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
                return 0;
 
@@ -745,19 +745,19 @@ static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                return -EINVAL;
 
        /* choose MCLK/BCLK/VBCLK */
-       snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
+       snd_soc_component_write(component, ALC5632_GPCR2, gbl_clk);
        /* choose PLL1 clock rate */
-       snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
+       snd_soc_component_write(component, ALC5632_PLL1_CTRL, pll_div);
        /* enable PLL1 */
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_PWR_ADD2_PLL1,
                                ALC5632_PWR_ADD2_PLL1);
        /* enable PLL2 */
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_PWR_ADD2_PLL2,
                                ALC5632_PWR_ADD2_PLL2);
        /* use PLL1 as main SYSCLK */
-       snd_soc_update_bits(codec, ALC5632_GPCR1,
+       snd_soc_component_update_bits(component, ALC5632_GPCR1,
                        ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
                        ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
 
@@ -775,9 +775,9 @@ static const struct _coeff_div coeff_div[] = {
        {512*1, 0x3075},
 };
 
-static int get_coeff(struct snd_soc_codec *codec, int rate)
+static int get_coeff(struct snd_soc_component *component, int rate)
 {
-       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+       struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
@@ -793,8 +793,8 @@ static int get_coeff(struct snd_soc_codec *codec, int rate)
 static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case  4096000:
@@ -815,7 +815,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 iface = 0;
 
        /* set master/slave audio interface */
@@ -864,17 +864,17 @@ static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+       return snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface);
 }
 
 static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int coeff, rate;
        u16 iface;
 
-       iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+       iface = snd_soc_component_read32(component, ALC5632_DAI_CONTROL);
        iface &= ~ALC5632_DAI_I2S_DL_MASK;
 
        /* bit size */
@@ -893,29 +893,29 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* set iface & srate */
-       snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+       snd_soc_component_write(component, ALC5632_DAI_CONTROL, iface);
        rate = params_rate(params);
-       coeff = get_coeff(codec, rate);
+       coeff = get_coeff(component, rate);
        if (coeff < 0)
                return -EINVAL;
 
        coeff = coeff_div[coeff].regvalue;
-       snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
+       snd_soc_component_write(component, ALC5632_DAC_CLK_CTRL1, coeff);
 
        return 0;
 }
 
 static int alc5632_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L
                                                |ALC5632_MISC_HP_DEPOP_MUTE_R;
-       u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
+       u16 mute_reg = snd_soc_component_read32(component, ALC5632_MISC_CTRL) & ~hp_mute;
 
        if (mute)
                mute_reg |= hp_mute;
 
-       return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
+       return snd_soc_component_write(component, ALC5632_MISC_CTRL, mute_reg);
 }
 
 #define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
@@ -929,73 +929,73 @@ static int alc5632_mute(struct snd_soc_dai *dai, int mute)
                | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
                | ALC5632_PWR_ADD1_MAIN_BIAS)
 
-static void enable_power_depop(struct snd_soc_codec *codec)
+static void enable_power_depop(struct snd_soc_component *component)
 {
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
                                ALC5632_PWR_ADD1_SOFTGEN_EN,
                                ALC5632_PWR_ADD1_SOFTGEN_EN);
 
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3,
                                ALC5632_ADD3_POWER_EN,
                                ALC5632_ADD3_POWER_EN);
 
-       snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+       snd_soc_component_update_bits(component, ALC5632_MISC_CTRL,
                                ALC5632_MISC_HP_DEPOP_MODE2_EN,
                                ALC5632_MISC_HP_DEPOP_MODE2_EN);
 
        /* "normal" mode: 0 @ 26 */
        /* set all PR0-7 mixers to 0 */
-       snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+       snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS,
                                ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
                                0);
 
        msleep(500);
 
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_ADD2_POWER_EN,
                                ALC5632_ADD2_POWER_EN);
 
-       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+       snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
                                ALC5632_ADD1_POWER_EN,
                                ALC5632_ADD1_POWER_EN);
 
        /* disable HP Depop2 */
-       snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+       snd_soc_component_update_bits(component, ALC5632_MISC_CTRL,
                                ALC5632_MISC_HP_DEPOP_MODE2_EN,
                                0);
 
 }
 
-static int alc5632_set_bias_level(struct snd_soc_codec *codec,
+static int alc5632_set_bias_level(struct snd_soc_component *component,
                                      enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
-               enable_power_depop(codec);
+               enable_power_depop(component);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
                /* everything off except vref/vmid, */
-               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+               snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
                                ALC5632_PWR_MANAG_ADD1_MASK,
                                ALC5632_PWR_ADD1_MAIN_BIAS);
-               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+               snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_PWR_MANAG_ADD2_MASK,
                                ALC5632_PWR_ADD2_VREF);
                /* "normal" mode: 0 @ 26 */
-               snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+               snd_soc_component_update_bits(component, ALC5632_PWR_DOWN_CTRL_STATUS,
                                ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
                                0xffff ^ (ALC5632_PWR_VREF_PR3
                                | ALC5632_PWR_VREF_PR2));
                break;
        case SND_SOC_BIAS_OFF:
                /* everything off, dac mute, inactive */
-               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+               snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD2,
                                ALC5632_PWR_MANAG_ADD2_MASK, 0);
-               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+               snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD3,
                                ALC5632_PWR_MANAG_ADD3_MASK, 0);
-               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+               snd_soc_component_update_bits(component, ALC5632_PWR_MANAG_ADD1,
                                ALC5632_PWR_MANAG_ADD1_MASK, 0);
                break;
        }
@@ -1038,9 +1038,9 @@ static struct snd_soc_dai_driver alc5632_dai = {
 };
 
 #ifdef CONFIG_PM
-static int alc5632_resume(struct snd_soc_codec *codec)
+static int alc5632_resume(struct snd_soc_component *component)
 {
-       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+       struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 
        regcache_sync(alc5632->regmap);
 
@@ -1050,13 +1050,13 @@ static int alc5632_resume(struct snd_soc_codec *codec)
 #define        alc5632_resume  NULL
 #endif
 
-static int alc5632_probe(struct snd_soc_codec *codec)
+static int alc5632_probe(struct snd_soc_component *component)
 {
-       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+       struct alc5632_priv *alc5632 = snd_soc_component_get_drvdata(component);
 
        switch (alc5632->id) {
        case 0x5c:
-               snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
+               snd_soc_add_component_controls(component, alc5632_vol_snd_controls,
                        ARRAY_SIZE(alc5632_vol_snd_controls));
                break;
        default:
@@ -1066,20 +1066,21 @@ static int alc5632_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_alc5632 = {
-       .probe = alc5632_probe,
-       .resume = alc5632_resume,
-       .set_bias_level = alc5632_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = alc5632_snd_controls,
-               .num_controls           = ARRAY_SIZE(alc5632_snd_controls),
-               .dapm_widgets           = alc5632_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(alc5632_dapm_widgets),
-               .dapm_routes            = alc5632_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(alc5632_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_device_alc5632 = {
+       .probe                  = alc5632_probe,
+       .resume                 = alc5632_resume,
+       .set_bias_level         = alc5632_set_bias_level,
+       .controls               = alc5632_snd_controls,
+       .num_controls           = ARRAY_SIZE(alc5632_snd_controls),
+       .dapm_widgets           = alc5632_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(alc5632_dapm_widgets),
+       .dapm_routes            = alc5632_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(alc5632_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config alc5632_regmap = {
@@ -1151,23 +1152,17 @@ static int alc5632_i2c_probe(struct i2c_client *client,
                return -EINVAL;
        }
 
-       ret = snd_soc_register_codec(&client->dev,
-               &soc_codec_device_alc5632, &alc5632_dai, 1);
+       ret = devm_snd_soc_register_component(&client->dev,
+               &soc_component_device_alc5632, &alc5632_dai, 1);
 
        if (ret < 0) {
-               dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&client->dev, "Failed to register component: %d\n", ret);
                return ret;
        }
 
        return ret;
 }
 
-static int alc5632_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id alc5632_i2c_table[] = {
        {"alc5632", 0x5c},
        {}
@@ -1187,7 +1182,6 @@ static struct i2c_driver alc5632_i2c_driver = {
                .of_match_table = of_match_ptr(alc5632_of_match),
        },
        .probe = alc5632_i2c_probe,
-       .remove =  alc5632_i2c_remove,
        .id_table = alc5632_i2c_table,
 };
 
index b3375e19598a8372dbedbb4e012cb343d5c0fbdb..5727ea079ad7addd5e07408ebc3fc0b0e3a0f3ec 100644 (file)
@@ -84,13 +84,14 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol,
                          int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        int val;
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
+               val = snd_soc_component_read32(component,
+                                              ARIZONA_INTERRUPT_RAW_STATUS_3);
                if (val & ARIZONA_SPK_OVERHEAT_STS) {
                        dev_crit(arizona->dev,
                                 "Speaker not enabled due to temperature\n");
@@ -169,10 +170,10 @@ static const struct snd_soc_dapm_widget arizona_spkr =
                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
                           SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
 
-int arizona_init_spk(struct snd_soc_codec *codec)
+int arizona_init_spk(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int ret;
 
@@ -238,10 +239,10 @@ static const struct snd_soc_dapm_route arizona_mono_routes[] = {
        { "OUT6R", NULL, "OUT6L" },
 };
 
-int arizona_init_mono(struct snd_soc_codec *codec)
+int arizona_init_mono(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int i;
 
@@ -255,11 +256,9 @@ int arizona_init_mono(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(arizona_init_mono);
 
-int arizona_init_gpio(struct snd_soc_codec *codec)
+int arizona_init_gpio(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int i;
 
@@ -643,7 +642,6 @@ const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
 };
 EXPORT_SYMBOL_GPL(arizona_rate_val);
 
-
 const struct soc_enum arizona_isrc_fsh[] = {
        SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
                              ARIZONA_ISRC1_FSH_SHIFT, 0xf,
@@ -882,9 +880,9 @@ const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
 };
 EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
 
-static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
+static void arizona_in_set_vu(struct snd_soc_component *component, int ena)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int val;
        int i;
 
@@ -894,15 +892,15 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
                val = 0;
 
        for (i = 0; i < priv->num_inputs; i++)
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                                    ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
                                    ARIZONA_IN_VU, val);
 }
 
-bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
+bool arizona_input_analog(struct snd_soc_component *component, int shift)
 {
        unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
-       unsigned int val = snd_soc_read(codec, reg);
+       unsigned int val = snd_soc_component_read32(component, reg);
 
        return !(val & ARIZONA_IN1_MODE_MASK);
 }
@@ -911,8 +909,8 @@ EXPORT_SYMBOL_GPL(arizona_input_analog);
 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
                  int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int reg;
 
        if (w->shift % 2)
@@ -925,25 +923,26 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
                priv->in_pending++;
                break;
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0);
+               snd_soc_component_update_bits(component, reg,
+                                             ARIZONA_IN1L_MUTE, 0);
 
                /* If this is the last input pending then allow VU */
                priv->in_pending--;
                if (priv->in_pending == 0) {
                        msleep(1);
-                       arizona_in_set_vu(codec, 1);
+                       arizona_in_set_vu(component, 1);
                }
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, reg,
+               snd_soc_component_update_bits(component, reg,
                                    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
                                    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
                break;
        case SND_SOC_DAPM_POST_PMD:
                /* Disable volume updates if no inputs are enabled */
-               reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
+               reg = snd_soc_component_read32(component, ARIZONA_INPUT_ENABLES);
                if (reg == 0)
-                       arizona_in_set_vu(codec, 0);
+                       arizona_in_set_vu(component, 0);
                break;
        default:
                break;
@@ -957,8 +956,8 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol,
                   int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
 
        switch (event) {
@@ -1001,7 +1000,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
                case ARIZONA_OUT4R_ENA_SHIFT:
                        priv->out_up_pending--;
                        if (!priv->out_up_pending && priv->out_up_delay) {
-                               dev_dbg(codec->dev, "Power up delay: %d\n",
+                               dev_dbg(component->dev, "Power up delay: %d\n",
                                        priv->out_up_delay);
                                msleep(priv->out_up_delay);
                                priv->out_up_delay = 0;
@@ -1054,7 +1053,7 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
                case ARIZONA_OUT4R_ENA_SHIFT:
                        priv->out_down_pending--;
                        if (!priv->out_down_pending && priv->out_down_delay) {
-                               dev_dbg(codec->dev, "Power down delay: %d\n",
+                               dev_dbg(component->dev, "Power down delay: %d\n",
                                        priv->out_down_delay);
                                msleep(priv->out_down_delay);
                                priv->out_down_delay = 0;
@@ -1072,12 +1071,11 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(arizona_out_ev);
 
-int arizona_hp_ev(struct snd_soc_dapm_widget *w,
-                  struct snd_kcontrol *kcontrol,
-                  int event)
+int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
+                 int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        unsigned int mask = 1 << w->shift;
        unsigned int val;
@@ -1111,15 +1109,15 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(arizona_hp_ev);
 
-static int arizona_dvfs_enable(struct snd_soc_codec *codec)
+static int arizona_dvfs_enable(struct snd_soc_component *component)
 {
-       const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int ret;
 
        ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
        if (ret) {
-               dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
+               dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
                return ret;
        }
 
@@ -1128,7 +1126,7 @@ static int arizona_dvfs_enable(struct snd_soc_codec *codec)
                                 ARIZONA_SUBSYS_MAX_FREQ,
                                 ARIZONA_SUBSYS_MAX_FREQ);
        if (ret) {
-               dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
+               dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
                regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
                return ret;
        }
@@ -1136,9 +1134,9 @@ static int arizona_dvfs_enable(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int arizona_dvfs_disable(struct snd_soc_codec *codec)
+static int arizona_dvfs_disable(struct snd_soc_component *component)
 {
-       const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int ret;
 
@@ -1146,28 +1144,28 @@ static int arizona_dvfs_disable(struct snd_soc_codec *codec)
                                 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
                                 ARIZONA_SUBSYS_MAX_FREQ, 0);
        if (ret) {
-               dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
+               dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
                return ret;
        }
 
        ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
        if (ret) {
-               dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
+               dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
                return ret;
        }
 
        return 0;
 }
 
-int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
+int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        mutex_lock(&priv->dvfs_lock);
 
        if (!priv->dvfs_cached && !priv->dvfs_reqs) {
-               ret = arizona_dvfs_enable(codec);
+               ret = arizona_dvfs_enable(component);
                if (ret)
                        goto err;
        }
@@ -1179,9 +1177,9 @@ err:
 }
 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
 
-int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
+int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int old_reqs;
        int ret = 0;
 
@@ -1191,7 +1189,7 @@ int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
        priv->dvfs_reqs &= ~flags;
 
        if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
-               ret = arizona_dvfs_disable(codec);
+               ret = arizona_dvfs_disable(component);
 
        mutex_unlock(&priv->dvfs_lock);
        return ret;
@@ -1201,8 +1199,8 @@ EXPORT_SYMBOL_GPL(arizona_dvfs_down);
 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        mutex_lock(&priv->dvfs_lock);
@@ -1210,7 +1208,7 @@ int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                if (priv->dvfs_reqs)
-                       ret = arizona_dvfs_enable(codec);
+                       ret = arizona_dvfs_enable(component);
 
                priv->dvfs_cached = false;
                break;
@@ -1222,7 +1220,7 @@ int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
                priv->dvfs_cached = true;
 
                if (priv->dvfs_reqs)
-                       ret = arizona_dvfs_disable(codec);
+                       ret = arizona_dvfs_disable(component);
                break;
        default:
                break;
@@ -1243,7 +1241,7 @@ int arizona_anc_ev(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol,
                   int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int val;
 
        switch (event) {
@@ -1257,7 +1255,7 @@ int arizona_anc_ev(struct snd_soc_dapm_widget *w,
                return 0;
        }
 
-       snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val);
+       snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
 
        return 0;
 }
@@ -1277,10 +1275,10 @@ static unsigned int arizona_opclk_ref_44k1_rates[] = {
        45158400,
 };
 
-static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
-                            unsigned int freq)
+static int arizona_set_opclk(struct snd_soc_component *component,
+                            unsigned int clk, unsigned int freq)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int reg;
        unsigned int *rates;
        int ref, div, refclk;
@@ -1304,13 +1302,13 @@ static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
                rates = arizona_opclk_ref_48k_rates;
 
        for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
-                    rates[ref] <= refclk; ref++) {
+            rates[ref] <= refclk; ref++) {
                div = 1;
                while (rates[ref] / div >= freq && div < 32) {
                        if (rates[ref] / div == freq) {
-                               dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
+                               dev_dbg(component->dev, "Configured %dHz OPCLK\n",
                                        freq);
-                               snd_soc_update_bits(codec, reg,
+                               snd_soc_component_update_bits(component, reg,
                                                    ARIZONA_OPCLK_DIV_MASK |
                                                    ARIZONA_OPCLK_SEL_MASK,
                                                    (div <<
@@ -1322,22 +1320,22 @@ static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
                }
        }
 
-       dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
+       dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
        return -EINVAL;
 }
 
 int arizona_clk_ev(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        unsigned int val;
        int clk_idx;
        int ret;
 
        ret = regmap_read(arizona->regmap, w->reg, &val);
        if (ret) {
-               dev_err(codec->dev, "Failed to check clock source: %d\n", ret);
+               dev_err(component->dev, "Failed to check clock source: %d\n", ret);
                return ret;
        }
 
@@ -1366,10 +1364,10 @@ int arizona_clk_ev(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(arizona_clk_ev);
 
-int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
                       int source, unsigned int freq, int dir)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        char *name;
        unsigned int reg;
@@ -1391,7 +1389,7 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                break;
        case ARIZONA_CLK_OPCLK:
        case ARIZONA_CLK_ASYNC_OPCLK:
-               return arizona_set_opclk(codec, clk_id, freq);
+               return arizona_set_opclk(component, clk_id, freq);
        default:
                return -EINVAL;
        }
@@ -1445,8 +1443,8 @@ EXPORT_SYMBOL_GPL(arizona_set_sysclk);
 
 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int lrclk, bclk, mode, base;
 
@@ -1620,8 +1618,8 @@ static const struct snd_pcm_hw_constraint_list arizona_constraint = {
 static int arizona_startup(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
        unsigned int base_rate;
 
@@ -1651,10 +1649,10 @@ static int arizona_startup(struct snd_pcm_substream *substream,
                                          &dai_priv->constraint);
 }
 
-static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
+static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
                                        unsigned int rate)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        struct reg_sequence dac_comp[] = {
                { 0x80, 0x3 },
@@ -1680,8 +1678,8 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *params,
                                  struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
        int base = dai->driver->base;
        int i, sr_val, ret;
@@ -1704,9 +1702,9 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
        case WM5102:
        case WM8997:
                if (arizona_sr_vals[sr_val] >= 88200)
-                       ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
+                       ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
                else
-                       ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
+                       ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
 
                if (ret) {
                        arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
@@ -1721,26 +1719,31 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
        case ARIZONA_CLK_SYSCLK:
                switch (priv->arizona->type) {
                case WM5102:
-                       arizona_wm5102_set_dac_comp(codec,
+                       arizona_wm5102_set_dac_comp(component,
                                                    params_rate(params));
                        break;
                default:
                        break;
                }
 
-               snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
-                                   ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
+               snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
+                                             ARIZONA_SAMPLE_RATE_1_MASK,
+                                             sr_val);
                if (base)
-                       snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
-                                           ARIZONA_AIF1_RATE_MASK, 0);
+                       snd_soc_component_update_bits(component,
+                                       base + ARIZONA_AIF_RATE_CTRL,
+                                       ARIZONA_AIF1_RATE_MASK, 0);
                break;
        case ARIZONA_CLK_ASYNCCLK:
-               snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
-                                   ARIZONA_ASYNC_SAMPLE_RATE_1_MASK, sr_val);
+               snd_soc_component_update_bits(component,
+                                             ARIZONA_ASYNC_SAMPLE_RATE_1,
+                                             ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
+                                             sr_val);
                if (base)
-                       snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
-                                           ARIZONA_AIF1_RATE_MASK,
-                                           8 << ARIZONA_AIF1_RATE_SHIFT);
+                       snd_soc_component_update_bits(component,
+                                       base + ARIZONA_AIF_RATE_CTRL,
+                                       ARIZONA_AIF1_RATE_MASK,
+                                       8 << ARIZONA_AIF1_RATE_SHIFT);
                break;
        default:
                arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
@@ -1750,20 +1753,20 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
+static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
                                    int base, int bclk, int lrclk, int frame)
 {
        int val;
 
-       val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
+       val = snd_soc_component_read32(component, base + ARIZONA_AIF_BCLK_CTRL);
        if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
                return true;
 
-       val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
+       val = snd_soc_component_read32(component, base + ARIZONA_AIF_TX_BCLK_RATE);
        if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
                return true;
 
-       val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
+       val = snd_soc_component_read32(component, base + ARIZONA_AIF_FRAME_CTRL_1);
        if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
                             ARIZONA_AIF1TX_SLOT_LEN_MASK)))
                return true;
@@ -1775,8 +1778,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int base = dai->driver->base;
        const int *rates;
@@ -1813,7 +1816,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* Force multiple of 2 channels for I2S mode */
-       val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
+       val = snd_soc_component_read32(component, base + ARIZONA_AIF_FORMAT);
        val &= ARIZONA_AIF1_FMT_MASK;
        if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
                arizona_aif_dbg(dai, "Forcing stereo mode\n");
@@ -1841,19 +1844,20 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
 
        frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
 
-       reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
+       reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
 
        if (reconfig) {
                /* Save AIF TX/RX state */
-               aif_tx_state = snd_soc_read(codec,
+               aif_tx_state = snd_soc_component_read32(component,
                                            base + ARIZONA_AIF_TX_ENABLES);
-               aif_rx_state = snd_soc_read(codec,
+               aif_rx_state = snd_soc_component_read32(component,
                                            base + ARIZONA_AIF_RX_ENABLES);
                /* Disable AIF TX/RX before reconfiguring it */
                regmap_update_bits_async(arizona->regmap,
-                                   base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
+                                        base + ARIZONA_AIF_TX_ENABLES,
+                                        0xff, 0x0);
                regmap_update_bits(arizona->regmap,
-                                   base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
+                                  base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
        }
 
        ret = arizona_hw_params_rate(substream, params, dai);
@@ -1908,9 +1912,9 @@ static const char *arizona_dai_clk_str(int clk_id)
 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
        struct snd_soc_dapm_route routes[2];
 
@@ -1926,12 +1930,12 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
                return 0;
 
        if (dai->active) {
-               dev_err(codec->dev, "Can't change clock on active DAI %d\n",
+               dev_err(component->dev, "Can't change clock on active DAI %d\n",
                        dai->id);
                return -EBUSY;
        }
 
-       dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
+       dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
                arizona_dai_clk_str(clk_id));
 
        memset(&routes, 0, sizeof(routes));
@@ -1953,7 +1957,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 
 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int base = dai->driver->base;
        unsigned int reg;
 
@@ -1962,16 +1966,17 @@ static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
        else
                reg = 0;
 
-       return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
-                                  ARIZONA_AIF1_TRI, reg);
+       return snd_soc_component_update_bits(component,
+                                            base + ARIZONA_AIF_RATE_CTRL,
+                                            ARIZONA_AIF1_TRI, reg);
 }
 
 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
                                         unsigned int base,
                                         int channels, unsigned int mask)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int slot, i;
 
@@ -1992,8 +1997,8 @@ static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                                unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        int base = dai->driver->base;
        int rx_max_chan = dai->driver->playback.channels_max;
@@ -2321,7 +2326,6 @@ static int arizona_calc_fll(struct arizona_fll *fll,
        arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
 
        return 0;
-
 }
 
 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
@@ -2567,9 +2571,8 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
        fll->ref_src = source;
        fll->ref_freq = Fref;
 
-       if (fll->fout && Fref > 0) {
+       if (fll->fout && Fref > 0)
                ret = arizona_enable_fll(fll);
-       }
 
        return ret;
 }
@@ -2645,7 +2648,7 @@ EXPORT_SYMBOL_GPL(arizona_init_fll);
 /**
  * arizona_set_output_mode - Set the mode of the specified output
  *
- * @codec: Device to configure
+ * @component: Device to configure
  * @output: Output number
  * @diff: True to set the output to differential mode
  *
@@ -2658,7 +2661,8 @@ EXPORT_SYMBOL_GPL(arizona_init_fll);
  * Most systems have a single static configuration and should use
  * platform data instead.
  */
-int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
+int arizona_set_output_mode(struct snd_soc_component *component, int output,
+                           bool diff)
 {
        unsigned int reg, val;
 
@@ -2672,7 +2676,8 @@ int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
        else
                val = 0;
 
-       return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
+       return snd_soc_component_update_bits(component, reg,
+                                            ARIZONA_OUT1_MONO, val);
 }
 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
 
@@ -2721,8 +2726,8 @@ static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        struct soc_bytes *params = (void *)kcontrol->private_value;
        unsigned int val;
        __be16 *data;
@@ -2765,8 +2770,8 @@ EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        __be16 *data = (__be16 *)ucontrol->value.bytes.data;
        s16 val = be16_to_cpu(*data);
 
index dfdf6d8c9687f72d4bfc0ff77d9c0b132687e56d..e3ccee5627c6bb474c3d1d428f0d2f3f2fd0f3d7 100644 (file)
@@ -273,7 +273,7 @@ int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
 
 int arizona_clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
                   int event);
-int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, int source,
+int arizona_set_sysclk(struct snd_soc_component *component, int clk_id, int source,
                       unsigned int freq, int dir);
 
 extern const struct snd_soc_dai_ops arizona_dai_ops;
@@ -297,8 +297,8 @@ struct arizona_fll {
        char clock_ok_name[ARIZONA_FLL_NAME_LEN];
 };
 
-int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags);
-int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags);
+int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags);
+int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags);
 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event);
 void arizona_init_dvfs(struct arizona_priv *priv);
@@ -310,9 +310,9 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 int arizona_set_fll(struct arizona_fll *fll, int source,
                    unsigned int Fref, unsigned int Fout);
 
-int arizona_init_spk(struct snd_soc_codec *codec);
-int arizona_init_gpio(struct snd_soc_codec *codec);
-int arizona_init_mono(struct snd_soc_codec *codec);
+int arizona_init_spk(struct snd_soc_component *component);
+int arizona_init_gpio(struct snd_soc_component *component);
+int arizona_init_mono(struct snd_soc_component *component);
 
 int arizona_init_common(struct arizona *arizona);
 int arizona_init_vol_limit(struct arizona *arizona);
@@ -322,20 +322,20 @@ int arizona_free_spk_irqs(struct arizona *arizona);
 
 int arizona_init_dai(struct arizona_priv *priv, int dai);
 
-int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
+int arizona_set_output_mode(struct snd_soc_component *component, int output,
                            bool diff);
 
-bool arizona_input_analog(struct snd_soc_codec *codec, int shift);
+bool arizona_input_analog(struct snd_soc_component *component, int shift);
 
 const char *arizona_sample_rate_val_to_name(unsigned int rate_val);
 
-static inline int arizona_register_notifier(struct snd_soc_codec *codec,
+static inline int arizona_register_notifier(struct snd_soc_component *component,
                                            struct notifier_block *nb,
                                            int (*notify)
                                            (struct notifier_block *nb,
                                            unsigned long action, void *data))
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
 
        nb->notifier_call = notify;
@@ -343,10 +343,10 @@ static inline int arizona_register_notifier(struct snd_soc_codec *codec,
        return blocking_notifier_chain_register(&arizona->notifier, nb);
 }
 
-static inline int arizona_unregister_notifier(struct snd_soc_codec *codec,
+static inline int arizona_unregister_notifier(struct snd_soc_component *component,
                                              struct notifier_block *nb)
 {
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
 
        return blocking_notifier_chain_unregister(&arizona->notifier, nb);
diff --git a/sound/soc/codecs/bd28623.c b/sound/soc/codecs/bd28623.c
new file mode 100644 (file)
index 0000000..31904ef
--- /dev/null
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// ROHM BD28623MUV class D speaker amplifier codec driver.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#define BD28623_NUM_SUPPLIES    3
+
+static const char *const bd28623_supply_names[BD28623_NUM_SUPPLIES] = {
+       "VCCA",
+       "VCCP1",
+       "VCCP2",
+};
+
+struct bd28623_priv {
+       struct device *dev;
+       struct regulator_bulk_data supplies[BD28623_NUM_SUPPLIES];
+       struct gpio_desc *reset_gpio;
+       struct gpio_desc *mute_gpio;
+
+       int switch_spk;
+};
+
+static const struct snd_soc_dapm_widget bd28623_widgets[] = {
+       SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_OUTPUT("OUT1P"),
+       SND_SOC_DAPM_OUTPUT("OUT1N"),
+       SND_SOC_DAPM_OUTPUT("OUT2P"),
+       SND_SOC_DAPM_OUTPUT("OUT2N"),
+};
+
+static const struct snd_soc_dapm_route bd28623_routes[] = {
+       { "OUT1P", NULL, "DAC" },
+       { "OUT1N", NULL, "DAC" },
+       { "OUT2P", NULL, "DAC" },
+       { "OUT2N", NULL, "DAC" },
+};
+
+static int bd28623_power_on(struct bd28623_priv *bd)
+{
+       int ret;
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(bd->supplies), bd->supplies);
+       if (ret) {
+               dev_err(bd->dev, "Failed to enable supplies: %d\n", ret);
+               return ret;
+       }
+
+       gpiod_set_value_cansleep(bd->reset_gpio, 0);
+       usleep_range(300000, 400000);
+
+       return 0;
+}
+
+static void bd28623_power_off(struct bd28623_priv *bd)
+{
+       gpiod_set_value_cansleep(bd->reset_gpio, 1);
+
+       regulator_bulk_disable(ARRAY_SIZE(bd->supplies), bd->supplies);
+}
+
+static int bd28623_get_switch_spk(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component =
+               snd_soc_kcontrol_component(kcontrol);
+       struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+       ucontrol->value.integer.value[0] = bd->switch_spk;
+
+       return 0;
+}
+
+static int bd28623_set_switch_spk(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component =
+               snd_soc_kcontrol_component(kcontrol);
+       struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+       if (bd->switch_spk == ucontrol->value.integer.value[0])
+               return 0;
+
+       bd->switch_spk = ucontrol->value.integer.value[0];
+
+       gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);
+
+       return 0;
+}
+
+static const struct snd_kcontrol_new bd28623_controls[] = {
+       SOC_SINGLE_BOOL_EXT("Speaker Switch", 0,
+                           bd28623_get_switch_spk, bd28623_set_switch_spk),
+};
+
+static int bd28623_codec_probe(struct snd_soc_component *component)
+{
+       struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+       int ret;
+
+       bd->switch_spk = 1;
+
+       ret = bd28623_power_on(bd);
+       if (ret)
+               return ret;
+
+       gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);
+
+       return 0;
+}
+
+static void bd28623_codec_remove(struct snd_soc_component *component)
+{
+       struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+       bd28623_power_off(bd);
+}
+
+static int bd28623_codec_suspend(struct snd_soc_component *component)
+{
+       struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+
+       bd28623_power_off(bd);
+
+       return 0;
+}
+
+static int bd28623_codec_resume(struct snd_soc_component *component)
+{
+       struct bd28623_priv *bd = snd_soc_component_get_drvdata(component);
+       int ret;
+
+       ret = bd28623_power_on(bd);
+       if (ret)
+               return ret;
+
+       gpiod_set_value_cansleep(bd->mute_gpio, bd->switch_spk ? 0 : 1);
+
+       return 0;
+}
+
+static const struct snd_soc_component_driver soc_codec_bd = {
+       .probe                  = bd28623_codec_probe,
+       .remove                 = bd28623_codec_remove,
+       .suspend                = bd28623_codec_suspend,
+       .resume                 = bd28623_codec_resume,
+       .dapm_widgets           = bd28623_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(bd28623_widgets),
+       .dapm_routes            = bd28623_routes,
+       .num_dapm_routes        = ARRAY_SIZE(bd28623_routes),
+       .controls               = bd28623_controls,
+       .num_controls           = ARRAY_SIZE(bd28623_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
+
+static struct snd_soc_dai_driver soc_dai_bd = {
+       .name     = "bd28623-speaker",
+       .playback = {
+               .stream_name  = "Playback",
+               .formats      = SNDRV_PCM_FMTBIT_S32_LE |
+                               SNDRV_PCM_FMTBIT_S24_LE |
+                               SNDRV_PCM_FMTBIT_S16_LE,
+               .rates        = SNDRV_PCM_RATE_48000 |
+                               SNDRV_PCM_RATE_44100 |
+                               SNDRV_PCM_RATE_32000,
+               .channels_min = 2,
+               .channels_max = 2,
+       },
+};
+
+static int bd28623_probe(struct platform_device *pdev)
+{
+       struct bd28623_priv *bd;
+       struct device *dev = &pdev->dev;
+       int i, ret;
+
+       bd = devm_kzalloc(&pdev->dev, sizeof(struct bd28623_priv), GFP_KERNEL);
+       if (!bd)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(bd->supplies); i++)
+               bd->supplies[i].supply = bd28623_supply_names[i];
+
+       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(bd->supplies),
+                                     bd->supplies);
+       if (ret) {
+               dev_err(dev, "Failed to get supplies: %d\n", ret);
+               return ret;
+       }
+
+       bd->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+                                                GPIOD_OUT_HIGH);
+       if (IS_ERR(bd->reset_gpio)) {
+               dev_err(dev, "Failed to request reset_gpio: %ld\n",
+                       PTR_ERR(bd->reset_gpio));
+               return PTR_ERR(bd->reset_gpio);
+       }
+
+       bd->mute_gpio = devm_gpiod_get_optional(dev, "mute",
+                                               GPIOD_OUT_HIGH);
+       if (IS_ERR(bd->mute_gpio)) {
+               dev_err(dev, "Failed to request mute_gpio: %ld\n",
+                       PTR_ERR(bd->mute_gpio));
+               return PTR_ERR(bd->mute_gpio);
+       }
+
+       platform_set_drvdata(pdev, bd);
+       bd->dev = dev;
+
+       return devm_snd_soc_register_component(dev, &soc_codec_bd,
+                                              &soc_dai_bd, 1);
+}
+
+static const struct of_device_id bd28623_of_match[] = {
+       { .compatible = "rohm,bd28623", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, bd28623_of_match);
+
+static struct platform_driver bd28623_codec_driver = {
+       .driver = {
+               .name = "bd28623",
+               .of_match_table = of_match_ptr(bd28623_of_match),
+       },
+       .probe  = bd28623_probe,
+};
+module_platform_driver(bd28623_codec_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("ROHM BD28623 speaker amplifier driver");
+MODULE_LICENSE("GPL v2");
index 806191addb44daedc0fbfca98bbabb0be4be8509..842204203eb36a93e920c875409ecd7ef98d8751 100644 (file)
@@ -62,25 +62,26 @@ static struct snd_soc_dai_driver bt_sco_dai[] = {
        }
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
-       .component_driver = {
-               .dapm_widgets           = bt_sco_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(bt_sco_widgets),
-               .dapm_routes            = bt_sco_routes,
-               .num_dapm_routes        = ARRAY_SIZE(bt_sco_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_bt_sco = {
+       .dapm_widgets           = bt_sco_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(bt_sco_widgets),
+       .dapm_routes            = bt_sco_routes,
+       .num_dapm_routes        = ARRAY_SIZE(bt_sco_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int bt_sco_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_bt_sco,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &soc_component_dev_bt_sco,
                                      bt_sco_dai, ARRAY_SIZE(bt_sco_dai));
 }
 
 static int bt_sco_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
-
        return 0;
 }
 
diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c
new file mode 100644 (file)
index 0000000..d7f05b3
--- /dev/null
@@ -0,0 +1,1562 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ALSA SoC CPCAP codec driver
+ *
+ * Copyright (C) 2017 - 2018 Sebastian Reichel <sre@kernel.org>
+ *
+ * Very loosely based on original driver from Motorola:
+ * Copyright (C) 2007 - 2009 Motorola, Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/motorola-cpcap.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+/* Register 513 CPCAP_REG_CC     --- CODEC */
+#define CPCAP_BIT_CDC_CLK2                15
+#define CPCAP_BIT_CDC_CLK1                14
+#define CPCAP_BIT_CDC_CLK0                13
+#define CPCAP_BIT_CDC_SR3                 12
+#define CPCAP_BIT_CDC_SR2                 11
+#define CPCAP_BIT_CDC_SR1                 10
+#define CPCAP_BIT_CDC_SR0                 9
+#define CPCAP_BIT_CDC_CLOCK_TREE_RESET    8
+#define CPCAP_BIT_MIC2_CDC_EN             7
+#define CPCAP_BIT_CDC_EN_RX               6
+#define CPCAP_BIT_DF_RESET                5
+#define CPCAP_BIT_MIC1_CDC_EN             4
+#define CPCAP_BIT_AUDOHPF_1              3
+#define CPCAP_BIT_AUDOHPF_0              2
+#define CPCAP_BIT_AUDIHPF_1              1
+#define CPCAP_BIT_AUDIHPF_0              0
+
+/* Register 514 CPCAP_REG_CDI    --- CODEC Digital Audio Interface */
+#define CPCAP_BIT_CDC_PLL_SEL             15
+#define CPCAP_BIT_CLK_IN_SEL              13
+#define CPCAP_BIT_DIG_AUD_IN              12
+#define CPCAP_BIT_CDC_CLK_EN              11
+#define CPCAP_BIT_CDC_DIG_AUD_FS1         10
+#define CPCAP_BIT_CDC_DIG_AUD_FS0         9
+#define CPCAP_BIT_MIC2_TIMESLOT2          8
+#define CPCAP_BIT_MIC2_TIMESLOT1          7
+#define CPCAP_BIT_MIC2_TIMESLOT0          6
+#define CPCAP_BIT_MIC1_RX_TIMESLOT2       5
+#define CPCAP_BIT_MIC1_RX_TIMESLOT1       4
+#define CPCAP_BIT_MIC1_RX_TIMESLOT0       3
+#define CPCAP_BIT_FS_INV                  2
+#define CPCAP_BIT_CLK_INV                 1
+#define CPCAP_BIT_SMB_CDC                 0
+
+/* Register 515 CPCAP_REG_SDAC   --- Stereo DAC */
+#define CPCAP_BIT_FSYNC_CLK_IN_COMMON     11
+#define CPCAP_BIT_SLAVE_PLL_CLK_INPUT     10
+#define CPCAP_BIT_ST_CLOCK_TREE_RESET     9
+#define CPCAP_BIT_DF_RESET_ST_DAC         8
+#define CPCAP_BIT_ST_SR3                  7
+#define CPCAP_BIT_ST_SR2                  6
+#define CPCAP_BIT_ST_SR1                  5
+#define CPCAP_BIT_ST_SR0                  4
+#define CPCAP_BIT_ST_DAC_CLK2             3
+#define CPCAP_BIT_ST_DAC_CLK1             2
+#define CPCAP_BIT_ST_DAC_CLK0             1
+#define CPCAP_BIT_ST_DAC_EN               0
+
+/* Register 516 CPCAP_REG_SDACDI --- Stereo DAC Digital Audio Interface */
+#define CPCAP_BIT_ST_L_TIMESLOT2          13
+#define CPCAP_BIT_ST_L_TIMESLOT1          12
+#define CPCAP_BIT_ST_L_TIMESLOT0          11
+#define CPCAP_BIT_ST_R_TIMESLOT2          10
+#define CPCAP_BIT_ST_R_TIMESLOT1          9
+#define CPCAP_BIT_ST_R_TIMESLOT0          8
+#define CPCAP_BIT_ST_DAC_CLK_IN_SEL       7
+#define CPCAP_BIT_ST_FS_INV               6
+#define CPCAP_BIT_ST_CLK_INV              5
+#define CPCAP_BIT_ST_DIG_AUD_FS1          4
+#define CPCAP_BIT_ST_DIG_AUD_FS0          3
+#define CPCAP_BIT_DIG_AUD_IN_ST_DAC       2
+#define CPCAP_BIT_ST_CLK_EN               1
+#define CPCAP_BIT_SMB_ST_DAC              0
+
+/* Register 517 CPCAP_REG_TXI    --- TX Interface */
+#define CPCAP_BIT_PTT_TH               15
+#define CPCAP_BIT_PTT_CMP_EN           14
+#define CPCAP_BIT_HS_ID_TX             13
+#define CPCAP_BIT_MB_ON2               12
+#define CPCAP_BIT_MB_ON1L              11
+#define CPCAP_BIT_MB_ON1R              10
+#define CPCAP_BIT_RX_L_ENCODE          9
+#define CPCAP_BIT_RX_R_ENCODE          8
+#define CPCAP_BIT_MIC2_MUX             7
+#define CPCAP_BIT_MIC2_PGA_EN          6
+#define CPCAP_BIT_CDET_DIS             5
+#define CPCAP_BIT_EMU_MIC_MUX          4
+#define CPCAP_BIT_HS_MIC_MUX           3
+#define CPCAP_BIT_MIC1_MUX             2
+#define CPCAP_BIT_MIC1_PGA_EN          1
+#define CPCAP_BIT_DLM                  0
+
+/* Register 518 CPCAP_REG_TXMP   --- Mic Gain */
+#define CPCAP_BIT_MB_BIAS_R1              11
+#define CPCAP_BIT_MB_BIAS_R0              10
+#define CPCAP_BIT_MIC2_GAIN_4             9
+#define CPCAP_BIT_MIC2_GAIN_3             8
+#define CPCAP_BIT_MIC2_GAIN_2             7
+#define CPCAP_BIT_MIC2_GAIN_1             6
+#define CPCAP_BIT_MIC2_GAIN_0             5
+#define CPCAP_BIT_MIC1_GAIN_4             4
+#define CPCAP_BIT_MIC1_GAIN_3             3
+#define CPCAP_BIT_MIC1_GAIN_2             2
+#define CPCAP_BIT_MIC1_GAIN_1             1
+#define CPCAP_BIT_MIC1_GAIN_0             0
+
+/* Register 519 CPCAP_REG_RXOA   --- RX Output Amplifier */
+#define CPCAP_BIT_UNUSED_519_15                15
+#define CPCAP_BIT_UNUSED_519_14                14
+#define CPCAP_BIT_UNUSED_519_13                13
+#define CPCAP_BIT_STDAC_LOW_PWR_DISABLE        12
+#define CPCAP_BIT_HS_LOW_PWR           11
+#define CPCAP_BIT_HS_ID_RX             10
+#define CPCAP_BIT_ST_HS_CP_EN          9
+#define CPCAP_BIT_EMU_SPKR_R_EN                8
+#define CPCAP_BIT_EMU_SPKR_L_EN                7
+#define CPCAP_BIT_HS_L_EN              6
+#define CPCAP_BIT_HS_R_EN              5
+#define CPCAP_BIT_A4_LINEOUT_L_EN      4
+#define CPCAP_BIT_A4_LINEOUT_R_EN      3
+#define CPCAP_BIT_A2_LDSP_L_EN         2
+#define CPCAP_BIT_A2_LDSP_R_EN         1
+#define CPCAP_BIT_A1_EAR_EN            0
+
+/* Register 520 CPCAP_REG_RXVC   --- RX Volume Control */
+#define CPCAP_BIT_VOL_EXT3                15
+#define CPCAP_BIT_VOL_EXT2                14
+#define CPCAP_BIT_VOL_EXT1                13
+#define CPCAP_BIT_VOL_EXT0                12
+#define CPCAP_BIT_VOL_DAC3                11
+#define CPCAP_BIT_VOL_DAC2                10
+#define CPCAP_BIT_VOL_DAC1                9
+#define CPCAP_BIT_VOL_DAC0                8
+#define CPCAP_BIT_VOL_DAC_LSB_1dB1        7
+#define CPCAP_BIT_VOL_DAC_LSB_1dB0        6
+#define CPCAP_BIT_VOL_CDC3                5
+#define CPCAP_BIT_VOL_CDC2                4
+#define CPCAP_BIT_VOL_CDC1                3
+#define CPCAP_BIT_VOL_CDC0                2
+#define CPCAP_BIT_VOL_CDC_LSB_1dB1        1
+#define CPCAP_BIT_VOL_CDC_LSB_1dB0        0
+
+/* Register 521 CPCAP_REG_RXCOA  --- Codec to Output Amp Switches */
+#define CPCAP_BIT_PGA_CDC_EN              10
+#define CPCAP_BIT_CDC_SW                  9
+#define CPCAP_BIT_PGA_OUTR_USBDP_CDC_SW   8
+#define CPCAP_BIT_PGA_OUTL_USBDN_CDC_SW   7
+#define CPCAP_BIT_ALEFT_HS_CDC_SW         6
+#define CPCAP_BIT_ARIGHT_HS_CDC_SW        5
+#define CPCAP_BIT_A4_LINEOUT_L_CDC_SW     4
+#define CPCAP_BIT_A4_LINEOUT_R_CDC_SW     3
+#define CPCAP_BIT_A2_LDSP_L_CDC_SW        2
+#define CPCAP_BIT_A2_LDSP_R_CDC_SW        1
+#define CPCAP_BIT_A1_EAR_CDC_SW           0
+
+/* Register 522 CPCAP_REG_RXSDOA --- RX Stereo DAC to Output Amp Switches */
+#define CPCAP_BIT_PGA_DAC_EN              12
+#define CPCAP_BIT_ST_DAC_SW               11
+#define CPCAP_BIT_MONO_DAC1               10
+#define CPCAP_BIT_MONO_DAC0               9
+#define CPCAP_BIT_PGA_OUTR_USBDP_DAC_SW   8
+#define CPCAP_BIT_PGA_OUTL_USBDN_DAC_SW   7
+#define CPCAP_BIT_ALEFT_HS_DAC_SW         6
+#define CPCAP_BIT_ARIGHT_HS_DAC_SW        5
+#define CPCAP_BIT_A4_LINEOUT_L_DAC_SW     4
+#define CPCAP_BIT_A4_LINEOUT_R_DAC_SW     3
+#define CPCAP_BIT_A2_LDSP_L_DAC_SW        2
+#define CPCAP_BIT_A2_LDSP_R_DAC_SW        1
+#define CPCAP_BIT_A1_EAR_DAC_SW           0
+
+/* Register 523 CPCAP_REG_RXEPOA --- RX External PGA to Output Amp Switches */
+#define CPCAP_BIT_PGA_EXT_L_EN            14
+#define CPCAP_BIT_PGA_EXT_R_EN            13
+#define CPCAP_BIT_PGA_IN_L_SW             12
+#define CPCAP_BIT_PGA_IN_R_SW             11
+#define CPCAP_BIT_MONO_EXT1               10
+#define CPCAP_BIT_MONO_EXT0               9
+#define CPCAP_BIT_PGA_OUTR_USBDP_EXT_SW   8
+#define CPCAP_BIT_PGA_OUTL_USBDN_EXT_SW   7
+#define CPCAP_BIT_ALEFT_HS_EXT_SW         6
+#define CPCAP_BIT_ARIGHT_HS_EXT_SW        5
+#define CPCAP_BIT_A4_LINEOUT_L_EXT_SW     4
+#define CPCAP_BIT_A4_LINEOUT_R_EXT_SW     3
+#define CPCAP_BIT_A2_LDSP_L_EXT_SW        2
+#define CPCAP_BIT_A2_LDSP_R_EXT_SW        1
+#define CPCAP_BIT_A1_EAR_EXT_SW           0
+
+/* Register 525 CPCAP_REG_A2LA --- SPK Amplifier and Clock Config for Headset */
+#define CPCAP_BIT_NCP_CLK_SYNC            7
+#define CPCAP_BIT_A2_CLK_SYNC             6
+#define CPCAP_BIT_A2_FREE_RUN             5
+#define CPCAP_BIT_A2_CLK2                 4
+#define CPCAP_BIT_A2_CLK1                 3
+#define CPCAP_BIT_A2_CLK0                 2
+#define CPCAP_BIT_A2_CLK_IN               1
+#define CPCAP_BIT_A2_CONFIG               0
+
+#define SLEEP_ACTIVATE_POWER 2
+#define CLOCK_TREE_RESET_TIME 1
+
+/* constants for ST delay workaround */
+#define STM_STDAC_ACTIVATE_RAMP_TIME   1
+#define STM_STDAC_EN_TEST_PRE          0x090C
+#define STM_STDAC_EN_TEST_POST         0x0000
+#define STM_STDAC_EN_ST_TEST1_PRE      0x2400
+#define STM_STDAC_EN_ST_TEST1_POST     0x0400
+
+struct cpcap_reg_info {
+       u16 reg;
+       u16 mask;
+       u16 val;
+};
+
+static const struct cpcap_reg_info cpcap_default_regs[] = {
+       { CPCAP_REG_CC, 0xFFFF, 0x0000 },
+       { CPCAP_REG_CC, 0xFFFF, 0x0000 },
+       { CPCAP_REG_CDI, 0xBFFF, 0x0000 },
+       { CPCAP_REG_SDAC, 0x0FFF, 0x0000 },
+       { CPCAP_REG_SDACDI, 0x3FFF, 0x0000 },
+       { CPCAP_REG_TXI, 0x0FDF, 0x0000 },
+       { CPCAP_REG_TXMP, 0x0FFF, 0x0400 },
+       { CPCAP_REG_RXOA, 0x01FF, 0x0000 },
+       { CPCAP_REG_RXVC, 0xFF3C, 0x0000 },
+       { CPCAP_REG_RXCOA, 0x07FF, 0x0000 },
+       { CPCAP_REG_RXSDOA, 0x1FFF, 0x0000 },
+       { CPCAP_REG_RXEPOA, 0x7FFF, 0x0000 },
+       { CPCAP_REG_A2LA, BIT(CPCAP_BIT_A2_FREE_RUN),
+         BIT(CPCAP_BIT_A2_FREE_RUN) },
+};
+
+enum cpcap_dai {
+       CPCAP_DAI_HIFI,
+       CPCAP_DAI_VOICE,
+};
+
+struct cpcap_audio {
+       struct snd_soc_component *component;
+       struct regmap *regmap;
+
+       u16 vendor;
+
+       int codec_clk_id;
+       int codec_freq;
+       int codec_format;
+};
+
+static int cpcap_st_workaround(struct snd_soc_dapm_widget *w,
+                              struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       int err = 0;
+
+       /* Only CPCAP from ST requires workaround */
+       if (cpcap->vendor != CPCAP_VENDOR_ST)
+               return 0;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
+                                  STM_STDAC_EN_TEST_PRE);
+               if (err)
+                       return err;
+               err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
+                                  STM_STDAC_EN_ST_TEST1_PRE);
+               break;
+       case SND_SOC_DAPM_POST_PMU:
+               msleep(STM_STDAC_ACTIVATE_RAMP_TIME);
+
+               err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
+                                  STM_STDAC_EN_ST_TEST1_POST);
+               if (err)
+                       return err;
+               err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
+                                  STM_STDAC_EN_TEST_POST);
+               break;
+       default:
+               break;
+       }
+
+       return err;
+}
+
+/* Capture Gain Control: 0dB to 31dB in 1dB steps */
+static const DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
+
+/* Playback Gain Control: -33dB to 12dB in 3dB steps */
+static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
+
+static const struct snd_kcontrol_new cpcap_snd_controls[] = {
+       /* Playback Gain */
+       SOC_SINGLE_TLV("HiFi Playback Volume",
+               CPCAP_REG_RXVC, CPCAP_BIT_VOL_DAC0, 0xF, 0, vol_tlv),
+       SOC_SINGLE_TLV("Voice Playback Volume",
+               CPCAP_REG_RXVC, CPCAP_BIT_VOL_CDC0, 0xF, 0, vol_tlv),
+       SOC_SINGLE_TLV("Ext Playback Volume",
+               CPCAP_REG_RXVC, CPCAP_BIT_VOL_EXT0, 0xF, 0, vol_tlv),
+
+       /* Capture Gain */
+       SOC_SINGLE_TLV("Mic1 Capture Volume",
+               CPCAP_REG_TXMP, CPCAP_BIT_MIC1_GAIN_0, 0x1F, 0, mic_gain_tlv),
+       SOC_SINGLE_TLV("Mic2 Capture Volume",
+               CPCAP_REG_TXMP, CPCAP_BIT_MIC2_GAIN_0, 0x1F, 0, mic_gain_tlv),
+
+       /* Phase Invert */
+       SOC_SINGLE("Hifi Left Phase Invert Switch",
+               CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC0, 1, 0),
+       SOC_SINGLE("Ext Left Phase Invert Switch",
+               CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
+};
+
+static const char * const cpcap_out_mux_texts[] = {
+       "Off", "Voice", "HiFi", "Ext"
+};
+
+static const char * const cpcap_in_right_mux_texts[] = {
+       "Off", "Mic 1", "Headset Mic", "EMU Mic", "Ext Right"
+};
+
+static const char * const cpcap_in_left_mux_texts[] = {
+       "Off", "Mic 2", "Ext Left"
+};
+
+/*
+ * input muxes use unusual register layout, so that we need to use custom
+ * getter/setter methods
+ */
+static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_left_mux_enum,
+                               cpcap_in_left_mux_texts);
+static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_right_mux_enum,
+                               cpcap_in_right_mux_texts);
+
+/*
+ * mux uses same bit in CPCAP_REG_RXCOA, CPCAP_REG_RXSDOA & CPCAP_REG_RXEPOA;
+ * even though the register layout makes it look like a mixer, this is a mux.
+ * Enabling multiple inputs will result in no audio being forwarded.
+ */
+static SOC_ENUM_SINGLE_DECL(cpcap_earpiece_mux_enum, 0, 0, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_spkr_r_mux_enum, 0, 1, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_spkr_l_mux_enum, 0, 2, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_line_r_mux_enum, 0, 3, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_line_l_mux_enum, 0, 4, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_hs_r_mux_enum, 0, 5, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_hs_l_mux_enum, 0, 6, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_emu_l_mux_enum, 0, 7, cpcap_out_mux_texts);
+static SOC_ENUM_SINGLE_DECL(cpcap_emu_r_mux_enum, 0, 8, cpcap_out_mux_texts);
+
+static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       unsigned int shift = e->shift_l;
+       int reg_voice, reg_hifi, reg_ext, status;
+       int err;
+
+       err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, &reg_voice);
+       if (err)
+               return err;
+       err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, &reg_hifi);
+       if (err)
+               return err;
+       err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, &reg_ext);
+       if (err)
+               return err;
+
+       reg_voice = (reg_voice >> shift) & 1;
+       reg_hifi = (reg_hifi >> shift) & 1;
+       reg_ext = (reg_ext >> shift) & 1;
+       status = reg_ext << 2 | reg_hifi << 1 | reg_voice;
+
+       switch (status) {
+       case 0x04:
+               ucontrol->value.enumerated.item[0] = 3;
+               break;
+       case 0x02:
+               ucontrol->value.enumerated.item[0] = 2;
+               break;
+       case 0x01:
+               ucontrol->value.enumerated.item[0] = 1;
+               break;
+       default:
+               ucontrol->value.enumerated.item[0] = 0;
+               break;
+       }
+
+       return 0;
+}
+
+static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm =
+               snd_soc_dapm_kcontrol_dapm(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       unsigned int muxval = ucontrol->value.enumerated.item[0];
+       unsigned int mask = BIT(e->shift_l);
+       u16 reg_voice = 0x00, reg_hifi = 0x00, reg_ext = 0x00;
+       int err;
+
+       switch (muxval) {
+       case 1:
+               reg_voice = mask;
+               break;
+       case 2:
+               reg_hifi = mask;
+               break;
+       case 3:
+               reg_ext = mask;
+               break;
+       default:
+               break;
+       }
+
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
+                                mask, reg_voice);
+       if (err)
+               return err;
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA,
+                                mask, reg_hifi);
+       if (err)
+               return err;
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA,
+                                mask, reg_ext);
+       if (err)
+               return err;
+
+       snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
+
+       return 0;
+}
+
+static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       int regval, mask;
+       int err;
+
+       err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval);
+       if (err)
+               return err;
+
+       mask = 0;
+       mask |= BIT(CPCAP_BIT_MIC1_MUX);
+       mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
+       mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
+       mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
+
+       switch (regval & mask) {
+       case BIT(CPCAP_BIT_RX_R_ENCODE):
+               ucontrol->value.enumerated.item[0] = 4;
+               break;
+       case BIT(CPCAP_BIT_EMU_MIC_MUX):
+               ucontrol->value.enumerated.item[0] = 3;
+               break;
+       case BIT(CPCAP_BIT_HS_MIC_MUX):
+               ucontrol->value.enumerated.item[0] = 2;
+               break;
+       case BIT(CPCAP_BIT_MIC1_MUX):
+               ucontrol->value.enumerated.item[0] = 1;
+               break;
+       default:
+               ucontrol->value.enumerated.item[0] = 0;
+               break;
+       }
+
+       return 0;
+}
+
+static int cpcap_input_right_mux_put_enum(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm =
+               snd_soc_dapm_kcontrol_dapm(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       unsigned int muxval = ucontrol->value.enumerated.item[0];
+       int regval = 0, mask;
+       int err;
+
+       mask = 0;
+       mask |= BIT(CPCAP_BIT_MIC1_MUX);
+       mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
+       mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
+       mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
+
+       switch (muxval) {
+       case 1:
+               regval = BIT(CPCAP_BIT_MIC1_MUX);
+               break;
+       case 2:
+               regval = BIT(CPCAP_BIT_HS_MIC_MUX);
+               break;
+       case 3:
+               regval = BIT(CPCAP_BIT_EMU_MIC_MUX);
+               break;
+       case 4:
+               regval = BIT(CPCAP_BIT_RX_R_ENCODE);
+               break;
+       default:
+               break;
+       }
+
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
+                                mask, regval);
+       if (err)
+               return err;
+
+       snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
+
+       return 0;
+}
+
+static int cpcap_input_left_mux_get_enum(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       int regval, mask;
+       int err;
+
+       err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval);
+       if (err)
+               return err;
+
+       mask = 0;
+       mask |= BIT(CPCAP_BIT_MIC2_MUX);
+       mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
+
+       switch (regval & mask) {
+       case BIT(CPCAP_BIT_RX_L_ENCODE):
+               ucontrol->value.enumerated.item[0] = 2;
+               break;
+       case BIT(CPCAP_BIT_MIC2_MUX):
+               ucontrol->value.enumerated.item[0] = 1;
+               break;
+       default:
+               ucontrol->value.enumerated.item[0] = 0;
+               break;
+       }
+
+       return 0;
+}
+
+static int cpcap_input_left_mux_put_enum(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm =
+               snd_soc_dapm_kcontrol_dapm(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       unsigned int muxval = ucontrol->value.enumerated.item[0];
+       int regval = 0, mask;
+       int err;
+
+       mask = 0;
+       mask |= BIT(CPCAP_BIT_MIC2_MUX);
+       mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
+
+       switch (muxval) {
+       case 1:
+               regval = BIT(CPCAP_BIT_MIC2_MUX);
+               break;
+       case 2:
+               regval = BIT(CPCAP_BIT_RX_L_ENCODE);
+               break;
+       default:
+               break;
+       }
+
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
+                                mask, regval);
+       if (err)
+               return err;
+
+       snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
+
+       return 0;
+}
+
+static const struct snd_kcontrol_new cpcap_input_left_mux =
+       SOC_DAPM_ENUM_EXT("Input Left", cpcap_input_left_mux_enum,
+                         cpcap_input_left_mux_get_enum,
+                         cpcap_input_left_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_input_right_mux =
+       SOC_DAPM_ENUM_EXT("Input Right", cpcap_input_right_mux_enum,
+                         cpcap_input_right_mux_get_enum,
+                         cpcap_input_right_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_emu_left_mux =
+       SOC_DAPM_ENUM_EXT("EMU Left", cpcap_emu_l_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_emu_right_mux =
+       SOC_DAPM_ENUM_EXT("EMU Right", cpcap_emu_r_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_hs_left_mux =
+       SOC_DAPM_ENUM_EXT("Headset Left", cpcap_hs_l_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_hs_right_mux =
+       SOC_DAPM_ENUM_EXT("Headset Right", cpcap_hs_r_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_line_left_mux =
+       SOC_DAPM_ENUM_EXT("Line Left", cpcap_line_l_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_line_right_mux =
+       SOC_DAPM_ENUM_EXT("Line Right", cpcap_line_r_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_speaker_left_mux =
+       SOC_DAPM_ENUM_EXT("Speaker Left", cpcap_spkr_l_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_speaker_right_mux =
+       SOC_DAPM_ENUM_EXT("Speaker Right", cpcap_spkr_r_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+static const struct snd_kcontrol_new cpcap_earpiece_mux =
+       SOC_DAPM_ENUM_EXT("Earpiece", cpcap_earpiece_mux_enum,
+                         cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
+
+static const struct snd_kcontrol_new cpcap_hifi_mono_mixer_controls[] = {
+       SOC_DAPM_SINGLE("HiFi Mono Playback Switch",
+               CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC1, 1, 0),
+};
+static const struct snd_kcontrol_new cpcap_ext_mono_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Ext Mono Playback Switch",
+               CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
+};
+
+static const struct snd_kcontrol_new cpcap_extr_mute_control =
+       SOC_DAPM_SINGLE("Switch",
+               CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_R_SW, 1, 0);
+static const struct snd_kcontrol_new cpcap_extl_mute_control =
+       SOC_DAPM_SINGLE("Switch",
+               CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_L_SW, 1, 0);
+
+static const struct snd_kcontrol_new cpcap_voice_loopback =
+       SOC_DAPM_SINGLE("Switch",
+               CPCAP_REG_TXI, CPCAP_BIT_DLM, 1, 0);
+
+static const struct snd_soc_dapm_widget cpcap_dapm_widgets[] = {
+       /* DAIs */
+       SND_SOC_DAPM_AIF_IN("HiFi RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_IN("Voice RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("Voice TX", NULL, 0, SND_SOC_NOPM, 0, 0),
+
+       /* Power Supply */
+       SND_SOC_DAPM_REGULATOR_SUPPLY("VAUDIO", SLEEP_ACTIVATE_POWER, 0),
+
+       /* Highpass Filters */
+       SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter RX",
+               CPCAP_REG_CC, CPCAP_BIT_AUDIHPF_0, 0x3, 0x3, 0x0),
+       SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter TX",
+               CPCAP_REG_CC, CPCAP_BIT_AUDOHPF_0, 0x3, 0x3, 0x0),
+
+       /* Clocks */
+       SND_SOC_DAPM_SUPPLY("HiFi DAI Clock",
+               CPCAP_REG_SDACDI, CPCAP_BIT_ST_CLK_EN, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Voice DAI Clock",
+               CPCAP_REG_CDI, CPCAP_BIT_CDC_CLK_EN, 0, NULL, 0),
+
+       /* Microphone Bias */
+       SND_SOC_DAPM_SUPPLY("MIC1R Bias",
+               CPCAP_REG_TXI, CPCAP_BIT_MB_ON1R, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("MIC1L Bias",
+               CPCAP_REG_TXI, CPCAP_BIT_MB_ON1L, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("MIC2 Bias",
+               CPCAP_REG_TXI, CPCAP_BIT_MB_ON2, 0, NULL, 0),
+
+       /* Inputs */
+       SND_SOC_DAPM_INPUT("MICR"),
+       SND_SOC_DAPM_INPUT("HSMIC"),
+       SND_SOC_DAPM_INPUT("EMUMIC"),
+       SND_SOC_DAPM_INPUT("MICL"),
+       SND_SOC_DAPM_INPUT("EXTR"),
+       SND_SOC_DAPM_INPUT("EXTL"),
+
+       /* Capture Route */
+       SND_SOC_DAPM_MUX("Right Capture Route",
+               SND_SOC_NOPM, 0, 0, &cpcap_input_right_mux),
+       SND_SOC_DAPM_MUX("Left Capture Route",
+               SND_SOC_NOPM, 0, 0, &cpcap_input_left_mux),
+
+       /* Capture PGAs */
+       SND_SOC_DAPM_PGA("Microphone 1 PGA",
+               CPCAP_REG_TXI, CPCAP_BIT_MIC1_PGA_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Microphone 2 PGA",
+               CPCAP_REG_TXI, CPCAP_BIT_MIC2_PGA_EN, 0, NULL, 0),
+
+       /* ADC */
+       SND_SOC_DAPM_ADC("ADC Right", NULL,
+               CPCAP_REG_CC, CPCAP_BIT_MIC1_CDC_EN, 0),
+       SND_SOC_DAPM_ADC("ADC Left", NULL,
+               CPCAP_REG_CC, CPCAP_BIT_MIC2_CDC_EN, 0),
+
+       /* DAC */
+       SND_SOC_DAPM_DAC_E("DAC HiFi", NULL,
+               CPCAP_REG_SDAC, CPCAP_BIT_ST_DAC_EN, 0,
+               cpcap_st_workaround,
+               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+       SND_SOC_DAPM_DAC_E("DAC Voice", NULL,
+               CPCAP_REG_CC, CPCAP_BIT_CDC_EN_RX, 0,
+               cpcap_st_workaround,
+               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+       /* Playback PGA */
+       SND_SOC_DAPM_PGA("HiFi PGA",
+               CPCAP_REG_RXSDOA, CPCAP_BIT_PGA_DAC_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Voice PGA",
+               CPCAP_REG_RXCOA, CPCAP_BIT_PGA_CDC_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA_E("Ext Right PGA",
+               CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_R_EN, 0,
+               NULL, 0,
+               cpcap_st_workaround,
+               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+       SND_SOC_DAPM_PGA_E("Ext Left PGA",
+               CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_L_EN, 0,
+               NULL, 0,
+               cpcap_st_workaround,
+               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
+
+       /* Playback Switch */
+       SND_SOC_DAPM_SWITCH("Ext Right Enable", SND_SOC_NOPM, 0, 0,
+               &cpcap_extr_mute_control),
+       SND_SOC_DAPM_SWITCH("Ext Left Enable", SND_SOC_NOPM, 0, 0,
+               &cpcap_extl_mute_control),
+
+       /* Loopback Switch */
+       SND_SOC_DAPM_SWITCH("Voice Loopback", SND_SOC_NOPM, 0, 0,
+               &cpcap_voice_loopback),
+
+       /* Mono Mixer */
+       SOC_MIXER_ARRAY("HiFi Mono Left Mixer", SND_SOC_NOPM, 0, 0,
+               cpcap_hifi_mono_mixer_controls),
+       SOC_MIXER_ARRAY("HiFi Mono Right Mixer", SND_SOC_NOPM, 0, 0,
+               cpcap_hifi_mono_mixer_controls),
+       SOC_MIXER_ARRAY("Ext Mono Left Mixer", SND_SOC_NOPM, 0, 0,
+               cpcap_ext_mono_mixer_controls),
+       SOC_MIXER_ARRAY("Ext Mono Right Mixer", SND_SOC_NOPM, 0, 0,
+               cpcap_ext_mono_mixer_controls),
+
+       /* Output Routes */
+       SND_SOC_DAPM_MUX("Earpiece Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_earpiece_mux),
+       SND_SOC_DAPM_MUX("Speaker Right Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_speaker_right_mux),
+       SND_SOC_DAPM_MUX("Speaker Left Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_speaker_left_mux),
+       SND_SOC_DAPM_MUX("Lineout Right Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_line_right_mux),
+       SND_SOC_DAPM_MUX("Lineout Left Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_line_left_mux),
+       SND_SOC_DAPM_MUX("Headset Right Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_hs_right_mux),
+       SND_SOC_DAPM_MUX("Headset Left Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_hs_left_mux),
+       SND_SOC_DAPM_MUX("EMU Right Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_emu_right_mux),
+       SND_SOC_DAPM_MUX("EMU Left Playback Route", SND_SOC_NOPM, 0, 0,
+               &cpcap_emu_left_mux),
+
+       /* Output Amplifier */
+       SND_SOC_DAPM_PGA("Earpiece PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_A1_EAR_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Speaker Right PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_R_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Speaker Left PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_L_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Lineout Right PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_R_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Lineout Left PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_L_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Headset Right PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_HS_R_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Headset Left PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_HS_L_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("EMU Right PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_R_EN, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("EMU Left PGA",
+               CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_L_EN, 0, NULL, 0),
+
+       /* Headet Charge Pump */
+       SND_SOC_DAPM_SUPPLY("Headset Charge Pump",
+               CPCAP_REG_RXOA, CPCAP_BIT_ST_HS_CP_EN, 0, NULL, 0),
+
+       /* Outputs */
+       SND_SOC_DAPM_OUTPUT("EP"),
+       SND_SOC_DAPM_OUTPUT("SPKR"),
+       SND_SOC_DAPM_OUTPUT("SPKL"),
+       SND_SOC_DAPM_OUTPUT("LINER"),
+       SND_SOC_DAPM_OUTPUT("LINEL"),
+       SND_SOC_DAPM_OUTPUT("HSR"),
+       SND_SOC_DAPM_OUTPUT("HSL"),
+       SND_SOC_DAPM_OUTPUT("EMUR"),
+       SND_SOC_DAPM_OUTPUT("EMUL"),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+       /* Power Supply */
+       {"HiFi PGA", NULL, "VAUDIO"},
+       {"Voice PGA", NULL, "VAUDIO"},
+       {"Ext Right PGA", NULL, "VAUDIO"},
+       {"Ext Left PGA", NULL, "VAUDIO"},
+       {"Microphone 1 PGA", NULL, "VAUDIO"},
+       {"Microphone 2 PGA", NULL, "VAUDIO"},
+
+       /* Stream -> AIF */
+       {"HiFi RX", NULL, "HiFi Playback"},
+       {"Voice RX", NULL, "Voice Playback"},
+       {"Voice Capture", NULL, "Voice TX"},
+
+       /* AIF clocks */
+       {"HiFi RX", NULL, "HiFi DAI Clock"},
+       {"Voice RX", NULL, "Voice DAI Clock"},
+       {"Voice TX", NULL, "Voice DAI Clock"},
+
+       /* Digital Loopback */
+       {"Voice Loopback", "Switch", "Voice TX"},
+       {"Voice RX", NULL, "Voice Loopback"},
+
+       /* Highpass Filters */
+       {"Highpass Filter RX", NULL, "Voice RX"},
+       {"Voice TX", NULL, "Highpass Filter TX"},
+
+       /* AIF -> DAC mapping */
+       {"DAC HiFi", NULL, "HiFi RX"},
+       {"DAC Voice", NULL, "Highpass Filter RX"},
+
+       /* DAC -> PGA */
+       {"HiFi PGA", NULL, "DAC HiFi"},
+       {"Voice PGA", NULL, "DAC Voice"},
+
+       /* Ext Input -> PGA */
+       {"Ext Right PGA", NULL, "EXTR"},
+       {"Ext Left PGA", NULL, "EXTL"},
+
+       /* Ext PGA -> Ext Playback Switch */
+       {"Ext Right Enable", "Switch", "Ext Right PGA"},
+       {"Ext Left Enable", "Switch", "Ext Left PGA"},
+
+       /* HiFi PGA -> Mono Mixer */
+       {"HiFi Mono Left Mixer", NULL, "HiFi PGA"},
+       {"HiFi Mono Left Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
+       {"HiFi Mono Right Mixer", NULL, "HiFi PGA"},
+       {"HiFi Mono Right Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
+
+       /* Ext Playback Switch -> Ext Mono Mixer */
+       {"Ext Mono Right Mixer", NULL, "Ext Right Enable"},
+       {"Ext Mono Right Mixer", "Ext Mono Playback Switch", "Ext Left Enable"},
+       {"Ext Mono Left Mixer", NULL, "Ext Left Enable"},
+       {"Ext Mono Left Mixer", "Ext Mono Playback Switch", "Ext Right Enable"},
+
+       /* HiFi Mono Mixer -> Output Route */
+       {"Earpiece Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+       {"Speaker Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+       {"Speaker Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+       {"Lineout Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+       {"Lineout Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+       {"Headset Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+       {"Headset Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+       {"EMU Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
+       {"EMU Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
+
+       /* Voice PGA -> Output Route */
+       {"Earpiece Playback Route", "Voice", "Voice PGA"},
+       {"Speaker Right Playback Route", "Voice", "Voice PGA"},
+       {"Speaker Left Playback Route", "Voice", "Voice PGA"},
+       {"Lineout Right Playback Route", "Voice", "Voice PGA"},
+       {"Lineout Left Playback Route", "Voice", "Voice PGA"},
+       {"Headset Right Playback Route", "Voice", "Voice PGA"},
+       {"Headset Left Playback Route", "Voice", "Voice PGA"},
+       {"EMU Right Playback Route", "Voice", "Voice PGA"},
+       {"EMU Left Playback Route", "Voice", "Voice PGA"},
+
+       /* Ext Mono Mixer -> Output Route */
+       {"Earpiece Playback Route", "Ext", "Ext Mono Right Mixer"},
+       {"Speaker Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+       {"Speaker Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+       {"Lineout Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+       {"Lineout Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+       {"Headset Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+       {"Headset Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+       {"EMU Right Playback Route", "Ext", "Ext Mono Right Mixer"},
+       {"EMU Left Playback Route", "Ext", "Ext Mono Left Mixer"},
+
+       /* Output Route -> Output Amplifier */
+       {"Earpiece PGA", NULL, "Earpiece Playback Route"},
+       {"Speaker Right PGA", NULL, "Speaker Right Playback Route"},
+       {"Speaker Left PGA", NULL, "Speaker Left Playback Route"},
+       {"Lineout Right PGA", NULL, "Lineout Right Playback Route"},
+       {"Lineout Left PGA", NULL, "Lineout Left Playback Route"},
+       {"Headset Right PGA", NULL, "Headset Right Playback Route"},
+       {"Headset Left PGA", NULL, "Headset Left Playback Route"},
+       {"EMU Right PGA", NULL, "EMU Right Playback Route"},
+       {"EMU Left PGA", NULL, "EMU Left Playback Route"},
+
+       /* Output Amplifier -> Output */
+       {"EP", NULL, "Earpiece PGA"},
+       {"SPKR", NULL, "Speaker Right PGA"},
+       {"SPKL", NULL, "Speaker Left PGA"},
+       {"LINER", NULL, "Lineout Right PGA"},
+       {"LINEL", NULL, "Lineout Left PGA"},
+       {"HSR", NULL, "Headset Right PGA"},
+       {"HSL", NULL, "Headset Left PGA"},
+       {"EMUR", NULL, "EMU Right PGA"},
+       {"EMUL", NULL, "EMU Left PGA"},
+
+       /* Headset Charge Pump -> Headset */
+       {"HSR", NULL, "Headset Charge Pump"},
+       {"HSL", NULL, "Headset Charge Pump"},
+
+       /* Mic -> Mic Route */
+       {"Right Capture Route", "Mic 1", "MICR"},
+       {"Right Capture Route", "Headset Mic", "HSMIC"},
+       {"Right Capture Route", "EMU Mic", "EMUMIC"},
+       {"Right Capture Route", "Ext Right", "EXTR"},
+       {"Left Capture Route", "Mic 2", "MICL"},
+       {"Left Capture Route", "Ext Left", "EXTL"},
+
+       /* Input Route -> Microphone PGA */
+       {"Microphone 1 PGA", NULL, "Right Capture Route"},
+       {"Microphone 2 PGA", NULL, "Left Capture Route"},
+
+       /* Microphone PGA -> ADC */
+       {"ADC Right", NULL, "Microphone 1 PGA"},
+       {"ADC Left", NULL, "Microphone 2 PGA"},
+
+       /* ADC -> Stream */
+       {"Highpass Filter TX", NULL, "ADC Right"},
+       {"Highpass Filter TX", NULL, "ADC Left"},
+
+       /* Mic Bias */
+       {"MICL", NULL, "MIC1L Bias"},
+       {"MICR", NULL, "MIC1R Bias"},
+};
+
+static int cpcap_set_sysclk(struct cpcap_audio *cpcap, enum cpcap_dai dai,
+                           int clk_id, int freq)
+{
+       u16 clkfreqreg, clkfreqshift;
+       u16 clkfreqmask, clkfreqval;
+       u16 clkidreg, clkidshift;
+       u16 mask, val;
+       int err;
+
+       switch (dai) {
+       case CPCAP_DAI_HIFI:
+               clkfreqreg = CPCAP_REG_SDAC;
+               clkfreqshift = CPCAP_BIT_ST_DAC_CLK0;
+               clkidreg = CPCAP_REG_SDACDI;
+               clkidshift = CPCAP_BIT_ST_DAC_CLK_IN_SEL;
+               break;
+       case CPCAP_DAI_VOICE:
+               clkfreqreg = CPCAP_REG_CC;
+               clkfreqshift = CPCAP_BIT_CDC_CLK0;
+               clkidreg = CPCAP_REG_CDI;
+               clkidshift = CPCAP_BIT_CLK_IN_SEL;
+               break;
+       default:
+               dev_err(cpcap->component->dev, "invalid DAI: %d", dai);
+               return -EINVAL;
+       }
+
+       /* setup clk id */
+       if (clk_id < 0 || clk_id > 1) {
+               dev_err(cpcap->component->dev, "invalid clk id %d", clk_id);
+               return -EINVAL;
+       }
+       err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift),
+                                clk_id ? BIT(clkidshift) : 0);
+       if (err)
+               return err;
+
+       /* enable PLL for Voice DAI */
+       if (dai == CPCAP_DAI_VOICE) {
+               mask = BIT(CPCAP_BIT_CDC_PLL_SEL);
+               val = BIT(CPCAP_BIT_CDC_PLL_SEL);
+               err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
+                                        mask, val);
+               if (err)
+                       return err;
+       }
+
+       /* setup frequency */
+       clkfreqmask = 0x7 << clkfreqshift;
+       switch (freq) {
+       case 15360000:
+               clkfreqval = 0x01 << clkfreqshift;
+               break;
+       case 16800000:
+               clkfreqval = 0x02 << clkfreqshift;
+               break;
+       case 19200000:
+               clkfreqval = 0x03 << clkfreqshift;
+               break;
+       case 26000000:
+               clkfreqval = 0x04 << clkfreqshift;
+               break;
+       case 33600000:
+               clkfreqval = 0x05 << clkfreqshift;
+               break;
+       case 38400000:
+               clkfreqval = 0x06 << clkfreqshift;
+               break;
+       default:
+               dev_err(cpcap->component->dev, "unsupported freq %u", freq);
+               return -EINVAL;
+       }
+
+       err = regmap_update_bits(cpcap->regmap, clkfreqreg,
+                                clkfreqmask, clkfreqval);
+       if (err)
+               return err;
+
+       if (dai == CPCAP_DAI_VOICE) {
+               cpcap->codec_clk_id = clk_id;
+               cpcap->codec_freq = freq;
+       }
+
+       return 0;
+}
+
+static int cpcap_set_samprate(struct cpcap_audio *cpcap, enum cpcap_dai dai,
+                             int samplerate)
+{
+       struct snd_soc_component *component = cpcap->component;
+       u16 sampreg, sampmask, sampshift, sampval, sampreset;
+       int err, sampreadval;
+
+       switch (dai) {
+       case CPCAP_DAI_HIFI:
+               sampreg = CPCAP_REG_SDAC;
+               sampshift = CPCAP_BIT_ST_SR0;
+               sampreset = BIT(CPCAP_BIT_DF_RESET_ST_DAC) |
+                           BIT(CPCAP_BIT_ST_CLOCK_TREE_RESET);
+               break;
+       case CPCAP_DAI_VOICE:
+               sampreg = CPCAP_REG_CC;
+               sampshift = CPCAP_BIT_CDC_SR0;
+               sampreset = BIT(CPCAP_BIT_DF_RESET) |
+                           BIT(CPCAP_BIT_CDC_CLOCK_TREE_RESET);
+               break;
+       default:
+               dev_err(component->dev, "invalid DAI: %d", dai);
+               return -EINVAL;
+       }
+
+       sampmask = 0xF << sampshift | sampreset;
+       switch (samplerate) {
+       case 48000:
+               sampval = 0x8 << sampshift;
+               break;
+       case 44100:
+               sampval = 0x7 << sampshift;
+               break;
+       case 32000:
+               sampval = 0x6 << sampshift;
+               break;
+       case 24000:
+               sampval = 0x5 << sampshift;
+               break;
+       case 22050:
+               sampval = 0x4 << sampshift;
+               break;
+       case 16000:
+               sampval = 0x3 << sampshift;
+               break;
+       case 12000:
+               sampval = 0x2 << sampshift;
+               break;
+       case 11025:
+               sampval = 0x1 << sampshift;
+               break;
+       case 8000:
+               sampval = 0x0 << sampshift;
+               break;
+       default:
+               dev_err(component->dev, "unsupported samplerate %d", samplerate);
+               return -EINVAL;
+       }
+       err = regmap_update_bits(cpcap->regmap, sampreg,
+                                sampmask, sampval | sampreset);
+       if (err)
+               return err;
+
+       /* Wait for clock tree reset to complete */
+       mdelay(CLOCK_TREE_RESET_TIME);
+
+       err = regmap_read(cpcap->regmap, sampreg, &sampreadval);
+       if (err)
+               return err;
+
+       if (sampreadval & sampreset) {
+               dev_err(component->dev, "reset self-clear failed: %04x",
+                       sampreadval);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int cpcap_hifi_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
+{
+       struct snd_soc_component *component = dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       int rate = params_rate(params);
+
+       dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate);
+       return cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, rate);
+}
+
+static int cpcap_hifi_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
+                                    unsigned int freq, int dir)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       struct device *dev = component->dev;
+
+       dev_dbg(dev, "HiFi setup sysclk: clk_id=%u, freq=%u", clk_id, freq);
+       return cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, clk_id, freq);
+}
+
+static int cpcap_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                                 unsigned int fmt)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       struct device *dev = component->dev;
+       static const u16 reg = CPCAP_REG_SDACDI;
+       static const u16 mask =
+               BIT(CPCAP_BIT_SMB_ST_DAC) |
+               BIT(CPCAP_BIT_ST_CLK_INV) |
+               BIT(CPCAP_BIT_ST_FS_INV) |
+               BIT(CPCAP_BIT_ST_DIG_AUD_FS0) |
+               BIT(CPCAP_BIT_ST_DIG_AUD_FS1) |
+               BIT(CPCAP_BIT_ST_L_TIMESLOT0) |
+               BIT(CPCAP_BIT_ST_L_TIMESLOT1) |
+               BIT(CPCAP_BIT_ST_L_TIMESLOT2) |
+               BIT(CPCAP_BIT_ST_R_TIMESLOT0) |
+               BIT(CPCAP_BIT_ST_R_TIMESLOT1) |
+               BIT(CPCAP_BIT_ST_R_TIMESLOT2);
+       u16 val = 0x0000;
+
+       dev_dbg(dev, "HiFi setup dai format (%08x)", fmt);
+
+       /*
+        * "HiFi Playback" should always be configured as
+        * SND_SOC_DAIFMT_CBM_CFM - codec clk & frm master
+        * SND_SOC_DAIFMT_I2S - I2S mode
+        */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               val &= ~BIT(CPCAP_BIT_SMB_ST_DAC);
+               break;
+       default:
+               dev_err(dev, "HiFi dai fmt failed: CPCAP should be master");
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_IB_IF:
+               val |= BIT(CPCAP_BIT_ST_FS_INV);
+               val |= BIT(CPCAP_BIT_ST_CLK_INV);
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               val &= ~BIT(CPCAP_BIT_ST_FS_INV);
+               val |= BIT(CPCAP_BIT_ST_CLK_INV);
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               val |= BIT(CPCAP_BIT_ST_FS_INV);
+               val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
+               break;
+       case SND_SOC_DAIFMT_NB_NF:
+               val &= ~BIT(CPCAP_BIT_ST_FS_INV);
+               val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
+               break;
+       default:
+               dev_err(dev, "HiFi dai fmt failed: unsupported clock invert mode");
+               return -EINVAL;
+       }
+
+       if (val & BIT(CPCAP_BIT_ST_CLK_INV))
+               val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
+       else
+               val |= BIT(CPCAP_BIT_ST_CLK_INV);
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
+               val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
+               break;
+       default:
+               /* 01 - 4 slots network mode */
+               val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
+               val &= ~BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
+               /* L on slot 1 */
+               val |= BIT(CPCAP_BIT_ST_L_TIMESLOT0);
+               break;
+       }
+
+       dev_dbg(dev, "HiFi dai format: val=%04x", val);
+       return regmap_update_bits(cpcap->regmap, reg, mask, val);
+}
+
+static int cpcap_hifi_set_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_component *component = dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       static const u16 reg = CPCAP_REG_RXSDOA;
+       static const u16 mask = BIT(CPCAP_BIT_ST_DAC_SW);
+       u16 val;
+
+       if (mute)
+               val = 0;
+       else
+               val = BIT(CPCAP_BIT_ST_DAC_SW);
+
+       dev_dbg(component->dev, "HiFi mute: %d", mute);
+       return regmap_update_bits(cpcap->regmap, reg, mask, val);
+}
+
+static const struct snd_soc_dai_ops cpcap_dai_hifi_ops = {
+       .hw_params      = cpcap_hifi_hw_params,
+       .set_sysclk     = cpcap_hifi_set_dai_sysclk,
+       .set_fmt        = cpcap_hifi_set_dai_fmt,
+       .digital_mute   = cpcap_hifi_set_mute,
+};
+
+static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
+{
+       struct snd_soc_component *component = dai->component;
+       struct device *dev = component->dev;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       static const u16 reg_cdi = CPCAP_REG_CDI;
+       int rate = params_rate(params);
+       int channels = params_channels(params);
+       int direction = substream->stream;
+       u16 val, mask;
+       int err;
+
+       dev_dbg(dev, "Voice setup HW params: rate=%d, direction=%d, chan=%d",
+               rate, direction, channels);
+
+       err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate);
+       if (err)
+               return err;
+
+       if (direction == SNDRV_PCM_STREAM_CAPTURE) {
+               mask = 0x0000;
+               mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0;
+               mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1;
+               mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2;
+               mask |= CPCAP_BIT_MIC2_TIMESLOT0;
+               mask |= CPCAP_BIT_MIC2_TIMESLOT1;
+               mask |= CPCAP_BIT_MIC2_TIMESLOT2;
+               val = 0x0000;
+               if (channels >= 2)
+                       val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
+               err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int cpcap_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
+                                     unsigned int freq, int dir)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+
+       dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u",
+               clk_id, freq);
+       return cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, clk_id, freq);
+}
+
+static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                                  unsigned int fmt)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       static const u16 mask = BIT(CPCAP_BIT_SMB_CDC) |
+                               BIT(CPCAP_BIT_CLK_INV) |
+                               BIT(CPCAP_BIT_FS_INV) |
+                               BIT(CPCAP_BIT_CDC_DIG_AUD_FS0) |
+                               BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
+       u16 val = 0x0000;
+       int err;
+
+       dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt);
+
+       /*
+        * "Voice Playback" and "Voice Capture" should always be
+        * configured as SND_SOC_DAIFMT_CBM_CFM - codec clk & frm
+        * master
+        */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               val &= ~BIT(CPCAP_BIT_SMB_CDC);
+               break;
+       default:
+               dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the master");
+               val &= ~BIT(CPCAP_BIT_SMB_CDC);
+               break;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_IB_IF:
+               val |= BIT(CPCAP_BIT_CLK_INV);
+               val |= BIT(CPCAP_BIT_FS_INV);
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               val |= BIT(CPCAP_BIT_CLK_INV);
+               val &= ~BIT(CPCAP_BIT_FS_INV);
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               val &= ~BIT(CPCAP_BIT_CLK_INV);
+               val |= BIT(CPCAP_BIT_FS_INV);
+               break;
+       case SND_SOC_DAIFMT_NB_NF:
+               val &= ~BIT(CPCAP_BIT_CLK_INV);
+               val &= ~BIT(CPCAP_BIT_FS_INV);
+               break;
+       default:
+               dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode");
+               break;
+       }
+
+       if (val & BIT(CPCAP_BIT_CLK_INV))
+               val &= ~BIT(CPCAP_BIT_CLK_INV);
+       else
+               val |= BIT(CPCAP_BIT_CLK_INV);
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               /* 11 - true I2S mode */
+               val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
+               val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
+               break;
+       default:
+               /* 4 timeslots network mode */
+               val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
+               val &= ~BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
+               break;
+       }
+
+       dev_dbg(component->dev, "Voice dai format: val=%04x", val);
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val);
+       if (err)
+               return err;
+
+       cpcap->codec_format = val;
+       return 0;
+}
+
+static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_component *component = dai->component;
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       static const u16 reg = CPCAP_REG_RXCOA;
+       static const u16 mask = BIT(CPCAP_BIT_CDC_SW);
+       u16 val;
+
+       if (mute)
+               val = 0;
+       else
+               val = BIT(CPCAP_BIT_CDC_SW);
+
+       dev_dbg(component->dev, "Voice mute: %d", mute);
+       return regmap_update_bits(cpcap->regmap, reg, mask, val);
+};
+
+static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
+       .hw_params      = cpcap_voice_hw_params,
+       .set_sysclk     = cpcap_voice_set_dai_sysclk,
+       .set_fmt        = cpcap_voice_set_dai_fmt,
+       .digital_mute   = cpcap_voice_set_mute,
+};
+
+static struct snd_soc_dai_driver cpcap_dai[] = {
+{
+       .id = 0,
+       .name = "cpcap-hifi",
+       .playback = {
+               .stream_name = "HiFi Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE,
+       },
+       .ops = &cpcap_dai_hifi_ops,
+},
+{
+       .id = 1,
+       .name = "cpcap-voice",
+       .playback = {
+               .stream_name = "Voice Playback",
+               .channels_min = 1,
+               .channels_max = 1,
+               .rates = SNDRV_PCM_RATE_8000_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .capture = {
+               .stream_name = "Voice Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_48000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .ops = &cpcap_dai_voice_ops,
+},
+};
+
+static int cpcap_dai_mux(struct cpcap_audio *cpcap, bool swap_dai_configuration)
+{
+       u16 hifi_val, voice_val;
+       u16 hifi_mask = BIT(CPCAP_BIT_DIG_AUD_IN_ST_DAC);
+       u16 voice_mask = BIT(CPCAP_BIT_DIG_AUD_IN);
+       int err;
+
+
+
+       if (!swap_dai_configuration) {
+               /* Codec on DAI0, HiFi on DAI1 */
+               voice_val = 0;
+               hifi_val = hifi_mask;
+       } else {
+               /* Codec on DAI1, HiFi on DAI0 */
+               voice_val = voice_mask;
+               hifi_val = 0;
+       }
+
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
+                                voice_mask, voice_val);
+       if (err)
+               return err;
+
+       err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI,
+                                hifi_mask, hifi_val);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int cpcap_audio_reset(struct snd_soc_component *component,
+                            bool swap_dai_configuration)
+{
+       struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
+       int i, err = 0;
+
+       dev_dbg(component->dev, "init audio codec");
+
+       for (i = 0; i < ARRAY_SIZE(cpcap_default_regs); i++) {
+               err = regmap_update_bits(cpcap->regmap,
+                                        cpcap_default_regs[i].reg,
+                                        cpcap_default_regs[i].mask,
+                                        cpcap_default_regs[i].val);
+               if (err)
+                       return err;
+       }
+
+       /* setup default settings */
+       err = cpcap_dai_mux(cpcap, swap_dai_configuration);
+       if (err)
+               return err;
+
+       err = cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, 0, 26000000);
+       if (err)
+               return err;
+       err = cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, 0, 26000000);
+       if (err)
+               return err;
+
+       err = cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, 48000);
+       if (err)
+               return err;
+
+       err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, 48000);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int cpcap_soc_probe(struct snd_soc_component *component)
+{
+       struct cpcap_audio *cpcap;
+       int err;
+
+       cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL);
+       if (!cpcap)
+               return -ENOMEM;
+       snd_soc_component_set_drvdata(component, cpcap);
+       cpcap->component = component;
+
+       cpcap->regmap = dev_get_regmap(component->dev->parent, NULL);
+       if (!cpcap->regmap)
+               return -ENODEV;
+       snd_soc_component_init_regmap(component, cpcap->regmap);
+
+       err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor);
+       if (err)
+               return err;
+
+       return cpcap_audio_reset(component, false);
+}
+
+static struct snd_soc_component_driver soc_codec_dev_cpcap = {
+       .probe                  = cpcap_soc_probe,
+       .controls               = cpcap_snd_controls,
+       .num_controls           = ARRAY_SIZE(cpcap_snd_controls),
+       .dapm_widgets           = cpcap_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cpcap_dapm_widgets),
+       .dapm_routes            = intercon,
+       .num_dapm_routes        = ARRAY_SIZE(intercon),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
+
+static int cpcap_codec_probe(struct platform_device *pdev)
+{
+       struct device_node *codec_node =
+               of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec");
+
+       pdev->dev.of_node = codec_node;
+
+       return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap,
+                                     cpcap_dai, ARRAY_SIZE(cpcap_dai));
+}
+
+static struct platform_driver cpcap_codec_driver = {
+       .probe          = cpcap_codec_probe,
+       .driver         = {
+               .name   = "cpcap-codec",
+       },
+};
+module_platform_driver(cpcap_codec_driver);
+
+MODULE_ALIAS("platform:cpcap-codec");
+MODULE_DESCRIPTION("ASoC CPCAP codec driver");
+MODULE_AUTHOR("Sebastian Reichel");
+MODULE_LICENSE("GPL v2");
index 3bf93652bb314ea2476b6511069b66f146ec90cc..3301861d35025ac5777c250638c17de851bdbed1 100644 (file)
@@ -45,7 +45,7 @@ static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
 
 static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 reg;
 
        if (mute)
@@ -53,7 +53,7 @@ static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
        else
                reg = 0;
 
-       snd_soc_update_bits(codec, DAVINCI_VC_REG09, DAVINCI_VC_REG09_MUTE,
+       snd_soc_component_update_bits(component, DAVINCI_VC_REG09, DAVINCI_VC_REG09_MUTE,
                            reg);
 
        return 0;
@@ -72,23 +72,23 @@ static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        return -EINVAL;
 }
 
-static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
+static int cq93vc_set_bias_level(struct snd_soc_component *component,
                                enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_write(codec, DAVINCI_VC_REG12,
+               snd_soc_component_write(component, DAVINCI_VC_REG12,
                             DAVINCI_VC_REG12_POWER_ALL_ON);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_write(codec, DAVINCI_VC_REG12,
+               snd_soc_component_write(component, DAVINCI_VC_REG12,
                             DAVINCI_VC_REG12_POWER_ALL_OFF);
                break;
        case SND_SOC_BIAS_OFF:
                /* force all power off */
-               snd_soc_write(codec, DAVINCI_VC_REG12,
+               snd_soc_component_write(component, DAVINCI_VC_REG12,
                             DAVINCI_VC_REG12_POWER_ALL_OFF);
                break;
        }
@@ -130,24 +130,25 @@ static int cq93vc_probe(struct snd_soc_component *component)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
-       .set_bias_level = cq93vc_set_bias_level,
-       .component_driver = {
-               .probe = cq93vc_probe,
-               .controls = cq93vc_snd_controls,
-               .num_controls = ARRAY_SIZE(cq93vc_snd_controls),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cq93vc = {
+       .set_bias_level         = cq93vc_set_bias_level,
+       .probe                  = cq93vc_probe,
+       .controls               = cq93vc_snd_controls,
+       .num_controls           = ARRAY_SIZE(cq93vc_snd_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int cq93vc_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_cq93vc, &cq93vc_dai, 1);
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_cq93vc, &cq93vc_dai, 1);
 }
 
 static int cq93vc_platform_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
index bc3a72e4c4ed73d4d7d674603c14334d6461596a..4297058b69381597bc950ff67690f5030e907324 100644 (file)
@@ -43,7 +43,7 @@ static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = {
 
 struct  cs35l32_private {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regulator_bulk_data supplies[CS35L32_NUM_SUPPLIES];
        struct cs35l32_platform_data pdata;
        struct gpio_desc *reset_gpio;
@@ -154,16 +154,16 @@ static const struct snd_soc_dapm_route cs35l32_audio_map[] = {
 
 static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               snd_soc_update_bits(codec, CS35L32_ADSP_CTL,
+               snd_soc_component_update_bits(component, CS35L32_ADSP_CTL,
                                    CS35L32_ADSP_MASTER_MASK,
                                CS35L32_ADSP_MASTER_MASK);
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               snd_soc_update_bits(codec, CS35L32_ADSP_CTL,
+               snd_soc_component_update_bits(component, CS35L32_ADSP_CTL,
                                    CS35L32_ADSP_MASTER_MASK, 0);
                break;
        default:
@@ -175,9 +175,9 @@ static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int cs35l32_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       return snd_soc_update_bits(codec, CS35L32_PWRCTL2,
+       return snd_soc_component_update_bits(component, CS35L32_PWRCTL2,
                                        CS35L32_SDOUT_3ST, tristate << 3);
 }
 
@@ -202,7 +202,7 @@ static struct snd_soc_dai_driver cs35l32_dai[] = {
        }
 };
 
-static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs35l32_component_set_sysclk(struct snd_soc_component *component,
                              int clk_id, int source, unsigned int freq, int dir)
 {
        unsigned int val;
@@ -224,21 +224,22 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       return snd_soc_update_bits(codec, CS35L32_CLK_CTL,
+       return snd_soc_component_update_bits(component, CS35L32_CLK_CTL,
                        CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
-       .set_sysclk = cs35l32_codec_set_sysclk,
-
-       .component_driver = {
-               .controls               = cs35l32_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs35l32_snd_controls),
-               .dapm_widgets           = cs35l32_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs35l32_dapm_widgets),
-               .dapm_routes            = cs35l32_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cs35l32_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs35l32 = {
+       .set_sysclk             = cs35l32_component_set_sysclk,
+       .controls               = cs35l32_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs35l32_snd_controls),
+       .dapm_widgets           = cs35l32_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs35l32_dapm_widgets),
+       .dapm_routes            = cs35l32_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs35l32_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /* Current and threshold powerup sequence Pg37 in datasheet */
@@ -483,8 +484,8 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
        /* Clear MCLK Error Bit since we don't have the clock yet */
        ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, &reg);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs35l32, cs35l32_dai,
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs35l32, cs35l32_dai,
                        ARRAY_SIZE(cs35l32_dai));
        if (ret < 0)
                goto err_disable;
@@ -501,8 +502,6 @@ static int cs35l32_i2c_remove(struct i2c_client *i2c_client)
 {
        struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client);
 
-       snd_soc_unregister_codec(&i2c_client->dev);
-
        /* Hold down reset */
        gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
 
index 854cf8f27605a87c97bc2e93a530bcd4a9ce5108..668cd3754209d944b2a908973032538069686df8 100644 (file)
@@ -42,7 +42,7 @@
 #define CS35L33_BOOT_DELAY     50
 
 struct cs35l33_private {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct cs35l33_pdata pdata;
        struct regmap *regmap;
        struct gpio_desc *reset_gpio;
@@ -201,8 +201,8 @@ static const struct snd_kcontrol_new cs35l33_snd_controls[] = {
 static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -211,15 +211,15 @@ static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
                        priv->amp_cal = true;
                        regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
                                    CS35L33_AMP_CAL, 0);
-                       dev_dbg(codec->dev, "Amp calibration done\n");
+                       dev_dbg(component->dev, "Amp calibration done\n");
                }
-               dev_dbg(codec->dev, "Amp turned on\n");
+               dev_dbg(component->dev, "Amp turned on\n");
                break;
        case SND_SOC_DAPM_POST_PMD:
-               dev_dbg(codec->dev, "Amp turned off\n");
+               dev_dbg(component->dev, "Amp turned off\n");
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
                break;
        }
 
@@ -229,8 +229,8 @@ static int cs35l33_spkrdrv_event(struct snd_soc_dapm_widget *w,
 static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        switch (event) {
@@ -240,14 +240,14 @@ static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
                val = priv->is_tdm_mode ? 0 : CS35L33_PDN_TDM;
                regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
                                    CS35L33_PDN_TDM, val);
-               dev_dbg(codec->dev, "BST turned on\n");
+               dev_dbg(component->dev, "BST turned on\n");
                break;
        case SND_SOC_DAPM_POST_PMU:
-               dev_dbg(codec->dev, "SDIN turned on\n");
+               dev_dbg(component->dev, "SDIN turned on\n");
                if (!priv->amp_cal) {
                        regmap_update_bits(priv->regmap, CS35L33_CLASSD_CTL,
                                    CS35L33_AMP_CAL, CS35L33_AMP_CAL);
-                       dev_dbg(codec->dev, "Amp calibration started\n");
+                       dev_dbg(component->dev, "Amp calibration started\n");
                        usleep_range(10000, 11000);
                }
                break;
@@ -257,10 +257,10 @@ static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
                usleep_range(4000, 4100);
                regmap_update_bits(priv->regmap, CS35L33_PWRCTL1,
                                    CS35L33_PDN_BST, CS35L33_PDN_BST);
-               dev_dbg(codec->dev, "BST and SDIN turned off\n");
+               dev_dbg(component->dev, "BST and SDIN turned off\n");
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
 
        }
 
@@ -270,8 +270,8 @@ static int cs35l33_sdin_event(struct snd_soc_dapm_widget *w,
 static int cs35l33_sdout_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
        unsigned int mask = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
        unsigned int mask2 = CS35L33_SDOUT_3ST_TDM;
        unsigned int val, val2;
@@ -289,15 +289,15 @@ static int cs35l33_sdout_event(struct snd_soc_dapm_widget *w,
                        /* set sdout_3st_tdm */
                        val2 = CS35L33_SDOUT_3ST_TDM;
                }
-               dev_dbg(codec->dev, "SDOUT turned on\n");
+               dev_dbg(component->dev, "SDOUT turned on\n");
                break;
        case SND_SOC_DAPM_PRE_PMD:
                val = CS35L33_SDOUT_3ST_I2S | CS35L33_PDN_TDM;
                val2 = CS35L33_SDOUT_3ST_TDM;
-               dev_dbg(codec->dev, "SDOUT turned off\n");
+               dev_dbg(component->dev, "SDOUT turned off\n");
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
                return 0;
        }
 
@@ -360,11 +360,11 @@ static const struct snd_soc_dapm_route cs35l33_vp_vbst_mon_route[] = {
        {"VBSTMON", NULL, "MON"},
 };
 
-static int cs35l33_set_bias_level(struct snd_soc_codec *codec,
+static int cs35l33_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
        unsigned int val;
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -441,19 +441,19 @@ static int cs35l33_get_mclk_coeff(int mclk, int srate)
 
 static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
                regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
                        CS35L33_MS_MASK, CS35L33_MS_MASK);
-               dev_dbg(codec->dev, "Audio port in master mode\n");
+               dev_dbg(component->dev, "Audio port in master mode\n");
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
                regmap_update_bits(priv->regmap, CS35L33_ADSP_CTL,
                        CS35L33_MS_MASK, 0);
-               dev_dbg(codec->dev, "Audio port in slave mode\n");
+               dev_dbg(component->dev, "Audio port in slave mode\n");
                break;
        default:
                return -EINVAL;
@@ -466,11 +466,11 @@ static int cs35l33_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                 * closely, it is dsp-a with fsync shifted left by half bclk
                 */
                priv->is_tdm_mode = true;
-               dev_dbg(codec->dev, "Audio port in TDM mode\n");
+               dev_dbg(component->dev, "Audio port in TDM mode\n");
                break;
        case SND_SOC_DAIFMT_I2S:
                priv->is_tdm_mode = false;
-               dev_dbg(codec->dev, "Audio port in I2S mode\n");
+               dev_dbg(component->dev, "Audio port in I2S mode\n");
                break;
        default:
                return -EINVAL;
@@ -483,8 +483,8 @@ static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
        int sample_size = params_width(params);
        int coeff = cs35l33_get_mclk_coeff(priv->mclk_int, params_rate(params));
 
@@ -505,7 +505,7 @@ static int cs35l33_pcm_hw_params(struct snd_pcm_substream *substream,
                        sample_size << CS35L33_AUDIN_RX_DEPTH_SHIFT);
        }
 
-       dev_dbg(codec->dev, "sample rate=%d, bits per sample=%d\n",
+       dev_dbg(component->dev, "sample rate=%d, bits per sample=%d\n",
                params_rate(params), params_width(params));
 
        return 0;
@@ -532,8 +532,8 @@ static int cs35l33_pcm_startup(struct snd_pcm_substream *substream,
 
 static int cs35l33_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
        if (tristate) {
                regmap_update_bits(priv->regmap, CS35L33_PWRCTL2,
@@ -553,9 +553,9 @@ static int cs35l33_set_tristate(struct snd_soc_dai *dai, int tristate)
 static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                                unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
        unsigned int reg, bit_pos, i;
        int slot, slot_num;
 
@@ -567,7 +567,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        if (slot >= 0) {
                regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
                        CS35L33_X_LOC, slot);
-               dev_dbg(codec->dev, "Audio starts from slots %d", slot);
+               dev_dbg(component->dev, "Audio starts from slots %d", slot);
        }
 
        /*
@@ -593,7 +593,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                if (slot_num == 0) {
                        regmap_update_bits(priv->regmap, CS35L33_TX_VMON,
                                CS35L33_X_STATE | CS35L33_X_LOC, slot);
-                       dev_dbg(codec->dev, "VMON enabled in slots %d-%d",
+                       dev_dbg(component->dev, "VMON enabled in slots %d-%d",
                                slot, slot + 1);
                }
 
@@ -601,7 +601,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                if (slot_num == 3) {
                        regmap_update_bits(priv->regmap, CS35L33_TX_IMON,
                                CS35L33_X_STATE | CS35L33_X_LOC, slot);
-                       dev_dbg(codec->dev, "IMON enabled in slots %d-%d",
+                       dev_dbg(component->dev, "IMON enabled in slots %d-%d",
                                slot, slot + 1);
                }
 
@@ -611,7 +611,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                                CS35L33_X_STATE | CS35L33_X_LOC, slot);
                        snd_soc_dapm_add_routes(dapm,
                                &cs35l33_vp_vbst_mon_route[0], 2);
-                       dev_dbg(codec->dev, "VPMON enabled in slots %d", slot);
+                       dev_dbg(component->dev, "VPMON enabled in slots %d", slot);
                }
 
                /* configure VBSTMON_TX_LOC */
@@ -620,7 +620,7 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                                CS35L33_X_STATE | CS35L33_X_LOC, slot);
                        snd_soc_dapm_add_routes(dapm,
                                &cs35l33_vp_vbst_mon_route[2], 2);
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "VBSTMON enabled in slots %d", slot);
                }
 
@@ -638,10 +638,10 @@ static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        return 0;
 }
 
-static int cs35l33_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs35l33_component_set_sysclk(struct snd_soc_component *component,
                int clk_id, int source, unsigned int freq, int dir)
 {
-       struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+       struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case CS35L33_MCLK_5644:
@@ -663,7 +663,7 @@ static int cs35l33_codec_set_sysclk(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev, "external mclk freq=%d, internal mclk freq=%d\n",
+       dev_dbg(component->dev, "external mclk freq=%d, internal mclk freq=%d\n",
                freq, cs35l33->mclk_int);
 
        return 0;
@@ -698,12 +698,12 @@ static struct snd_soc_dai_driver cs35l33_dai = {
                .symmetric_rates = 1,
 };
 
-static int cs35l33_set_hg_data(struct snd_soc_codec *codec,
+static int cs35l33_set_hg_data(struct snd_soc_component *component,
                               struct cs35l33_pdata *pdata)
 {
        struct cs35l33_hg *hg_config = &pdata->hg_config;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct cs35l33_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
 
        if (hg_config->enable_hg_algo) {
                regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL,
@@ -747,20 +747,20 @@ static int cs35l33_set_hg_data(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int cs35l33_set_bst_ipk(struct snd_soc_codec *codec, unsigned int bst)
+static int cs35l33_set_bst_ipk(struct snd_soc_component *component, unsigned int bst)
 {
-       struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+       struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
        int ret = 0, steps = 0;
 
        /* Boost current in uA */
        if (bst > 3600000 || bst < 1850000) {
-               dev_err(codec->dev, "Invalid boost current %d\n", bst);
+               dev_err(component->dev, "Invalid boost current %d\n", bst);
                ret = -EINVAL;
                goto err;
        }
 
        if (bst % 15625) {
-               dev_err(codec->dev, "Current not a multiple of 15625uA (%d)\n",
+               dev_err(component->dev, "Current not a multiple of 15625uA (%d)\n",
                        bst);
                ret = -EINVAL;
                goto err;
@@ -778,12 +778,12 @@ err:
        return ret;
 }
 
-static int cs35l33_probe(struct snd_soc_codec *codec)
+static int cs35l33_probe(struct snd_soc_component *component)
 {
-       struct cs35l33_private *cs35l33 = snd_soc_codec_get_drvdata(codec);
+       struct cs35l33_private *cs35l33 = snd_soc_component_get_drvdata(component);
 
-       cs35l33->codec = codec;
-       pm_runtime_get_sync(codec->dev);
+       cs35l33->component = component;
+       pm_runtime_get_sync(component->dev);
 
        regmap_update_bits(cs35l33->regmap, CS35L33_PROTECT_CTL,
                CS35L33_ALIVE_WD_DIS, 0x8);
@@ -799,24 +799,24 @@ static int cs35l33_probe(struct snd_soc_codec *codec)
                cs35l33->pdata.amp_drv_sel << CS35L33_AMP_DRV_SEL_SHIFT);
 
        if (cs35l33->pdata.boost_ipk)
-               cs35l33_set_bst_ipk(codec, cs35l33->pdata.boost_ipk);
+               cs35l33_set_bst_ipk(component, cs35l33->pdata.boost_ipk);
 
        if (cs35l33->enable_soft_ramp) {
-               snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+               snd_soc_component_update_bits(component, CS35L33_DAC_CTL,
                        CS35L33_DIGSFT, CS35L33_DIGSFT);
-               snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+               snd_soc_component_update_bits(component, CS35L33_DAC_CTL,
                        CS35L33_DSR_RATE, cs35l33->pdata.ramp_rate);
        } else {
-               snd_soc_update_bits(codec, CS35L33_DAC_CTL,
+               snd_soc_component_update_bits(component, CS35L33_DAC_CTL,
                        CS35L33_DIGSFT, 0);
        }
 
        /* update IMON scaling rate if different from default of 0x8 */
        if (cs35l33->pdata.imon_adc_scale != 0x8)
-               snd_soc_update_bits(codec, CS35L33_ADC_CTL,
+               snd_soc_component_update_bits(component, CS35L33_ADC_CTL,
                        CS35L33_IMON_SCALE, cs35l33->pdata.imon_adc_scale);
 
-       cs35l33_set_hg_data(codec, &(cs35l33->pdata));
+       cs35l33_set_hg_data(component, &(cs35l33->pdata));
 
        /*
         * unmask important interrupts that causes the chip to enter
@@ -826,26 +826,24 @@ static int cs35l33_probe(struct snd_soc_codec *codec)
                CS35L33_M_OTE | CS35L33_M_OTW | CS35L33_M_AMP_SHORT |
                CS35L33_M_CAL_ERR, 0);
 
-       pm_runtime_put_sync(codec->dev);
+       pm_runtime_put_sync(component->dev);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
-       .probe = cs35l33_probe,
-
-       .set_bias_level = cs35l33_set_bias_level,
-       .set_sysclk = cs35l33_codec_set_sysclk,
-
-       .component_driver = {
-               .controls               = cs35l33_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs35l33_snd_controls),
-               .dapm_widgets           = cs35l33_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs35l33_dapm_widgets),
-               .dapm_routes            = cs35l33_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cs35l33_audio_map),
-       },
-       .idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_cs35l33 = {
+       .probe                  = cs35l33_probe,
+       .set_bias_level         = cs35l33_set_bias_level,
+       .set_sysclk             = cs35l33_component_set_sysclk,
+       .controls               = cs35l33_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs35l33_snd_controls),
+       .dapm_widgets           = cs35l33_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs35l33_dapm_widgets),
+       .dapm_routes            = cs35l33_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs35l33_audio_map),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config cs35l33_regmap = {
@@ -967,7 +965,7 @@ static int cs35l33_get_hg_data(const struct device_node *np,
 static irqreturn_t cs35l33_irq_thread(int irq, void *data)
 {
        struct cs35l33_private *cs35l33 = data;
-       struct snd_soc_codec *codec = cs35l33->codec;
+       struct snd_soc_component *component = cs35l33->component;
        unsigned int sticky_val1, sticky_val2, current_val, mask1, mask2;
 
        regmap_read(cs35l33->regmap, CS35L33_INT_STATUS_2,
@@ -989,9 +987,9 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
        /* handle the interrupts */
 
        if (sticky_val1 & CS35L33_AMP_SHORT) {
-               dev_crit(codec->dev, "Amp short error\n");
+               dev_crit(component->dev, "Amp short error\n");
                if (!(current_val & CS35L33_AMP_SHORT)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Amp short error release\n");
                        regmap_update_bits(cs35l33->regmap,
                                CS35L33_AMP_CTL,
@@ -1007,13 +1005,13 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
        }
 
        if (sticky_val1 & CS35L33_CAL_ERR) {
-               dev_err(codec->dev, "Cal error\n");
+               dev_err(component->dev, "Cal error\n");
 
                /* redo the calibration in next power up */
                cs35l33->amp_cal = false;
 
                if (!(current_val & CS35L33_CAL_ERR)) {
-                       dev_dbg(codec->dev, "Cal error release\n");
+                       dev_dbg(component->dev, "Cal error release\n");
                        regmap_update_bits(cs35l33->regmap,
                                CS35L33_AMP_CTL, CS35L33_CAL_ERR_RLS,
                                0);
@@ -1027,9 +1025,9 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
        }
 
        if (sticky_val1 & CS35L33_OTE) {
-               dev_crit(codec->dev, "Over temperature error\n");
+               dev_crit(component->dev, "Over temperature error\n");
                if (!(current_val & CS35L33_OTE)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Over temperature error release\n");
                        regmap_update_bits(cs35l33->regmap,
                                CS35L33_AMP_CTL, CS35L33_OTE_RLS, 0);
@@ -1042,9 +1040,9 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
        }
 
        if (sticky_val1 & CS35L33_OTW) {
-               dev_err(codec->dev, "Over temperature warning\n");
+               dev_err(component->dev, "Over temperature warning\n");
                if (!(current_val & CS35L33_OTW)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Over temperature warning release\n");
                        regmap_update_bits(cs35l33->regmap,
                                CS35L33_AMP_CTL, CS35L33_OTW_RLS, 0);
@@ -1056,21 +1054,21 @@ static irqreturn_t cs35l33_irq_thread(int irq, void *data)
                }
        }
        if (CS35L33_ALIVE_ERR & sticky_val1)
-               dev_err(codec->dev, "ERROR: ADSPCLK Interrupt\n");
+               dev_err(component->dev, "ERROR: ADSPCLK Interrupt\n");
 
        if (CS35L33_MCLK_ERR & sticky_val1)
-               dev_err(codec->dev, "ERROR: MCLK Interrupt\n");
+               dev_err(component->dev, "ERROR: MCLK Interrupt\n");
 
        if (CS35L33_VMON_OVFL & sticky_val2)
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "ERROR: VMON Overflow Interrupt\n");
 
        if (CS35L33_IMON_OVFL & sticky_val2)
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "ERROR: IMON Overflow Interrupt\n");
 
        if (CS35L33_VPMON_OVFL & sticky_val2)
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "ERROR: VPMON Overflow Interrupt\n");
 
        return IRQ_HANDLED;
@@ -1236,10 +1234,10 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
        pm_runtime_set_active(&i2c_client->dev);
        pm_runtime_enable(&i2c_client->dev);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs35l33, &cs35l33_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs35l33, &cs35l33_dai, 1);
        if (ret < 0) {
-               dev_err(&i2c_client->dev, "%s: Register codec failed\n",
+               dev_err(&i2c_client->dev, "%s: Register component failed\n",
                        __func__);
                goto err_enable;
        }
@@ -1257,8 +1255,6 @@ static int cs35l33_i2c_remove(struct i2c_client *client)
 {
        struct cs35l33_private *cs35l33 = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
-
        gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
 
        pm_runtime_disable(&client->dev);
index 0600d5264c4c7de155f92e1c27b6ac2c6acb6d58..5063c05afa27242dd2b1ff22665e7b04eb2e966e 100644 (file)
@@ -43,7 +43,7 @@
 #define CS35L34_START_DELAY 50
 
 struct  cs35l34_private {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct cs35l34_platform_data pdata;
        struct regmap *regmap;
        struct regulator_bulk_data core_supplies[2];
@@ -237,8 +237,8 @@ static bool cs35l34_precious_register(struct device *dev, unsigned int reg)
 static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (event) {
@@ -250,7 +250,7 @@ static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
                ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,
                                                CS35L34_PDN_ALL, 0);
                if (ret < 0) {
-                       dev_err(codec->dev, "Cannot set Power bits %d\n", ret);
+                       dev_err(component->dev, "Cannot set Power bits %d\n", ret);
                        return ret;
                }
                usleep_range(5000, 5100);
@@ -272,8 +272,8 @@ static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
 static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                                unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
        unsigned int reg, bit_pos;
        int slot, slot_num;
 
@@ -284,7 +284,7 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        /* scan rx_mask for aud slot */
        slot = ffs(rx_mask) - 1;
        if (slot >= 0)
-               snd_soc_update_bits(codec, CS35L34_TDM_RX_CTL_1_AUDIN,
+               snd_soc_component_update_bits(component, CS35L34_TDM_RX_CTL_1_AUDIN,
                                        CS35L34_X_LOC, slot);
 
        /* scan tx_mask: vmon(2 slots); imon (2 slots); vpmon (1 slot)
@@ -294,10 +294,10 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        slot_num = 0;
 
        /* disable vpmon/vbstmon: enable later if set in tx_mask */
-       snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_3_VPMON,
+       snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,
                                CS35L34_X_STATE | CS35L34_X_LOC,
                                CS35L34_X_STATE | CS35L34_X_LOC);
-       snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_4_VBSTMON,
+       snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_4_VBSTMON,
                                CS35L34_X_STATE | CS35L34_X_LOC,
                                CS35L34_X_STATE | CS35L34_X_LOC);
 
@@ -305,22 +305,22 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        while (slot >= 0) {
                /* configure VMON_TX_LOC */
                if (slot_num == 0)
-                       snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_1_VMON,
+                       snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_1_VMON,
                                        CS35L34_X_STATE | CS35L34_X_LOC, slot);
 
                /* configure IMON_TX_LOC */
                if (slot_num == 4) {
-                       snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_2_IMON,
+                       snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_2_IMON,
                                        CS35L34_X_STATE | CS35L34_X_LOC, slot);
                }
                /* configure VPMON_TX_LOC */
                if (slot_num == 3) {
-                       snd_soc_update_bits(codec, CS35L34_TDM_TX_CTL_3_VPMON,
+                       snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,
                                        CS35L34_X_STATE | CS35L34_X_LOC, slot);
                }
                /* configure VBSTMON_TX_LOC */
                if (slot_num == 7) {
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                CS35L34_TDM_TX_CTL_4_VBSTMON,
                                CS35L34_X_STATE | CS35L34_X_LOC, slot);
                }
@@ -328,7 +328,7 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                /* Enable the relevant tx slot */
                reg = CS35L34_TDM_TX_SLOT_EN_4 - (slot/8);
                bit_pos = slot - ((slot / 8) * (8));
-               snd_soc_update_bits(codec, reg,
+               snd_soc_component_update_bits(component, reg,
                        1 << bit_pos, 1 << bit_pos);
 
                tx_mask &= ~(1 << slot);
@@ -342,8 +342,8 @@ static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int cs35l34_main_amp_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -382,8 +382,8 @@ static const struct snd_kcontrol_new cs35l34_snd_controls[] = {
 static int cs35l34_mclk_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
        int ret, i;
        unsigned int reg;
 
@@ -524,8 +524,8 @@ static int cs35l34_get_mclk_coeff(int mclk, int srate)
 
 static int cs35l34_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -546,15 +546,15 @@ static int cs35l34_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l34_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
        int srate = params_rate(params);
        int ret;
 
        int coeff = cs35l34_get_mclk_coeff(priv->mclk_int, srate);
 
        if (coeff < 0) {
-               dev_err(codec->dev, "ERROR: Invalid mclk %d and/or srate %d\n",
+               dev_err(component->dev, "ERROR: Invalid mclk %d and/or srate %d\n",
                        priv->mclk_int, srate);
                return coeff;
        }
@@ -562,7 +562,7 @@ static int cs35l34_pcm_hw_params(struct snd_pcm_substream *substream,
        ret = regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,
                CS35L34_ADSP_RATE, cs35l34_mclk_coeffs[coeff].adsp_rate);
        if (ret != 0)
-               dev_err(codec->dev, "Failed to set clock state %d\n", ret);
+               dev_err(component->dev, "Failed to set clock state %d\n", ret);
 
        return ret;
 }
@@ -590,13 +590,13 @@ static int cs35l34_pcm_startup(struct snd_pcm_substream *substream,
 static int cs35l34_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
 
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (tristate)
-               snd_soc_update_bits(codec, CS35L34_PWRCTL3,
+               snd_soc_component_update_bits(component, CS35L34_PWRCTL3,
                                        CS35L34_PDN_SDOUT, CS35L34_PDN_SDOUT);
        else
-               snd_soc_update_bits(codec, CS35L34_PWRCTL3,
+               snd_soc_component_update_bits(component, CS35L34_PWRCTL3,
                                        CS35L34_PDN_SDOUT, 0);
        return 0;
 }
@@ -604,8 +604,8 @@ static int cs35l34_set_tristate(struct snd_soc_dai *dai, int tristate)
 static int cs35l34_dai_set_sysclk(struct snd_soc_dai *dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l34_private *cs35l34 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);
        unsigned int value;
 
        switch (freq) {
@@ -634,7 +634,7 @@ static int cs35l34_dai_set_sysclk(struct snd_soc_dai *dai,
                cs35l34->mclk_int = freq / 2;
        break;
        default:
-               dev_err(codec->dev, "ERROR: Invalid Frequency %d\n", freq);
+               dev_err(component->dev, "ERROR: Invalid Frequency %d\n", freq);
                cs35l34->mclk_int = 0;
                return -EINVAL;
        }
@@ -676,7 +676,7 @@ static struct snd_soc_dai_driver cs35l34_dai = {
 static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,
        unsigned int inductor)
 {
-       struct snd_soc_codec *codec = cs35l34->codec;
+       struct snd_soc_component *component = cs35l34->component;
 
        switch (inductor) {
        case 1000: /* 1 uH */
@@ -708,19 +708,19 @@ static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,
                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 3);
                break;
        default:
-               dev_err(codec->dev, "%s Invalid Inductor Value %d uH\n",
+               dev_err(component->dev, "%s Invalid Inductor Value %d uH\n",
                        __func__, inductor);
                return -EINVAL;
        }
        return 0;
 }
 
-static int cs35l34_probe(struct snd_soc_codec *codec)
+static int cs35l34_probe(struct snd_soc_component *component)
 {
        int ret = 0;
-       struct cs35l34_private *cs35l34 = snd_soc_codec_get_drvdata(codec);
+       struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);
 
-       pm_runtime_get_sync(codec->dev);
+       pm_runtime_get_sync(component->dev);
 
        /* Set over temperature warning attenuation to 6 dB */
        regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,
@@ -773,23 +773,24 @@ static int cs35l34_probe(struct snd_soc_codec *codec)
                regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_TDM_CTL,
                        1, 1);
 
-       pm_runtime_put_sync(codec->dev);
+       pm_runtime_put_sync(component->dev);
 
        return ret;
 }
 
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l34 = {
-       .probe = cs35l34_probe,
-
-       .component_driver = {
-               .dapm_widgets = cs35l34_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(cs35l34_dapm_widgets),
-               .dapm_routes = cs35l34_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(cs35l34_audio_map),
-               .controls = cs35l34_snd_controls,
-               .num_controls = ARRAY_SIZE(cs35l34_snd_controls),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs35l34 = {
+       .probe                  = cs35l34_probe,
+       .dapm_widgets           = cs35l34_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs35l34_dapm_widgets),
+       .dapm_routes            = cs35l34_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs35l34_audio_map),
+       .controls               = cs35l34_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs35l34_snd_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct regmap_config cs35l34_regmap = {
@@ -864,7 +865,7 @@ static int cs35l34_handle_of_data(struct i2c_client *i2c_client,
 static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 {
        struct cs35l34_private *cs35l34 = data;
-       struct snd_soc_codec *codec = cs35l34->codec;
+       struct snd_soc_component *component = cs35l34->component;
        unsigned int sticky1, sticky2, sticky3, sticky4;
        unsigned int mask1, mask2, mask3, mask4, current1;
 
@@ -887,11 +888,11 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
        regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_1, &current1);
 
        if (sticky1 & CS35L34_CAL_ERR) {
-               dev_err(codec->dev, "Cal error\n");
+               dev_err(component->dev, "Cal error\n");
 
                /* error is no longer asserted; safe to reset */
                if (!(current1 & CS35L34_CAL_ERR)) {
-                       dev_dbg(codec->dev, "Cal error release\n");
+                       dev_dbg(component->dev, "Cal error release\n");
                        regmap_update_bits(cs35l34->regmap,
                                        CS35L34_PROT_RELEASE_CTL,
                                        CS35L34_CAL_ERR_RLS, 0);
@@ -907,14 +908,14 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
        }
 
        if (sticky1 & CS35L34_ALIVE_ERR)
-               dev_err(codec->dev, "Alive error\n");
+               dev_err(component->dev, "Alive error\n");
 
        if (sticky1 & CS35L34_AMP_SHORT) {
-               dev_crit(codec->dev, "Amp short error\n");
+               dev_crit(component->dev, "Amp short error\n");
 
                /* error is no longer asserted; safe to reset */
                if (!(current1 & CS35L34_AMP_SHORT)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Amp short error release\n");
                        regmap_update_bits(cs35l34->regmap,
                                        CS35L34_PROT_RELEASE_CTL,
@@ -930,11 +931,11 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
        }
 
        if (sticky1 & CS35L34_OTW) {
-               dev_crit(codec->dev, "Over temperature warning\n");
+               dev_crit(component->dev, "Over temperature warning\n");
 
                /* error is no longer asserted; safe to reset */
                if (!(current1 & CS35L34_OTW)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Over temperature warning release\n");
                        regmap_update_bits(cs35l34->regmap,
                                        CS35L34_PROT_RELEASE_CTL,
@@ -950,11 +951,11 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
        }
 
        if (sticky1 & CS35L34_OTE) {
-               dev_crit(codec->dev, "Over temperature error\n");
+               dev_crit(component->dev, "Over temperature error\n");
 
                /* error is no longer asserted; safe to reset */
                if (!(current1 & CS35L34_OTE)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Over temperature error release\n");
                        regmap_update_bits(cs35l34->regmap,
                                        CS35L34_PROT_RELEASE_CTL,
@@ -970,7 +971,7 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
        }
 
        if (sticky3 & CS35L34_BST_HIGH) {
-               dev_crit(codec->dev, "VBST too high error; powering off!\n");
+               dev_crit(component->dev, "VBST too high error; powering off!\n");
                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,
                                CS35L34_PDN_AMP, CS35L34_PDN_AMP);
                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,
@@ -978,7 +979,7 @@ static irqreturn_t cs35l34_irq_thread(int irq, void *data)
        }
 
        if (sticky3 & CS35L34_LBST_SHORT) {
-               dev_crit(codec->dev, "LBST short error; powering off!\n");
+               dev_crit(component->dev, "LBST short error; powering off!\n");
                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,
                                CS35L34_PDN_AMP, CS35L34_PDN_AMP);
                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,
@@ -1108,11 +1109,11 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
        pm_runtime_set_active(&i2c_client->dev);
        pm_runtime_enable(&i2c_client->dev);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs35l34, &cs35l34_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs35l34, &cs35l34_dai, 1);
        if (ret < 0) {
                dev_err(&i2c_client->dev,
-                       "%s: Register codec failed\n", __func__);
+                       "%s: Register component failed\n", __func__);
                goto err_regulator;
        }
 
@@ -1129,8 +1130,6 @@ static int cs35l34_i2c_remove(struct i2c_client *client)
 {
        struct cs35l34_private *cs35l34 = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
-
        gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
 
        pm_runtime_disable(&client->dev);
index 129978d1243ebcdd3a1558c1c0f1f0dd2056bdd7..a4a2cb171bdf15dd2647a430a09eaf91bcc99f1c 100644 (file)
@@ -194,8 +194,8 @@ static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
 static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (event) {
@@ -231,7 +231,7 @@ static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
                                   1 << CS35L35_AMP_DIGSFT_SHIFT);
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
                ret = -EINVAL;
        }
        return ret;
@@ -240,8 +240,8 @@ static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
 static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
        unsigned int reg[4];
        int i;
 
@@ -301,7 +301,7 @@ static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
 
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
        }
        return 0;
 }
@@ -369,8 +369,8 @@ static const struct snd_soc_dapm_route cs35l35_audio_map[] = {
 
 static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -470,8 +470,8 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
        struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
        int srate = params_rate(params);
        int ret = 0;
@@ -482,7 +482,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
        int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);
 
        if (clk_ctl < 0) {
-               dev_err(codec->dev, "Invalid CLK:Rate %d:%d\n",
+               dev_err(component->dev, "Invalid CLK:Rate %d:%d\n",
                        cs35l35->sysclk, srate);
                return -EINVAL;
        }
@@ -490,7 +490,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
        ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,
                          CS35L35_CLK_CTL2_MASK, clk_ctl);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to set port config %d\n", ret);
+               dev_err(component->dev, "Failed to set port config %d\n", ret);
                return ret;
        }
 
@@ -509,7 +509,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                                        CS35L35_CH_WKFET_DEL_MASK,
                                        0 << CS35L35_CH_WKFET_DEL_SHIFT);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to set fet config %d\n",
+                       dev_err(component->dev, "Failed to set fet config %d\n",
                                ret);
                        return ret;
                }
@@ -531,7 +531,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                        audin_format = CS35L35_SDIN_DEPTH_24;
                        break;
                default:
-                       dev_err(codec->dev, "Unsupported Width %d\n",
+                       dev_err(component->dev, "Unsupported Width %d\n",
                                params_width(params));
                        return -EINVAL;
                }
@@ -554,7 +554,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                 * to configure the CLOCK_CTL3 register correctly
                 */
                if ((cs35l35->sclk / srate) % 4) {
-                       dev_err(codec->dev, "Unsupported sclk/fs ratio %d:%d\n",
+                       dev_err(component->dev, "Unsupported sclk/fs ratio %d:%d\n",
                                        cs35l35->sclk, srate);
                        return -EINVAL;
                }
@@ -568,7 +568,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                        case CS35L35_SP_SCLKS_64FS:
                                break;
                        default:
-                               dev_err(codec->dev, "ratio not supported\n");
+                               dev_err(component->dev, "ratio not supported\n");
                                return -EINVAL;
                        }
                } else {
@@ -578,7 +578,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                        case CS35L35_SP_SCLKS_64FS:
                                break;
                        default:
-                               dev_err(codec->dev, "ratio not supported\n");
+                               dev_err(component->dev, "ratio not supported\n");
                                return -EINVAL;
                        }
                }
@@ -587,7 +587,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
                                        CS35L35_SP_SCLKS_MASK, sp_sclks <<
                                        CS35L35_SP_SCLKS_SHIFT);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to set fsclk %d\n", ret);
+                       dev_err(component->dev, "Failed to set fsclk %d\n", ret);
                        return ret;
                }
        }
@@ -607,8 +607,8 @@ static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
 static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
        if (!substream->runtime)
                return 0;
@@ -635,8 +635,8 @@ static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
 static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
        if (!substream->runtime)
                return 0;
@@ -655,8 +655,8 @@ static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
 static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 
        /* Need the SCLK Frequency regardless of sysclk source for I2S */
        cs35l35->sclk = freq;
@@ -712,11 +712,11 @@ static struct snd_soc_dai_driver cs35l35_dai[] = {
        },
 };
 
-static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs35l35_component_set_sysclk(struct snd_soc_component *component,
                                int clk_id, int source, unsigned int freq,
                                int dir)
 {
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
        int clksrc;
        int ret = 0;
 
@@ -731,7 +731,7 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
                clksrc = CS35L35_CLK_SOURCE_PDM;
                break;
        default:
-               dev_err(codec->dev, "Invalid CLK Source\n");
+               dev_err(component->dev, "Invalid CLK Source\n");
                return -EINVAL;
        }
 
@@ -749,7 +749,7 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
                cs35l35->sysclk = freq;
                break;
        default:
-               dev_err(codec->dev, "Invalid CLK Frequency Input : %d\n", freq);
+               dev_err(component->dev, "Invalid CLK Frequency Input : %d\n", freq);
                return -EINVAL;
        }
 
@@ -757,7 +757,7 @@ static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
                                CS35L35_CLK_SOURCE_MASK,
                                clksrc << CS35L35_CLK_SOURCE_SHIFT);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to set sysclk %d\n", ret);
+               dev_err(component->dev, "Failed to set sysclk %d\n", ret);
                return ret;
        }
 
@@ -834,9 +834,9 @@ static int cs35l35_boost_inductor(struct cs35l35_private *cs35l35,
        return 0;
 }
 
-static int cs35l35_codec_probe(struct snd_soc_codec *codec)
+static int cs35l35_component_probe(struct snd_soc_component *component)
 {
-       struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
+       struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
        struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
        struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;
        int ret;
@@ -880,7 +880,7 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec)
                        regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,
                                        CS35L35_CH_STEREO_MASK,
                                        1 << CS35L35_CH_STEREO_SHIFT);
-               ret = snd_soc_add_codec_controls(codec, cs35l35_adv_controls,
+               ret = snd_soc_add_component_controls(component, cs35l35_adv_controls,
                                        ARRAY_SIZE(cs35l35_adv_controls));
                if (ret)
                        return ret;
@@ -1079,20 +1079,19 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs35l35 = {
-       .probe = cs35l35_codec_probe,
-       .set_sysclk = cs35l35_codec_set_sysclk,
-       .component_driver = {
-               .dapm_widgets = cs35l35_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(cs35l35_dapm_widgets),
-
-               .dapm_routes = cs35l35_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(cs35l35_audio_map),
-
-               .controls = cs35l35_aud_controls,
-               .num_controls = ARRAY_SIZE(cs35l35_aud_controls),
-       },
-
+static const struct snd_soc_component_driver soc_component_dev_cs35l35 = {
+       .probe                  = cs35l35_component_probe,
+       .set_sysclk             = cs35l35_component_set_sysclk,
+       .dapm_widgets           = cs35l35_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs35l35_dapm_widgets),
+       .dapm_routes            = cs35l35_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs35l35_audio_map),
+       .controls               = cs35l35_aud_controls,
+       .num_controls           = ARRAY_SIZE(cs35l35_aud_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct regmap_config cs35l35_regmap = {
@@ -1617,10 +1616,10 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
        regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
                CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);
 
-       ret =  snd_soc_register_codec(dev, &soc_codec_dev_cs35l35, cs35l35_dai,
-                                     ARRAY_SIZE(cs35l35_dai));
+       ret = devm_snd_soc_register_component(dev, &soc_component_dev_cs35l35,
+                                       cs35l35_dai, ARRAY_SIZE(cs35l35_dai));
        if (ret < 0) {
-               dev_err(dev, "Failed to register codec: %d\n", ret);
+               dev_err(dev, "Failed to register component: %d\n", ret);
                goto err;
        }
 
@@ -1634,12 +1633,6 @@ err:
        return ret;
 }
 
-static int cs35l35_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct of_device_id cs35l35_of_match[] = {
        {.compatible = "cirrus,cs35l35"},
        {},
@@ -1660,7 +1653,6 @@ static struct i2c_driver cs35l35_i2c_driver = {
        },
        .id_table = cs35l35_id,
        .probe = cs35l35_i2c_probe,
-       .remove = cs35l35_i2c_remove,
 };
 
 module_i2c_driver(cs35l35_i2c_driver);
index fd966bb851cbcb0c2dcd8b5a3713c26b5e6ec7c8..275677de669f0562b8fea2fe82c4cf07f33a90cd 100644 (file)
@@ -322,12 +322,12 @@ static int cs4265_get_clk_index(int mclk, int rate)
 static int cs4265_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
                        unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4265_private *cs4265 = snd_soc_component_get_drvdata(component);
        int i;
 
        if (clk_id != 0) {
-               dev_err(codec->dev, "Invalid clk_id %d\n", clk_id);
+               dev_err(component->dev, "Invalid clk_id %d\n", clk_id);
                return -EINVAL;
        }
        for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
@@ -337,24 +337,24 @@ static int cs4265_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
                }
        }
        cs4265->sysclk = 0;
-       dev_err(codec->dev, "Invalid freq parameter %d\n", freq);
+       dev_err(component->dev, "Invalid freq parameter %d\n", freq);
        return -EINVAL;
 }
 
 static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4265_private *cs4265 = snd_soc_component_get_drvdata(component);
        u8 iface = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               snd_soc_update_bits(codec, CS4265_ADC_CTL,
+               snd_soc_component_update_bits(component, CS4265_ADC_CTL,
                                CS4265_ADC_MASTER,
                                CS4265_ADC_MASTER);
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               snd_soc_update_bits(codec, CS4265_ADC_CTL,
+               snd_soc_component_update_bits(component, CS4265_ADC_CTL,
                                CS4265_ADC_MASTER,
                                0);
                break;
@@ -383,20 +383,20 @@ static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int cs4265_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute) {
-               snd_soc_update_bits(codec, CS4265_DAC_CTL,
+               snd_soc_component_update_bits(component, CS4265_DAC_CTL,
                        CS4265_DAC_CTL_MUTE,
                        CS4265_DAC_CTL_MUTE);
-               snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+               snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
                        CS4265_SPDIF_CTL2_MUTE,
                        CS4265_SPDIF_CTL2_MUTE);
        } else {
-               snd_soc_update_bits(codec, CS4265_DAC_CTL,
+               snd_soc_component_update_bits(component, CS4265_DAC_CTL,
                        CS4265_DAC_CTL_MUTE,
                        0);
-               snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+               snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
                        CS4265_SPDIF_CTL2_MUTE,
                        0);
        }
@@ -407,8 +407,8 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *params,
                                     struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs4265_private *cs4265 = snd_soc_component_get_drvdata(component);
        int index;
 
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
@@ -418,45 +418,45 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
 
        index = cs4265_get_clk_index(cs4265->sysclk, params_rate(params));
        if (index >= 0) {
-               snd_soc_update_bits(codec, CS4265_ADC_CTL,
+               snd_soc_component_update_bits(component, CS4265_ADC_CTL,
                        CS4265_ADC_FM, clk_map_table[index].fm_mode << 6);
-               snd_soc_update_bits(codec, CS4265_MCLK_FREQ,
+               snd_soc_component_update_bits(component, CS4265_MCLK_FREQ,
                        CS4265_MCLK_FREQ_MASK,
                        clk_map_table[index].mclkdiv << 4);
 
        } else {
-               dev_err(codec->dev, "can't get correct mclk\n");
+               dev_err(component->dev, "can't get correct mclk\n");
                return -EINVAL;
        }
 
        switch (cs4265->format & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               snd_soc_update_bits(codec, CS4265_DAC_CTL,
+               snd_soc_component_update_bits(component, CS4265_DAC_CTL,
                        CS4265_DAC_CTL_DIF, (1 << 4));
-               snd_soc_update_bits(codec, CS4265_ADC_CTL,
+               snd_soc_component_update_bits(component, CS4265_ADC_CTL,
                        CS4265_ADC_DIF, (1 << 4));
-               snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+               snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
                        CS4265_SPDIF_CTL2_DIF, (1 << 6));
                break;
        case SND_SOC_DAIFMT_RIGHT_J:
                if (params_width(params) == 16) {
-                       snd_soc_update_bits(codec, CS4265_DAC_CTL,
+                       snd_soc_component_update_bits(component, CS4265_DAC_CTL,
                                CS4265_DAC_CTL_DIF, (2 << 4));
-                       snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+                       snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
                                CS4265_SPDIF_CTL2_DIF, (2 << 6));
                } else {
-                       snd_soc_update_bits(codec, CS4265_DAC_CTL,
+                       snd_soc_component_update_bits(component, CS4265_DAC_CTL,
                                CS4265_DAC_CTL_DIF, (3 << 4));
-                       snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+                       snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
                                CS4265_SPDIF_CTL2_DIF, (3 << 6));
                }
                break;
        case SND_SOC_DAIFMT_LEFT_J:
-               snd_soc_update_bits(codec, CS4265_DAC_CTL,
+               snd_soc_component_update_bits(component, CS4265_DAC_CTL,
                        CS4265_DAC_CTL_DIF, 0);
-               snd_soc_update_bits(codec, CS4265_ADC_CTL,
+               snd_soc_component_update_bits(component, CS4265_ADC_CTL,
                        CS4265_ADC_DIF, 0);
-               snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
+               snd_soc_component_update_bits(component, CS4265_SPDIF_CTL2,
                        CS4265_SPDIF_CTL2_DIF, 0);
 
                break;
@@ -466,23 +466,23 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int cs4265_set_bias_level(struct snd_soc_codec *codec,
+static int cs4265_set_bias_level(struct snd_soc_component *component,
                                        enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, CS4265_PWRCTL,
+               snd_soc_component_update_bits(component, CS4265_PWRCTL,
                        CS4265_PWRCTL_PDN, 0);
                break;
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, CS4265_PWRCTL,
+               snd_soc_component_update_bits(component, CS4265_PWRCTL,
                        CS4265_PWRCTL_PDN,
                        CS4265_PWRCTL_PDN);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, CS4265_PWRCTL,
+               snd_soc_component_update_bits(component, CS4265_PWRCTL,
                        CS4265_PWRCTL_PDN,
                        CS4265_PWRCTL_PDN);
                break;
@@ -544,17 +544,18 @@ static struct snd_soc_dai_driver cs4265_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_cs4265 = {
-       .set_bias_level = cs4265_set_bias_level,
-
-       .component_driver = {
-               .controls               = cs4265_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs4265_snd_controls),
-               .dapm_widgets           = cs4265_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs4265_dapm_widgets),
-               .dapm_routes            = cs4265_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cs4265_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_cs4265 = {
+       .set_bias_level         = cs4265_set_bias_level,
+       .controls               = cs4265_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs4265_snd_controls),
+       .dapm_widgets           = cs4265_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs4265_dapm_widgets),
+       .dapm_routes            = cs4265_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs4265_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config cs4265_regmap = {
@@ -616,18 +617,12 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
 
        regmap_write(cs4265->regmap, CS4265_PWRCTL, 0x0F);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_cs4265, cs4265_dai,
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_cs4265, cs4265_dai,
                        ARRAY_SIZE(cs4265_dai));
        return ret;
 }
 
-static int cs4265_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct of_device_id cs4265_of_match[] = {
        { .compatible = "cirrus,cs4265", },
        { }
@@ -647,7 +642,6 @@ static struct i2c_driver cs4265_i2c_driver = {
        },
        .id_table = cs4265_id,
        .probe =    cs4265_i2c_probe,
-       .remove =   cs4265_i2c_remove,
 };
 
 module_i2c_driver(cs4265_i2c_driver);
index 84f86745c30e93cd746935113f3c0aa08fd4021e..2a7a4168c072a0112939c2a8cd2440bf1fffa481 100644 (file)
@@ -254,8 +254,8 @@ static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
 static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 
        cs4270->mclk = freq;
        return 0;
@@ -277,8 +277,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 
        /* set DAI format */
        switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -287,7 +287,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
                cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
                break;
        default:
-               dev_err(codec->dev, "invalid dai format\n");
+               dev_err(component->dev, "invalid dai format\n");
                return -EINVAL;
        }
 
@@ -301,7 +301,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
                break;
        default:
                /* all other modes are unsupported by the hardware */
-               dev_err(codec->dev, "Unknown master/slave configuration\n");
+               dev_err(component->dev, "Unknown master/slave configuration\n");
                return -EINVAL;
        }
 
@@ -326,8 +326,8 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
        int ret;
        unsigned int i;
        unsigned int rate;
@@ -346,13 +346,13 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
 
        if (i == NUM_MCLK_RATIOS) {
                /* We did not find a matching ratio */
-               dev_err(codec->dev, "could not find matching ratio\n");
+               dev_err(component->dev, "could not find matching ratio\n");
                return -EINVAL;
        }
 
        /* Set the sample rate */
 
-       reg = snd_soc_read(codec, CS4270_MODE);
+       reg = snd_soc_component_read32(component, CS4270_MODE);
        reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
        reg |= cs4270_mode_ratios[i].mclk;
 
@@ -361,15 +361,15 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
        else
                reg |= cs4270_mode_ratios[i].speed_mode;
 
-       ret = snd_soc_write(codec, CS4270_MODE, reg);
+       ret = snd_soc_component_write(component, CS4270_MODE, reg);
        if (ret < 0) {
-               dev_err(codec->dev, "i2c write failed\n");
+               dev_err(component->dev, "i2c write failed\n");
                return ret;
        }
 
        /* Set the DAI format */
 
-       reg = snd_soc_read(codec, CS4270_FORMAT);
+       reg = snd_soc_component_read32(component, CS4270_FORMAT);
        reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
 
        switch (cs4270->mode) {
@@ -380,13 +380,13 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
                reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
                break;
        default:
-               dev_err(codec->dev, "unknown dai format\n");
+               dev_err(component->dev, "unknown dai format\n");
                return -EINVAL;
        }
 
-       ret = snd_soc_write(codec, CS4270_FORMAT, reg);
+       ret = snd_soc_component_write(component, CS4270_FORMAT, reg);
        if (ret < 0) {
-               dev_err(codec->dev, "i2c write failed\n");
+               dev_err(component->dev, "i2c write failed\n");
                return ret;
        }
 
@@ -405,11 +405,11 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
  */
 static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
        int reg6;
 
-       reg6 = snd_soc_read(codec, CS4270_MUTE);
+       reg6 = snd_soc_component_read32(component, CS4270_MUTE);
 
        if (mute)
                reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
@@ -418,7 +418,7 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
                reg6 |= cs4270->manual_mute;
        }
 
-       return snd_soc_write(codec, CS4270_MUTE, reg6);
+       return snd_soc_component_write(component, CS4270_MUTE, reg6);
 }
 
 /**
@@ -438,8 +438,8 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
 static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
        int left = !ucontrol->value.integer.value[0];
        int right = !ucontrol->value.integer.value[1];
 
@@ -501,9 +501,9 @@ static struct snd_soc_dai_driver cs4270_dai = {
  * This function is called when ASoC has all the pieces it needs to
  * instantiate a sound driver.
  */
-static int cs4270_probe(struct snd_soc_codec *codec)
+static int cs4270_probe(struct snd_soc_component *component)
 {
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
        int ret;
 
        /* Disable auto-mute.  This feature appears to be buggy.  In some
@@ -511,9 +511,9 @@ static int cs4270_probe(struct snd_soc_codec *codec)
         * this feature disabled by default.  An application (e.g. alsactl) can
         * re-enabled it by using the controls.
         */
-       ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
+       ret = snd_soc_component_update_bits(component, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "i2c write failed\n");
+               dev_err(component->dev, "i2c write failed\n");
                return ret;
        }
 
@@ -522,10 +522,10 @@ static int cs4270_probe(struct snd_soc_codec *codec)
         * playback has started.  An application (e.g. alsactl) can
         * re-enabled it by using the controls.
         */
-       ret = snd_soc_update_bits(codec, CS4270_TRANS,
+       ret = snd_soc_component_update_bits(component, CS4270_TRANS,
                CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "i2c write failed\n");
+               dev_err(component->dev, "i2c write failed\n");
                return ret;
        }
 
@@ -541,13 +541,11 @@ static int cs4270_probe(struct snd_soc_codec *codec)
  *
  * This function is the counterpart to cs4270_probe().
  */
-static int cs4270_remove(struct snd_soc_codec *codec)
+static void cs4270_remove(struct snd_soc_component *component)
 {
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
 
        regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
-
-       return 0;
 };
 
 #ifdef CONFIG_PM
@@ -561,16 +559,16 @@ static int cs4270_remove(struct snd_soc_codec *codec)
  * and all registers are written back to the hardware when resuming.
  */
 
-static int cs4270_soc_suspend(struct snd_soc_codec *codec)
+static int cs4270_soc_suspend(struct snd_soc_component *component)
 {
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
        int reg, ret;
 
-       reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
+       reg = snd_soc_component_read32(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
        if (reg < 0)
                return reg;
 
-       ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
+       ret = snd_soc_component_write(component, CS4270_PWRCTL, reg);
        if (ret < 0)
                return ret;
 
@@ -580,9 +578,9 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int cs4270_soc_resume(struct snd_soc_codec *codec)
+static int cs4270_soc_resume(struct snd_soc_component *component)
 {
-       struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+       struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component);
        int reg, ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
@@ -598,10 +596,10 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
        regcache_sync(cs4270->regmap);
 
        /* ... then disable the power-down bits */
-       reg = snd_soc_read(codec, CS4270_PWRCTL);
+       reg = snd_soc_component_read32(component, CS4270_PWRCTL);
        reg &= ~CS4270_PWRCTL_PDN_ALL;
 
-       return snd_soc_write(codec, CS4270_PWRCTL, reg);
+       return snd_soc_component_write(component, CS4270_PWRCTL, reg);
 }
 #else
 #define cs4270_soc_suspend     NULL
@@ -611,20 +609,21 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
 /*
  * ASoC codec driver structure
  */
-static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
-       .probe =                cs4270_probe,
-       .remove =               cs4270_remove,
-       .suspend =              cs4270_soc_suspend,
-       .resume =               cs4270_soc_resume,
-
-       .component_driver = {
-               .controls =             cs4270_snd_controls,
-               .num_controls =         ARRAY_SIZE(cs4270_snd_controls),
-               .dapm_widgets =         cs4270_dapm_widgets,
-               .num_dapm_widgets =     ARRAY_SIZE(cs4270_dapm_widgets),
-               .dapm_routes =          cs4270_dapm_routes,
-               .num_dapm_routes =      ARRAY_SIZE(cs4270_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_device_cs4270 = {
+       .probe                  = cs4270_probe,
+       .remove                 = cs4270_remove,
+       .suspend                = cs4270_soc_suspend,
+       .resume                 = cs4270_soc_resume,
+       .controls               = cs4270_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs4270_snd_controls),
+       .dapm_widgets           = cs4270_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs4270_dapm_widgets),
+       .dapm_routes            = cs4270_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs4270_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /*
@@ -718,23 +717,11 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 
        i2c_set_clientdata(i2c_client, cs4270);
 
-       ret = snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_device_cs4270, &cs4270_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_device_cs4270, &cs4270_dai, 1);
        return ret;
 }
 
-/**
- * cs4270_i2c_remove - remove an I2C device
- * @i2c_client: the I2C client object
- *
- * This function is the counterpart to cs4270_i2c_probe().
- */
-static int cs4270_i2c_remove(struct i2c_client *i2c_client)
-{
-       snd_soc_unregister_codec(&i2c_client->dev);
-       return 0;
-}
-
 /*
  * cs4270_id - I2C device IDs supported by this driver
  */
@@ -757,7 +744,6 @@ static struct i2c_driver cs4270_i2c_driver = {
        },
        .id_table = cs4270_id,
        .probe = cs4270_i2c_probe,
-       .remove = cs4270_i2c_remove,
 };
 
 module_i2c_driver(cs4270_i2c_driver);
index dcb3223d7d8f7cc909a357689d3292bb2a7f0ac6..ff737304d50b9d8acfe151c7e64c54b346404fe0 100644 (file)
@@ -33,12 +33,6 @@ static int cs4271_i2c_probe(struct i2c_client *client,
                            devm_regmap_init_i2c(client, &config));
 }
 
-static int cs4271_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id cs4271_i2c_id[] = {
        { "cs4271", 0 },
        { }
@@ -51,7 +45,6 @@ static struct i2c_driver cs4271_i2c_driver = {
                .of_match_table = of_match_ptr(cs4271_dt_ids),
        },
        .probe = cs4271_i2c_probe,
-       .remove = cs4271_i2c_remove,
        .id_table = cs4271_i2c_id,
 };
 module_i2c_driver(cs4271_i2c_driver);
index 1ff5f520196af3c9ee901ac2a430ab21c6c39122..217f6dc869e52b66f4daaf6a7a19fbee23629e93 100644 (file)
@@ -33,19 +33,12 @@ static int cs4271_spi_probe(struct spi_device *spi)
        return cs4271_probe(&spi->dev, devm_regmap_init_spi(spi, &config));
 }
 
-static int cs4271_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver cs4271_spi_driver = {
        .driver = {
                .name   = "cs4271",
                .of_match_table = of_match_ptr(cs4271_dt_ids),
        },
        .probe          = cs4271_spi_probe,
-       .remove         = cs4271_spi_remove,
 };
 module_spi_driver(cs4271_spi_driver);
 
index 49a80627af121d9f45d4adc6ffbd8530c553993a..849fdb2cb26043f03753fcfac000fd22aa88faed 100644 (file)
@@ -206,8 +206,8 @@ static const struct snd_soc_dapm_route cs4271_dapm_routes[] = {
 static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        cs4271->mclk = freq;
        return 0;
@@ -216,8 +216,8 @@ static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
        int ret;
 
@@ -230,7 +230,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
                val |= CS4271_MODE1_MASTER;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -250,7 +250,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
                        return ret;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -263,9 +263,9 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int cs4271_deemph[] = {0, 44100, 48000, 32000};
 
-static int cs4271_set_deemph(struct snd_soc_codec *codec)
+static int cs4271_set_deemph(struct snd_soc_component *component)
 {
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
        int i, ret;
        int val = CS4271_DACCTL_DEM_DIS;
 
@@ -289,8 +289,8 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec)
 static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = cs4271->deemph;
        return 0;
@@ -299,11 +299,11 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
 static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        cs4271->deemph = ucontrol->value.integer.value[0];
-       return cs4271_set_deemph(codec);
+       return cs4271_set_deemph(component);
 }
 
 struct cs4271_clk_cfg {
@@ -349,8 +349,8 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
        int i, ret;
        unsigned int ratio, val;
 
@@ -399,7 +399,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
                        break;
 
        if (i == CS4171_NR_RATIOS) {
-               dev_err(codec->dev, "Invalid sample rate\n");
+               dev_err(component->dev, "Invalid sample rate\n");
                return -EINVAL;
        }
 
@@ -410,13 +410,13 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       return cs4271_set_deemph(codec);
+       return cs4271_set_deemph(component);
 }
 
 static int cs4271_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
        int ret;
        int val_a = 0;
        int val_b = 0;
@@ -493,9 +493,9 @@ static struct snd_soc_dai_driver cs4271_dai = {
        .symmetric_rates = 1,
 };
 
-static int cs4271_reset(struct snd_soc_codec *codec)
+static int cs4271_reset(struct snd_soc_component *component)
 {
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(cs4271->gpio_nreset)) {
                gpio_direction_output(cs4271->gpio_nreset, 0);
@@ -508,10 +508,10 @@ static int cs4271_reset(struct snd_soc_codec *codec)
 }
 
 #ifdef CONFIG_PM
-static int cs4271_soc_suspend(struct snd_soc_codec *codec)
+static int cs4271_soc_suspend(struct snd_soc_component *component)
 {
        int ret;
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        /* Set power-down bit */
        ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
@@ -525,20 +525,20 @@ static int cs4271_soc_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int cs4271_soc_resume(struct snd_soc_codec *codec)
+static int cs4271_soc_resume(struct snd_soc_component *component)
 {
        int ret;
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        ret = regulator_bulk_enable(ARRAY_SIZE(cs4271->supplies),
                                    cs4271->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+               dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
                return ret;
        }
 
        /* Do a proper reset after power up */
-       cs4271_reset(codec);
+       cs4271_reset(component);
 
        /* Restore codec state */
        ret = regcache_sync(cs4271->regmap);
@@ -567,20 +567,20 @@ MODULE_DEVICE_TABLE(of, cs4271_dt_ids);
 EXPORT_SYMBOL_GPL(cs4271_dt_ids);
 #endif
 
-static int cs4271_codec_probe(struct snd_soc_codec *codec)
+static int cs4271_component_probe(struct snd_soc_component *component)
 {
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
-       struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
+       struct cs4271_platform_data *cs4271plat = component->dev->platform_data;
        int ret;
        bool amutec_eq_bmutec = false;
 
 #ifdef CONFIG_OF
-       if (of_match_device(cs4271_dt_ids, codec->dev)) {
-               if (of_get_property(codec->dev->of_node,
+       if (of_match_device(cs4271_dt_ids, component->dev)) {
+               if (of_get_property(component->dev->of_node,
                                     "cirrus,amutec-eq-bmutec", NULL))
                        amutec_eq_bmutec = true;
 
-               if (of_get_property(codec->dev->of_node,
+               if (of_get_property(component->dev->of_node,
                                     "cirrus,enable-soft-reset", NULL))
                        cs4271->enable_soft_reset = true;
        }
@@ -589,7 +589,7 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
        ret = regulator_bulk_enable(ARRAY_SIZE(cs4271->supplies),
                                    cs4271->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+               dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
                return ret;
        }
 
@@ -599,7 +599,7 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
        }
 
        /* Reset codec */
-       cs4271_reset(codec);
+       cs4271_reset(component);
 
        ret = regcache_sync(cs4271->regmap);
        if (ret < 0)
@@ -625,9 +625,9 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int cs4271_codec_remove(struct snd_soc_codec *codec)
+static void cs4271_component_remove(struct snd_soc_component *component)
 {
-       struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
+       struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(cs4271->gpio_nreset))
                /* Set codec to the reset state */
@@ -635,24 +635,23 @@ static int cs4271_codec_remove(struct snd_soc_codec *codec)
 
        regcache_mark_dirty(cs4271->regmap);
        regulator_bulk_disable(ARRAY_SIZE(cs4271->supplies), cs4271->supplies);
-
-       return 0;
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
-       .probe                  = cs4271_codec_probe,
-       .remove                 = cs4271_codec_remove,
+static const struct snd_soc_component_driver soc_component_dev_cs4271 = {
+       .probe                  = cs4271_component_probe,
+       .remove                 = cs4271_component_remove,
        .suspend                = cs4271_soc_suspend,
        .resume                 = cs4271_soc_resume,
-
-       .component_driver = {
-               .controls               = cs4271_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs4271_snd_controls),
-               .dapm_widgets           = cs4271_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs4271_dapm_widgets),
-               .dapm_routes            = cs4271_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(cs4271_dapm_routes),
-       },
+       .controls               = cs4271_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs4271_snd_controls),
+       .dapm_widgets           = cs4271_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs4271_dapm_widgets),
+       .dapm_routes            = cs4271_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs4271_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int cs4271_common_probe(struct device *dev,
@@ -721,8 +720,8 @@ int cs4271_probe(struct device *dev, struct regmap *regmap)
        dev_set_drvdata(dev, cs4271);
        cs4271->regmap = regmap;
 
-       return snd_soc_register_codec(dev, &soc_codec_dev_cs4271, &cs4271_dai,
-                                     1);
+       return devm_snd_soc_register_component(dev, &soc_component_dev_cs4271,
+                                              &cs4271_dai, 1);
 }
 EXPORT_SYMBOL_GPL(cs4271_probe);
 
index a2324a0e72ee516c6dfb6069a462f588734e06bf..651329bf974325e48fc39b0740e010a661ba6541 100644 (file)
@@ -468,33 +468,33 @@ static const struct snd_kcontrol_new cs42l42_snd_controls[] = {
 static int cs42l42_hpdrv_evt(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        if (event & SND_SOC_DAPM_POST_PMU) {
                /* Enable the channels */
-               snd_soc_update_bits(codec, CS42L42_ASP_RX_DAI0_EN,
+               snd_soc_component_update_bits(component, CS42L42_ASP_RX_DAI0_EN,
                                CS42L42_ASP_RX0_CH_EN_MASK,
                                (CS42L42_ASP_RX0_CH1_EN |
                                CS42L42_ASP_RX0_CH2_EN) <<
                                CS42L42_ASP_RX0_CH_EN_SHIFT);
 
                /* Power up */
-               snd_soc_update_bits(codec, CS42L42_PWR_CTL1,
+               snd_soc_component_update_bits(component, CS42L42_PWR_CTL1,
                        CS42L42_ASP_DAI_PDN_MASK | CS42L42_MIXER_PDN_MASK |
                                CS42L42_HP_PDN_MASK, 0);
        } else if (event & SND_SOC_DAPM_PRE_PMD) {
                /* Disable the channels */
-               snd_soc_update_bits(codec, CS42L42_ASP_RX_DAI0_EN,
+               snd_soc_component_update_bits(component, CS42L42_ASP_RX_DAI0_EN,
                                CS42L42_ASP_RX0_CH_EN_MASK, 0);
 
                /* Power down */
-               snd_soc_update_bits(codec, CS42L42_PWR_CTL1,
+               snd_soc_component_update_bits(component, CS42L42_PWR_CTL1,
                        CS42L42_ASP_DAI_PDN_MASK | CS42L42_MIXER_PDN_MASK |
                                CS42L42_HP_PDN_MASK,
                        CS42L42_ASP_DAI_PDN_MASK | CS42L42_MIXER_PDN_MASK |
                                CS42L42_HP_PDN_MASK);
        } else {
-               dev_err(codec->dev, "Invalid event 0x%x\n", event);
+               dev_err(component->dev, "Invalid event 0x%x\n", event);
        }
        return 0;
 }
@@ -515,10 +515,10 @@ static const struct snd_soc_dapm_route cs42l42_audio_map[] = {
        {"HP", NULL, "HPDRV"}
 };
 
-static int cs42l42_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l42_set_bias_level(struct snd_soc_component *component,
                                        enum snd_soc_bias_level level)
 {
-       struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -527,14 +527,14 @@ static int cs42l42_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        regcache_cache_only(cs42l42->regmap, false);
                        regcache_sync(cs42l42->regmap);
                        ret = regulator_bulk_enable(
                                                ARRAY_SIZE(cs42l42->supplies),
                                                cs42l42->supplies);
                        if (ret != 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to enable regulators: %d\n",
                                        ret);
                                return ret;
@@ -552,30 +552,28 @@ static int cs42l42_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int cs42l42_codec_probe(struct snd_soc_codec *codec)
+static int cs42l42_component_probe(struct snd_soc_component *component)
 {
        struct cs42l42_private *cs42l42 =
-               (struct cs42l42_private *)snd_soc_codec_get_drvdata(codec);
+               (struct cs42l42_private *)snd_soc_component_get_drvdata(component);
 
-       cs42l42->codec = codec;
+       cs42l42->component = component;
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l42 = {
-       .probe = cs42l42_codec_probe,
-       .set_bias_level = cs42l42_set_bias_level,
-       .ignore_pmdown_time = true,
-
-       .component_driver = {
-               .dapm_widgets = cs42l42_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
-               .dapm_routes = cs42l42_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map),
-
-               .controls = cs42l42_snd_controls,
-               .num_controls = ARRAY_SIZE(cs42l42_snd_controls),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
+       .probe                  = cs42l42_component_probe,
+       .set_bias_level         = cs42l42_set_bias_level,
+       .dapm_widgets           = cs42l42_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs42l42_dapm_widgets),
+       .dapm_routes            = cs42l42_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs42l42_audio_map),
+       .controls               = cs42l42_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs42l42_snd_controls),
+       .idle_bias_on           = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 struct cs42l42_pll_params {
@@ -613,16 +611,16 @@ static const struct cs42l42_pll_params pll_ratio_table[] = {
        { 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0 }
 };
 
-static int cs42l42_pll_config(struct snd_soc_codec *codec)
+static int cs42l42_pll_config(struct snd_soc_component *component)
 {
-       struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
        int i;
        u32 fsync;
 
        for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
                if (pll_ratio_table[i].sclk == cs42l42->sclk) {
                        /* Configure the internal sample rate */
-                       snd_soc_update_bits(codec, CS42L42_MCLK_CTL,
+                       snd_soc_component_update_bits(component, CS42L42_MCLK_CTL,
                                        CS42L42_INTERNAL_FS_MASK,
                                        ((pll_ratio_table[i].mclk_int !=
                                        12000000) &&
@@ -632,7 +630,7 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
                        /* Set the MCLK src (PLL or SCLK) and the divide
                         * ratio
                         */
-                       snd_soc_update_bits(codec, CS42L42_MCLK_SRC_SEL,
+                       snd_soc_component_update_bits(component, CS42L42_MCLK_SRC_SEL,
                                        CS42L42_MCLK_SRC_SEL_MASK |
                                        CS42L42_MCLKDIV_MASK,
                                        (pll_ratio_table[i].mclk_src_sel
@@ -643,62 +641,62 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
                        fsync = cs42l42->sclk / cs42l42->srate;
                        if (((fsync * cs42l42->srate) != cs42l42->sclk)
                                || ((fsync % 2) != 0)) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Unsupported sclk %d/sample rate %d\n",
                                        cs42l42->sclk,
                                        cs42l42->srate);
                                return -EINVAL;
                        }
                        /* Set the LRCLK period */
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_FSYNC_P_LOWER,
                                        CS42L42_FSYNC_PERIOD_MASK,
                                        CS42L42_FRAC0_VAL(fsync - 1) <<
                                        CS42L42_FSYNC_PERIOD_SHIFT);
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_FSYNC_P_UPPER,
                                        CS42L42_FSYNC_PERIOD_MASK,
                                        CS42L42_FRAC1_VAL(fsync - 1) <<
                                        CS42L42_FSYNC_PERIOD_SHIFT);
                        /* Set the LRCLK to 50% duty cycle */
                        fsync = fsync / 2;
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_FSYNC_PW_LOWER,
                                        CS42L42_FSYNC_PULSE_WIDTH_MASK,
                                        CS42L42_FRAC0_VAL(fsync - 1) <<
                                        CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_FSYNC_PW_UPPER,
                                        CS42L42_FSYNC_PULSE_WIDTH_MASK,
                                        CS42L42_FRAC1_VAL(fsync - 1) <<
                                        CS42L42_FSYNC_PULSE_WIDTH_SHIFT);
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_ASP_FRM_CFG,
                                        CS42L42_ASP_5050_MASK,
                                        CS42L42_ASP_5050_MASK);
                        /* Set the frame delay to 1.0 SCLK clocks */
-                       snd_soc_update_bits(codec, CS42L42_ASP_FRM_CFG,
+                       snd_soc_component_update_bits(component, CS42L42_ASP_FRM_CFG,
                                        CS42L42_ASP_FSD_MASK,
                                        CS42L42_ASP_FSD_1_0 <<
                                        CS42L42_ASP_FSD_SHIFT);
                        /* Set the sample rates (96k or lower) */
-                       snd_soc_update_bits(codec, CS42L42_FS_RATE_EN,
+                       snd_soc_component_update_bits(component, CS42L42_FS_RATE_EN,
                                        CS42L42_FS_EN_MASK,
                                        (CS42L42_FS_EN_IASRC_96K |
                                        CS42L42_FS_EN_OASRC_96K) <<
                                        CS42L42_FS_EN_SHIFT);
                        /* Set the input/output internal MCLK clock ~12 MHz */
-                       snd_soc_update_bits(codec, CS42L42_IN_ASRC_CLK,
+                       snd_soc_component_update_bits(component, CS42L42_IN_ASRC_CLK,
                                        CS42L42_CLK_IASRC_SEL_MASK,
                                        CS42L42_CLK_IASRC_SEL_12 <<
                                        CS42L42_CLK_IASRC_SEL_SHIFT);
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_OUT_ASRC_CLK,
                                        CS42L42_CLK_OASRC_SEL_MASK,
                                        CS42L42_CLK_OASRC_SEL_12 <<
                                        CS42L42_CLK_OASRC_SEL_SHIFT);
                        /* channel 1 on low LRCLK, 32 bit */
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_ASP_RX_DAI0_CH1_AP_RES,
                                        CS42L42_ASP_RX_CH_AP_MASK |
                                        CS42L42_ASP_RX_CH_RES_MASK,
@@ -707,7 +705,7 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
                                        (CS42L42_ASP_RX_CH_RES_32 <<
                                        CS42L42_ASP_RX_CH_RES_SHIFT));
                        /* Channel 2 on high LRCLK, 32 bit */
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                        CS42L42_ASP_RX_DAI0_CH2_AP_RES,
                                        CS42L42_ASP_RX_CH_AP_MASK |
                                        CS42L42_ASP_RX_CH_RES_MASK,
@@ -717,50 +715,50 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
                                        CS42L42_ASP_RX_CH_RES_SHIFT));
                        if (pll_ratio_table[i].mclk_src_sel == 0) {
                                /* Pass the clock straight through */
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_CTL1,
                                        CS42L42_PLL_START_MASK, 0);
                        } else {
                                /* Configure PLL per table 4-5 */
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_DIV_CFG1,
                                        CS42L42_SCLK_PREDIV_MASK,
                                        pll_ratio_table[i].sclk_prediv
                                        << CS42L42_SCLK_PREDIV_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_DIV_INT,
                                        CS42L42_PLL_DIV_INT_MASK,
                                        pll_ratio_table[i].pll_div_int
                                        << CS42L42_PLL_DIV_INT_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_DIV_FRAC0,
                                        CS42L42_PLL_DIV_FRAC_MASK,
                                        CS42L42_FRAC0_VAL(
                                        pll_ratio_table[i].pll_div_frac)
                                        << CS42L42_PLL_DIV_FRAC_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_DIV_FRAC1,
                                        CS42L42_PLL_DIV_FRAC_MASK,
                                        CS42L42_FRAC1_VAL(
                                        pll_ratio_table[i].pll_div_frac)
                                        << CS42L42_PLL_DIV_FRAC_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_DIV_FRAC2,
                                        CS42L42_PLL_DIV_FRAC_MASK,
                                        CS42L42_FRAC2_VAL(
                                        pll_ratio_table[i].pll_div_frac)
                                        << CS42L42_PLL_DIV_FRAC_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_CTL4,
                                        CS42L42_PLL_MODE_MASK,
                                        pll_ratio_table[i].pll_mode
                                        << CS42L42_PLL_MODE_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_CTL3,
                                        CS42L42_PLL_DIVOUT_MASK,
                                        pll_ratio_table[i].pll_divout
                                        << CS42L42_PLL_DIVOUT_SHIFT);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        CS42L42_PLL_CAL_RATIO,
                                        CS42L42_PLL_CAL_RATIO_MASK,
                                        pll_ratio_table[i].pll_cal_ratio
@@ -775,7 +773,7 @@ static int cs42l42_pll_config(struct snd_soc_codec *codec)
 
 static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u32 asp_cfg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -820,7 +818,7 @@ static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                break;
        }
 
-       snd_soc_update_bits(codec, CS42L42_ASP_CLK_CFG,
+       snd_soc_component_update_bits(component, CS42L42_ASP_CLK_CFG,
                                CS42L42_ASP_MODE_MASK |
                                CS42L42_ASP_SCPOL_IN_DAC_MASK |
                                CS42L42_ASP_LCPOL_IN_MASK, asp_cfg_val);
@@ -832,14 +830,14 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
        int retval;
 
        cs42l42->srate = params_rate(params);
        cs42l42->swidth = params_width(params);
 
-       retval = cs42l42_pll_config(codec);
+       retval = cs42l42_pll_config(component);
 
        return retval;
 }
@@ -847,8 +845,8 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
 static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l42_private *cs42l42 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
 
        cs42l42->sclk = freq;
 
@@ -857,7 +855,7 @@ static int cs42l42_set_sysclk(struct snd_soc_dai *dai,
 
 static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int regval;
        u8 fullScaleVol;
 
@@ -865,25 +863,25 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
                /* Mark SCLK as not present to turn on the internal
                 * oscillator.
                 */
-               snd_soc_update_bits(codec, CS42L42_OSC_SWITCH,
+               snd_soc_component_update_bits(component, CS42L42_OSC_SWITCH,
                                                CS42L42_SCLK_PRESENT_MASK, 0);
 
-               snd_soc_update_bits(codec, CS42L42_PLL_CTL1,
+               snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
                                CS42L42_PLL_START_MASK,
                                0 << CS42L42_PLL_START_SHIFT);
 
                /* Mute the headphone */
-               snd_soc_update_bits(codec, CS42L42_HP_CTL,
+               snd_soc_component_update_bits(component, CS42L42_HP_CTL,
                                CS42L42_HP_ANA_AMUTE_MASK |
                                CS42L42_HP_ANA_BMUTE_MASK,
                                CS42L42_HP_ANA_AMUTE_MASK |
                                CS42L42_HP_ANA_BMUTE_MASK);
        } else {
-               snd_soc_update_bits(codec, CS42L42_PLL_CTL1,
+               snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
                                CS42L42_PLL_START_MASK,
                                1 << CS42L42_PLL_START_SHIFT);
                /* Read the headphone load */
-               regval = snd_soc_read(codec, CS42L42_LOAD_DET_RCSTAT);
+               regval = snd_soc_component_read32(component, CS42L42_LOAD_DET_RCSTAT);
                if (((regval & CS42L42_RLA_STAT_MASK) >>
                        CS42L42_RLA_STAT_SHIFT) == CS42L42_RLA_STAT_15_OHM) {
                        fullScaleVol = CS42L42_HP_FULL_SCALE_VOL_MASK;
@@ -892,13 +890,13 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
                }
 
                /* Un-mute the headphone, set the full scale volume flag */
-               snd_soc_update_bits(codec, CS42L42_HP_CTL,
+               snd_soc_component_update_bits(component, CS42L42_HP_CTL,
                                CS42L42_HP_ANA_AMUTE_MASK |
                                CS42L42_HP_ANA_BMUTE_MASK |
                                CS42L42_HP_FULL_SCALE_VOL_MASK, fullScaleVol);
 
                /* Mark SCLK as present, turn off internal oscillator */
-               snd_soc_update_bits(codec, CS42L42_OSC_SWITCH,
+               snd_soc_component_update_bits(component, CS42L42_OSC_SWITCH,
                                CS42L42_SCLK_PRESENT_MASK,
                                CS42L42_SCLK_PRESENT_MASK);
        }
@@ -1262,16 +1260,16 @@ static void cs42l42_handle_button_press(struct cs42l42_private *cs42l42)
 
        switch (bias_level) {
        case 1: /* Function C button press */
-               dev_dbg(cs42l42->codec->dev, "Function C button press\n");
+               dev_dbg(cs42l42->component->dev, "Function C button press\n");
                break;
        case 2: /* Function B button press */
-               dev_dbg(cs42l42->codec->dev, "Function B button press\n");
+               dev_dbg(cs42l42->component->dev, "Function B button press\n");
                break;
        case 3: /* Function D button press */
-               dev_dbg(cs42l42->codec->dev, "Function D button press\n");
+               dev_dbg(cs42l42->component->dev, "Function D button press\n");
                break;
        case 4: /* Function A button press */
-               dev_dbg(cs42l42->codec->dev, "Function A button press\n");
+               dev_dbg(cs42l42->component->dev, "Function A button press\n");
                break;
        }
 
@@ -1340,7 +1338,7 @@ static const struct cs42l42_irq_params irq_params_table[] = {
 static irqreturn_t cs42l42_irq_thread(int irq, void *data)
 {
        struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data;
-       struct snd_soc_codec *codec = cs42l42->codec;
+       struct snd_soc_component *component = cs42l42->component;
        unsigned int stickies[12];
        unsigned int masks[12];
        unsigned int current_plug_status;
@@ -1372,7 +1370,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
        if ((~masks[5]) & irq_params_table[5].mask) {
                if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) {
                        cs42l42_process_hs_type_detect(cs42l42);
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Auto detect done (%d)\n",
                                cs42l42->hs_type);
                }
@@ -1392,7 +1390,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
                        if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
                                cs42l42->plug_state = CS42L42_TS_UNPLUG;
                                cs42l42_cancel_hs_type_detect(cs42l42);
-                               dev_dbg(codec->dev,
+                               dev_dbg(component->dev,
                                        "Unplug event\n");
                        }
                        break;
@@ -1410,7 +1408,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
 
                        if (current_button_status &
                                CS42L42_M_DETECT_TF_MASK) {
-                               dev_dbg(codec->dev,
+                               dev_dbg(component->dev,
                                        "Button released\n");
                        } else if (current_button_status &
                                CS42L42_M_DETECT_FT_MASK) {
@@ -1879,8 +1877,8 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
        cs42l42_set_interrupt_masks(cs42l42);
 
        /* Register codec for machine driver */
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs42l42, &cs42l42_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs42l42, &cs42l42_dai, 1);
        if (ret < 0)
                goto err_disable;
        return 0;
@@ -1895,8 +1893,6 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client)
 {
        struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client);
 
-       snd_soc_unregister_codec(&i2c_client->dev);
-
        /* Hold down reset */
        gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
 
index d87a0a5322d589bd5f0d2d96a57b72c73ddd80e3..09b0a93203efbac86360b2c5f302811ea46ea92f 100644 (file)
@@ -754,7 +754,7 @@ static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = {
 
 struct  cs42l42_private {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regulator_bulk_data supplies[CS42L42_NUM_SUPPLIES];
        struct gpio_desc *reset_gpio;
        struct completion pdn_done;
index 9bad478474fa3eda856b01b3911cefd2edb410c2..4b5731a4187622ceeddf24d7b6f3969536ef45fe 100644 (file)
@@ -35,20 +35,12 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c,
        return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config));
 }
 
-static int cs42l51_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static struct i2c_driver cs42l51_i2c_driver = {
        .driver = {
                .name = "cs42l51",
                .of_match_table = cs42l51_of_match,
        },
        .probe = cs42l51_i2c_probe,
-       .remove = cs42l51_i2c_remove,
        .id_table = cs42l51_i2c_id,
 };
 
index f8072f1897d4c47a7d91c9c6d00eedffd9ef2fba..5080d7a3c27982a4e619f75bc2069c1e2bfbf6ac 100644 (file)
@@ -54,8 +54,8 @@ struct cs42l51_private {
 static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
                        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3;
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       unsigned long value = snd_soc_component_read32(component, CS42L51_PCM_MIXER)&3;
 
        switch (value) {
        default:
@@ -82,7 +82,7 @@ static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
 static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
                        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned char val;
 
        switch (ucontrol->value.enumerated.item[0]) {
@@ -98,7 +98,7 @@ static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
                break;
        }
 
-       snd_soc_write(codec, CS42L51_PCM_MIXER, val);
+       snd_soc_component_write(component, CS42L51_PCM_MIXER, val);
 
        return 1;
 }
@@ -153,17 +153,17 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
 static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, CS42L51_POWER_CTL1,
+               snd_soc_component_update_bits(component, CS42L51_POWER_CTL1,
                                    CS42L51_POWER_CTL1_PDN,
                                    CS42L51_POWER_CTL1_PDN);
                break;
        default:
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, CS42L51_POWER_CTL1,
+               snd_soc_component_update_bits(component, CS42L51_POWER_CTL1,
                                    CS42L51_POWER_CTL1_PDN, 0);
                break;
        }
@@ -263,8 +263,8 @@ static const struct snd_soc_dapm_route cs42l51_routes[] = {
 static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
 
        switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
@@ -273,7 +273,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
                cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
                break;
        default:
-               dev_err(codec->dev, "invalid DAI format\n");
+               dev_err(component->dev, "invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -285,7 +285,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
                cs42l51->func = MODE_SLAVE_AUTO;
                break;
        default:
-               dev_err(codec->dev, "Unknown master/slave configuration\n");
+               dev_err(component->dev, "Unknown master/slave configuration\n");
                return -EINVAL;
        }
 
@@ -326,8 +326,8 @@ static struct cs42l51_ratios slave_auto_ratios[] = {
 static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
 
        cs42l51->mclk = freq;
        return 0;
@@ -337,8 +337,8 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
        int ret;
        unsigned int i;
        unsigned int rate;
@@ -370,12 +370,12 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
 
        if (i == nr_ratios) {
                /* We did not find a matching ratio */
-               dev_err(codec->dev, "could not find matching ratio\n");
+               dev_err(component->dev, "could not find matching ratio\n");
                return -EINVAL;
        }
 
-       intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL);
-       power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL);
+       intf_ctl = snd_soc_component_read32(component, CS42L51_INTF_CTL);
+       power_ctl = snd_soc_component_read32(component, CS42L51_MIC_POWER_CTL);
 
        intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
                        | CS42L51_INTF_CTL_DAC_FORMAT(7));
@@ -418,24 +418,24 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
                        fmt = CS42L51_DAC_DIF_RJ24;
                        break;
                default:
-                       dev_err(codec->dev, "unknown format\n");
+                       dev_err(component->dev, "unknown format\n");
                        return -EINVAL;
                }
                intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
                break;
        default:
-               dev_err(codec->dev, "unknown format\n");
+               dev_err(component->dev, "unknown format\n");
                return -EINVAL;
        }
 
        if (ratios[i].mclk)
                power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
 
-       ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl);
+       ret = snd_soc_component_write(component, CS42L51_INTF_CTL, intf_ctl);
        if (ret < 0)
                return ret;
 
-       ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl);
+       ret = snd_soc_component_write(component, CS42L51_MIC_POWER_CTL, power_ctl);
        if (ret < 0)
                return ret;
 
@@ -444,18 +444,18 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
 
 static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int reg;
        int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
 
-       reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL);
+       reg = snd_soc_component_read32(component, CS42L51_DAC_OUT_CTL);
 
        if (mute)
                reg |= mask;
        else
                reg &= ~mask;
 
-       return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
+       return snd_soc_component_write(component, CS42L51_DAC_OUT_CTL, reg);
 }
 
 static const struct snd_soc_dai_ops cs42l51_dai_ops = {
@@ -484,7 +484,7 @@ static struct snd_soc_dai_driver cs42l51_dai = {
        .ops = &cs42l51_dai_ops,
 };
 
-static int cs42l51_codec_probe(struct snd_soc_codec *codec)
+static int cs42l51_component_probe(struct snd_soc_component *component)
 {
        int ret, reg;
 
@@ -497,24 +497,25 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec)
         */
        reg = CS42L51_DAC_CTL_DATA_SEL(1)
                | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
-       ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
+       ret = snd_soc_component_write(component, CS42L51_DAC_CTL, reg);
        if (ret < 0)
                return ret;
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
-       .probe = cs42l51_codec_probe,
-
-       .component_driver = {
-               .controls               = cs42l51_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs42l51_snd_controls),
-               .dapm_widgets           = cs42l51_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs42l51_dapm_widgets),
-               .dapm_routes            = cs42l51_routes,
-               .num_dapm_routes        = ARRAY_SIZE(cs42l51_routes),
-       },
+static const struct snd_soc_component_driver soc_component_device_cs42l51 = {
+       .probe                  = cs42l51_component_probe,
+       .controls               = cs42l51_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs42l51_snd_controls),
+       .dapm_widgets           = cs42l51_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs42l51_dapm_widgets),
+       .dapm_routes            = cs42l51_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs42l51_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 const struct regmap_config cs42l51_regmap = {
@@ -555,8 +556,8 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap)
        dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n",
                 val & CS42L51_CHIP_REV_MASK);
 
-       ret =  snd_soc_register_codec(dev,
-                       &soc_codec_device_cs42l51, &cs42l51_dai, 1);
+       ret = devm_snd_soc_register_component(dev,
+                       &soc_component_device_cs42l51, &cs42l51_dai, 1);
 error:
        return ret;
 }
index 9731e5dff291495e168f505e0a0126e4b8fbd4ea..3d83c1be12922d5f26c9ea3792a5aea36e761e7d 100644 (file)
@@ -42,7 +42,7 @@ struct sp_config {
 
 struct  cs42l52_private {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct device *dev;
        struct sp_config config;
        struct cs42l52_platform_data pdata;
@@ -473,17 +473,17 @@ static const struct snd_kcontrol_new cs42l52_micb_controls[] = {
        SOC_ENUM("MICB Select", micb_enum),
 };
 
-static int cs42l52_add_mic_controls(struct snd_soc_codec *codec)
+static int cs42l52_add_mic_controls(struct snd_soc_component *component)
 {
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
        struct cs42l52_platform_data *pdata = &cs42l52->pdata;
 
        if (!pdata->mica_diff_cfg)
-               snd_soc_add_codec_controls(codec, cs42l52_mica_controls,
+               snd_soc_add_component_controls(component, cs42l52_mica_controls,
                                     ARRAY_SIZE(cs42l52_mica_controls));
 
        if (!pdata->micb_diff_cfg)
-               snd_soc_add_codec_controls(codec, cs42l52_micb_controls,
+               snd_soc_add_component_controls(component, cs42l52_micb_controls,
                                     ARRAY_SIZE(cs42l52_micb_controls));
 
        return 0;
@@ -716,13 +716,13 @@ static int cs42l52_get_clk(int mclk, int rate)
 static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
                        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
        if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
                cs42l52->sysclk = freq;
        } else {
-               dev_err(codec->dev, "Invalid freq parameter\n");
+               dev_err(component->dev, "Invalid freq parameter\n");
                return -EINVAL;
        }
        return 0;
@@ -730,8 +730,8 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
        u8 iface = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -783,21 +783,21 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
        cs42l52->config.format = iface;
-       snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
+       snd_soc_component_write(component, CS42L52_IFACE_CTL1, cs42l52->config.format);
 
        return 0;
 }
 
 static int cs42l52_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute)
-               snd_soc_update_bits(codec, CS42L52_PB_CTL1,
+               snd_soc_component_update_bits(component, CS42L52_PB_CTL1,
                                    CS42L52_PB_CTL1_MUTE_MASK,
                                CS42L52_PB_CTL1_MUTE);
        else
-               snd_soc_update_bits(codec, CS42L52_PB_CTL1,
+               snd_soc_component_update_bits(component, CS42L52_PB_CTL1,
                                    CS42L52_PB_CTL1_MUTE_MASK,
                                CS42L52_PB_CTL1_UNMUTE);
 
@@ -808,8 +808,8 @@ static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *params,
                                     struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
        u32 clk = 0;
        int index;
 
@@ -823,36 +823,36 @@ static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
                (clk_map_table[index].ratio << CLK_RATIO_SHIFT) |
                clk_map_table[index].mclkdiv2;
 
-               snd_soc_write(codec, CS42L52_CLK_CTL, clk);
+               snd_soc_component_write(component, CS42L52_CLK_CTL, clk);
        } else {
-               dev_err(codec->dev, "can't get correct mclk\n");
+               dev_err(component->dev, "can't get correct mclk\n");
                return -EINVAL;
        }
 
        return 0;
 }
 
-static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l52_set_bias_level(struct snd_soc_component *component,
                                        enum snd_soc_bias_level level)
 {
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, CS42L52_PWRCTL1,
+               snd_soc_component_update_bits(component, CS42L52_PWRCTL1,
                                    CS42L52_PWRCTL1_PDN_CODEC, 0);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        regcache_cache_only(cs42l52->regmap, false);
                        regcache_sync(cs42l52->regmap);
                }
-               snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
+               snd_soc_component_write(component, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
+               snd_soc_component_write(component, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
                regcache_cache_only(cs42l52->regmap, true);
                break;
        }
@@ -902,8 +902,8 @@ static void cs42l52_beep_work(struct work_struct *work)
 {
        struct cs42l52_private *cs42l52 =
                container_of(work, struct cs42l52_private, beep_work);
-       struct snd_soc_codec *codec = cs42l52->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = cs42l52->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int i;
        int val = 0;
        int best = 0;
@@ -915,18 +915,18 @@ static void cs42l52_beep_work(struct work_struct *work)
                                best = i;
                }
 
-               dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
+               dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
                        beep_rates[best], cs42l52->beep_rate);
 
                val = (best << CS42L52_BEEP_RATE_SHIFT);
 
                snd_soc_dapm_enable_pin(dapm, "Beep");
        } else {
-               dev_dbg(codec->dev, "Disabling beep\n");
+               dev_dbg(component->dev, "Disabling beep\n");
                snd_soc_dapm_disable_pin(dapm, "Beep");
        }
 
-       snd_soc_update_bits(codec, CS42L52_BEEP_FREQ,
+       snd_soc_component_update_bits(component, CS42L52_BEEP_FREQ,
                            CS42L52_BEEP_RATE_MASK, val);
 
        snd_soc_dapm_sync(dapm);
@@ -938,10 +938,10 @@ static void cs42l52_beep_work(struct work_struct *work)
 static int cs42l52_beep_event(struct input_dev *dev, unsigned int type,
                             unsigned int code, int hz)
 {
-       struct snd_soc_codec *codec = input_get_drvdata(dev);
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = input_get_drvdata(dev);
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
+       dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
 
        switch (code) {
        case SND_BELL:
@@ -978,14 +978,14 @@ static ssize_t cs42l52_beep_set(struct device *dev,
 
 static DEVICE_ATTR(beep, 0200, NULL, cs42l52_beep_set);
 
-static void cs42l52_init_beep(struct snd_soc_codec *codec)
+static void cs42l52_init_beep(struct snd_soc_component *component)
 {
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       cs42l52->beep = devm_input_allocate_device(codec->dev);
+       cs42l52->beep = devm_input_allocate_device(component->dev);
        if (!cs42l52->beep) {
-               dev_err(codec->dev, "Failed to allocate beep device\n");
+               dev_err(component->dev, "Failed to allocate beep device\n");
                return;
        }
 
@@ -993,49 +993,49 @@ static void cs42l52_init_beep(struct snd_soc_codec *codec)
        cs42l52->beep_rate = 0;
 
        cs42l52->beep->name = "CS42L52 Beep Generator";
-       cs42l52->beep->phys = dev_name(codec->dev);
+       cs42l52->beep->phys = dev_name(component->dev);
        cs42l52->beep->id.bustype = BUS_I2C;
 
        cs42l52->beep->evbit[0] = BIT_MASK(EV_SND);
        cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
        cs42l52->beep->event = cs42l52_beep_event;
-       cs42l52->beep->dev.parent = codec->dev;
-       input_set_drvdata(cs42l52->beep, codec);
+       cs42l52->beep->dev.parent = component->dev;
+       input_set_drvdata(cs42l52->beep, component);
 
        ret = input_register_device(cs42l52->beep);
        if (ret != 0) {
                cs42l52->beep = NULL;
-               dev_err(codec->dev, "Failed to register beep device\n");
+               dev_err(component->dev, "Failed to register beep device\n");
        }
 
-       ret = device_create_file(codec->dev, &dev_attr_beep);
+       ret = device_create_file(component->dev, &dev_attr_beep);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to create keyclick file: %d\n",
+               dev_err(component->dev, "Failed to create keyclick file: %d\n",
                        ret);
        }
 }
 
-static void cs42l52_free_beep(struct snd_soc_codec *codec)
+static void cs42l52_free_beep(struct snd_soc_component *component)
 {
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
-       device_remove_file(codec->dev, &dev_attr_beep);
+       device_remove_file(component->dev, &dev_attr_beep);
        cancel_work_sync(&cs42l52->beep_work);
        cs42l52->beep = NULL;
 
-       snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL,
+       snd_soc_component_update_bits(component, CS42L52_BEEP_TONE_CTL,
                            CS42L52_BEEP_EN_MASK, 0);
 }
 
-static int cs42l52_probe(struct snd_soc_codec *codec)
+static int cs42l52_probe(struct snd_soc_component *component)
 {
-       struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l52_private *cs42l52 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(cs42l52->regmap, true);
 
-       cs42l52_add_mic_controls(codec);
+       cs42l52_add_mic_controls(component);
 
-       cs42l52_init_beep(codec);
+       cs42l52_init_beep(component);
 
        cs42l52->sysclk = CS42L52_DEFAULT_CLK;
        cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
@@ -1043,27 +1043,26 @@ static int cs42l52_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int cs42l52_remove(struct snd_soc_codec *codec)
+static void cs42l52_remove(struct snd_soc_component *component)
 {
-       cs42l52_free_beep(codec);
-
-       return 0;
+       cs42l52_free_beep(component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
-       .probe = cs42l52_probe,
-       .remove = cs42l52_remove,
-       .set_bias_level = cs42l52_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = cs42l52_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs42l52_snd_controls),
-               .dapm_widgets           = cs42l52_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs42l52_dapm_widgets),
-               .dapm_routes            = cs42l52_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cs42l52_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs42l52 = {
+       .probe                  = cs42l52_probe,
+       .remove                 = cs42l52_remove,
+       .set_bias_level         = cs42l52_set_bias_level,
+       .controls               = cs42l52_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs42l52_snd_controls),
+       .dapm_widgets           = cs42l52_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs42l52_dapm_widgets),
+       .dapm_routes            = cs42l52_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs42l52_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /* Current and threshold powerup sequence Pg37 */
@@ -1202,19 +1201,13 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
                                   CS42L52_IFACE_CTL2_BIAS_LVL,
                                cs42l52->pdata.micbias_lvl);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs42l52, &cs42l52_dai, 1);
+       ret =  devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs42l52, &cs42l52_dai, 1);
        if (ret < 0)
                return ret;
        return 0;
 }
 
-static int cs42l52_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct of_device_id cs42l52_of_match[] = {
        { .compatible = "cirrus,cs42l52", },
        {},
@@ -1235,7 +1228,6 @@ static struct i2c_driver cs42l52_i2c_driver = {
        },
        .id_table = cs42l52_id,
        .probe =    cs42l52_i2c_probe,
-       .remove =   cs42l52_i2c_remove,
 };
 
 module_i2c_driver(cs42l52_i2c_driver);
index fd7b8d32c2b21276b6972fbacad6c8a1ba3ee496..a5c8736fad7779ec5bc6982f35675f9d52a98ef5 100644 (file)
@@ -45,7 +45,7 @@ static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = {
 
 struct  cs42l56_private {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct device *dev;
        struct cs42l56_platform_data pdata;
        struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES];
@@ -726,8 +726,8 @@ static int cs42l56_get_mclk_ratio(int mclk, int rate)
 static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
                        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case CS42L56_MCLK_5P6448MHZ:
@@ -753,10 +753,10 @@ static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
        }
        cs42l56->mclk = freq;
 
-       snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+       snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
                            CS42L56_MCLK_PREDIV_MASK,
                                cs42l56->mclk_prediv);
-       snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+       snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
                            CS42L56_MCLK_DIV2_MASK,
                                cs42l56->mclk_div2);
 
@@ -765,8 +765,8 @@ static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -803,22 +803,22 @@ static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+       snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
                            CS42L56_MS_MODE_MASK, cs42l56->iface);
-       snd_soc_update_bits(codec, CS42L56_SERIAL_FMT,
+       snd_soc_component_update_bits(component, CS42L56_SERIAL_FMT,
                            CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt);
-       snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+       snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
                            CS42L56_SCLK_INV_MASK, cs42l56->iface_inv);
        return 0;
 }
 
 static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute) {
                /* Hit the DSP Mixer first */
-               snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
+               snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
                                    CS42L56_ADCAMIX_MUTE_MASK |
                                    CS42L56_ADCBMIX_MUTE_MASK |
                                    CS42L56_PCMAMIX_MUTE_MASK |
@@ -827,21 +827,21 @@ static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
                                    CS42L56_MSTA_MUTE_MASK,
                                    CS42L56_MUTE_ALL);
                /* Mute ADC's */
-               snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
+               snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
                                    CS42L56_ADCA_MUTE_MASK |
                                    CS42L56_ADCB_MUTE_MASK,
                                    CS42L56_MUTE_ALL);
                /* HP And LO */
-               snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
                                    CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
-               snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
                                    CS42L56_HP_MUTE_MASK, CS42L56_MUTE_ALL);
-               snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
                                    CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
-               snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
                                    CS42L56_LO_MUTE_MASK, CS42L56_MUTE_ALL);
        } else {
-               snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL,
+               snd_soc_component_update_bits(component, CS42L56_DSP_MUTE_CTL,
                                    CS42L56_ADCAMIX_MUTE_MASK |
                                    CS42L56_ADCBMIX_MUTE_MASK |
                                    CS42L56_PCMAMIX_MUTE_MASK |
@@ -850,18 +850,18 @@ static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute)
                                    CS42L56_MSTA_MUTE_MASK,
                                    CS42L56_UNMUTE);
 
-               snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL,
+               snd_soc_component_update_bits(component, CS42L56_MISC_ADC_CTL,
                                    CS42L56_ADCA_MUTE_MASK |
                                    CS42L56_ADCB_MUTE_MASK,
                                    CS42L56_UNMUTE);
 
-               snd_soc_update_bits(codec, CS42L56_HPA_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_HPA_VOLUME,
                                    CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
-               snd_soc_update_bits(codec, CS42L56_HPB_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_HPB_VOLUME,
                                    CS42L56_HP_MUTE_MASK, CS42L56_UNMUTE);
-               snd_soc_update_bits(codec, CS42L56_LOA_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_LOA_VOLUME,
                                    CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
-               snd_soc_update_bits(codec, CS42L56_LOB_VOLUME,
+               snd_soc_component_update_bits(component, CS42L56_LOB_VOLUME,
                                    CS42L56_LO_MUTE_MASK, CS42L56_UNMUTE);
        }
        return 0;
@@ -871,39 +871,39 @@ static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *params,
                                     struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
        int ratio;
 
        ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params));
        if (ratio >= 0) {
-               snd_soc_update_bits(codec, CS42L56_CLKCTL_2,
+               snd_soc_component_update_bits(component, CS42L56_CLKCTL_2,
                                    CS42L56_CLK_RATIO_MASK, ratio);
        } else {
-               dev_err(codec->dev, "unsupported mclk/sclk/lrclk ratio\n");
+               dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n");
                return -EINVAL;
        }
 
        return 0;
 }
 
-static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l56_set_bias_level(struct snd_soc_component *component,
                                        enum snd_soc_bias_level level)
 {
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+               snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
                                    CS42L56_MCLK_DIS_MASK, 0);
-               snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
+               snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
                                    CS42L56_PDN_ALL_MASK, 0);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        regcache_cache_only(cs42l56->regmap, false);
                        regcache_sync(cs42l56->regmap);
                        ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
@@ -915,13 +915,13 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
                                return ret;
                        }
                }
-               snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
+               snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
                                    CS42L56_PDN_ALL_MASK, 1);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, CS42L56_PWRCTL_1,
+               snd_soc_component_update_bits(component, CS42L56_PWRCTL_1,
                                    CS42L56_PDN_ALL_MASK, 1);
-               snd_soc_update_bits(codec, CS42L56_CLKCTL_1,
+               snd_soc_component_update_bits(component, CS42L56_CLKCTL_1,
                                    CS42L56_MCLK_DIS_MASK, 1);
                regcache_cache_only(cs42l56->regmap, true);
                regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
@@ -974,8 +974,8 @@ static void cs42l56_beep_work(struct work_struct *work)
 {
        struct cs42l56_private *cs42l56 =
                container_of(work, struct cs42l56_private, beep_work);
-       struct snd_soc_codec *codec = cs42l56->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = cs42l56->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int i;
        int val = 0;
        int best = 0;
@@ -987,18 +987,18 @@ static void cs42l56_beep_work(struct work_struct *work)
                                best = i;
                }
 
-               dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
+               dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n",
                        beep_freq[best], cs42l56->beep_rate);
 
                val = (best << CS42L56_BEEP_RATE_SHIFT);
 
                snd_soc_dapm_enable_pin(dapm, "Beep");
        } else {
-               dev_dbg(codec->dev, "Disabling beep\n");
+               dev_dbg(component->dev, "Disabling beep\n");
                snd_soc_dapm_disable_pin(dapm, "Beep");
        }
 
-       snd_soc_update_bits(codec, CS42L56_BEEP_FREQ_ONTIME,
+       snd_soc_component_update_bits(component, CS42L56_BEEP_FREQ_ONTIME,
                            CS42L56_BEEP_FREQ_MASK, val);
 
        snd_soc_dapm_sync(dapm);
@@ -1010,10 +1010,10 @@ static void cs42l56_beep_work(struct work_struct *work)
 static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
                             unsigned int code, int hz)
 {
-       struct snd_soc_codec *codec = input_get_drvdata(dev);
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = input_get_drvdata(dev);
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
+       dev_dbg(component->dev, "Beep event %x %x\n", code, hz);
 
        switch (code) {
        case SND_BELL:
@@ -1050,14 +1050,14 @@ static ssize_t cs42l56_beep_set(struct device *dev,
 
 static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set);
 
-static void cs42l56_init_beep(struct snd_soc_codec *codec)
+static void cs42l56_init_beep(struct snd_soc_component *component)
 {
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       cs42l56->beep = devm_input_allocate_device(codec->dev);
+       cs42l56->beep = devm_input_allocate_device(component->dev);
        if (!cs42l56->beep) {
-               dev_err(codec->dev, "Failed to allocate beep device\n");
+               dev_err(component->dev, "Failed to allocate beep device\n");
                return;
        }
 
@@ -1065,68 +1065,67 @@ static void cs42l56_init_beep(struct snd_soc_codec *codec)
        cs42l56->beep_rate = 0;
 
        cs42l56->beep->name = "CS42L56 Beep Generator";
-       cs42l56->beep->phys = dev_name(codec->dev);
+       cs42l56->beep->phys = dev_name(component->dev);
        cs42l56->beep->id.bustype = BUS_I2C;
 
        cs42l56->beep->evbit[0] = BIT_MASK(EV_SND);
        cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
        cs42l56->beep->event = cs42l56_beep_event;
-       cs42l56->beep->dev.parent = codec->dev;
-       input_set_drvdata(cs42l56->beep, codec);
+       cs42l56->beep->dev.parent = component->dev;
+       input_set_drvdata(cs42l56->beep, component);
 
        ret = input_register_device(cs42l56->beep);
        if (ret != 0) {
                cs42l56->beep = NULL;
-               dev_err(codec->dev, "Failed to register beep device\n");
+               dev_err(component->dev, "Failed to register beep device\n");
        }
 
-       ret = device_create_file(codec->dev, &dev_attr_beep);
+       ret = device_create_file(component->dev, &dev_attr_beep);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to create keyclick file: %d\n",
+               dev_err(component->dev, "Failed to create keyclick file: %d\n",
                        ret);
        }
 }
 
-static void cs42l56_free_beep(struct snd_soc_codec *codec)
+static void cs42l56_free_beep(struct snd_soc_component *component)
 {
-       struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l56_private *cs42l56 = snd_soc_component_get_drvdata(component);
 
-       device_remove_file(codec->dev, &dev_attr_beep);
+       device_remove_file(component->dev, &dev_attr_beep);
        cancel_work_sync(&cs42l56->beep_work);
        cs42l56->beep = NULL;
 
-       snd_soc_update_bits(codec, CS42L56_BEEP_TONE_CFG,
+       snd_soc_component_update_bits(component, CS42L56_BEEP_TONE_CFG,
                            CS42L56_BEEP_EN_MASK, 0);
 }
 
-static int cs42l56_probe(struct snd_soc_codec *codec)
+static int cs42l56_probe(struct snd_soc_component *component)
 {
-       cs42l56_init_beep(codec);
+       cs42l56_init_beep(component);
 
        return 0;
 }
 
-static int cs42l56_remove(struct snd_soc_codec *codec)
+static void cs42l56_remove(struct snd_soc_component *component)
 {
-       cs42l56_free_beep(codec);
-
-       return 0;
+       cs42l56_free_beep(component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
-       .probe = cs42l56_probe,
-       .remove = cs42l56_remove,
-       .set_bias_level = cs42l56_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = cs42l56_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs42l56_snd_controls),
-               .dapm_widgets           = cs42l56_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs42l56_dapm_widgets),
-               .dapm_routes            = cs42l56_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cs42l56_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs42l56 = {
+       .probe                  = cs42l56_probe,
+       .remove                 = cs42l56_remove,
+       .set_bias_level         = cs42l56_set_bias_level,
+       .controls               = cs42l56_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs42l56_snd_controls),
+       .dapm_widgets           = cs42l56_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs42l56_dapm_widgets),
+       .dapm_routes            = cs42l56_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs42l56_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config cs42l56_regmap = {
@@ -1315,8 +1314,8 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
                                   CS42L56_ADAPT_PWR_MASK,
                                cs42l56->pdata.adaptive_pwr);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs42l56, &cs42l56_dai, 1);
+       ret =  devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs42l56, &cs42l56_dai, 1);
        if (ret < 0)
                return ret;
 
@@ -1332,7 +1331,6 @@ static int cs42l56_i2c_remove(struct i2c_client *client)
 {
        struct cs42l56_private *cs42l56 = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
        regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies),
                               cs42l56->supplies);
        return 0;
index aebaa97490b6fb1b914b9db83ceec95007e83b51..36b57ee00a30a18e56d6aa957e4876d7f92e8dac 100644 (file)
@@ -490,8 +490,8 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
 static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
        switch (event) {
        case SND_SOC_DAPM_POST_PMD:
                /* 150 ms delay between setting PDN and MCLKDIS */
@@ -506,8 +506,8 @@ static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
 static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
        switch (event) {
        case SND_SOC_DAPM_POST_PMD:
                /* 50 ms delay between setting PDN and MCLKDIS */
@@ -524,8 +524,8 @@ static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
 static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
        switch (event) {
        case SND_SOC_DAPM_POST_PMD:
                /* 30 ms delay between setting PDN and MCLKDIS */
@@ -884,8 +884,8 @@ static int cs42l73_get_mclk_coeff(int mclk, int srate)
 
 static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 
        int mclkx_coeff;
        u32 mclk = 0;
@@ -899,14 +899,14 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
        mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx /
                cs42l73_mclkx_coeffs[mclkx_coeff].ratio;
 
-       dev_dbg(codec->dev, "MCLK%u %u  <-> internal MCLK %u\n",
+       dev_dbg(component->dev, "MCLK%u %u  <-> internal MCLK %u\n",
                 priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx,
                 mclk);
 
        dmmcc = (priv->mclksel << 4) |
                (cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1);
 
-       snd_soc_write(codec, CS42L73_DMMCC, dmmcc);
+       snd_soc_component_write(component, CS42L73_DMMCC, dmmcc);
 
        priv->sysclk = mclkx_coeff;
        priv->mclk = mclk;
@@ -917,8 +917,8 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
 static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
                              int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case CS42L73_CLKID_MCLK1:
@@ -930,7 +930,7 @@ static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
        }
 
        if ((cs42l73_set_mclk(dai, freq)) < 0) {
-               dev_err(codec->dev, "Unable to set MCLK for dai %s\n",
+               dev_err(component->dev, "Unable to set MCLK for dai %s\n",
                        dai->name);
                return -EINVAL;
        }
@@ -942,14 +942,14 @@ static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
 
 static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
        u8 id = codec_dai->id;
        unsigned int inv, format;
        u8 spc, mmcc;
 
-       spc = snd_soc_read(codec, CS42L73_SPC(id));
-       mmcc = snd_soc_read(codec, CS42L73_MMCC(id));
+       spc = snd_soc_component_read32(component, CS42L73_SPC(id));
+       mmcc = snd_soc_component_read32(component, CS42L73_MMCC(id));
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -974,12 +974,12 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        case SND_SOC_DAIFMT_DSP_A:
        case SND_SOC_DAIFMT_DSP_B:
                if (mmcc & CS42L73_MS_MASTER) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "PCM format in slave mode only\n");
                        return -EINVAL;
                }
                if (id == CS42L73_ASP) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "PCM format is not supported on ASP port\n");
                        return -EINVAL;
                }
@@ -1029,7 +1029,7 @@ static unsigned int cs42l73_get_xspfs_coeff(u32 rate)
        return 0;               /* 0 = Don't know */
 }
 
-static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
+static void cs42l73_update_asrc(struct snd_soc_component *component, int id, int srate)
 {
        u8 spfs = 0;
 
@@ -1038,13 +1038,13 @@ static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
 
        switch (id) {
        case CS42L73_XSP:
-               snd_soc_update_bits(codec, CS42L73_VXSPFS, 0x0f, spfs);
+               snd_soc_component_update_bits(component, CS42L73_VXSPFS, 0x0f, spfs);
        break;
        case CS42L73_ASP:
-               snd_soc_update_bits(codec, CS42L73_ASPC, 0x3c, spfs << 2);
+               snd_soc_component_update_bits(component, CS42L73_ASPC, 0x3c, spfs << 2);
        break;
        case CS42L73_VSP:
-               snd_soc_update_bits(codec, CS42L73_VXSPFS, 0xf0, spfs << 4);
+               snd_soc_component_update_bits(component, CS42L73_VXSPFS, 0xf0, spfs << 4);
        break;
        default:
        break;
@@ -1055,8 +1055,8 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42l73_private *priv = snd_soc_component_get_drvdata(component);
        int id = dai->id;
        int mclk_coeff;
        int srate = params_rate(params);
@@ -1070,7 +1070,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
                if (mclk_coeff < 0)
                        return -EINVAL;
 
-               dev_dbg(codec->dev,
+               dev_dbg(component->dev,
                         "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n",
                         id, priv->mclk, srate,
                         cs42l73_mclk_coeffs[mclk_coeff].mmcc);
@@ -1091,38 +1091,38 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
        /* Update ASRCs */
        priv->config[id].srate = srate;
 
-       snd_soc_write(codec, CS42L73_SPC(id), priv->config[id].spc);
-       snd_soc_write(codec, CS42L73_MMCC(id), priv->config[id].mmcc);
+       snd_soc_component_write(component, CS42L73_SPC(id), priv->config[id].spc);
+       snd_soc_component_write(component, CS42L73_MMCC(id), priv->config[id].mmcc);
 
-       cs42l73_update_asrc(codec, id, srate);
+       cs42l73_update_asrc(component, id, srate);
 
        return 0;
 }
 
-static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
+static int cs42l73_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 0);
-               snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 0);
+               snd_soc_component_update_bits(component, CS42L73_DMMCC, CS42L73_MCLKDIS, 0);
+               snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 0);
                break;
 
        case SND_SOC_BIAS_PREPARE:
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        regcache_cache_only(cs42l73->regmap, false);
                        regcache_sync(cs42l73->regmap);
                }
-               snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1);
+               snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 1);
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1);
+               snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 1);
                if (cs42l73->shutdwn_delay > 0) {
                        mdelay(cs42l73->shutdwn_delay);
                        cs42l73->shutdwn_delay = 0;
@@ -1131,7 +1131,7 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
                                     * down.
                                     */
                }
-               snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
+               snd_soc_component_update_bits(component, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
                break;
        }
        return 0;
@@ -1139,10 +1139,10 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
 
 static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int id = dai->id;
 
-       return snd_soc_update_bits(codec, CS42L73_SPC(id), CS42L73_SP_3ST,
+       return snd_soc_component_update_bits(component, CS42L73_SPC(id), CS42L73_SP_3ST,
                                   tristate << 7);
 }
 
@@ -1235,13 +1235,13 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
         }
 };
 
-static int cs42l73_probe(struct snd_soc_codec *codec)
+static int cs42l73_probe(struct snd_soc_component *component)
 {
-       struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+       struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component);
 
        /* Set Charge Pump Frequency */
        if (cs42l73->pdata.chgfreq)
-               snd_soc_update_bits(codec, CS42L73_CPFCHC,
+               snd_soc_component_update_bits(component, CS42L73_CPFCHC,
                                    CS42L73_CHARGEPUMP_MASK,
                                        cs42l73->pdata.chgfreq << 4);
 
@@ -1252,19 +1252,20 @@ static int cs42l73_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
-       .probe = cs42l73_probe,
-       .set_bias_level = cs42l73_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = cs42l73_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs42l73_snd_controls),
-               .dapm_widgets           = cs42l73_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs42l73_dapm_widgets),
-               .dapm_routes            = cs42l73_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cs42l73_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs42l73 = {
+       .probe                  = cs42l73_probe,
+       .set_bias_level         = cs42l73_set_bias_level,
+       .controls               = cs42l73_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs42l73_snd_controls),
+       .dapm_widgets           = cs42l73_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs42l73_dapm_widgets),
+       .dapm_routes            = cs42l73_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cs42l73_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config cs42l73_regmap = {
@@ -1361,20 +1362,14 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
        dev_info(&i2c_client->dev,
                 "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF);
 
-       ret =  snd_soc_register_codec(&i2c_client->dev,
-                       &soc_codec_dev_cs42l73, cs42l73_dai,
+       ret = devm_snd_soc_register_component(&i2c_client->dev,
+                       &soc_component_dev_cs42l73, cs42l73_dai,
                        ARRAY_SIZE(cs42l73_dai));
        if (ret < 0)
                return ret;
        return 0;
 }
 
-static int cs42l73_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct of_device_id cs42l73_of_match[] = {
        { .compatible = "cirrus,cs42l73", },
        {},
@@ -1395,7 +1390,6 @@ static struct i2c_driver cs42l73_i2c_driver = {
                   },
        .id_table = cs42l73_id,
        .probe = cs42l73_i2c_probe,
-       .remove = cs42l73_i2c_remove,
 
 };
 
index 800c1d549347194a7aa80c514161eae8752ec3d7..0214e3ab9da00d387324373486860eb3ee8b8bf1 100644 (file)
@@ -33,7 +33,6 @@ static int cs42xx8_i2c_probe(struct i2c_client *i2c,
 
 static int cs42xx8_i2c_remove(struct i2c_client *i2c)
 {
-       snd_soc_unregister_codec(&i2c->dev);
        pm_runtime_disable(&i2c->dev);
 
        return 0;
index c1785bd4ff199fca82ad331abc273707793cd6cd..ebb9e0cf83647b80fae1b9949fcd04e556ba9eed 100644 (file)
@@ -194,8 +194,8 @@ static const struct cs42xx8_ratios cs42xx8_ratios[] = {
 static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
 
        cs42xx8->sysclk = freq;
 
@@ -205,8 +205,8 @@ static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
                               unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
        u32 val;
 
        /* Set DAI format */
@@ -224,7 +224,7 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
                val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM;
                break;
        default:
-               dev_err(codec->dev, "unsupported dai format\n");
+               dev_err(component->dev, "unsupported dai format\n");
                return -EINVAL;
        }
 
@@ -241,7 +241,7 @@ static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
                cs42xx8->slave_mode = false;
                break;
        default:
-               dev_err(codec->dev, "unsupported master/slave mode\n");
+               dev_err(component->dev, "unsupported master/slave mode\n");
                return -EINVAL;
        }
 
@@ -252,8 +252,8 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
        u32 ratio = cs42xx8->sysclk / params_rate(params);
        u32 i, fm, val, mask;
@@ -267,7 +267,7 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (i == ARRAY_SIZE(cs42xx8_ratios)) {
-               dev_err(codec->dev, "unsupported sysclk ratio\n");
+               dev_err(component->dev, "unsupported sysclk ratio\n");
                return -EINVAL;
        }
 
@@ -285,8 +285,8 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
 
 static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
        u8 dac_unmute = cs42xx8->tx_channels ?
                        ~((0x1 << cs42xx8->tx_channels) - 1) : 0;
 
@@ -382,14 +382,14 @@ const struct regmap_config cs42xx8_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
 
-static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
+static int cs42xx8_component_probe(struct snd_soc_component *component)
 {
-       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        switch (cs42xx8->drvdata->num_adcs) {
        case 3:
-               snd_soc_add_codec_controls(codec, cs42xx8_adc3_snd_controls,
+               snd_soc_add_component_controls(component, cs42xx8_adc3_snd_controls,
                                        ARRAY_SIZE(cs42xx8_adc3_snd_controls));
                snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets,
                                        ARRAY_SIZE(cs42xx8_adc3_dapm_widgets));
@@ -406,18 +406,17 @@ static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver cs42xx8_driver = {
-       .probe = cs42xx8_codec_probe,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = cs42xx8_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs42xx8_snd_controls),
-               .dapm_widgets           = cs42xx8_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs42xx8_dapm_widgets),
-               .dapm_routes            = cs42xx8_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(cs42xx8_dapm_routes),
-       },
+static const struct snd_soc_component_driver cs42xx8_driver = {
+       .probe                  = cs42xx8_component_probe,
+       .controls               = cs42xx8_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs42xx8_snd_controls),
+       .dapm_widgets           = cs42xx8_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs42xx8_dapm_widgets),
+       .dapm_routes            = cs42xx8_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs42xx8_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 const struct cs42xx8_driver_data cs42448_data = {
@@ -520,9 +519,9 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
        /* Each adc supports stereo input */
        cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2;
 
-       ret = snd_soc_register_codec(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
+       ret = devm_snd_soc_register_component(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
        if (ret) {
-               dev_err(dev, "failed to register codec:%d\n", ret);
+               dev_err(dev, "failed to register component:%d\n", ret);
                goto err_enable;
        }
 
index 5ba0edc19df44c930a1717564e7a965fd6be355c..feca0a672976c21ab60699895633629cfec699b3 100644 (file)
@@ -236,12 +236,12 @@ static const struct cs43130_pll_params *cs43130_get_pll_table(
        return NULL;
 }
 
-static int cs43130_pll_config(struct snd_soc_codec *codec)
+static int cs43130_pll_config(struct snd_soc_component *component)
 {
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
        const struct cs43130_pll_params *pll_entry;
 
-       dev_dbg(codec->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",
+       dev_dbg(component->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",
                cs43130->mclk, cs43130->mclk_int);
 
        pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int);
@@ -286,11 +286,11 @@ static int cs43130_pll_config(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int cs43130_set_pll(struct snd_soc_component *component, int pll_id, int source,
                           unsigned int freq_in, unsigned int freq_out)
 {
        int ret = 0;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (freq_in) {
        case 9600000:
@@ -306,7 +306,7 @@ static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
                cs43130->mclk = freq_in;
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "unsupported pll input reference clock:%d\n", freq_in);
                return -EINVAL;
        }
@@ -319,21 +319,21 @@ static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
                cs43130->mclk_int = freq_out;
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "unsupported pll output ref clock: %u\n", freq_out);
                return -EINVAL;
        }
 
-       ret = cs43130_pll_config(codec);
-       dev_dbg(codec->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);
+       ret = cs43130_pll_config(component);
+       dev_dbg(component->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);
        return ret;
 }
 
-static int cs43130_change_clksrc(struct snd_soc_codec *codec,
+static int cs43130_change_clksrc(struct snd_soc_component *component,
                                 enum cs43130_mclk_src_sel src)
 {
        int ret;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
        int mclk_int_decoded;
 
        if (src == cs43130->mclk_int_src) {
@@ -349,7 +349,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
                mclk_int_decoded = CS43130_MCLK_24P5;
                break;
        default:
-               dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);
+               dev_err(component->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);
                return -EINVAL;
        }
 
@@ -373,7 +373,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
                                           CS43130_XTAL_RDY_INT_MASK,
                                           1 << CS43130_XTAL_RDY_INT_SHIFT);
                        if (ret == 0) {
-                               dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
+                               dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n");
                                return -ETIMEDOUT;
                        }
                }
@@ -409,7 +409,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
                                           CS43130_XTAL_RDY_INT_MASK,
                                           1 << CS43130_XTAL_RDY_INT_SHIFT);
                        if (ret == 0) {
-                               dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
+                               dev_err(component->dev, "Timeout waiting for XTAL_READY interrupt\n");
                                return -ETIMEDOUT;
                        }
                }
@@ -425,7 +425,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
                                   CS43130_PLL_RDY_INT_MASK,
                                   1 << CS43130_PLL_RDY_INT_SHIFT);
                if (ret == 0) {
-                       dev_err(codec->dev, "Timeout waiting for PLL_READY interrupt\n");
+                       dev_err(component->dev, "Timeout waiting for PLL_READY interrupt\n");
                        return -ETIMEDOUT;
                }
 
@@ -456,7 +456,7 @@ static int cs43130_change_clksrc(struct snd_soc_codec *codec,
                                   1 << CS43130_PDN_PLL_SHIFT);
                break;
        default:
-               dev_err(codec->dev, "Invalid MCLK source value\n");
+               dev_err(component->dev, "Invalid MCLK source value\n");
                return -EINVAL;
        }
 
@@ -774,8 +774,8 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
        unsigned int required_clk;
        u8 dsd_speed;
 
@@ -787,11 +787,11 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
                else
                        required_clk = CS43130_MCLK_24M;
 
-               cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
+               cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
                if (cs43130->pll_bypass)
-                       cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+                       cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
                else
-                       cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+                       cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
        }
 
        cs43130->clk_req++;
@@ -807,7 +807,7 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
                dsd_speed = 1;
                break;
        default:
-               dev_err(codec->dev, "Rate(%u) not supported\n",
+               dev_err(component->dev, "Rate(%u) not supported\n",
                        params_rate(params));
                return -EINVAL;
        }
@@ -833,8 +833,8 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
        const struct cs43130_rate_map *rate_map;
        unsigned int sclk = cs43130->dais[dai->id].sclk;
        unsigned int bitwidth_sclk;
@@ -850,11 +850,11 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
                else
                        required_clk = CS43130_MCLK_24M;
 
-               cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
+               cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
                if (cs43130->pll_bypass)
-                       cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+                       cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
                else
-                       cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+                       cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
        }
 
        cs43130->clk_req++;
@@ -878,7 +878,7 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
                        dsd_speed = 1;
                        break;
                default:
-                       dev_err(codec->dev, "Rate(%u) not supported\n",
+                       dev_err(component->dev, "Rate(%u) not supported\n",
                                params_rate(params));
                        return -EINVAL;
                }
@@ -895,7 +895,7 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
                regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI (%d)\n", dai->id);
+               dev_err(component->dev, "Invalid DAI (%d)\n", dai->id);
                return -EINVAL;
        }
 
@@ -919,21 +919,21 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 
        if (!sclk) {
                /* at this point, SCLK must be set */
-               dev_err(codec->dev, "SCLK freq is not set\n");
+               dev_err(component->dev, "SCLK freq is not set\n");
                return -EINVAL;
        }
 
        bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);
        if (bitwidth_sclk < bitwidth_dai) {
-               dev_err(codec->dev, "Format not supported: SCLK freq is too low\n");
+               dev_err(component->dev, "Format not supported: SCLK freq is too low\n");
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev,
+       dev_dbg(component->dev,
                "sclk = %u, fs = %d, bitwidth_dai = %u\n",
                sclk, params_rate(params), bitwidth_dai);
 
-       dev_dbg(codec->dev,
+       dev_dbg(component->dev,
                "bitwidth_sclk = %u, num_ch = %u\n",
                bitwidth_sclk, params_channels(params));
 
@@ -946,14 +946,14 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
 static int cs43130_hw_free(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        mutex_lock(&cs43130->clk_mutex);
        cs43130->clk_req--;
        if (!cs43130->clk_req) {
                /* no DAI is currently using clk */
-               cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
+               cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
                cs43130_pcm_dsd_mix(false, cs43130->regmap);
        }
        mutex_unlock(&cs43130->clk_mutex);
@@ -1023,8 +1023,8 @@ static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol,
 {
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned int *item = ucontrol->value.enumerated.item;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (item[0] >= e->items)
@@ -1144,8 +1144,8 @@ static const struct reg_sequence unmute_seq[] = {
 static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
                              struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -1192,7 +1192,7 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
                }
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
                return -EINVAL;
        }
        return 0;
@@ -1201,8 +1201,8 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
 static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
                              struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -1249,7 +1249,7 @@ static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
                }
                break;
        default:
-               dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid event = 0x%x\n", event);
                return -EINVAL;
        }
        return 0;
@@ -1270,8 +1270,8 @@ static const struct reg_sequence dac_postpmd_seq[] = {
 static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -1325,7 +1325,7 @@ static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
                }
                break;
        default:
-               dev_err(codec->dev, "Invalid DAC event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid DAC event = 0x%x\n", event);
                return -EINVAL;
        }
        return 0;
@@ -1350,8 +1350,8 @@ static const struct reg_sequence hpin_postpmu_seq[] = {
 static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,
                              struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMD:
@@ -1363,7 +1363,7 @@ static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,
                                       ARRAY_SIZE(hpin_postpmu_seq));
                break;
        default:
-               dev_err(codec->dev, "Invalid HPIN event = 0x%x\n", event);
+               dev_err(component->dev, "Invalid HPIN event = 0x%x\n", event);
                return -EINVAL;
        }
        return 0;
@@ -1471,8 +1471,8 @@ static int cs43130_dop_startup(struct snd_pcm_substream *substream,
 
 static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -1482,7 +1482,7 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
                break;
        default:
-               dev_err(codec->dev, "unsupported mode\n");
+               dev_err(component->dev, "unsupported mode\n");
                return -EINVAL;
        }
 
@@ -1500,12 +1500,12 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B;
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "unsupported audio format\n");
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev, "dai_id = %d,  dai_mode = %u, dai_format = %u\n",
+       dev_dbg(component->dev, "dai_id = %d,  dai_mode = %u, dai_format = %u\n",
                codec_dai->id,
                cs43130->dais[codec_dai->id].dai_mode,
                cs43130->dais[codec_dai->id].dai_format);
@@ -1515,8 +1515,8 @@ static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -1526,11 +1526,11 @@ static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
                break;
        default:
-               dev_err(codec->dev, "Unsupported DAI format.\n");
+               dev_err(component->dev, "Unsupported DAI format.\n");
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev, "dai_mode = 0x%x\n",
+       dev_dbg(component->dev, "dai_mode = 0x%x\n",
                cs43130->dais[codec_dai->id].dai_mode);
 
        return 0;
@@ -1539,11 +1539,11 @@ static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
        cs43130->dais[codec_dai->id].sclk = freq;
-       dev_dbg(codec->dev, "dai_id = %d,  sclk = %u\n", codec_dai->id,
+       dev_dbg(component->dev, "dai_id = %d,  sclk = %u\n", codec_dai->id,
                cs43130->dais[codec_dai->id].sclk);
 
        return 0;
@@ -1627,13 +1627,13 @@ static struct snd_soc_dai_driver cs43130_dai[] = {
 
 };
 
-static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec,
+static int cs43130_component_set_sysclk(struct snd_soc_component *component,
                                    int clk_id, int source, unsigned int freq,
                                    int dir)
 {
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
+       dev_dbg(component->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
                clk_id, source, freq, dir);
 
        switch (freq) {
@@ -1642,14 +1642,14 @@ static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec,
                cs43130->mclk = freq;
                break;
        default:
-               dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", freq);
+               dev_err(component->dev, "Invalid MCLK INT freq: %u\n", freq);
                return -EINVAL;
        }
 
        if (source == CS43130_MCLK_SRC_EXT) {
                cs43130->pll_bypass = true;
        } else {
-               dev_err(codec->dev, "Invalid MCLK source\n");
+               dev_err(component->dev, "Invalid MCLK source\n");
                return -EINVAL;
        }
 
@@ -1929,7 +1929,7 @@ static int cs43130_update_hpload(unsigned int msk, int ac_idx,
        unsigned int reg;
        u32 addr;
        u16 impedance;
-       struct snd_soc_codec *codec = cs43130->codec;
+       struct snd_soc_component *component = cs43130->component;
 
        switch (msk) {
        case CS43130_HPLOAD_DC_INT:
@@ -1959,7 +1959,7 @@ static int cs43130_update_hpload(unsigned int msk, int ac_idx,
                else
                        cs43130->hpload_dc[HP_RIGHT] = impedance;
 
-               dev_dbg(codec->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,
+               dev_dbg(component->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,
                        impedance);
        } else {
                if (left_ch)
@@ -1967,7 +1967,7 @@ static int cs43130_update_hpload(unsigned int msk, int ac_idx,
                else
                        cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance;
 
-               dev_dbg(codec->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",
+               dev_dbg(component->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",
                        cs43130->ac_freq[ac_idx], !left_ch, impedance);
        }
 
@@ -1981,7 +1981,7 @@ static int cs43130_hpload_proc(struct cs43130_private *cs43130,
        int ret;
        unsigned int msk;
        u16 ac_reg_val;
-       struct snd_soc_codec *codec = cs43130->codec;
+       struct snd_soc_component *component = cs43130->component;
 
        reinit_completion(&cs43130->hpload_evt);
 
@@ -2004,17 +2004,17 @@ static int cs43130_hpload_proc(struct cs43130_private *cs43130,
                                          msecs_to_jiffies(1000));
        regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk);
        if (!ret) {
-               dev_err(codec->dev, "Timeout waiting for HPLOAD interrupt\n");
+               dev_err(component->dev, "Timeout waiting for HPLOAD interrupt\n");
                return -1;
        }
 
-       dev_dbg(codec->dev, "HP load stat: %x, INT_MASK_4: %x\n",
+       dev_dbg(component->dev, "HP load stat: %x, INT_MASK_4: %x\n",
                cs43130->hpload_stat, msk);
        if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT |
                                     CS43130_HPLOAD_UNPLUG_INT |
                                     CS43130_HPLOAD_OOR_INT)) ||
            !(cs43130->hpload_stat & rslt_msk)) {
-               dev_dbg(codec->dev, "HP load measure failed\n");
+               dev_dbg(component->dev, "HP load measure failed\n");
                return -1;
        }
 
@@ -2056,11 +2056,11 @@ static void cs43130_imp_meas(struct work_struct *wk)
        unsigned int reg, seq_size;
        int i, ret, ac_idx;
        struct cs43130_private *cs43130;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct reg_sequences *hpload_seq;
 
        cs43130 = container_of(wk, struct cs43130_private, work);
-       codec = cs43130->codec;
+       component = cs43130->component;
 
        if (!cs43130->mclk)
                return;
@@ -2070,11 +2070,11 @@ static void cs43130_imp_meas(struct work_struct *wk)
        mutex_lock(&cs43130->clk_mutex);
        if (!cs43130->clk_req) {
                /* clk not in use */
-               cs43130_set_pll(codec, 0, 0, cs43130->mclk, CS43130_MCLK_22M);
+               cs43130_set_pll(component, 0, 0, cs43130->mclk, CS43130_MCLK_22M);
                if (cs43130->pll_bypass)
-                       cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+                       cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
                else
-                       cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+                       cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
        }
 
        cs43130->clk_req++;
@@ -2125,9 +2125,9 @@ static void cs43130_imp_meas(struct work_struct *wk)
                snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE,
                                    CS43130_JACK_MASK);
 
-       dev_dbg(codec->dev, "Set HP output control. DC threshold\n");
+       dev_dbg(component->dev, "Set HP output control. DC threshold\n");
        for (i = 0; i < CS43130_DC_THRESHOLD; i++)
-               dev_dbg(codec->dev, "DC threshold[%d]: %u.\n", i,
+               dev_dbg(component->dev, "DC threshold[%d]: %u.\n", i,
                        cs43130->dc_threshold[i]);
 
        cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT],
@@ -2154,14 +2154,14 @@ exit:
        cs43130->clk_req--;
        /* clk not in use */
        if (!cs43130->clk_req)
-               cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
+               cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
        mutex_unlock(&cs43130->clk_mutex);
 }
 
 static irqreturn_t cs43130_irq_thread(int irq, void *data)
 {
        struct cs43130_private *cs43130 = (struct cs43130_private *)data;
-       struct snd_soc_codec *codec = cs43130->codec;
+       struct snd_soc_component *component = cs43130->component;
        unsigned int stickies[CS43130_NUM_INT];
        unsigned int irq_occurrence = 0;
        unsigned int masks[CS43130_NUM_INT];
@@ -2179,7 +2179,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
                for (j = 0; j < 8; j++)
                        irq_occurrence += (stickies[i] >> j) & 1;
        }
-       dev_dbg(codec->dev, "number of interrupts occurred (%u)\n",
+       dev_dbg(component->dev, "number of interrupts occurred (%u)\n",
                irq_occurrence);
 
        if (!irq_occurrence)
@@ -2197,7 +2197,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "DC load has not completed before AC load (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
@@ -2206,7 +2206,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_err(codec->dev, "HP unplugged during measurement (%x)\n",
+               dev_err(component->dev, "HP unplugged during measurement (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
                return IRQ_HANDLED;
@@ -2214,7 +2214,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_OOR_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_err(codec->dev, "HP load out of range (%x)\n",
+               dev_err(component->dev, "HP load out of range (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
                return IRQ_HANDLED;
@@ -2222,7 +2222,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_AC_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_dbg(codec->dev, "HP AC load measurement done (%x)\n",
+               dev_dbg(component->dev, "HP AC load measurement done (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
                return IRQ_HANDLED;
@@ -2230,7 +2230,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_DC_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_dbg(codec->dev, "HP DC load measurement done (%x)\n",
+               dev_dbg(component->dev, "HP DC load measurement done (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
                return IRQ_HANDLED;
@@ -2238,7 +2238,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_ON_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_dbg(codec->dev, "HP load state machine on done (%x)\n",
+               dev_dbg(component->dev, "HP load state machine on done (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
                return IRQ_HANDLED;
@@ -2246,19 +2246,19 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
 
        if (stickies[3] & CS43130_HPLOAD_OFF_INT) {
                cs43130->hpload_stat = stickies[3];
-               dev_dbg(codec->dev, "HP load state machine off done (%x)\n",
+               dev_dbg(component->dev, "HP load state machine off done (%x)\n",
                        cs43130->hpload_stat);
                complete(&cs43130->hpload_evt);
                return IRQ_HANDLED;
        }
 
        if (stickies[0] & CS43130_XTAL_ERR_INT) {
-               dev_err(codec->dev, "Crystal err: clock is not running\n");
+               dev_err(component->dev, "Crystal err: clock is not running\n");
                return IRQ_HANDLED;
        }
 
        if (stickies[0] & CS43130_HP_UNPLUG_INT) {
-               dev_dbg(codec->dev, "HP unplugged\n");
+               dev_dbg(component->dev, "HP unplugged\n");
                cs43130->hpload_done = false;
                snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK);
                return IRQ_HANDLED;
@@ -2267,7 +2267,7 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
        if (stickies[0] & CS43130_HP_PLUG_INT) {
                if (cs43130->dc_meas && !cs43130->hpload_done &&
                    !work_busy(&cs43130->work)) {
-                       dev_dbg(codec->dev, "HP load queue work\n");
+                       dev_dbg(component->dev, "HP load queue work\n");
                        queue_work(cs43130->wq, &cs43130->work);
                }
 
@@ -2279,14 +2279,14 @@ static irqreturn_t cs43130_irq_thread(int irq, void *data)
        return IRQ_NONE;
 }
 
-static int cs43130_probe(struct snd_soc_codec *codec)
+static int cs43130_probe(struct snd_soc_component *component)
 {
        int ret;
-       struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_card *card = codec->component.card;
+       struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_card *card = component->card;
        unsigned int reg;
 
-       cs43130->codec = codec;
+       cs43130->component = component;
 
        if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) {
                regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET,
@@ -2299,25 +2299,25 @@ static int cs43130_probe(struct snd_soc_codec *codec)
        ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK,
                                    &cs43130->jack, NULL, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Cannot create jack\n");
+               dev_err(component->dev, "Cannot create jack\n");
                return ret;
        }
 
        cs43130->hpload_done = false;
        if (cs43130->dc_meas) {
-               ret = device_create_file(codec->dev, &dev_attr_hpload_dc_l);
+               ret = device_create_file(component->dev, &dev_attr_hpload_dc_l);
                if (ret < 0)
                        return ret;
 
-               ret = device_create_file(codec->dev, &dev_attr_hpload_dc_r);
+               ret = device_create_file(component->dev, &dev_attr_hpload_dc_r);
                if (ret < 0)
                        return ret;
 
-               ret = device_create_file(codec->dev, &dev_attr_hpload_ac_l);
+               ret = device_create_file(component->dev, &dev_attr_hpload_ac_l);
                if (ret < 0)
                        return ret;
 
-               ret = device_create_file(codec->dev, &dev_attr_hpload_ac_r);
+               ret = device_create_file(component->dev, &dev_attr_hpload_ac_r);
                if (ret < 0)
                        return ret;
 
@@ -2338,14 +2338,16 @@ static int cs43130_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_cs43130 = {
+static struct snd_soc_component_driver soc_component_dev_cs43130 = {
        .probe                  = cs43130_probe,
-       .component_driver = {
-               .controls               = cs43130_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs43130_snd_controls),
-       },
-       .set_sysclk             = cs43130_codec_set_sysclk,
+       .controls               = cs43130_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs43130_snd_controls),
+       .set_sysclk             = cs43130_component_set_sysclk,
        .set_pll                = cs43130_set_pll,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config cs43130_regmap = {
@@ -2536,33 +2538,34 @@ static int cs43130_i2c_probe(struct i2c_client *client,
                memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes),
                       analog_hp_routes, sizeof(analog_hp_routes));
 
-               soc_codec_dev_cs43130.component_driver.dapm_widgets =
+               soc_component_dev_cs43130.dapm_widgets =
                        all_hp_widgets;
-               soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
+               soc_component_dev_cs43130.num_dapm_widgets =
                        ARRAY_SIZE(all_hp_widgets);
-               soc_codec_dev_cs43130.component_driver.dapm_routes =
+               soc_component_dev_cs43130.dapm_routes =
                        all_hp_routes;
-               soc_codec_dev_cs43130.component_driver.num_dapm_routes =
+               soc_component_dev_cs43130.num_dapm_routes =
                        ARRAY_SIZE(all_hp_routes);
                break;
        case CS43198_CHIP_ID:
        case CS4399_CHIP_ID:
-               soc_codec_dev_cs43130.component_driver.dapm_widgets =
+               soc_component_dev_cs43130.dapm_widgets =
                        digital_hp_widgets;
-               soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
+               soc_component_dev_cs43130.num_dapm_widgets =
                        ARRAY_SIZE(digital_hp_widgets);
-               soc_codec_dev_cs43130.component_driver.dapm_routes =
+               soc_component_dev_cs43130.dapm_routes =
                        digital_hp_routes;
-               soc_codec_dev_cs43130.component_driver.num_dapm_routes =
+               soc_component_dev_cs43130.num_dapm_routes =
                        ARRAY_SIZE(digital_hp_routes);
                break;
        }
 
-       ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130,
+       ret = devm_snd_soc_register_component(&client->dev,
+                                    &soc_component_dev_cs43130,
                                     cs43130_dai, ARRAY_SIZE(cs43130_dai));
        if (ret < 0) {
                dev_err(&client->dev,
-                       "snd_soc_register_codec failed with ret = %d\n", ret);
+                       "snd_soc_register_component failed with ret = %d\n", ret);
                goto err;
        }
 
@@ -2604,8 +2607,6 @@ static int cs43130_i2c_remove(struct i2c_client *client)
        pm_runtime_disable(&client->dev);
        regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
 
-       snd_soc_unregister_codec(&client->dev);
-
        return 0;
 }
 
index 781258418d893a21c7fdfdef9cf6782b7680e714..c3c6eef61e87cf00fa8b2ece94c16f053bc66f5f 100644 (file)
@@ -508,7 +508,7 @@ struct cs43130_dai {
 };
 
 struct cs43130_private {
-       struct snd_soc_codec            *codec;
+       struct snd_soc_component        *component;
        struct regmap                   *regmap;
        struct regulator_bulk_data      supplies[CS43130_NUM_SUPPLIES];
        struct gpio_desc                *reset_gpio;
index 0a749c79ef579bdd6bcf9688d6a24f784cfdc6db..bee0e343723fee44c3661d3446f2382a49b58d4e 100644 (file)
@@ -74,8 +74,8 @@ static bool cs4349_writeable_register(struct device *dev, unsigned int reg)
 static int cs4349_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct cs4349_private *cs4349 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct cs4349_private *cs4349 = snd_soc_component_get_drvdata(component);
        unsigned int fmt;
 
        fmt = format & SND_SOC_DAIFMT_FORMAT_MASK;
@@ -97,8 +97,8 @@ static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct cs4349_private *cs4349 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct cs4349_private *cs4349 = snd_soc_component_get_drvdata(component);
        int fmt, ret;
 
        cs4349->rate = params_rate(params);
@@ -126,7 +126,7 @@ static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       ret = snd_soc_update_bits(codec, CS4349_MODE, DIF_MASK,
+       ret = snd_soc_component_update_bits(component, CS4349_MODE, DIF_MASK,
                                  MODE_FORMAT(fmt));
        if (ret < 0)
                return ret;
@@ -136,14 +136,14 @@ static int cs4349_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int cs4349_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int reg;
 
        reg = 0;
        if (mute)
                reg = MUTE_AB_MASK;
 
-       return snd_soc_update_bits(codec, CS4349_MUTE, MUTE_AB_MASK, reg);
+       return snd_soc_component_update_bits(component, CS4349_MUTE, MUTE_AB_MASK, reg);
 }
 
 static DECLARE_TLV_DB_SCALE(dig_tlv, -12750, 50, 0);
@@ -255,15 +255,17 @@ static struct snd_soc_dai_driver cs4349_dai = {
        .symmetric_rates = 1,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs4349 = {
-       .component_driver = {
-               .controls               = cs4349_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs4349_snd_controls),
-               .dapm_widgets           = cs4349_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs4349_dapm_widgets),
-               .dapm_routes            = cs4349_routes,
-               .num_dapm_routes        = ARRAY_SIZE(cs4349_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_cs4349 = {
+       .controls               = cs4349_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs4349_snd_controls),
+       .dapm_widgets           = cs4349_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs4349_dapm_widgets),
+       .dapm_routes            = cs4349_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs4349_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config cs4349_regmap = {
@@ -305,7 +307,8 @@ static int cs4349_i2c_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, cs4349);
 
-       return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4349,
+       return devm_snd_soc_register_component(&client->dev,
+               &soc_component_dev_cs4349,
                &cs4349_dai, 1);
 }
 
@@ -313,8 +316,6 @@ static int cs4349_i2c_remove(struct i2c_client *client)
 {
        struct cs4349_private *cs4349 = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
-
        /* Hold down reset */
        gpiod_set_value_cansleep(cs4349->reset_gpio, 0);
 
index be2750680838cacf688e748b47f2010326117184..196e9c343aeb79711530581209050f8568fb9e78 100644 (file)
@@ -33,6 +33,8 @@
 #include "wm_adsp.h"
 #include "cs47l24.h"
 
+#define DRV_NAME "cs47l24-codec"
+
 struct cs47l24_priv {
        struct arizona_priv core;
        struct arizona_fll fll[2];
@@ -60,14 +62,14 @@ static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
 static int cs47l24_adsp_power_ev(struct snd_soc_dapm_widget *w,
                                 struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        unsigned int v;
        int ret;
 
        ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
+               dev_err(component->dev, "Failed to read SYSCLK state: %d\n", ret);
                return ret;
        }
 
@@ -194,14 +196,13 @@ SOC_SINGLE("HPOUT1 SC Protect Switch", ARIZONA_HP1_SHORT_CIRCUIT_CTRL,
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
 SOC_SINGLE("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
-            ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
+          ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
 
 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
                 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
-                ARIZONA_OUT4L_VOL_SHIFT,
-                0xbf, 0, digital_tlv),
+              ARIZONA_OUT4L_VOL_SHIFT, 0xbf, 0, digital_tlv),
 
 SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
 SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
@@ -492,8 +493,7 @@ SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
                 ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-                      &cs47l24_aec_loopback_mux),
+                ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &cs47l24_aec_loopback_mux),
 
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
                     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
@@ -929,10 +929,10 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
        { "DSP3 Voice Trigger", "Switch", "DSP3" },
 };
 
-static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-                         unsigned int Fref, unsigned int Fout)
+static int cs47l24_set_fll(struct snd_soc_component *component, int fll_id,
+                          int source, unsigned int Fref, unsigned int Fout)
 {
-       struct cs47l24_priv *cs47l24 = snd_soc_codec_get_drvdata(codec);
+       struct cs47l24_priv *cs47l24 = snd_soc_component_get_drvdata(component);
 
        switch (fll_id) {
        case CS47L24_FLL1:
@@ -1069,7 +1069,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
 static int cs47l24_open(struct snd_compr_stream *stream)
 {
        struct snd_soc_pcm_runtime *rtd = stream->private_data;
-       struct cs47l24_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->core.arizona;
        int n_adsp;
 
@@ -1115,34 +1116,34 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int cs47l24_codec_probe(struct snd_soc_codec *codec)
+static int cs47l24_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-       struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->core.arizona;
        int ret;
 
        arizona->dapm = dapm;
-       snd_soc_codec_init_regmap(codec, arizona->regmap);
+       snd_soc_component_init_regmap(component, arizona->regmap);
 
-       ret = arizona_init_spk(codec);
+       ret = arizona_init_spk(component);
        if (ret < 0)
                return ret;
 
-       arizona_init_gpio(codec);
-       arizona_init_mono(codec);
+       arizona_init_gpio(component);
+       arizona_init_mono(component);
 
-       ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
+       ret = wm_adsp2_component_probe(&priv->core.adsp[1], component);
        if (ret)
                goto err_adsp2_codec_probe;
 
-       ret = wm_adsp2_codec_probe(&priv->core.adsp[2], codec);
+       ret = wm_adsp2_component_probe(&priv->core.adsp[2], component);
        if (ret)
                goto err_adsp2_codec_probe;
 
-       ret = snd_soc_add_codec_controls(codec,
-                                        &arizona_adsp2_rate_controls[1], 2);
+       ret = snd_soc_add_component_controls(component,
+                                            &arizona_adsp2_rate_controls[1],
+                                            2);
        if (ret)
                goto err_adsp2_codec_probe;
 
@@ -1151,22 +1152,20 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
        return 0;
 
 err_adsp2_codec_probe:
-       wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
-       wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
+       wm_adsp2_component_remove(&priv->core.adsp[1], component);
+       wm_adsp2_component_remove(&priv->core.adsp[2], component);
 
        return ret;
 }
 
-static int cs47l24_codec_remove(struct snd_soc_codec *codec)
+static void cs47l24_component_remove(struct snd_soc_component *component)
 {
-       struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
 
-       wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
-       wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
+       wm_adsp2_component_remove(&priv->core.adsp[1], component);
+       wm_adsp2_component_remove(&priv->core.adsp[2], component);
 
        priv->core.arizona->dapm = NULL;
-
-       return 0;
 }
 
 #define CS47L24_DIG_VU 0x0200
@@ -1177,37 +1176,32 @@ static unsigned int cs47l24_digital_vu[] = {
        ARIZONA_DAC_DIGITAL_VOLUME_4L,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
-       .probe = cs47l24_codec_probe,
-       .remove = cs47l24_codec_remove,
-
-       .idle_bias_off = true,
-
-       .set_sysclk = arizona_set_sysclk,
-       .set_pll = cs47l24_set_fll,
-
-       .component_driver = {
-               .controls               = cs47l24_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs47l24_snd_controls),
-               .dapm_widgets           = cs47l24_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs47l24_dapm_widgets),
-               .dapm_routes            = cs47l24_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(cs47l24_dapm_routes),
-       },
-};
-
-static const struct snd_compr_ops cs47l24_compr_ops = {
-       .open = cs47l24_open,
-       .free = wm_adsp_compr_free,
-       .set_params = wm_adsp_compr_set_params,
-       .get_caps = wm_adsp_compr_get_caps,
-       .trigger = wm_adsp_compr_trigger,
-       .pointer = wm_adsp_compr_pointer,
-       .copy = wm_adsp_compr_copy,
+static struct snd_compr_ops cs47l24_compr_ops = {
+       .open           = cs47l24_open,
+       .free           = wm_adsp_compr_free,
+       .set_params     = wm_adsp_compr_set_params,
+       .get_caps       = wm_adsp_compr_get_caps,
+       .trigger        = wm_adsp_compr_trigger,
+       .pointer        = wm_adsp_compr_pointer,
+       .copy           = wm_adsp_compr_copy,
 };
 
-static const struct snd_soc_platform_driver cs47l24_compr_platform = {
-       .compr_ops = &cs47l24_compr_ops,
+static const struct snd_soc_component_driver soc_component_dev_cs47l24 = {
+       .probe                  = cs47l24_component_probe,
+       .remove                 = cs47l24_component_remove,
+       .set_sysclk             = arizona_set_sysclk,
+       .set_pll                = cs47l24_set_fll,
+       .name                   = DRV_NAME,
+       .compr_ops              = &cs47l24_compr_ops,
+       .controls               = cs47l24_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs47l24_snd_controls),
+       .dapm_widgets           = cs47l24_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs47l24_dapm_widgets),
+       .dapm_routes            = cs47l24_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs47l24_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int cs47l24_probe(struct platform_device *pdev)
@@ -1219,7 +1213,7 @@ static int cs47l24_probe(struct platform_device *pdev)
        BUILD_BUG_ON(ARRAY_SIZE(cs47l24_dai) > ARIZONA_MAX_DAI);
 
        cs47l24 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l24_priv),
-                             GFP_KERNEL);
+                              GFP_KERNEL);
        if (!cs47l24)
                return -ENOMEM;
 
@@ -1298,23 +1292,17 @@ static int cs47l24_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_dsp_irq;
 
-       ret = snd_soc_register_platform(&pdev->dev, &cs47l24_compr_platform);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &soc_component_dev_cs47l24,
+                                             cs47l24_dai,
+                                             ARRAY_SIZE(cs47l24_dai));
        if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
                goto err_spk_irqs;
        }
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
-                                     cs47l24_dai, ARRAY_SIZE(cs47l24_dai));
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-               goto err_platform;
-       }
-
        return ret;
 
-err_platform:
-       snd_soc_unregister_platform(&pdev->dev);
 err_spk_irqs:
        arizona_free_spk_irqs(arizona);
 err_dsp_irq:
@@ -1328,8 +1316,6 @@ static int cs47l24_remove(struct platform_device *pdev)
        struct cs47l24_priv *cs47l24 = platform_get_drvdata(pdev);
        struct arizona *arizona = cs47l24->core.arizona;
 
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_codec(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        wm_adsp2_remove(&cs47l24->core.adsp[1]);
index c7edf2df5e36b707095817640edb525e550d92cb..8995ea45b4ca822150a900dbc38c39d9d0e6c3bf 100644 (file)
@@ -549,7 +549,7 @@ static int cs53l30_get_mclk_coeff(int mclk_rate, int srate)
 static int cs53l30_set_sysclk(struct snd_soc_dai *dai,
                              int clk_id, unsigned int freq, int dir)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
        int mclkx_coeff;
        u32 mclk_rate;
 
@@ -572,7 +572,7 @@ static int cs53l30_set_sysclk(struct snd_soc_dai *dai,
 
 static int cs53l30_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
        u8 aspcfg = 0, aspctl1 = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -626,7 +626,7 @@ static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
        int srate = params_rate(params);
        int mclk_coeff;
 
@@ -650,11 +650,11 @@ static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
+static int cs53l30_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(component);
        unsigned int reg;
        int i, inter_max_check, ret;
 
@@ -670,7 +670,7 @@ static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
                if (dapm->bias_level == SND_SOC_BIAS_OFF) {
                        ret = clk_prepare_enable(priv->mclk);
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "failed to enable MCLK: %d\n", ret);
                                return ret;
                        }
@@ -736,7 +736,7 @@ static int cs53l30_set_bias_level(struct snd_soc_codec *codec,
 
 static int cs53l30_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
        u8 val = tristate ? CS53L30_ASP_3ST : 0;
 
        return regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1,
@@ -770,7 +770,7 @@ static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
                                    unsigned int tx_mask, unsigned int rx_mask,
                                    int slots, int slot_width)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
        unsigned int loc[CS53L30_TDM_SLOT_MAX] = {48, 48, 48, 48};
        unsigned int slot_next, slot_step;
        u64 tx_enable = 0;
@@ -840,7 +840,7 @@ static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
 static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
 
        gpiod_set_value_cansleep(priv->mute_gpio, mute);
 
@@ -876,10 +876,10 @@ static struct snd_soc_dai_driver cs53l30_dai = {
        .symmetric_rates = 1,
 };
 
-static int cs53l30_codec_probe(struct snd_soc_codec *codec)
+static int cs53l30_component_probe(struct snd_soc_component *component)
 {
-       struct cs53l30_private *priv = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct cs53l30_private *priv = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (priv->use_sdout2)
                snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout2,
@@ -891,19 +891,18 @@ static int cs53l30_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver cs53l30_driver = {
-       .probe = cs53l30_codec_probe,
-       .set_bias_level = cs53l30_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = cs53l30_snd_controls,
-               .num_controls           = ARRAY_SIZE(cs53l30_snd_controls),
-               .dapm_widgets           = cs53l30_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cs53l30_dapm_widgets),
-               .dapm_routes            = cs53l30_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(cs53l30_dapm_routes),
-       },
+static const struct snd_soc_component_driver cs53l30_driver = {
+       .probe                  = cs53l30_component_probe,
+       .set_bias_level         = cs53l30_set_bias_level,
+       .controls               = cs53l30_snd_controls,
+       .num_controls           = ARRAY_SIZE(cs53l30_snd_controls),
+       .dapm_widgets           = cs53l30_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cs53l30_dapm_widgets),
+       .dapm_routes            = cs53l30_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(cs53l30_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct regmap_config cs53l30_regmap = {
@@ -1033,9 +1032,9 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
 
        dev_info(dev, "Cirrus Logic CS53L30, Revision: %02X\n", reg & 0xFF);
 
-       ret = snd_soc_register_codec(dev, &cs53l30_driver, &cs53l30_dai, 1);
+       ret = devm_snd_soc_register_component(dev, &cs53l30_driver, &cs53l30_dai, 1);
        if (ret) {
-               dev_err(dev, "failed to register codec: %d\n", ret);
+               dev_err(dev, "failed to register component: %d\n", ret);
                goto error;
        }
 
@@ -1051,8 +1050,6 @@ static int cs53l30_i2c_remove(struct i2c_client *client)
 {
        struct cs53l30_private *cs53l30 = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
-
        /* Hold down reset */
        gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
 
index 95bb10ba80dcfb447d811f04032a7eb600168b51..07dd33b095967d6fd7aebf999068eff0f496d72e 100644 (file)
@@ -89,10 +89,10 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
        {"ADC", NULL, "Input Mixer"},
 };
 
-static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
+static unsigned int cx20442_read_reg_cache(struct snd_soc_component *component,
                                           unsigned int reg)
 {
-       struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+       struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
 
        if (reg >= 1)
                return -EINVAL;
@@ -153,10 +153,10 @@ static int cx20442_pm_to_v253_vsp(u8 value)
        return (value & (1 << CX20442_AGC)) ? -EINVAL : 0;
 }
 
-static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
+static int cx20442_write(struct snd_soc_component *component, unsigned int reg,
                                                        unsigned int value)
 {
-       struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+       struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
        int vls, vsp, old, len;
        char buf[18];
 
@@ -193,7 +193,7 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
        if (unlikely(len > (ARRAY_SIZE(buf) - 1)))
                return -ENOMEM;
 
-       dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
+       dev_dbg(component->dev, "%s: %s\n", __func__, buf);
        if (cx20442->tty->ops->write(cx20442->tty, buf, len) != len)
                return -EIO;
 
@@ -240,19 +240,19 @@ err:
 /* Line discipline .close() */
 static void v253_close(struct tty_struct *tty)
 {
-       struct snd_soc_codec *codec = tty->disc_data;
+       struct snd_soc_component *component = tty->disc_data;
        struct cx20442_priv *cx20442;
 
        tty->disc_data = NULL;
 
-       if (!codec)
+       if (!component)
                return;
 
-       cx20442 = snd_soc_codec_get_drvdata(codec);
+       cx20442 = snd_soc_component_get_drvdata(component);
 
        /* Prevent the codec driver from further accessing the modem */
        cx20442->tty = NULL;
-       codec->component.card->pop_time = 0;
+       component->card->pop_time = 0;
 }
 
 /* Line discipline .hangup() */
@@ -266,20 +266,20 @@ static int v253_hangup(struct tty_struct *tty)
 static void v253_receive(struct tty_struct *tty,
                                const unsigned char *cp, char *fp, int count)
 {
-       struct snd_soc_codec *codec = tty->disc_data;
+       struct snd_soc_component *component = tty->disc_data;
        struct cx20442_priv *cx20442;
 
-       if (!codec)
+       if (!component)
                return;
 
-       cx20442 = snd_soc_codec_get_drvdata(codec);
+       cx20442 = snd_soc_component_get_drvdata(component);
 
        if (!cx20442->tty) {
                /* First modem response, complete setup procedure */
 
                /* Set up codec driver access to modem controls */
                cx20442->tty = tty;
-               codec->component.card->pop_time = 1;
+               component->card->pop_time = 1;
        }
 }
 
@@ -323,15 +323,15 @@ static struct snd_soc_dai_driver cx20442_dai = {
        },
 };
 
-static int cx20442_set_bias_level(struct snd_soc_codec *codec,
+static int cx20442_set_bias_level(struct snd_soc_component *component,
                enum snd_soc_bias_level level)
 {
-       struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+       struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
        int err = 0;
 
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
-               if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_STANDBY)
+               if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_STANDBY)
                        break;
                if (IS_ERR(cx20442->por))
                        err = PTR_ERR(cx20442->por);
@@ -339,7 +339,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
                        err = regulator_enable(cx20442->por);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_PREPARE)
+               if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_PREPARE)
                        break;
                if (IS_ERR(cx20442->por))
                        err = PTR_ERR(cx20442->por);
@@ -353,7 +353,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
        return err;
 }
 
-static int cx20442_codec_probe(struct snd_soc_codec *codec)
+static int cx20442_component_probe(struct snd_soc_component *component)
 {
        struct cx20442_priv *cx20442;
 
@@ -361,21 +361,21 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
        if (cx20442 == NULL)
                return -ENOMEM;
 
-       cx20442->por = regulator_get(codec->dev, "POR");
+       cx20442->por = regulator_get(component->dev, "POR");
        if (IS_ERR(cx20442->por))
-               dev_warn(codec->dev, "failed to get the regulator");
+               dev_warn(component->dev, "failed to get the regulator");
        cx20442->tty = NULL;
 
-       snd_soc_codec_set_drvdata(codec, cx20442);
-       codec->component.card->pop_time = 0;
+       snd_soc_component_set_drvdata(component, cx20442);
+       component->card->pop_time = 0;
 
        return 0;
 }
 
 /* power down chip */
-static int cx20442_codec_remove(struct snd_soc_codec *codec)
+static void cx20442_component_remove(struct snd_soc_component *component)
 {
-       struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+       struct cx20442_priv *cx20442 = snd_soc_component_get_drvdata(component);
 
        if (cx20442->tty) {
                struct tty_struct *tty = cx20442->tty;
@@ -387,36 +387,30 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
                regulator_put(cx20442->por);
        }
 
-       snd_soc_codec_set_drvdata(codec, NULL);
+       snd_soc_component_set_drvdata(component, NULL);
        kfree(cx20442);
-       return 0;
 }
 
-static const struct snd_soc_codec_driver cx20442_codec_dev = {
-       .probe =        cx20442_codec_probe,
-       .remove =       cx20442_codec_remove,
-       .set_bias_level = cx20442_set_bias_level,
-       .read = cx20442_read_reg_cache,
-       .write = cx20442_write,
-
-       .component_driver = {
-               .dapm_widgets           = cx20442_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(cx20442_dapm_widgets),
-               .dapm_routes            = cx20442_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(cx20442_audio_map),
-       },
+static const struct snd_soc_component_driver cx20442_component_dev = {
+       .probe                  = cx20442_component_probe,
+       .remove                 = cx20442_component_remove,
+       .set_bias_level         = cx20442_set_bias_level,
+       .read                   = cx20442_read_reg_cache,
+       .write                  = cx20442_write,
+       .dapm_widgets           = cx20442_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(cx20442_dapm_widgets),
+       .dapm_routes            = cx20442_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(cx20442_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int cx20442_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &cx20442_codec_dev, &cx20442_dai, 1);
-}
-
-static int cx20442_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &cx20442_component_dev, &cx20442_dai, 1);
 }
 
 static struct platform_driver cx20442_platform_driver = {
@@ -424,7 +418,6 @@ static struct platform_driver cx20442_platform_driver = {
                .name = "cx20442-codec",
                },
        .probe = cx20442_platform_probe,
-       .remove = cx20442_platform_remove,
 };
 
 module_platform_driver(cx20442_platform_driver);
index 1af443ccbc51531c2039a0e889909a1439635b3f..a664111b71844eeafa256b71af510a0acd682c2a 100644 (file)
@@ -331,12 +331,12 @@ static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel,
 static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
 
        if (ucontrol->value.integer.value[0]) {
                /* Check if noise suppression is enabled */
-               if (snd_soc_read(codec, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
-                       dev_dbg(codec->dev,
+               if (snd_soc_component_read32(component, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) {
+                       dev_dbg(component->dev,
                                "Disable noise suppression to enable ALC\n");
                        return -EINVAL;
                }
@@ -354,32 +354,32 @@ static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol,
 static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        u8 val;
 
        if (ucontrol->value.integer.value[0]) {
                /* Check if ALC is enabled */
-               if (snd_soc_read(codec, DA7210_ADC) & DA7210_ADC_ALC_EN)
+               if (snd_soc_component_read32(component, DA7210_ADC) & DA7210_ADC_ALC_EN)
                        goto err;
 
                /* Check ZC for HP and AUX1 PGA */
-               if ((snd_soc_read(codec, DA7210_ZERO_CROSS) &
+               if ((snd_soc_component_read32(component, DA7210_ZERO_CROSS) &
                        (DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC |
                        DA7210_HP_R_ZC)) != (DA7210_AUX1_L_ZC |
                        DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | DA7210_HP_R_ZC))
                        goto err;
 
                /* Check INPGA_L_VOL and INPGA_R_VOL */
-               val = snd_soc_read(codec, DA7210_IN_GAIN);
+               val = snd_soc_component_read32(component, DA7210_IN_GAIN);
                if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) ||
                        (((val & DA7210_INPGA_R_VOL) >> 4) <
                        DA7210_INPGA_MIN_VOL_NS))
                        goto err;
 
                /* Check AUX1_L_VOL and AUX1_R_VOL */
-               if (((snd_soc_read(codec, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
+               if (((snd_soc_component_read32(component, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) <
                    DA7210_AUX1_MIN_VOL_NS) ||
-                   ((snd_soc_read(codec, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
+                   ((snd_soc_component_read32(component, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) <
                    DA7210_AUX1_MIN_VOL_NS))
                        goto err;
        }
@@ -760,19 +760,19 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
        u32 dai_cfg1;
        u32 fs, sysclk;
 
        /* set DAI source to Left and Right ADC */
-       snd_soc_write(codec, DA7210_DAI_SRC_SEL,
+       snd_soc_component_write(component, DA7210_DAI_SRC_SEL,
                     DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
 
        /* Enable DAI */
-       snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
+       snd_soc_component_write(component, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
 
-       dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1);
+       dai_cfg1 = 0xFC & snd_soc_component_read32(component, DA7210_DAI_CFG1);
 
        switch (params_width(params)) {
        case 16:
@@ -791,7 +791,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
+       snd_soc_component_write(component, DA7210_DAI_CFG1, dai_cfg1);
 
        switch (params_rate(params)) {
        case 8000:
@@ -839,17 +839,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* Disable active mode */
-       snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
+       snd_soc_component_update_bits(component, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
 
-       snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
+       snd_soc_component_update_bits(component, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
 
        if (da7210->mclk_rate && (da7210->mclk_rate != sysclk)) {
                /* PLL mode, disable PLL bypass */
-               snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, 0);
+               snd_soc_component_update_bits(component, DA7210_PLL_DIV3, DA7210_PLL_BYP, 0);
 
                if (!da7210->master) {
                        /* PLL slave mode, also enable SRM */
-                       snd_soc_update_bits(codec, DA7210_PLL,
+                       snd_soc_component_update_bits(component, DA7210_PLL,
                                                   (DA7210_MCLK_SRM_EN |
                                                    DA7210_MCLK_DET_EN),
                                                   (DA7210_MCLK_SRM_EN |
@@ -857,13 +857,13 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
                }
        } else {
                /* PLL bypass mode, enable PLL bypass and Auto Detection */
-               snd_soc_update_bits(codec, DA7210_PLL, DA7210_MCLK_DET_EN,
+               snd_soc_component_update_bits(component, DA7210_PLL, DA7210_MCLK_DET_EN,
                                                       DA7210_MCLK_DET_EN);
-               snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP,
+               snd_soc_component_update_bits(component, DA7210_PLL_DIV3, DA7210_PLL_BYP,
                                                            DA7210_PLL_BYP);
        }
        /* Enable active mode */
-       snd_soc_update_bits(codec, DA7210_STARTUP1,
+       snd_soc_component_update_bits(component, DA7210_STARTUP1,
                            DA7210_SC_MST_EN, DA7210_SC_MST_EN);
 
        return 0;
@@ -874,16 +874,16 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
  */
 static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
        u32 dai_cfg1;
        u32 dai_cfg3;
 
-       dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
-       dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
+       dai_cfg1 = 0x7f & snd_soc_component_read32(component, DA7210_DAI_CFG1);
+       dai_cfg3 = 0xfc & snd_soc_component_read32(component, DA7210_DAI_CFG3);
 
-       if ((snd_soc_read(codec, DA7210_PLL) & DA7210_PLL_EN) &&
-               (!(snd_soc_read(codec, DA7210_PLL_DIV3) & DA7210_PLL_BYP)))
+       if ((snd_soc_component_read32(component, DA7210_PLL) & DA7210_PLL_EN) &&
+               (!(snd_soc_component_read32(component, DA7210_PLL_DIV3) & DA7210_PLL_BYP)))
                return -EINVAL;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -923,21 +923,21 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
         */
        dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
 
-       snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1);
-       snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3);
+       snd_soc_component_write(component, DA7210_DAI_CFG1, dai_cfg1);
+       snd_soc_component_write(component, DA7210_DAI_CFG3, dai_cfg3);
 
        return 0;
 }
 
 static int da7210_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u8 mute_reg = snd_soc_read(codec, DA7210_DAC_HPF) & 0xFB;
+       struct snd_soc_component *component = dai->component;
+       u8 mute_reg = snd_soc_component_read32(component, DA7210_DAC_HPF) & 0xFB;
 
        if (mute)
-               snd_soc_write(codec, DA7210_DAC_HPF, mute_reg | 0x4);
+               snd_soc_component_write(component, DA7210_DAC_HPF, mute_reg | 0x4);
        else
-               snd_soc_write(codec, DA7210_DAC_HPF, mute_reg);
+               snd_soc_component_write(component, DA7210_DAC_HPF, mute_reg);
        return 0;
 }
 
@@ -947,8 +947,8 @@ static int da7210_mute(struct snd_soc_dai *dai, int mute)
 static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case DA7210_CLKSRC_MCLK:
@@ -988,8 +988,8 @@ static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int fref, unsigned int fout)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 
        u8 pll_div1, pll_div2, pll_div3, cnt;
 
@@ -1014,18 +1014,18 @@ static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                goto err;
 
        /* Disable active mode */
-       snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
+       snd_soc_component_update_bits(component, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
        /* Write PLL dividers */
-       snd_soc_write(codec, DA7210_PLL_DIV1, pll_div1);
-       snd_soc_write(codec, DA7210_PLL_DIV2, pll_div2);
-       snd_soc_update_bits(codec, DA7210_PLL_DIV3,
+       snd_soc_component_write(component, DA7210_PLL_DIV1, pll_div1);
+       snd_soc_component_write(component, DA7210_PLL_DIV2, pll_div2);
+       snd_soc_component_update_bits(component, DA7210_PLL_DIV3,
                                   DA7210_PLL_DIV_L_MASK, pll_div3);
 
        /* Enable PLL */
-       snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
+       snd_soc_component_update_bits(component, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
 
        /* Enable active mode */
-       snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN,
+       snd_soc_component_update_bits(component, DA7210_STARTUP1, DA7210_SC_MST_EN,
                                                    DA7210_SC_MST_EN);
        return 0;
 err:
@@ -1064,53 +1064,53 @@ static struct snd_soc_dai_driver da7210_dai = {
        .symmetric_rates = 1,
 };
 
-static int da7210_probe(struct snd_soc_codec *codec)
+static int da7210_probe(struct snd_soc_component *component)
 {
-       struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
+       struct da7210_priv *da7210 = snd_soc_component_get_drvdata(component);
 
-       dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
+       dev_info(component->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
 
        da7210->mclk_rate       = 0;    /* This will be set from set_sysclk() */
        da7210->master          = 0;    /* This will be set from set_fmt() */
 
        /* Enable internal regulator & bias current */
-       snd_soc_write(codec, DA7210_CONTROL, DA7210_REG_EN | DA7210_BIAS_EN);
+       snd_soc_component_write(component, DA7210_CONTROL, DA7210_REG_EN | DA7210_BIAS_EN);
 
        /*
         * ADC settings
         */
 
        /* Enable Left & Right MIC PGA and Mic Bias */
-       snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
-       snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
+       snd_soc_component_write(component, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
+       snd_soc_component_write(component, DA7210_MIC_R, DA7210_MIC_R_EN);
 
        /* Enable Left and Right input PGA */
-       snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
-       snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
+       snd_soc_component_write(component, DA7210_INMIX_L, DA7210_IN_L_EN);
+       snd_soc_component_write(component, DA7210_INMIX_R, DA7210_IN_R_EN);
 
        /* Enable Left and Right ADC */
-       snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
+       snd_soc_component_write(component, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
 
        /*
         * DAC settings
         */
 
        /* Enable Left and Right DAC */
-       snd_soc_write(codec, DA7210_DAC_SEL,
+       snd_soc_component_write(component, DA7210_DAC_SEL,
                     DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
                     DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
 
        /* Enable Left and Right out PGA */
-       snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
-       snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
+       snd_soc_component_write(component, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
+       snd_soc_component_write(component, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
 
        /* Enable Left and Right HeadPhone PGA */
-       snd_soc_write(codec, DA7210_HP_CFG,
+       snd_soc_component_write(component, DA7210_HP_CFG,
                     DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
                     DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
 
        /* Enable ramp mode for DAC gain update */
-       snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN);
+       snd_soc_component_write(component, DA7210_SOFTMUTE, DA7210_RAMP_EN);
 
        /*
         * For DA7210 codec, there are two ways to enable/disable analog IOs
@@ -1138,43 +1138,44 @@ static int da7210_probe(struct snd_soc_codec *codec)
         */
 
        /* Enable Line out amplifiers */
-       snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN);
-       snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN);
-       snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN |
+       snd_soc_component_write(component, DA7210_OUT1_L, DA7210_OUT1_L_EN);
+       snd_soc_component_write(component, DA7210_OUT1_R, DA7210_OUT1_R_EN);
+       snd_soc_component_write(component, DA7210_OUT2, DA7210_OUT2_EN |
                     DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R);
 
        /* Enable Aux1 */
-       snd_soc_write(codec, DA7210_AUX1_L, DA7210_AUX1_L_EN);
-       snd_soc_write(codec, DA7210_AUX1_R, DA7210_AUX1_R_EN);
+       snd_soc_component_write(component, DA7210_AUX1_L, DA7210_AUX1_L_EN);
+       snd_soc_component_write(component, DA7210_AUX1_R, DA7210_AUX1_R_EN);
        /* Enable Aux2 */
-       snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN);
+       snd_soc_component_write(component, DA7210_AUX2, DA7210_AUX2_EN);
 
        /* Set PLL Master clock range 10-20 MHz, enable PLL bypass */
-       snd_soc_write(codec, DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ |
+       snd_soc_component_write(component, DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ |
                                              DA7210_PLL_BYP);
 
        /* Diable PLL and bypass it */
-       snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
+       snd_soc_component_write(component, DA7210_PLL, DA7210_PLL_FS_48000);
 
        /* Activate all enabled subsystem */
-       snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
+       snd_soc_component_write(component, DA7210_STARTUP1, DA7210_SC_MST_EN);
 
-       dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
+       dev_info(component->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7210 = {
+static const struct snd_soc_component_driver soc_component_dev_da7210 = {
        .probe                  = da7210_probe,
-
-       .component_driver = {
-               .controls               = da7210_snd_controls,
-               .num_controls           = ARRAY_SIZE(da7210_snd_controls),
-               .dapm_widgets           = da7210_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(da7210_dapm_widgets),
-               .dapm_routes            = da7210_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(da7210_audio_map),
-       },
+       .controls               = da7210_snd_controls,
+       .num_controls           = ARRAY_SIZE(da7210_snd_controls),
+       .dapm_widgets           = da7210_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(da7210_dapm_widgets),
+       .dapm_routes            = da7210_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(da7210_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 #if IS_ENABLED(CONFIG_I2C)
@@ -1232,20 +1233,14 @@ static int da7210_i2c_probe(struct i2c_client *i2c,
        if (ret != 0)
                dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_da7210, &da7210_dai, 1);
+       ret =  devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_da7210, &da7210_dai, 1);
        if (ret < 0)
-               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 
        return ret;
 }
 
-static int da7210_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id da7210_i2c_id[] = {
        { "da7210", 0 },
        { }
@@ -1258,7 +1253,6 @@ static struct i2c_driver da7210_i2c_driver = {
                .name = "da7210",
        },
        .probe          = da7210_i2c_probe,
-       .remove         = da7210_i2c_remove,
        .id_table       = da7210_i2c_id,
 };
 #endif
@@ -1325,24 +1319,17 @@ static int da7210_spi_probe(struct spi_device *spi)
        if (ret != 0)
                dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_da7210, &da7210_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_da7210, &da7210_dai, 1);
 
        return ret;
 }
 
-static int da7210_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver da7210_spi_driver = {
        .driver = {
                .name = "da7210",
        },
        .probe = da7210_spi_probe,
-       .remove = da7210_spi_remove
 };
 #endif
 
index b2b4e90fc02adc5c25d9aa5511e360eaa0b4c76d..54cb5f24969f3137ff3bfc2c2de16bb07499cae1 100644 (file)
@@ -194,7 +194,7 @@ static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
  * Control Functions
  */
 
-static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
+static int da7213_get_alc_data(struct snd_soc_component *component, u8 reg_val)
 {
        int mid_data, top_data;
        int sum = 0;
@@ -203,17 +203,17 @@ static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
        for (iteration = 0; iteration < DA7213_ALC_AVG_ITERATIONS;
             iteration++) {
                /* Select the left or right channel and capture data */
-               snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL, reg_val);
+               snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL, reg_val);
 
                /* Select middle 8 bits for read back from data register */
-               snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
+               snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL,
                              reg_val | DA7213_ALC_DATA_MIDDLE);
-               mid_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
+               mid_data = snd_soc_component_read32(component, DA7213_ALC_CIC_OP_LVL_DATA);
 
                /* Select top 8 bits for read back from data register */
-               snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
+               snd_soc_component_write(component, DA7213_ALC_CIC_OP_LVL_CTRL,
                              reg_val | DA7213_ALC_DATA_TOP);
-               top_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
+               top_data = snd_soc_component_read32(component, DA7213_ALC_CIC_OP_LVL_DATA);
 
                sum += ((mid_data << 8) | (top_data << 16));
        }
@@ -221,17 +221,17 @@ static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
        return sum / DA7213_ALC_AVG_ITERATIONS;
 }
 
-static void da7213_alc_calib_man(struct snd_soc_codec *codec)
+static void da7213_alc_calib_man(struct snd_soc_component *component)
 {
        u8 reg_val;
        int avg_left_data, avg_right_data, offset_l, offset_r;
 
        /* Calculate average for Left and Right data */
        /* Left Data */
-       avg_left_data = da7213_get_alc_data(codec,
+       avg_left_data = da7213_get_alc_data(component,
                        DA7213_ALC_CIC_OP_CHANNEL_LEFT);
        /* Right Data */
-       avg_right_data = da7213_get_alc_data(codec,
+       avg_right_data = da7213_get_alc_data(component,
                         DA7213_ALC_CIC_OP_CHANNEL_RIGHT);
 
        /* Calculate DC offset */
@@ -239,122 +239,122 @@ static void da7213_alc_calib_man(struct snd_soc_codec *codec)
        offset_r = -avg_right_data;
 
        reg_val = (offset_l & DA7213_ALC_OFFSET_15_8) >> 8;
-       snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_L, reg_val);
+       snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_M_L, reg_val);
        reg_val = (offset_l & DA7213_ALC_OFFSET_19_16) >> 16;
-       snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_L, reg_val);
+       snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_U_L, reg_val);
 
        reg_val = (offset_r & DA7213_ALC_OFFSET_15_8) >> 8;
-       snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_R, reg_val);
+       snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_M_R, reg_val);
        reg_val = (offset_r & DA7213_ALC_OFFSET_19_16) >> 16;
-       snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_R, reg_val);
+       snd_soc_component_write(component, DA7213_ALC_OFFSET_MAN_U_R, reg_val);
 
        /* Enable analog/digital gain mode & offset cancellation */
-       snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+       snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
                            DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
                            DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
 }
 
-static void da7213_alc_calib_auto(struct snd_soc_codec *codec)
+static void da7213_alc_calib_auto(struct snd_soc_component *component)
 {
        u8 alc_ctrl1;
 
        /* Begin auto calibration and wait for completion */
-       snd_soc_update_bits(codec, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN,
+       snd_soc_component_update_bits(component, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN,
                            DA7213_ALC_AUTO_CALIB_EN);
        do {
-               alc_ctrl1 = snd_soc_read(codec, DA7213_ALC_CTRL1);
+               alc_ctrl1 = snd_soc_component_read32(component, DA7213_ALC_CTRL1);
        } while (alc_ctrl1 & DA7213_ALC_AUTO_CALIB_EN);
 
        /* If auto calibration fails, fall back to digital gain only mode */
        if (alc_ctrl1 & DA7213_ALC_CALIB_OVERFLOW) {
-               dev_warn(codec->dev,
+               dev_warn(component->dev,
                         "ALC auto calibration failed with overflow\n");
-               snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+               snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
                                    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
                                    0);
        } else {
                /* Enable analog/digital gain mode & offset cancellation */
-               snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+               snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
                                    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
                                    DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
        }
 
 }
 
-static void da7213_alc_calib(struct snd_soc_codec *codec)
+static void da7213_alc_calib(struct snd_soc_component *component)
 {
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
        u8 adc_l_ctrl, adc_r_ctrl;
        u8 mixin_l_sel, mixin_r_sel;
        u8 mic_1_ctrl, mic_2_ctrl;
 
        /* Save current values from ADC control registers */
-       adc_l_ctrl = snd_soc_read(codec, DA7213_ADC_L_CTRL);
-       adc_r_ctrl = snd_soc_read(codec, DA7213_ADC_R_CTRL);
+       adc_l_ctrl = snd_soc_component_read32(component, DA7213_ADC_L_CTRL);
+       adc_r_ctrl = snd_soc_component_read32(component, DA7213_ADC_R_CTRL);
 
        /* Save current values from MIXIN_L/R_SELECT registers */
-       mixin_l_sel = snd_soc_read(codec, DA7213_MIXIN_L_SELECT);
-       mixin_r_sel = snd_soc_read(codec, DA7213_MIXIN_R_SELECT);
+       mixin_l_sel = snd_soc_component_read32(component, DA7213_MIXIN_L_SELECT);
+       mixin_r_sel = snd_soc_component_read32(component, DA7213_MIXIN_R_SELECT);
 
        /* Save current values from MIC control registers */
-       mic_1_ctrl = snd_soc_read(codec, DA7213_MIC_1_CTRL);
-       mic_2_ctrl = snd_soc_read(codec, DA7213_MIC_2_CTRL);
+       mic_1_ctrl = snd_soc_component_read32(component, DA7213_MIC_1_CTRL);
+       mic_2_ctrl = snd_soc_component_read32(component, DA7213_MIC_2_CTRL);
 
        /* Enable ADC Left and Right */
-       snd_soc_update_bits(codec, DA7213_ADC_L_CTRL, DA7213_ADC_EN,
+       snd_soc_component_update_bits(component, DA7213_ADC_L_CTRL, DA7213_ADC_EN,
                            DA7213_ADC_EN);
-       snd_soc_update_bits(codec, DA7213_ADC_R_CTRL, DA7213_ADC_EN,
+       snd_soc_component_update_bits(component, DA7213_ADC_R_CTRL, DA7213_ADC_EN,
                            DA7213_ADC_EN);
 
        /* Enable MIC paths */
-       snd_soc_update_bits(codec, DA7213_MIXIN_L_SELECT,
+       snd_soc_component_update_bits(component, DA7213_MIXIN_L_SELECT,
                            DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
                            DA7213_MIXIN_L_MIX_SELECT_MIC_2,
                            DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
                            DA7213_MIXIN_L_MIX_SELECT_MIC_2);
-       snd_soc_update_bits(codec, DA7213_MIXIN_R_SELECT,
+       snd_soc_component_update_bits(component, DA7213_MIXIN_R_SELECT,
                            DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
                            DA7213_MIXIN_R_MIX_SELECT_MIC_1,
                            DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
                            DA7213_MIXIN_R_MIX_SELECT_MIC_1);
 
        /* Mute MIC PGAs */
-       snd_soc_update_bits(codec, DA7213_MIC_1_CTRL, DA7213_MUTE_EN,
+       snd_soc_component_update_bits(component, DA7213_MIC_1_CTRL, DA7213_MUTE_EN,
                            DA7213_MUTE_EN);
-       snd_soc_update_bits(codec, DA7213_MIC_2_CTRL, DA7213_MUTE_EN,
+       snd_soc_component_update_bits(component, DA7213_MIC_2_CTRL, DA7213_MUTE_EN,
                            DA7213_MUTE_EN);
 
        /* Perform calibration */
        if (da7213->alc_calib_auto)
-               da7213_alc_calib_auto(codec);
+               da7213_alc_calib_auto(component);
        else
-               da7213_alc_calib_man(codec);
+               da7213_alc_calib_man(component);
 
        /* Restore MIXIN_L/R_SELECT registers to their original states */
-       snd_soc_write(codec, DA7213_MIXIN_L_SELECT, mixin_l_sel);
-       snd_soc_write(codec, DA7213_MIXIN_R_SELECT, mixin_r_sel);
+       snd_soc_component_write(component, DA7213_MIXIN_L_SELECT, mixin_l_sel);
+       snd_soc_component_write(component, DA7213_MIXIN_R_SELECT, mixin_r_sel);
 
        /* Restore ADC control registers to their original states */
-       snd_soc_write(codec, DA7213_ADC_L_CTRL, adc_l_ctrl);
-       snd_soc_write(codec, DA7213_ADC_R_CTRL, adc_r_ctrl);
+       snd_soc_component_write(component, DA7213_ADC_L_CTRL, adc_l_ctrl);
+       snd_soc_component_write(component, DA7213_ADC_R_CTRL, adc_r_ctrl);
 
        /* Restore original values of MIC control registers */
-       snd_soc_write(codec, DA7213_MIC_1_CTRL, mic_1_ctrl);
-       snd_soc_write(codec, DA7213_MIC_2_CTRL, mic_2_ctrl);
+       snd_soc_component_write(component, DA7213_MIC_1_CTRL, mic_1_ctrl);
+       snd_soc_component_write(component, DA7213_MIC_2_CTRL, mic_2_ctrl);
 }
 
 static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
 
        /* If ALC in operation, make sure calibrated offsets are updated */
        if ((!ret) && (da7213->alc_en))
-               da7213_alc_calib(codec);
+               da7213_alc_calib(component);
 
        return ret;
 }
@@ -362,14 +362,14 @@ static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol,
 static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol,
                            struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 
        /* Force ALC offset calibration if enabling ALC */
        if (ucontrol->value.integer.value[0] ||
            ucontrol->value.integer.value[1]) {
                if (!da7213->alc_en) {
-                       da7213_alc_calib(codec);
+                       da7213_alc_calib(component);
                        da7213->alc_en = true;
                }
        } else {
@@ -735,8 +735,8 @@ static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
 static int da7213_dai_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
        u8 pll_ctrl, pll_status;
        int i = 0;
        bool srm_lock = false;
@@ -745,29 +745,29 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_PRE_PMU:
                /* Enable DAI clks for master mode */
                if (da7213->master)
-                       snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
+                       snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
                                            DA7213_DAI_CLK_EN_MASK,
                                            DA7213_DAI_CLK_EN_MASK);
 
                /* PC synchronised to DAI */
-               snd_soc_update_bits(codec, DA7213_PC_COUNT,
+               snd_soc_component_update_bits(component, DA7213_PC_COUNT,
                                    DA7213_PC_FREERUN_MASK, 0);
 
                /* If SRM not enabled then nothing more to do */
-               pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
+               pll_ctrl = snd_soc_component_read32(component, DA7213_PLL_CTRL);
                if (!(pll_ctrl & DA7213_PLL_SRM_EN))
                        return 0;
 
                /* Assist 32KHz mode PLL lock */
                if (pll_ctrl & DA7213_PLL_32K_MODE) {
-                       snd_soc_write(codec, 0xF0, 0x8B);
-                       snd_soc_write(codec, 0xF2, 0x03);
-                       snd_soc_write(codec, 0xF0, 0x00);
+                       snd_soc_component_write(component, 0xF0, 0x8B);
+                       snd_soc_component_write(component, 0xF2, 0x03);
+                       snd_soc_component_write(component, 0xF0, 0x00);
                }
 
                /* Check SRM has locked */
                do {
-                       pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
+                       pll_status = snd_soc_component_read32(component, DA7213_PLL_STATUS);
                        if (pll_status & DA7219_PLL_SRM_LOCK) {
                                srm_lock = true;
                        } else {
@@ -777,26 +777,26 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
                } while ((i < DA7213_SRM_CHECK_RETRIES) && (!srm_lock));
 
                if (!srm_lock)
-                       dev_warn(codec->dev, "SRM failed to lock\n");
+                       dev_warn(component->dev, "SRM failed to lock\n");
 
                return 0;
        case SND_SOC_DAPM_POST_PMD:
                /* Revert 32KHz PLL lock udpates if applied previously */
-               pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
+               pll_ctrl = snd_soc_component_read32(component, DA7213_PLL_CTRL);
                if (pll_ctrl & DA7213_PLL_32K_MODE) {
-                       snd_soc_write(codec, 0xF0, 0x8B);
-                       snd_soc_write(codec, 0xF2, 0x01);
-                       snd_soc_write(codec, 0xF0, 0x00);
+                       snd_soc_component_write(component, 0xF0, 0x8B);
+                       snd_soc_component_write(component, 0xF2, 0x01);
+                       snd_soc_component_write(component, 0xF0, 0x00);
                }
 
                /* PC free-running */
-               snd_soc_update_bits(codec, DA7213_PC_COUNT,
+               snd_soc_component_update_bits(component, DA7213_PC_COUNT,
                                    DA7213_PC_FREERUN_MASK,
                                    DA7213_PC_FREERUN_MASK);
 
                /* Disable DAI clks if in master mode */
                if (da7213->master)
-                       snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
+                       snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
                                            DA7213_DAI_CLK_EN_MASK, 0);
                return 0;
        default:
@@ -1150,7 +1150,7 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 dai_ctrl = 0;
        u8 fs;
 
@@ -1208,17 +1208,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
+       snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
                            dai_ctrl);
-       snd_soc_write(codec, DA7213_SR, fs);
+       snd_soc_component_write(component, DA7213_SR, fs);
 
        return 0;
 }
 
 static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
        u8 dai_clk_mode = 0, dai_ctrl = 0;
        u8 dai_offset = 0;
 
@@ -1305,27 +1305,27 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        /* By default only 64 BCLK per WCLK is supported */
        dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_64;
 
-       snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
-       snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
+       snd_soc_component_write(component, DA7213_DAI_CLK_MODE, dai_clk_mode);
+       snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
                            dai_ctrl);
-       snd_soc_write(codec, DA7213_DAI_OFFSET, dai_offset);
+       snd_soc_component_write(component, DA7213_DAI_OFFSET, dai_offset);
 
        return 0;
 }
 
 static int da7213_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute) {
-               snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
+               snd_soc_component_update_bits(component, DA7213_DAC_L_CTRL,
                                    DA7213_MUTE_EN, DA7213_MUTE_EN);
-               snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
+               snd_soc_component_update_bits(component, DA7213_DAC_R_CTRL,
                                    DA7213_MUTE_EN, DA7213_MUTE_EN);
        } else {
-               snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
+               snd_soc_component_update_bits(component, DA7213_DAC_L_CTRL,
                                    DA7213_MUTE_EN, 0);
-               snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
+               snd_soc_component_update_bits(component, DA7213_DAC_R_CTRL,
                                    DA7213_MUTE_EN, 0);
        }
 
@@ -1338,8 +1338,8 @@ static int da7213_mute(struct snd_soc_dai *dai, int mute)
 static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if ((da7213->clk_src == clk_id) && (da7213->mclk_rate == freq))
@@ -1353,11 +1353,11 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
        switch (clk_id) {
        case DA7213_CLKSRC_MCLK:
-               snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
                                    DA7213_PLL_MCLK_SQR_EN, 0);
                break;
        case DA7213_CLKSRC_MCLK_SQR:
-               snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
                                    DA7213_PLL_MCLK_SQR_EN,
                                    DA7213_PLL_MCLK_SQR_EN);
                break;
@@ -1387,8 +1387,8 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int fref, unsigned int fout)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 
        u8 pll_ctrl, indiv_bits, indiv;
        u8 pll_frac_top, pll_frac_bot, pll_integer;
@@ -1398,7 +1398,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        /* Workout input divider based on MCLK rate */
        if (da7213->mclk_rate == 32768) {
                if (!da7213->master) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "32KHz only valid if codec is clock master\n");
                        return -EINVAL;
                }
@@ -1411,7 +1411,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
        } else {
                if (da7213->mclk_rate < 5000000) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "PLL input clock %d below valid range\n",
                                da7213->mclk_rate);
                        return -EINVAL;
@@ -1428,7 +1428,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                        indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ;
                        indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL;
                } else {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "PLL input clock %d above valid range\n",
                                da7213->mclk_rate);
                        return -EINVAL;
@@ -1441,7 +1441,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        /* Configure PLL */
        switch (source) {
        case DA7213_SYSCLK_MCLK:
-               snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
                                    DA7213_PLL_INDIV_MASK |
                                    DA7213_PLL_MODE_MASK, pll_ctrl);
                return 0;
@@ -1453,7 +1453,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                break;
        case DA7213_SYSCLK_PLL_32KHZ:
                if (da7213->mclk_rate != 32768) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "32KHz mode only valid with 32KHz MCLK\n");
                        return -EINVAL;
                }
@@ -1462,7 +1462,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                fout = DA7213_PLL_FREQ_OUT_94310400;
                break;
        default:
-               dev_err(codec->dev, "Invalid PLL config\n");
+               dev_err(component->dev, "Invalid PLL config\n");
                return -EINVAL;
        }
 
@@ -1474,22 +1474,22 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        pll_frac_bot = (frac_div) & DA7213_BYTE_MASK;
 
        /* Write PLL dividers */
-       snd_soc_write(codec, DA7213_PLL_FRAC_TOP, pll_frac_top);
-       snd_soc_write(codec, DA7213_PLL_FRAC_BOT, pll_frac_bot);
-       snd_soc_write(codec, DA7213_PLL_INTEGER, pll_integer);
+       snd_soc_component_write(component, DA7213_PLL_FRAC_TOP, pll_frac_top);
+       snd_soc_component_write(component, DA7213_PLL_FRAC_BOT, pll_frac_bot);
+       snd_soc_component_write(component, DA7213_PLL_INTEGER, pll_integer);
 
        /* Enable PLL */
        pll_ctrl |= DA7213_PLL_EN;
-       snd_soc_update_bits(codec, DA7213_PLL_CTRL,
+       snd_soc_component_update_bits(component, DA7213_PLL_CTRL,
                            DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK,
                            pll_ctrl);
 
        /* Assist 32KHz mode PLL lock */
        if (source == DA7213_SYSCLK_PLL_32KHZ) {
-               snd_soc_write(codec, 0xF0, 0x8B);
-               snd_soc_write(codec, 0xF1, 0x03);
-               snd_soc_write(codec, 0xF1, 0x01);
-               snd_soc_write(codec, 0xF0, 0x00);
+               snd_soc_component_write(component, 0xF0, 0x8B);
+               snd_soc_component_write(component, 0xF1, 0x03);
+               snd_soc_component_write(component, 0xF1, 0x01);
+               snd_soc_component_write(component, 0xF0, 0x00);
        }
 
        return 0;
@@ -1526,10 +1526,10 @@ static struct snd_soc_dai_driver da7213_dai = {
        .symmetric_rates = 1,
 };
 
-static int da7213_set_bias_level(struct snd_soc_codec *codec,
+static int da7213_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1537,11 +1537,11 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_PREPARE:
                /* Enable MCLK for transition to ON state */
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
                        if (da7213->mclk) {
                                ret = clk_prepare_enable(da7213->mclk);
                                if (ret) {
-                                       dev_err(codec->dev,
+                                       dev_err(component->dev,
                                                "Failed to enable mclk\n");
                                        return ret;
                                }
@@ -1549,9 +1549,9 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
                }
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Enable VMID reference & master bias */
-                       snd_soc_update_bits(codec, DA7213_REFERENCES,
+                       snd_soc_component_update_bits(component, DA7213_REFERENCES,
                                            DA7213_VMID_EN | DA7213_BIAS_EN,
                                            DA7213_VMID_EN | DA7213_BIAS_EN);
                } else {
@@ -1562,7 +1562,7 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_OFF:
                /* Disable VMID reference & master bias */
-               snd_soc_update_bits(codec, DA7213_REFERENCES,
+               snd_soc_component_update_bits(component, DA7213_REFERENCES,
                                    DA7213_VMID_EN | DA7213_BIAS_EN, 0);
                break;
        }
@@ -1588,7 +1588,7 @@ MODULE_DEVICE_TABLE(acpi, da7213_acpi_match);
 #endif
 
 static enum da7213_micbias_voltage
-       da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
+       da7213_of_micbias_lvl(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1600:
@@ -1600,39 +1600,39 @@ static enum da7213_micbias_voltage
        case 3000:
                return DA7213_MICBIAS_3_0V;
        default:
-               dev_warn(codec->dev, "Invalid micbias level\n");
+               dev_warn(component->dev, "Invalid micbias level\n");
                return DA7213_MICBIAS_2_2V;
        }
 }
 
 static enum da7213_dmic_data_sel
-       da7213_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
+       da7213_of_dmic_data_sel(struct snd_soc_component *component, const char *str)
 {
        if (!strcmp(str, "lrise_rfall")) {
                return DA7213_DMIC_DATA_LRISE_RFALL;
        } else if (!strcmp(str, "lfall_rrise")) {
                return DA7213_DMIC_DATA_LFALL_RRISE;
        } else {
-               dev_warn(codec->dev, "Invalid DMIC data select type\n");
+               dev_warn(component->dev, "Invalid DMIC data select type\n");
                return DA7213_DMIC_DATA_LRISE_RFALL;
        }
 }
 
 static enum da7213_dmic_samplephase
-       da7213_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
+       da7213_of_dmic_samplephase(struct snd_soc_component *component, const char *str)
 {
        if (!strcmp(str, "on_clkedge")) {
                return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
        } else if (!strcmp(str, "between_clkedge")) {
                return DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE;
        } else {
-               dev_warn(codec->dev, "Invalid DMIC sample phase\n");
+               dev_warn(component->dev, "Invalid DMIC sample phase\n");
                return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
        }
 }
 
 static enum da7213_dmic_clk_rate
-       da7213_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
+       da7213_of_dmic_clkrate(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1500000:
@@ -1640,46 +1640,46 @@ static enum da7213_dmic_clk_rate
        case 3000000:
                return DA7213_DMIC_CLK_3_0MHZ;
        default:
-               dev_warn(codec->dev, "Invalid DMIC clock rate\n");
+               dev_warn(component->dev, "Invalid DMIC clock rate\n");
                return DA7213_DMIC_CLK_1_5MHZ;
        }
 }
 
 static struct da7213_platform_data
-       *da7213_fw_to_pdata(struct snd_soc_codec *codec)
+       *da7213_fw_to_pdata(struct snd_soc_component *component)
 {
-       struct device *dev = codec->dev;
+       struct device *dev = component->dev;
        struct da7213_platform_data *pdata;
        const char *fw_str;
        u32 fw_val32;
 
-       pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
+       pdata = devm_kzalloc(component->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return NULL;
 
        if (device_property_read_u32(dev, "dlg,micbias1-lvl", &fw_val32) >= 0)
-               pdata->micbias1_lvl = da7213_of_micbias_lvl(codec, fw_val32);
+               pdata->micbias1_lvl = da7213_of_micbias_lvl(component, fw_val32);
        else
                pdata->micbias1_lvl = DA7213_MICBIAS_2_2V;
 
        if (device_property_read_u32(dev, "dlg,micbias2-lvl", &fw_val32) >= 0)
-               pdata->micbias2_lvl = da7213_of_micbias_lvl(codec, fw_val32);
+               pdata->micbias2_lvl = da7213_of_micbias_lvl(component, fw_val32);
        else
                pdata->micbias2_lvl = DA7213_MICBIAS_2_2V;
 
        if (!device_property_read_string(dev, "dlg,dmic-data-sel", &fw_str))
-               pdata->dmic_data_sel = da7213_of_dmic_data_sel(codec, fw_str);
+               pdata->dmic_data_sel = da7213_of_dmic_data_sel(component, fw_str);
        else
                pdata->dmic_data_sel = DA7213_DMIC_DATA_LRISE_RFALL;
 
        if (!device_property_read_string(dev, "dlg,dmic-samplephase", &fw_str))
                pdata->dmic_samplephase =
-                       da7213_of_dmic_samplephase(codec, fw_str);
+                       da7213_of_dmic_samplephase(component, fw_str);
        else
                pdata->dmic_samplephase = DA7213_DMIC_SAMPLE_ON_CLKEDGE;
 
        if (device_property_read_u32(dev, "dlg,dmic-clkrate", &fw_val32) >= 0)
-               pdata->dmic_clk_rate = da7213_of_dmic_clkrate(codec, fw_val32);
+               pdata->dmic_clk_rate = da7213_of_dmic_clkrate(component, fw_val32);
        else
                pdata->dmic_clk_rate = DA7213_DMIC_CLK_3_0MHZ;
 
@@ -1687,41 +1687,41 @@ static struct da7213_platform_data
 }
 
 
-static int da7213_probe(struct snd_soc_codec *codec)
+static int da7213_probe(struct snd_soc_component *component)
 {
-       struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
+       struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
 
        /* Default to using ALC auto offset calibration mode. */
-       snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
+       snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
                            DA7213_ALC_CALIB_MODE_MAN, 0);
        da7213->alc_calib_auto = true;
 
        /* Default PC counter to free-running */
-       snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
+       snd_soc_component_update_bits(component, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
                            DA7213_PC_FREERUN_MASK);
 
        /* Enable all Gain Ramps */
-       snd_soc_update_bits(codec, DA7213_AUX_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_AUX_L_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_AUX_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_AUX_R_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_MIXIN_L_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_MIXIN_R_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_ADC_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_ADC_L_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_ADC_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_ADC_R_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_DAC_L_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_DAC_R_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_HP_L_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_HP_R_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
-       snd_soc_update_bits(codec, DA7213_LINE_CTRL,
+       snd_soc_component_update_bits(component, DA7213_LINE_CTRL,
                            DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
 
        /*
@@ -1732,28 +1732,28 @@ static int da7213_probe(struct snd_soc_codec *codec)
         * being managed by DAPM while other (non power related) bits are
         * enabled here
         */
-       snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_MIXIN_L_CTRL,
                            DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
-       snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_MIXIN_R_CTRL,
                            DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
 
-       snd_soc_update_bits(codec, DA7213_MIXOUT_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_MIXOUT_L_CTRL,
                            DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
-       snd_soc_update_bits(codec, DA7213_MIXOUT_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_MIXOUT_R_CTRL,
                            DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
 
-       snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7213_HP_L_CTRL,
                            DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
-       snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7213_HP_R_CTRL,
                            DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
 
-       snd_soc_update_bits(codec, DA7213_LINE_CTRL,
+       snd_soc_component_update_bits(component, DA7213_LINE_CTRL,
                            DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE);
 
        /* Handle DT/Platform data */
-       da7213->pdata = dev_get_platdata(codec->dev);
+       da7213->pdata = dev_get_platdata(component->dev);
        if (!da7213->pdata)
-               da7213->pdata = da7213_fw_to_pdata(codec);
+               da7213->pdata = da7213_fw_to_pdata(component);
 
        /* Set platform data values */
        if (da7213->pdata) {
@@ -1779,7 +1779,7 @@ static int da7213_probe(struct snd_soc_codec *codec)
                                         DA7213_MICBIAS2_LEVEL_SHIFT);
                        break;
                }
-               snd_soc_update_bits(codec, DA7213_MICBIAS_CTRL,
+               snd_soc_component_update_bits(component, DA7213_MICBIAS_CTRL,
                                    DA7213_MICBIAS1_LEVEL_MASK |
                                    DA7213_MICBIAS2_LEVEL_MASK, micbias_lvl);
 
@@ -1805,14 +1805,14 @@ static int da7213_probe(struct snd_soc_codec *codec)
                                     DA7213_DMIC_CLK_RATE_SHIFT);
                        break;
                }
-               snd_soc_update_bits(codec, DA7213_MIC_CONFIG,
+               snd_soc_component_update_bits(component, DA7213_MIC_CONFIG,
                                    DA7213_DMIC_DATA_SEL_MASK |
                                    DA7213_DMIC_SAMPLEPHASE_MASK |
                                    DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
        }
 
        /* Check if MCLK provided */
-       da7213->mclk = devm_clk_get(codec->dev, "mclk");
+       da7213->mclk = devm_clk_get(component->dev, "mclk");
        if (IS_ERR(da7213->mclk)) {
                if (PTR_ERR(da7213->mclk) != -ENOENT)
                        return PTR_ERR(da7213->mclk);
@@ -1823,18 +1823,19 @@ static int da7213_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7213 = {
+static const struct snd_soc_component_driver soc_component_dev_da7213 = {
        .probe                  = da7213_probe,
        .set_bias_level         = da7213_set_bias_level,
-
-       .component_driver = {
-               .controls               = da7213_snd_controls,
-               .num_controls           = ARRAY_SIZE(da7213_snd_controls),
-               .dapm_widgets           = da7213_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(da7213_dapm_widgets),
-               .dapm_routes            = da7213_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(da7213_audio_map),
-       },
+       .controls               = da7213_snd_controls,
+       .num_controls           = ARRAY_SIZE(da7213_snd_controls),
+       .dapm_widgets           = da7213_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(da7213_dapm_widgets),
+       .dapm_routes            = da7213_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(da7213_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config da7213_regmap_config = {
@@ -1866,21 +1867,15 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_da7213, &da7213_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_da7213, &da7213_dai, 1);
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register da7213 codec: %d\n",
+               dev_err(&i2c->dev, "Failed to register da7213 component: %d\n",
                        ret);
        }
        return ret;
 }
 
-static int da7213_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id da7213_i2c_id[] = {
        { "da7213", 0 },
        { }
@@ -1895,7 +1890,6 @@ static struct i2c_driver da7213_i2c_driver = {
                .acpi_match_table = ACPI_PTR(da7213_acpi_match),
        },
        .probe          = da7213_i2c_probe,
-       .remove         = da7213_remove,
        .id_table       = da7213_i2c_id,
 };
 
index 96c644a15b1137ec6ecc49868e5660553f7b6e1d..ddc90ac0b19f59dcdc89cbe9659a53da14e1bbd6 100644 (file)
@@ -291,7 +291,7 @@ static const struct soc_enum da7218_cp_tau_delay =
  */
 
 /* ALC */
-static void da7218_alc_calib(struct snd_soc_codec *codec)
+static void da7218_alc_calib(struct snd_soc_component *component)
 {
        u8 mic_1_ctrl, mic_2_ctrl;
        u8 mixin_1_ctrl, mixin_2_ctrl;
@@ -302,59 +302,59 @@ static void da7218_alc_calib(struct snd_soc_codec *codec)
        bool calibrated = false;
 
        /* Save current state of MIC control registers */
-       mic_1_ctrl = snd_soc_read(codec, DA7218_MIC_1_CTRL);
-       mic_2_ctrl = snd_soc_read(codec, DA7218_MIC_2_CTRL);
+       mic_1_ctrl = snd_soc_component_read32(component, DA7218_MIC_1_CTRL);
+       mic_2_ctrl = snd_soc_component_read32(component, DA7218_MIC_2_CTRL);
 
        /* Save current state of input mixer control registers */
-       mixin_1_ctrl = snd_soc_read(codec, DA7218_MIXIN_1_CTRL);
-       mixin_2_ctrl = snd_soc_read(codec, DA7218_MIXIN_2_CTRL);
+       mixin_1_ctrl = snd_soc_component_read32(component, DA7218_MIXIN_1_CTRL);
+       mixin_2_ctrl = snd_soc_component_read32(component, DA7218_MIXIN_2_CTRL);
 
        /* Save current state of input filter control registers */
-       in_1l_filt_ctrl = snd_soc_read(codec, DA7218_IN_1L_FILTER_CTRL);
-       in_1r_filt_ctrl = snd_soc_read(codec, DA7218_IN_1R_FILTER_CTRL);
-       in_2l_filt_ctrl = snd_soc_read(codec, DA7218_IN_2L_FILTER_CTRL);
-       in_2r_filt_ctrl = snd_soc_read(codec, DA7218_IN_2R_FILTER_CTRL);
+       in_1l_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_1L_FILTER_CTRL);
+       in_1r_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_1R_FILTER_CTRL);
+       in_2l_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_2L_FILTER_CTRL);
+       in_2r_filt_ctrl = snd_soc_component_read32(component, DA7218_IN_2R_FILTER_CTRL);
 
        /* Save current state of input HPF control registers */
-       in_1_hpf_ctrl = snd_soc_read(codec, DA7218_IN_1_HPF_FILTER_CTRL);
-       in_2_hpf_ctrl = snd_soc_read(codec, DA7218_IN_2_HPF_FILTER_CTRL);
+       in_1_hpf_ctrl = snd_soc_component_read32(component, DA7218_IN_1_HPF_FILTER_CTRL);
+       in_2_hpf_ctrl = snd_soc_component_read32(component, DA7218_IN_2_HPF_FILTER_CTRL);
 
        /* Enable then Mute MIC PGAs */
-       snd_soc_update_bits(codec, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,
                            DA7218_MIC_1_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,
                            DA7218_MIC_2_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_MIC_1_CTRL,
+       snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL,
                            DA7218_MIC_1_AMP_MUTE_EN_MASK,
                            DA7218_MIC_1_AMP_MUTE_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_MIC_2_CTRL,
+       snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL,
                            DA7218_MIC_2_AMP_MUTE_EN_MASK,
                            DA7218_MIC_2_AMP_MUTE_EN_MASK);
 
        /* Enable input mixers unmuted */
-       snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
+       snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL,
                            DA7218_MIXIN_1_AMP_EN_MASK |
                            DA7218_MIXIN_1_AMP_MUTE_EN_MASK,
                            DA7218_MIXIN_1_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
+       snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL,
                            DA7218_MIXIN_2_AMP_EN_MASK |
                            DA7218_MIXIN_2_AMP_MUTE_EN_MASK,
                            DA7218_MIXIN_2_AMP_EN_MASK);
 
        /* Enable input filters unmuted */
-       snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL,
                            DA7218_IN_1L_FILTER_EN_MASK |
                            DA7218_IN_1L_MUTE_EN_MASK,
                            DA7218_IN_1L_FILTER_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL,
                            DA7218_IN_1R_FILTER_EN_MASK |
                            DA7218_IN_1R_MUTE_EN_MASK,
                            DA7218_IN_1R_FILTER_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL,
                            DA7218_IN_2L_FILTER_EN_MASK |
                            DA7218_IN_2L_MUTE_EN_MASK,
                            DA7218_IN_2L_FILTER_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL,
                            DA7218_IN_2R_FILTER_EN_MASK |
                            DA7218_IN_2R_MUTE_EN_MASK,
                            DA7218_IN_2R_FILTER_EN_MASK);
@@ -364,16 +364,16 @@ static void da7218_alc_calib(struct snd_soc_codec *codec)
         * rates above 32KHz the ADC signals will be stopped and will cause
         * calibration to lock up.
         */
-       snd_soc_update_bits(codec, DA7218_IN_1_HPF_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_1_HPF_FILTER_CTRL,
                            DA7218_IN_1_VOICE_EN_MASK, 0);
-       snd_soc_update_bits(codec, DA7218_IN_2_HPF_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_2_HPF_FILTER_CTRL,
                            DA7218_IN_2_VOICE_EN_MASK, 0);
 
        /* Perform auto calibration */
-       snd_soc_update_bits(codec, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,
+       snd_soc_component_update_bits(component, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,
                            DA7218_CALIB_AUTO_EN_MASK);
        do {
-               calib_ctrl = snd_soc_read(codec, DA7218_CALIB_CTRL);
+               calib_ctrl = snd_soc_component_read32(component, DA7218_CALIB_CTRL);
                if (calib_ctrl & DA7218_CALIB_AUTO_EN_MASK) {
                        ++i;
                        usleep_range(DA7218_ALC_CALIB_DELAY_MIN,
@@ -386,51 +386,51 @@ static void da7218_alc_calib(struct snd_soc_codec *codec)
 
        /* If auto calibration fails, disable DC offset, hybrid ALC */
        if ((!calibrated) || (calib_ctrl & DA7218_CALIB_OVERFLOW_MASK)) {
-               dev_warn(codec->dev,
+               dev_warn(component->dev,
                         "ALC auto calibration failed - %s\n",
                         (calibrated) ? "overflow" : "timeout");
-               snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
+               snd_soc_component_update_bits(component, DA7218_CALIB_CTRL,
                                    DA7218_CALIB_OFFSET_EN_MASK, 0);
-               snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
+               snd_soc_component_update_bits(component, DA7218_ALC_CTRL1,
                                    DA7218_ALC_SYNC_MODE_MASK, 0);
 
        } else {
                /* Enable DC offset cancellation */
-               snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
+               snd_soc_component_update_bits(component, DA7218_CALIB_CTRL,
                                    DA7218_CALIB_OFFSET_EN_MASK,
                                    DA7218_CALIB_OFFSET_EN_MASK);
 
                /* Enable ALC hybrid mode */
-               snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
+               snd_soc_component_update_bits(component, DA7218_ALC_CTRL1,
                                    DA7218_ALC_SYNC_MODE_MASK,
                                    DA7218_ALC_SYNC_MODE_CH1 |
                                    DA7218_ALC_SYNC_MODE_CH2);
        }
 
        /* Restore input HPF control registers to original states */
-       snd_soc_write(codec, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);
-       snd_soc_write(codec, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);
+       snd_soc_component_write(component, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);
+       snd_soc_component_write(component, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);
 
        /* Restore input filter control registers to original states */
-       snd_soc_write(codec, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);
-       snd_soc_write(codec, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);
-       snd_soc_write(codec, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);
-       snd_soc_write(codec, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);
+       snd_soc_component_write(component, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);
+       snd_soc_component_write(component, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);
+       snd_soc_component_write(component, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);
+       snd_soc_component_write(component, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);
 
        /* Restore input mixer control registers to original state */
-       snd_soc_write(codec, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);
-       snd_soc_write(codec, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);
+       snd_soc_component_write(component, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);
+       snd_soc_component_write(component, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);
 
        /* Restore MIC control registers to original states */
-       snd_soc_write(codec, DA7218_MIC_1_CTRL, mic_1_ctrl);
-       snd_soc_write(codec, DA7218_MIC_2_CTRL, mic_2_ctrl);
+       snd_soc_component_write(component, DA7218_MIC_1_CTRL, mic_1_ctrl);
+       snd_soc_component_write(component, DA7218_MIC_2_CTRL, mic_2_ctrl);
 }
 
 static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_soc_put_volsw(kcontrol, ucontrol);
@@ -440,7 +440,7 @@ static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,
         * make sure calibrated offsets are updated.
         */
        if ((ret == 1) && (da7218->alc_en))
-               da7218_alc_calib(codec);
+               da7218_alc_calib(component);
 
        return ret;
 }
@@ -450,8 +450,8 @@ static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *) kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        unsigned int lvalue = ucontrol->value.integer.value[0];
        unsigned int rvalue = ucontrol->value.integer.value[1];
        unsigned int lshift = mc->shift;
@@ -460,7 +460,7 @@ static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
 
        /* Force ALC offset calibration if enabling ALC */
        if ((lvalue || rvalue) && (!da7218->alc_en))
-               da7218_alc_calib(codec);
+               da7218_alc_calib(component);
 
        /* Update bits to detail which channels are enabled/disabled */
        da7218->alc_en &= ~mask;
@@ -473,8 +473,8 @@ static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
 static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mixer_ctrl =
                (struct soc_mixer_control *) kcontrol->private_value;
        unsigned int reg = mixer_ctrl->reg;
@@ -497,8 +497,8 @@ static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,
 static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mixer_ctrl =
                (struct soc_mixer_control *) kcontrol->private_value;
        unsigned int reg = mixer_ctrl->reg;
@@ -517,8 +517,8 @@ static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,
 static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mixer_ctrl =
                (struct soc_mixer_control *) kcontrol->private_value;
        unsigned int lvalue = ucontrol->value.integer.value[0];
@@ -537,15 +537,15 @@ static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,
         * power the path (IN_FILTER widget events). This handling avoids
         * unwanted level detect events.
         */
-       return snd_soc_write(codec, mixer_ctrl->reg,
+       return snd_soc_component_write(component, mixer_ctrl->reg,
                             (da7218->in_filt_en & da7218->mic_lvl_det_en));
 }
 
 static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mixer_ctrl =
                (struct soc_mixer_control *) kcontrol->private_value;
        unsigned int lshift = mixer_ctrl->shift;
@@ -564,8 +564,8 @@ static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,
 static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct soc_bytes_ext *bytes_ext =
                (struct soc_bytes_ext *) kcontrol->private_value;
 
@@ -589,8 +589,8 @@ static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,
 static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct soc_bytes_ext *bytes_ext =
                (struct soc_bytes_ext *) kcontrol->private_value;
        u8 reg, out_filt1l;
@@ -617,8 +617,8 @@ static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
        }
 
        /* Make sure at least out filter1 enabled to allow programming */
-       out_filt1l = snd_soc_read(codec, DA7218_OUT_1L_FILTER_CTRL);
-       snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL,
+       out_filt1l = snd_soc_component_read32(component, DA7218_OUT_1L_FILTER_CTRL);
+       snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL,
                      out_filt1l | DA7218_OUT_1L_FILTER_EN_MASK);
 
        for (i = 0; i < bytes_ext->max; ++i) {
@@ -628,7 +628,7 @@ static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
        }
 
        /* Restore filter to previous setting */
-       snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);
+       snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);
 
        return 0;
 }
@@ -1349,8 +1349,8 @@ static const struct snd_kcontrol_new da7218_st_out_filtr_mix_controls[] = {
 static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        u8 mask;
 
        switch (w->reg) {
@@ -1389,7 +1389,7 @@ static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
        }
 
        /* Enable configured level detection paths */
-       snd_soc_write(codec, DA7218_LVL_DET_CTRL,
+       snd_soc_component_write(component, DA7218_LVL_DET_CTRL,
                      (da7218->in_filt_en & da7218->mic_lvl_det_en));
 
        return 0;
@@ -1398,8 +1398,8 @@ static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
 static int da7218_dai_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        u8 pll_ctrl, pll_status, refosc_cal;
        int i;
        bool success;
@@ -1408,14 +1408,14 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_POST_PMU:
                if (da7218->master)
                        /* Enable DAI clks for master mode */
-                       snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+                       snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
                                            DA7218_DAI_CLK_EN_MASK,
                                            DA7218_DAI_CLK_EN_MASK);
 
                /* Tune reference oscillator */
-               snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
+               snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL,
                              DA7218_PLL_REFOSC_CAL_START_MASK);
-               snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
+               snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL,
                              DA7218_PLL_REFOSC_CAL_START_MASK |
                              DA7218_PLL_REFOSC_CAL_EN_MASK);
 
@@ -1423,7 +1423,7 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
                i = 0;
                success = false;
                do {
-                       refosc_cal = snd_soc_read(codec, DA7218_PLL_REFOSC_CAL);
+                       refosc_cal = snd_soc_component_read32(component, DA7218_PLL_REFOSC_CAL);
                        if (!(refosc_cal & DA7218_PLL_REFOSC_CAL_START_MASK)) {
                                success = true;
                        } else {
@@ -1434,15 +1434,15 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
                } while ((i < DA7218_REF_OSC_CHECK_TRIES) && (!success));
 
                if (!success)
-                       dev_warn(codec->dev,
+                       dev_warn(component->dev,
                                 "Reference oscillator failed calibration\n");
 
                /* PC synchronised to DAI */
-               snd_soc_write(codec, DA7218_PC_COUNT,
+               snd_soc_component_write(component, DA7218_PC_COUNT,
                              DA7218_PC_RESYNC_AUTO_MASK);
 
                /* If SRM not enabled, we don't need to check status */
-               pll_ctrl = snd_soc_read(codec, DA7218_PLL_CTRL);
+               pll_ctrl = snd_soc_component_read32(component, DA7218_PLL_CTRL);
                if ((pll_ctrl & DA7218_PLL_MODE_MASK) != DA7218_PLL_MODE_SRM)
                        return 0;
 
@@ -1450,7 +1450,7 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
                i = 0;
                success = false;
                do {
-                       pll_status = snd_soc_read(codec, DA7218_PLL_STATUS);
+                       pll_status = snd_soc_component_read32(component, DA7218_PLL_STATUS);
                        if (pll_status & DA7218_PLL_SRM_STATUS_SRM_LOCK) {
                                success = true;
                        } else {
@@ -1460,16 +1460,16 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
                } while ((i < DA7218_SRM_CHECK_TRIES) && (!success));
 
                if (!success)
-                       dev_warn(codec->dev, "SRM failed to lock\n");
+                       dev_warn(component->dev, "SRM failed to lock\n");
 
                return 0;
        case SND_SOC_DAPM_POST_PMD:
                /* PC free-running */
-               snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
+               snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
 
                if (da7218->master)
                        /* Disable DAI clks for master mode */
-                       snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+                       snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
                                            DA7218_DAI_CLK_EN_MASK, 0);
 
                return 0;
@@ -1481,8 +1481,8 @@ static int da7218_dai_event(struct snd_soc_dapm_widget *w,
 static int da7218_cp_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
        /*
         * If this is DA7217 and we're using single supply for differential
@@ -1493,11 +1493,11 @@ static int da7218_cp_event(struct snd_soc_dapm_widget *w,
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
+               snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
                                    DA7218_CP_EN_MASK);
                return 0;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
+               snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
                                    0);
                return 0;
        default:
@@ -1508,17 +1508,17 @@ static int da7218_cp_event(struct snd_soc_dapm_widget *w,
 static int da7218_hp_pga_event(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* Enable headphone output */
-               snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK,
+               snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK,
                                    DA7218_HP_AMP_OE_MASK);
                return 0;
        case SND_SOC_DAPM_PRE_PMD:
                /* Headphone output high impedance */
-               snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK, 0);
+               snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK, 0);
                return 0;
        default:
                return -EINVAL;
@@ -1813,8 +1813,8 @@ static const struct snd_soc_dapm_route da7218_audio_map[] = {
 static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        int ret;
 
        if (da7218->mclk_rate == freq)
@@ -1828,12 +1828,12 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
        switch (clk_id) {
        case DA7218_CLKSRC_MCLK_SQR:
-               snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
                                    DA7218_PLL_MCLK_SQR_EN_MASK,
                                    DA7218_PLL_MCLK_SQR_EN_MASK);
                break;
        case DA7218_CLKSRC_MCLK:
-               snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
                                    DA7218_PLL_MCLK_SQR_EN_MASK, 0);
                break;
        default:
@@ -1859,8 +1859,8 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int fref, unsigned int fout)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
        u8 pll_ctrl, indiv_bits, indiv;
        u8 pll_frac_top, pll_frac_bot, pll_integer;
@@ -1869,7 +1869,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
        /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
        if (da7218->mclk_rate < 2000000) {
-               dev_err(codec->dev, "PLL input clock %d below valid range\n",
+               dev_err(component->dev, "PLL input clock %d below valid range\n",
                        da7218->mclk_rate);
                return -EINVAL;
        } else if (da7218->mclk_rate <= 4500000) {
@@ -1888,7 +1888,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                indiv_bits = DA7218_PLL_INDIV_36_TO_54_MHZ;
                indiv = DA7218_PLL_INDIV_36_TO_54_MHZ_VAL;
        } else {
-               dev_err(codec->dev, "PLL input clock %d above valid range\n",
+               dev_err(component->dev, "PLL input clock %d above valid range\n",
                        da7218->mclk_rate);
                return -EINVAL;
        }
@@ -1899,7 +1899,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        switch (source) {
        case DA7218_SYSCLK_MCLK:
                pll_ctrl |= DA7218_PLL_MODE_BYPASS;
-               snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
                                    DA7218_PLL_INDIV_MASK |
                                    DA7218_PLL_MODE_MASK, pll_ctrl);
                return 0;
@@ -1910,7 +1910,7 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                pll_ctrl |= DA7218_PLL_MODE_SRM;
                break;
        default:
-               dev_err(codec->dev, "Invalid PLL config\n");
+               dev_err(component->dev, "Invalid PLL config\n");
                return -EINVAL;
        }
 
@@ -1922,10 +1922,10 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        pll_frac_bot = (frac_div) & DA7218_BYTE_MASK;
 
        /* Write PLL config & dividers */
-       snd_soc_write(codec, DA7218_PLL_FRAC_TOP, pll_frac_top);
-       snd_soc_write(codec, DA7218_PLL_FRAC_BOT, pll_frac_bot);
-       snd_soc_write(codec, DA7218_PLL_INTEGER, pll_integer);
-       snd_soc_update_bits(codec, DA7218_PLL_CTRL,
+       snd_soc_component_write(component, DA7218_PLL_FRAC_TOP, pll_frac_top);
+       snd_soc_component_write(component, DA7218_PLL_FRAC_BOT, pll_frac_bot);
+       snd_soc_component_write(component, DA7218_PLL_INTEGER, pll_integer);
+       snd_soc_component_update_bits(component, DA7218_PLL_CTRL,
                            DA7218_PLL_MODE_MASK | DA7218_PLL_INDIV_MASK,
                            pll_ctrl);
 
@@ -1934,8 +1934,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
 static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        u8 dai_clk_mode = 0, dai_ctrl = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -2012,8 +2012,8 @@ static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        /* By default 64 BCLKs per WCLK is supported */
        dai_clk_mode |= DA7218_DAI_BCLKS_PER_WCLK_64;
 
-       snd_soc_write(codec, DA7218_DAI_CLK_MODE, dai_clk_mode);
-       snd_soc_update_bits(codec, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,
+       snd_soc_component_write(component, DA7218_DAI_CLK_MODE, dai_clk_mode);
+       snd_soc_component_update_bits(component, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,
                            dai_ctrl);
 
        return 0;
@@ -2023,16 +2023,16 @@ static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
                                   unsigned int tx_mask, unsigned int rx_mask,
                                   int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 dai_bclks_per_wclk;
        u32 frame_size;
 
        /* No channels enabled so disable TDM, revert to 64-bit frames */
        if (!tx_mask) {
-               snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
+               snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL,
                                    DA7218_DAI_TDM_CH_EN_MASK |
                                    DA7218_DAI_TDM_MODE_EN_MASK, 0);
-               snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+               snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
                                    DA7218_DAI_BCLKS_PER_WCLK_MASK,
                                    DA7218_DAI_BCLKS_PER_WCLK_64);
                return 0;
@@ -2040,14 +2040,14 @@ static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
        /* Check we have valid slots */
        if (fls(tx_mask) > DA7218_DAI_TDM_MAX_SLOTS) {
-               dev_err(codec->dev, "Invalid number of slots, max = %d\n",
+               dev_err(component->dev, "Invalid number of slots, max = %d\n",
                        DA7218_DAI_TDM_MAX_SLOTS);
                return -EINVAL;
        }
 
        /* Check we have a valid offset given (first 2 bytes of rx_mask) */
        if (rx_mask >> DA7218_2BYTE_SHIFT) {
-               dev_err(codec->dev, "Invalid slot offset, max = %d\n",
+               dev_err(component->dev, "Invalid slot offset, max = %d\n",
                        DA7218_2BYTE_MASK);
                return -EINVAL;
        }
@@ -2068,18 +2068,18 @@ static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
                dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_256;
                break;
        default:
-               dev_err(codec->dev, "Invalid frame size\n");
+               dev_err(component->dev, "Invalid frame size\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
+       snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,
                            DA7218_DAI_BCLKS_PER_WCLK_MASK,
                            dai_bclks_per_wclk);
-       snd_soc_write(codec, DA7218_DAI_OFFSET_LOWER,
+       snd_soc_component_write(component, DA7218_DAI_OFFSET_LOWER,
                      (rx_mask & DA7218_BYTE_MASK));
-       snd_soc_write(codec, DA7218_DAI_OFFSET_UPPER,
+       snd_soc_component_write(component, DA7218_DAI_OFFSET_UPPER,
                      ((rx_mask >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK));
-       snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
+       snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL,
                            DA7218_DAI_TDM_CH_EN_MASK |
                            DA7218_DAI_TDM_MODE_EN_MASK,
                            (tx_mask << DA7218_DAI_TDM_CH_EN_SHIFT) |
@@ -2092,7 +2092,7 @@ static int da7218_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 dai_ctrl = 0, fs;
        unsigned int channels;
 
@@ -2115,7 +2115,7 @@ static int da7218_hw_params(struct snd_pcm_substream *substream,
 
        channels = params_channels(params);
        if ((channels < 1) || (channels > DA7218_DAI_CH_NUM_MAX)) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Invalid number of channels, only 1 to %d supported\n",
                        DA7218_DAI_CH_NUM_MAX);
                return -EINVAL;
@@ -2160,11 +2160,11 @@ static int da7218_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, DA7218_DAI_CTRL,
+       snd_soc_component_update_bits(component, DA7218_DAI_CTRL,
                            DA7218_DAI_WORD_LENGTH_MASK | DA7218_DAI_CH_NUM_MASK,
                            dai_ctrl);
        /* SRs tied for ADCs and DACs. */
-       snd_soc_write(codec, DA7218_SR,
+       snd_soc_component_write(component, DA7218_SR,
                      (fs << DA7218_SR_DAC_SHIFT) | (fs << DA7218_SR_ADC_SHIFT));
 
        return 0;
@@ -2208,15 +2208,15 @@ static struct snd_soc_dai_driver da7218_dai = {
  * HP Detect
  */
 
-int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int da7218_hpldet(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
        if (da7218->dev_id == DA7217_DEV_ID)
                return -EINVAL;
 
        da7218->jack = jack;
-       snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
+       snd_soc_component_update_bits(component, DA7218_HPLDET_JACK,
                            DA7218_HPLDET_JACK_EN_MASK,
                            jack ? DA7218_HPLDET_JACK_EN_MASK : 0);
 
@@ -2224,23 +2224,23 @@ int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 }
 EXPORT_SYMBOL_GPL(da7218_hpldet);
 
-static void da7218_micldet_irq(struct snd_soc_codec *codec)
+static void da7218_micldet_irq(struct snd_soc_component *component)
 {
        char *envp[] = {
                "EVENT=MIC_LEVEL_DETECT",
                NULL,
        };
 
-       kobject_uevent_env(&codec->dev->kobj, KOBJ_CHANGE, envp);
+       kobject_uevent_env(&component->dev->kobj, KOBJ_CHANGE, envp);
 }
 
-static void da7218_hpldet_irq(struct snd_soc_codec *codec)
+static void da7218_hpldet_irq(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        u8 jack_status;
        int report;
 
-       jack_status = snd_soc_read(codec, DA7218_EVENT_STATUS);
+       jack_status = snd_soc_component_read32(component, DA7218_EVENT_STATUS);
 
        if (jack_status & DA7218_HPLDET_JACK_STS_MASK)
                report = SND_JACK_HEADPHONE;
@@ -2256,24 +2256,24 @@ static void da7218_hpldet_irq(struct snd_soc_codec *codec)
 
 static irqreturn_t da7218_irq_thread(int irq, void *data)
 {
-       struct snd_soc_codec *codec = data;
+       struct snd_soc_component *component = data;
        u8 status;
 
        /* Read IRQ status reg */
-       status = snd_soc_read(codec, DA7218_EVENT);
+       status = snd_soc_component_read32(component, DA7218_EVENT);
        if (!status)
                return IRQ_NONE;
 
        /* Mic level detect */
        if (status & DA7218_LVL_DET_EVENT_MASK)
-               da7218_micldet_irq(codec);
+               da7218_micldet_irq(component);
 
        /* HP detect */
        if (status & DA7218_HPLDET_JACK_EVENT_MASK)
-               da7218_hpldet_irq(codec);
+               da7218_hpldet_irq(component);
 
        /* Clear interrupts */
-       snd_soc_write(codec, DA7218_EVENT, status);
+       snd_soc_component_write(component, DA7218_EVENT, status);
 
        return IRQ_HANDLED;
 }
@@ -2300,7 +2300,7 @@ static inline int da7218_of_get_id(struct device *dev)
 }
 
 static enum da7218_micbias_voltage
-       da7218_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
+       da7218_of_micbias_lvl(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1200:
@@ -2322,13 +2322,13 @@ static enum da7218_micbias_voltage
        case 3000:
                return DA7218_MICBIAS_3_0V;
        default:
-               dev_warn(codec->dev, "Invalid micbias level");
+               dev_warn(component->dev, "Invalid micbias level");
                return DA7218_MICBIAS_1_6V;
        }
 }
 
 static enum da7218_mic_amp_in_sel
-       da7218_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str)
+       da7218_of_mic_amp_in_sel(struct snd_soc_component *component, const char *str)
 {
        if (!strcmp(str, "diff")) {
                return DA7218_MIC_AMP_IN_SEL_DIFF;
@@ -2337,39 +2337,39 @@ static enum da7218_mic_amp_in_sel
        } else if (!strcmp(str, "se_n")) {
                return DA7218_MIC_AMP_IN_SEL_SE_N;
        } else {
-               dev_warn(codec->dev, "Invalid mic input type selection");
+               dev_warn(component->dev, "Invalid mic input type selection");
                return DA7218_MIC_AMP_IN_SEL_DIFF;
        }
 }
 
 static enum da7218_dmic_data_sel
-       da7218_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
+       da7218_of_dmic_data_sel(struct snd_soc_component *component, const char *str)
 {
        if (!strcmp(str, "lrise_rfall")) {
                return DA7218_DMIC_DATA_LRISE_RFALL;
        } else if (!strcmp(str, "lfall_rrise")) {
                return DA7218_DMIC_DATA_LFALL_RRISE;
        } else {
-               dev_warn(codec->dev, "Invalid DMIC data type selection");
+               dev_warn(component->dev, "Invalid DMIC data type selection");
                return DA7218_DMIC_DATA_LRISE_RFALL;
        }
 }
 
 static enum da7218_dmic_samplephase
-       da7218_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
+       da7218_of_dmic_samplephase(struct snd_soc_component *component, const char *str)
 {
        if (!strcmp(str, "on_clkedge")) {
                return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
        } else if (!strcmp(str, "between_clkedge")) {
                return DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE;
        } else {
-               dev_warn(codec->dev, "Invalid DMIC sample phase");
+               dev_warn(component->dev, "Invalid DMIC sample phase");
                return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
        }
 }
 
 static enum da7218_dmic_clk_rate
-       da7218_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
+       da7218_of_dmic_clkrate(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1500000:
@@ -2377,13 +2377,13 @@ static enum da7218_dmic_clk_rate
        case 3000000:
                return DA7218_DMIC_CLK_3_0MHZ;
        default:
-               dev_warn(codec->dev, "Invalid DMIC clock rate");
+               dev_warn(component->dev, "Invalid DMIC clock rate");
                return DA7218_DMIC_CLK_3_0MHZ;
        }
 }
 
 static enum da7218_hpldet_jack_rate
-       da7218_of_jack_rate(struct snd_soc_codec *codec, u32 val)
+       da7218_of_jack_rate(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 5:
@@ -2403,13 +2403,13 @@ static enum da7218_hpldet_jack_rate
        case 640:
                return DA7218_HPLDET_JACK_RATE_640US;
        default:
-               dev_warn(codec->dev, "Invalid jack detect rate");
+               dev_warn(component->dev, "Invalid jack detect rate");
                return DA7218_HPLDET_JACK_RATE_40US;
        }
 }
 
 static enum da7218_hpldet_jack_debounce
-       da7218_of_jack_debounce(struct snd_soc_codec *codec, u32 val)
+       da7218_of_jack_debounce(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 0:
@@ -2421,13 +2421,13 @@ static enum da7218_hpldet_jack_debounce
        case 4:
                return DA7218_HPLDET_JACK_DEBOUNCE_4;
        default:
-               dev_warn(codec->dev, "Invalid jack debounce");
+               dev_warn(component->dev, "Invalid jack debounce");
                return DA7218_HPLDET_JACK_DEBOUNCE_2;
        }
 }
 
 static enum da7218_hpldet_jack_thr
-       da7218_of_jack_thr(struct snd_soc_codec *codec, u32 val)
+       da7218_of_jack_thr(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 84:
@@ -2439,76 +2439,76 @@ static enum da7218_hpldet_jack_thr
        case 96:
                return DA7218_HPLDET_JACK_THR_96PCT;
        default:
-               dev_warn(codec->dev, "Invalid jack threshold level");
+               dev_warn(component->dev, "Invalid jack threshold level");
                return DA7218_HPLDET_JACK_THR_84PCT;
        }
 }
 
-static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
+static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
-       struct device_node *np = codec->dev->of_node;
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
+       struct device_node *np = component->dev->of_node;
        struct device_node *hpldet_np;
        struct da7218_pdata *pdata;
        struct da7218_hpldet_pdata *hpldet_pdata;
        const char *of_str;
        u32 of_val32;
 
-       pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
+       pdata = devm_kzalloc(component->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return NULL;
 
        if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0)
-               pdata->micbias1_lvl = da7218_of_micbias_lvl(codec, of_val32);
+               pdata->micbias1_lvl = da7218_of_micbias_lvl(component, of_val32);
        else
                pdata->micbias1_lvl = DA7218_MICBIAS_1_6V;
 
        if (of_property_read_u32(np, "dlg,micbias2-lvl-millivolt", &of_val32) >= 0)
-               pdata->micbias2_lvl = da7218_of_micbias_lvl(codec, of_val32);
+               pdata->micbias2_lvl = da7218_of_micbias_lvl(component, of_val32);
        else
                pdata->micbias2_lvl = DA7218_MICBIAS_1_6V;
 
        if (!of_property_read_string(np, "dlg,mic1-amp-in-sel", &of_str))
                pdata->mic1_amp_in_sel =
-                       da7218_of_mic_amp_in_sel(codec, of_str);
+                       da7218_of_mic_amp_in_sel(component, of_str);
        else
                pdata->mic1_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
 
        if (!of_property_read_string(np, "dlg,mic2-amp-in-sel", &of_str))
                pdata->mic2_amp_in_sel =
-                       da7218_of_mic_amp_in_sel(codec, of_str);
+                       da7218_of_mic_amp_in_sel(component, of_str);
        else
                pdata->mic2_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
 
        if (!of_property_read_string(np, "dlg,dmic1-data-sel", &of_str))
-               pdata->dmic1_data_sel = da7218_of_dmic_data_sel(codec, of_str);
+               pdata->dmic1_data_sel = da7218_of_dmic_data_sel(component, of_str);
        else
                pdata->dmic1_data_sel = DA7218_DMIC_DATA_LRISE_RFALL;
 
        if (!of_property_read_string(np, "dlg,dmic1-samplephase", &of_str))
                pdata->dmic1_samplephase =
-                       da7218_of_dmic_samplephase(codec, of_str);
+                       da7218_of_dmic_samplephase(component, of_str);
        else
                pdata->dmic1_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
 
        if (of_property_read_u32(np, "dlg,dmic1-clkrate-hz", &of_val32) >= 0)
-               pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
+               pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(component, of_val32);
        else
                pdata->dmic1_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
 
        if (!of_property_read_string(np, "dlg,dmic2-data-sel", &of_str))
-               pdata->dmic2_data_sel = da7218_of_dmic_data_sel(codec, of_str);
+               pdata->dmic2_data_sel = da7218_of_dmic_data_sel(component, of_str);
        else
                pdata->dmic2_data_sel = DA7218_DMIC_DATA_LRISE_RFALL;
 
        if (!of_property_read_string(np, "dlg,dmic2-samplephase", &of_str))
                pdata->dmic2_samplephase =
-                       da7218_of_dmic_samplephase(codec, of_str);
+                       da7218_of_dmic_samplephase(component, of_str);
        else
                pdata->dmic2_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
 
        if (of_property_read_u32(np, "dlg,dmic2-clkrate-hz", &of_val32) >= 0)
-               pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
+               pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(component, of_val32);
        else
                pdata->dmic2_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
 
@@ -2522,7 +2522,7 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
                if (!hpldet_np)
                        return pdata;
 
-               hpldet_pdata = devm_kzalloc(codec->dev, sizeof(*hpldet_pdata),
+               hpldet_pdata = devm_kzalloc(component->dev, sizeof(*hpldet_pdata),
                                            GFP_KERNEL);
                if (!hpldet_pdata) {
                        of_node_put(hpldet_np);
@@ -2533,14 +2533,14 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
                if (of_property_read_u32(hpldet_np, "dlg,jack-rate-us",
                                         &of_val32) >= 0)
                        hpldet_pdata->jack_rate =
-                               da7218_of_jack_rate(codec, of_val32);
+                               da7218_of_jack_rate(component, of_val32);
                else
                        hpldet_pdata->jack_rate = DA7218_HPLDET_JACK_RATE_40US;
 
                if (of_property_read_u32(hpldet_np, "dlg,jack-debounce",
                                         &of_val32) >= 0)
                        hpldet_pdata->jack_debounce =
-                               da7218_of_jack_debounce(codec, of_val32);
+                               da7218_of_jack_debounce(component, of_val32);
                else
                        hpldet_pdata->jack_debounce =
                                DA7218_HPLDET_JACK_DEBOUNCE_2;
@@ -2548,7 +2548,7 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
                if (of_property_read_u32(hpldet_np, "dlg,jack-threshold-pct",
                                         &of_val32) >= 0)
                        hpldet_pdata->jack_thr =
-                               da7218_of_jack_thr(codec, of_val32);
+                               da7218_of_jack_thr(component, of_val32);
                else
                        hpldet_pdata->jack_thr = DA7218_HPLDET_JACK_THR_84PCT;
 
@@ -2572,10 +2572,10 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
  * Codec driver functions
  */
 
-static int da7218_set_bias_level(struct snd_soc_codec *codec,
+static int da7218_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -2583,11 +2583,11 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_PREPARE:
                /* Enable MCLK for transition to ON state */
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
                        if (da7218->mclk) {
                                ret = clk_prepare_enable(da7218->mclk);
                                if (ret) {
-                                       dev_err(codec->dev, "Failed to enable mclk\n");
+                                       dev_err(component->dev, "Failed to enable mclk\n");
                                        return ret;
                                }
                        }
@@ -2595,14 +2595,14 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
 
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Master bias */
-                       snd_soc_update_bits(codec, DA7218_REFERENCES,
+                       snd_soc_component_update_bits(component, DA7218_REFERENCES,
                                            DA7218_BIAS_EN_MASK,
                                            DA7218_BIAS_EN_MASK);
 
                        /* Internal LDO */
-                       snd_soc_update_bits(codec, DA7218_LDO_CTRL,
+                       snd_soc_component_update_bits(component, DA7218_LDO_CTRL,
                                            DA7218_LDO_EN_MASK,
                                            DA7218_LDO_EN_MASK);
                } else {
@@ -2615,11 +2615,11 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
                /* Only disable if jack detection disabled */
                if (!da7218->jack) {
                        /* Internal LDO */
-                       snd_soc_update_bits(codec, DA7218_LDO_CTRL,
+                       snd_soc_component_update_bits(component, DA7218_LDO_CTRL,
                                            DA7218_LDO_EN_MASK, 0);
 
                        /* Master bias */
-                       snd_soc_update_bits(codec, DA7218_REFERENCES,
+                       snd_soc_component_update_bits(component, DA7218_REFERENCES,
                                            DA7218_BIAS_EN_MASK, 0);
                }
                break;
@@ -2634,9 +2634,9 @@ static const char *da7218_supply_names[DA7218_NUM_SUPPLIES] = {
        [DA7218_SUPPLY_VDDIO] = "VDDIO",
 };
 
-static int da7218_handle_supplies(struct snd_soc_codec *codec)
+static int da7218_handle_supplies(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct regulator *vddio;
        u8 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V;
        int i, ret;
@@ -2645,10 +2645,10 @@ static int da7218_handle_supplies(struct snd_soc_codec *codec)
        for (i = 0; i < DA7218_NUM_SUPPLIES; ++i)
                da7218->supplies[i].supply = da7218_supply_names[i];
 
-       ret = devm_regulator_bulk_get(codec->dev, DA7218_NUM_SUPPLIES,
+       ret = devm_regulator_bulk_get(component->dev, DA7218_NUM_SUPPLIES,
                                      da7218->supplies);
        if (ret) {
-               dev_err(codec->dev, "Failed to get supplies\n");
+               dev_err(component->dev, "Failed to get supplies\n");
                return ret;
        }
 
@@ -2656,29 +2656,29 @@ static int da7218_handle_supplies(struct snd_soc_codec *codec)
        vddio = da7218->supplies[DA7218_SUPPLY_VDDIO].consumer;
        ret = regulator_get_voltage(vddio);
        if (ret < 1500000)
-               dev_warn(codec->dev, "Invalid VDDIO voltage\n");
+               dev_warn(component->dev, "Invalid VDDIO voltage\n");
        else if (ret < 2500000)
                io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V;
 
        /* Enable main supplies */
        ret = regulator_bulk_enable(DA7218_NUM_SUPPLIES, da7218->supplies);
        if (ret) {
-               dev_err(codec->dev, "Failed to enable supplies\n");
+               dev_err(component->dev, "Failed to enable supplies\n");
                return ret;
        }
 
        /* Ensure device in active mode */
-       snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);
+       snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);
 
        /* Update IO voltage level range */
-       snd_soc_write(codec, DA7218_IO_CTRL, io_voltage_lvl);
+       snd_soc_component_write(component, DA7218_IO_CTRL, io_voltage_lvl);
 
        return 0;
 }
 
-static void da7218_handle_pdata(struct snd_soc_codec *codec)
+static void da7218_handle_pdata(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        struct da7218_pdata *pdata = da7218->pdata;
 
        if (pdata) {
@@ -2719,14 +2719,14 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                        break;
                }
 
-               snd_soc_write(codec, DA7218_MICBIAS_CTRL, micbias_lvl);
+               snd_soc_component_write(component, DA7218_MICBIAS_CTRL, micbias_lvl);
 
                /* Mic */
                switch (pdata->mic1_amp_in_sel) {
                case DA7218_MIC_AMP_IN_SEL_DIFF:
                case DA7218_MIC_AMP_IN_SEL_SE_P:
                case DA7218_MIC_AMP_IN_SEL_SE_N:
-                       snd_soc_write(codec, DA7218_MIC_1_SELECT,
+                       snd_soc_component_write(component, DA7218_MIC_1_SELECT,
                                      pdata->mic1_amp_in_sel);
                        break;
                }
@@ -2735,7 +2735,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                case DA7218_MIC_AMP_IN_SEL_DIFF:
                case DA7218_MIC_AMP_IN_SEL_SE_P:
                case DA7218_MIC_AMP_IN_SEL_SE_N:
-                       snd_soc_write(codec, DA7218_MIC_2_SELECT,
+                       snd_soc_component_write(component, DA7218_MIC_2_SELECT,
                                      pdata->mic2_amp_in_sel);
                        break;
                }
@@ -2765,7 +2765,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                        break;
                }
 
-               snd_soc_update_bits(codec, DA7218_DMIC_1_CTRL,
+               snd_soc_component_update_bits(component, DA7218_DMIC_1_CTRL,
                                    DA7218_DMIC_1_DATA_SEL_MASK |
                                    DA7218_DMIC_1_SAMPLEPHASE_MASK |
                                    DA7218_DMIC_1_CLK_RATE_MASK, dmic_cfg);
@@ -2795,7 +2795,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                        break;
                }
 
-               snd_soc_update_bits(codec, DA7218_DMIC_2_CTRL,
+               snd_soc_component_update_bits(component, DA7218_DMIC_2_CTRL,
                                    DA7218_DMIC_2_DATA_SEL_MASK |
                                    DA7218_DMIC_2_SAMPLEPHASE_MASK |
                                    DA7218_DMIC_2_CLK_RATE_MASK, dmic_cfg);
@@ -2806,9 +2806,9 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                                pdata->hp_diff_single_supply;
 
                        if (da7218->hp_single_supply) {
-                               snd_soc_write(codec, DA7218_HP_DIFF_UNLOCK,
+                               snd_soc_component_write(component, DA7218_HP_DIFF_UNLOCK,
                                              DA7218_HP_DIFF_UNLOCK_VAL);
-                               snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
+                               snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL,
                                                    DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK,
                                                    DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK);
                        }
@@ -2857,7 +2857,7 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                                         DA7218_HPLDET_JACK_THR_SHIFT);
                                break;
                        }
-                       snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
+                       snd_soc_component_update_bits(component, DA7218_HPLDET_JACK,
                                            DA7218_HPLDET_JACK_RATE_MASK |
                                            DA7218_HPLDET_JACK_DEBOUNCE_MASK |
                                            DA7218_HPLDET_JACK_THR_MASK,
@@ -2873,31 +2873,31 @@ static void da7218_handle_pdata(struct snd_soc_codec *codec)
                        if (hpldet_pdata->discharge)
                                hpldet_cfg |= DA7218_HPLDET_DISCHARGE_EN_MASK;
 
-                       snd_soc_write(codec, DA7218_HPLDET_CTRL, hpldet_cfg);
+                       snd_soc_component_write(component, DA7218_HPLDET_CTRL, hpldet_cfg);
                }
        }
 }
 
-static int da7218_probe(struct snd_soc_codec *codec)
+static int da7218_probe(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
        int ret;
 
        /* Regulator configuration */
-       ret = da7218_handle_supplies(codec);
+       ret = da7218_handle_supplies(component);
        if (ret)
                return ret;
 
        /* Handle DT/Platform data */
-       if (codec->dev->of_node)
-               da7218->pdata = da7218_of_to_pdata(codec);
+       if (component->dev->of_node)
+               da7218->pdata = da7218_of_to_pdata(component);
        else
-               da7218->pdata = dev_get_platdata(codec->dev);
+               da7218->pdata = dev_get_platdata(component->dev);
 
-       da7218_handle_pdata(codec);
+       da7218_handle_pdata(component);
 
        /* Check if MCLK provided, if not the clock is NULL */
-       da7218->mclk = devm_clk_get(codec->dev, "mclk");
+       da7218->mclk = devm_clk_get(component->dev, "mclk");
        if (IS_ERR(da7218->mclk)) {
                if (PTR_ERR(da7218->mclk) != -ENOENT) {
                        ret = PTR_ERR(da7218->mclk);
@@ -2908,74 +2908,74 @@ static int da7218_probe(struct snd_soc_codec *codec)
        }
 
        /* Default PC to free-running */
-       snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
+       snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
 
        /*
         * Default Output Filter mixers to off otherwise DAPM will power
         * Mic to HP passthrough paths by default at startup.
         */
-       snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1L, 0);
-       snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1R, 0);
+       snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1L, 0);
+       snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1R, 0);
 
        /* Default CP to normal load, power mode */
-       snd_soc_update_bits(codec, DA7218_CP_CTRL,
+       snd_soc_component_update_bits(component, DA7218_CP_CTRL,
                            DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK, 0);
 
        /* Default gain ramping */
-       snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
+       snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL,
                            DA7218_MIXIN_1_AMP_RAMP_EN_MASK,
                            DA7218_MIXIN_1_AMP_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
+       snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL,
                            DA7218_MIXIN_2_AMP_RAMP_EN_MASK,
                            DA7218_MIXIN_2_AMP_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL,
                            DA7218_IN_1L_RAMP_EN_MASK,
                            DA7218_IN_1L_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL,
                            DA7218_IN_1R_RAMP_EN_MASK,
                            DA7218_IN_1R_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL,
                            DA7218_IN_2L_RAMP_EN_MASK,
                            DA7218_IN_2L_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL,
                            DA7218_IN_2R_RAMP_EN_MASK,
                            DA7218_IN_2R_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_DGS_GAIN_CTRL,
+       snd_soc_component_update_bits(component, DA7218_DGS_GAIN_CTRL,
                            DA7218_DGS_RAMP_EN_MASK, DA7218_DGS_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_OUT_1L_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_OUT_1L_FILTER_CTRL,
                            DA7218_OUT_1L_RAMP_EN_MASK,
                            DA7218_OUT_1L_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_OUT_1R_FILTER_CTRL,
+       snd_soc_component_update_bits(component, DA7218_OUT_1R_FILTER_CTRL,
                            DA7218_OUT_1R_RAMP_EN_MASK,
                            DA7218_OUT_1R_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7218_HP_L_CTRL,
                            DA7218_HP_L_AMP_RAMP_EN_MASK,
                            DA7218_HP_L_AMP_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7218_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7218_HP_R_CTRL,
                            DA7218_HP_R_AMP_RAMP_EN_MASK,
                            DA7218_HP_R_AMP_RAMP_EN_MASK);
 
        /* Default infinite tone gen, start/stop by Kcontrol */
-       snd_soc_write(codec, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);
+       snd_soc_component_write(component, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);
 
        /* DA7217 specific config */
        if (da7218->dev_id == DA7217_DEV_ID) {
-               snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
+               snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL,
                                    DA7218_HP_AMP_DIFF_MODE_EN_MASK,
                                    DA7218_HP_AMP_DIFF_MODE_EN_MASK);
 
                /* Only DA7218 supports HP detect, mask off for DA7217 */
-               snd_soc_write(codec, DA7218_EVENT_MASK,
+               snd_soc_component_write(component, DA7218_EVENT_MASK,
                              DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK);
        }
 
        if (da7218->irq) {
-               ret = devm_request_threaded_irq(codec->dev, da7218->irq, NULL,
+               ret = devm_request_threaded_irq(component->dev, da7218->irq, NULL,
                                                da7218_irq_thread,
                                                IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                               "da7218", codec);
+                                               "da7218", component);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
+                       dev_err(component->dev, "Failed to request IRQ %d: %d\n",
                                da7218->irq, ret);
                        goto err_disable_reg;
                }
@@ -2990,39 +2990,37 @@ err_disable_reg:
        return ret;
 }
 
-static int da7218_remove(struct snd_soc_codec *codec)
+static void da7218_remove(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
        regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int da7218_suspend(struct snd_soc_codec *codec)
+static int da7218_suspend(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
-       da7218_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       da7218_set_bias_level(component, SND_SOC_BIAS_OFF);
 
        /* Put device into standby mode if jack detection disabled */
        if (!da7218->jack)
-               snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, 0);
+               snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, 0);
 
        return 0;
 }
 
-static int da7218_resume(struct snd_soc_codec *codec)
+static int da7218_resume(struct snd_soc_component *component)
 {
-       struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
+       struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);
 
        /* Put device into active mode if previously moved to standby */
        if (!da7218->jack)
-               snd_soc_write(codec, DA7218_SYSTEM_ACTIVE,
+               snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE,
                              DA7218_SYSTEM_ACTIVE_MASK);
 
-       da7218_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       da7218_set_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        return 0;
 }
@@ -3031,21 +3029,22 @@ static int da7218_resume(struct snd_soc_codec *codec)
 #define da7218_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7218 = {
+static const struct snd_soc_component_driver soc_component_dev_da7218 = {
        .probe                  = da7218_probe,
        .remove                 = da7218_remove,
        .suspend                = da7218_suspend,
        .resume                 = da7218_resume,
        .set_bias_level         = da7218_set_bias_level,
-
-       .component_driver = {
-               .controls               = da7218_snd_controls,
-               .num_controls           = ARRAY_SIZE(da7218_snd_controls),
-               .dapm_widgets           = da7218_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(da7218_dapm_widgets),
-               .dapm_routes            = da7218_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(da7218_audio_map),
-       },
+       .controls               = da7218_snd_controls,
+       .num_controls           = ARRAY_SIZE(da7218_snd_controls),
+       .dapm_widgets           = da7218_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(da7218_dapm_widgets),
+       .dapm_routes            = da7218_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(da7218_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 
@@ -3295,21 +3294,15 @@ static int da7218_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_da7218, &da7218_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_da7218, &da7218_dai, 1);
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register da7218 codec: %d\n",
+               dev_err(&i2c->dev, "Failed to register da7218 component: %d\n",
                        ret);
        }
        return ret;
 }
 
-static int da7218_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id da7218_i2c_id[] = {
        { "da7217", DA7217_DEV_ID },
        { "da7218", DA7218_DEV_ID },
@@ -3323,7 +3316,6 @@ static struct i2c_driver da7218_i2c_driver = {
                .of_match_table = of_match_ptr(da7218_of_match),
        },
        .probe          = da7218_i2c_probe,
-       .remove         = da7218_i2c_remove,
        .id_table       = da7218_i2c_id,
 };
 
index 4f7ec21069a48d098b0ff8dceb0ddc2db0614dd5..19e6cee2e42ebab059bafebfdf2ad3ce42694a96 100644 (file)
@@ -1410,6 +1410,6 @@ struct da7218_priv {
 };
 
 /* HP detect control */
-int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int da7218_hpldet(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif /* _DA7218_H */
index 1d1d10dd92ae233635d0d95783f82d2a15eeabdd..a49ab751a036c26ee89b414be0ba69f8b22db7aa 100644 (file)
@@ -32,9 +32,9 @@
  * Detection control
  */
 
-void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
        da7219->aad->jack = jack;
        da7219->aad->jack_inserted = false;
@@ -43,7 +43,7 @@ void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
        snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
 
        /* Enable/Disable jack detection */
-       snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+       snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
                            DA7219_ACCDET_EN_MASK,
                            (jack ? DA7219_ACCDET_EN_MASK : 0));
 }
@@ -57,17 +57,17 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
 {
        struct da7219_aad_priv *da7219_aad =
                container_of(work, struct da7219_aad_priv, btn_det_work);
-       struct snd_soc_codec *codec = da7219_aad->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = da7219_aad->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        u8 statusa, micbias_ctrl;
        bool micbias_up = false;
        int retries = 0;
 
        /* Drive headphones/lineout */
-       snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
                            DA7219_HP_L_AMP_OE_MASK,
                            DA7219_HP_L_AMP_OE_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
                            DA7219_HP_R_AMP_OE_MASK,
                            DA7219_HP_R_AMP_OE_MASK);
 
@@ -76,7 +76,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
        snd_soc_dapm_sync(dapm);
 
        do {
-               statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
+               statusa = snd_soc_component_read32(component, DA7219_ACCDET_STATUS_A);
                if (statusa & DA7219_MICBIAS_UP_STS_MASK)
                        micbias_up = true;
                else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
@@ -84,7 +84,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
        } while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
 
        if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
-               dev_warn(codec->dev, "Mic bias status check timed out");
+               dev_warn(component->dev, "Mic bias status check timed out");
 
        /*
         * Mic bias pulse required to enable mic, must be done before enabling
@@ -92,16 +92,16 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
         */
        if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
                /* Pulse higher level voltage */
-               micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
-               snd_soc_update_bits(codec, DA7219_MICBIAS_CTRL,
+               micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
+               snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
                                    DA7219_MICBIAS1_LEVEL_MASK,
                                    da7219_aad->micbias_pulse_lvl);
                msleep(da7219_aad->micbias_pulse_time);
-               snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_ctrl);
+               snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl);
 
        }
 
-       snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+       snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
                            DA7219_BUTTON_CONFIG_MASK,
                            da7219_aad->btn_cfg);
 }
@@ -110,9 +110,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 {
        struct da7219_aad_priv *da7219_aad =
                container_of(work, struct da7219_aad_priv, hptest_work);
-       struct snd_soc_codec *codec = da7219_aad->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = da7219_aad->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
        u16 tonegen_freq_hptest;
        u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
@@ -127,7 +127,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
        if (da7219->mclk) {
                ret = clk_prepare_enable(da7219->mclk);
                if (ret) {
-                       dev_err(codec->dev, "Failed to enable mclk - %d\n", ret);
+                       dev_err(component->dev, "Failed to enable mclk - %d\n", ret);
                        mutex_unlock(&da7219->pll_lock);
                        mutex_unlock(&da7219->ctrl_lock);
                        snd_soc_dapm_mutex_unlock(dapm);
@@ -142,90 +142,90 @@ static void da7219_aad_hptest_work(struct work_struct *work)
         * If MCLK is present, but PLL is not enabled then we enable it here to
         * ensure a consistent detection procedure.
         */
-       pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS);
+       pll_srm_sts = snd_soc_component_read32(component, DA7219_PLL_SRM_STS);
        if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
                tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
 
-               pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
+               pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL);
                if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)
-                       da7219_set_pll(codec, DA7219_SYSCLK_PLL,
+                       da7219_set_pll(component, DA7219_SYSCLK_PLL,
                                       DA7219_PLL_FREQ_OUT_98304);
        } else {
                tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
        }
 
        /* Ensure gain ramping at fastest rate */
-       gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
-       snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
+       gain_ramp_ctrl = snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
+       snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
 
        /* Bypass cache so it saves current settings */
        regcache_cache_bypass(da7219->regmap, true);
 
        /* Make sure Tone Generator is disabled */
-       snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
+       snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 
        /* Enable HPTest block, 1KOhms check */
-       snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
+       snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
                            DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
                            DA7219_HPTEST_EN_MASK |
                            DA7219_HPTEST_RES_SEL_1KOHMS);
 
        /* Set gains to 0db */
-       snd_soc_write(codec, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
-       snd_soc_write(codec, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
-       snd_soc_write(codec, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
-       snd_soc_write(codec, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
+       snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
+       snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
+       snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
+       snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
 
        /* Disable DAC filters, EQs and soft mute */
-       snd_soc_update_bits(codec, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
+       snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
                            0);
-       snd_soc_update_bits(codec, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
+       snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
                            0);
-       snd_soc_update_bits(codec, DA7219_DAC_FILTERS5,
+       snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
                            DA7219_DAC_SOFTMUTE_EN_MASK, 0);
 
        /* Enable HP left & right paths */
-       snd_soc_update_bits(codec, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
                            DA7219_CP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_DIG_ROUTING_DAC,
+       snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC,
                            DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
                            DA7219_DAC_L_SRC_TONEGEN |
                            DA7219_DAC_R_SRC_TONEGEN);
-       snd_soc_update_bits(codec, DA7219_DAC_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL,
                            DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
                            DA7219_DAC_L_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_DAC_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL,
                            DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
                            DA7219_DAC_R_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_MIXOUT_L_SELECT,
+       snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT,
                            DA7219_MIXOUT_L_MIX_SELECT_MASK,
                            DA7219_MIXOUT_L_MIX_SELECT_MASK);
-       snd_soc_update_bits(codec, DA7219_MIXOUT_R_SELECT,
+       snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT,
                            DA7219_MIXOUT_R_MIX_SELECT_MASK,
                            DA7219_MIXOUT_R_MIX_SELECT_MASK);
-       snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1L,
+       snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L,
                            DA7219_OUTFILT_ST_1L_SRC_MASK,
                            DA7219_DMIX_ST_SRC_OUTFILT1L);
-       snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1R,
+       snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R,
                            DA7219_OUTFILT_ST_1R_SRC_MASK,
                            DA7219_DMIX_ST_SRC_OUTFILT1R);
-       snd_soc_update_bits(codec, DA7219_MIXOUT_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL,
                            DA7219_MIXOUT_L_AMP_EN_MASK,
                            DA7219_MIXOUT_L_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_MIXOUT_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL,
                            DA7219_MIXOUT_R_AMP_EN_MASK,
                            DA7219_MIXOUT_R_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
                            DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
                            DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
                            DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
                            DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
        msleep(DA7219_SETTLING_DELAY);
-       snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
                            DA7219_HP_L_AMP_MUTE_EN_MASK |
                            DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
-       snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
                            DA7219_HP_R_AMP_MUTE_EN_MASK |
                            DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
 
@@ -237,26 +237,26 @@ static void da7219_aad_hptest_work(struct work_struct *work)
                msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 
        /* Configure & start Tone Generator */
-       snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
+       snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
        regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
                         &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
-       snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
+       snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2,
                            DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
                            DA7219_SWG_SEL_SRAMP |
                            DA7219_TONE_GEN_GAIN_MINUS_15DB);
-       snd_soc_write(codec, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
+       snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
 
        msleep(DA7219_AAD_HPTEST_PERIOD);
 
        /* Grab comparator reading */
-       accdet_cfg8 = snd_soc_read(codec, DA7219_ACCDET_CONFIG_8);
+       accdet_cfg8 = snd_soc_component_read32(component, DA7219_ACCDET_CONFIG_8);
        if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
                report |= SND_JACK_HEADPHONE;
        else
                report |= SND_JACK_LINEOUT;
 
        /* Stop tone generator */
-       snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
+       snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
 
        msleep(DA7219_AAD_HPTEST_PERIOD);
 
@@ -294,7 +294,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
        regcache_cache_bypass(da7219->regmap, false);
 
        /* Disable HPTest block */
-       snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
+       snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
                            DA7219_HPTEST_EN_MASK, 0);
 
        /*
@@ -305,18 +305,18 @@ static void da7219_aad_hptest_work(struct work_struct *work)
                msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
 
        /* Restore gain ramping rate */
-       snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
+       snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
 
        /* Drive Headphones/lineout */
-       snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
+       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
                            DA7219_HP_L_AMP_OE_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
+       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
                            DA7219_HP_R_AMP_OE_MASK);
 
        /* Restore PLL to previous configuration, if re-configured */
        if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
            ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
-               da7219_set_pll(codec, DA7219_SYSCLK_MCLK, 0);
+               da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0);
 
        /* Remove MCLK, if previously enabled */
        if (da7219->mclk)
@@ -343,9 +343,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 {
        struct da7219_aad_priv *da7219_aad = data;
-       struct snd_soc_codec *codec = da7219_aad->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = da7219_aad->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        u8 events[DA7219_AAD_IRQ_REG_MAX];
        u8 statusa;
        int i, report = 0, mask = 0;
@@ -358,13 +358,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
                return IRQ_NONE;
 
        /* Read status register for jack insertion & type status */
-       statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
+       statusa = snd_soc_component_read32(component, DA7219_ACCDET_STATUS_A);
 
        /* Clear events */
        regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
                          events, DA7219_AAD_IRQ_REG_MAX);
 
-       dev_dbg(codec->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
+       dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
                events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
                statusa);
 
@@ -430,13 +430,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
                        da7219_aad->jack_inserted = false;
 
                        /* Un-drive headphones/lineout */
-                       snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+                       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
                                            DA7219_HP_R_AMP_OE_MASK, 0);
-                       snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+                       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
                                            DA7219_HP_L_AMP_OE_MASK, 0);
 
                        /* Ensure button detection disabled */
-                       snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+                       snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
                                            DA7219_BUTTON_CONFIG_MASK, 0);
 
                        /* Disable mic bias */
@@ -459,7 +459,7 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
  */
 
 static enum da7219_aad_micbias_pulse_lvl
-       da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 2800:
@@ -467,13 +467,13 @@ static enum da7219_aad_micbias_pulse_lvl
        case 2900:
                return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
        default:
-               dev_warn(codec->dev, "Invalid micbias pulse level");
+               dev_warn(component->dev, "Invalid micbias pulse level");
                return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
        }
 }
 
 static enum da7219_aad_btn_cfg
-       da7219_aad_fw_btn_cfg(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_btn_cfg(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 2:
@@ -491,13 +491,13 @@ static enum da7219_aad_btn_cfg
        case 500:
                return DA7219_AAD_BTN_CFG_500MS;
        default:
-               dev_warn(codec->dev, "Invalid button config");
+               dev_warn(component->dev, "Invalid button config");
                return DA7219_AAD_BTN_CFG_10MS;
        }
 }
 
 static enum da7219_aad_mic_det_thr
-       da7219_aad_fw_mic_det_thr(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_mic_det_thr(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 200:
@@ -509,13 +509,13 @@ static enum da7219_aad_mic_det_thr
        case 1000:
                return DA7219_AAD_MIC_DET_THR_1000_OHMS;
        default:
-               dev_warn(codec->dev, "Invalid mic detect threshold");
+               dev_warn(component->dev, "Invalid mic detect threshold");
                return DA7219_AAD_MIC_DET_THR_500_OHMS;
        }
 }
 
 static enum da7219_aad_jack_ins_deb
-       da7219_aad_fw_jack_ins_deb(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_jack_ins_deb(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 5:
@@ -535,13 +535,13 @@ static enum da7219_aad_jack_ins_deb
        case 1000:
                return DA7219_AAD_JACK_INS_DEB_1S;
        default:
-               dev_warn(codec->dev, "Invalid jack insert debounce");
+               dev_warn(component->dev, "Invalid jack insert debounce");
                return DA7219_AAD_JACK_INS_DEB_20MS;
        }
 }
 
 static enum da7219_aad_jack_det_rate
-       da7219_aad_fw_jack_det_rate(struct snd_soc_codec *codec, const char *str)
+       da7219_aad_fw_jack_det_rate(struct snd_soc_component *component, const char *str)
 {
        if (!strcmp(str, "32ms_64ms")) {
                return DA7219_AAD_JACK_DET_RATE_32_64MS;
@@ -552,13 +552,13 @@ static enum da7219_aad_jack_det_rate
        } else if (!strcmp(str, "256ms_512ms")) {
                return DA7219_AAD_JACK_DET_RATE_256_512MS;
        } else {
-               dev_warn(codec->dev, "Invalid jack detect rate");
+               dev_warn(component->dev, "Invalid jack detect rate");
                return DA7219_AAD_JACK_DET_RATE_256_512MS;
        }
 }
 
 static enum da7219_aad_jack_rem_deb
-       da7219_aad_fw_jack_rem_deb(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_jack_rem_deb(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1:
@@ -570,13 +570,13 @@ static enum da7219_aad_jack_rem_deb
        case 20:
                return DA7219_AAD_JACK_REM_DEB_20MS;
        default:
-               dev_warn(codec->dev, "Invalid jack removal debounce");
+               dev_warn(component->dev, "Invalid jack removal debounce");
                return DA7219_AAD_JACK_REM_DEB_1MS;
        }
 }
 
 static enum da7219_aad_btn_avg
-       da7219_aad_fw_btn_avg(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_btn_avg(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1:
@@ -588,13 +588,13 @@ static enum da7219_aad_btn_avg
        case 8:
                return DA7219_AAD_BTN_AVG_8;
        default:
-               dev_warn(codec->dev, "Invalid button average value");
+               dev_warn(component->dev, "Invalid button average value");
                return DA7219_AAD_BTN_AVG_2;
        }
 }
 
 static enum da7219_aad_adc_1bit_rpt
-       da7219_aad_fw_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val)
+       da7219_aad_fw_adc_1bit_rpt(struct snd_soc_component *component, u32 val)
 {
        switch (val) {
        case 1:
@@ -606,14 +606,14 @@ static enum da7219_aad_adc_1bit_rpt
        case 8:
                return DA7219_AAD_ADC_1BIT_RPT_8;
        default:
-               dev_warn(codec->dev, "Invalid ADC 1-bit repeat value");
+               dev_warn(component->dev, "Invalid ADC 1-bit repeat value");
                return DA7219_AAD_ADC_1BIT_RPT_1;
        }
 }
 
-static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *codec)
+static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_component *component)
 {
-       struct device *dev = codec->dev;
+       struct device *dev = component->dev;
        struct i2c_client *i2c = to_i2c_client(dev);
        struct fwnode_handle *aad_np;
        struct da7219_aad_pdata *aad_pdata;
@@ -624,7 +624,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
        if (!aad_np)
                return NULL;
 
-       aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL);
+       aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
        if (!aad_pdata)
                return NULL;
 
@@ -633,7 +633,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
        if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
                                     &fw_val32) >= 0)
                aad_pdata->micbias_pulse_lvl =
-                       da7219_aad_fw_micbias_pulse_lvl(codec, fw_val32);
+                       da7219_aad_fw_micbias_pulse_lvl(component, fw_val32);
        else
                aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
 
@@ -642,31 +642,31 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
                aad_pdata->micbias_pulse_time = fw_val32;
 
        if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
-               aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(codec, fw_val32);
+               aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(component, fw_val32);
        else
                aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
 
        if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
                aad_pdata->mic_det_thr =
-                       da7219_aad_fw_mic_det_thr(codec, fw_val32);
+                       da7219_aad_fw_mic_det_thr(component, fw_val32);
        else
                aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
 
        if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
                aad_pdata->jack_ins_deb =
-                       da7219_aad_fw_jack_ins_deb(codec, fw_val32);
+                       da7219_aad_fw_jack_ins_deb(component, fw_val32);
        else
                aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
 
        if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
                aad_pdata->jack_det_rate =
-                       da7219_aad_fw_jack_det_rate(codec, fw_str);
+                       da7219_aad_fw_jack_det_rate(component, fw_str);
        else
                aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
 
        if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
                aad_pdata->jack_rem_deb =
-                       da7219_aad_fw_jack_rem_deb(codec, fw_val32);
+                       da7219_aad_fw_jack_rem_deb(component, fw_val32);
        else
                aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
 
@@ -691,22 +691,22 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
                aad_pdata->c_mic_btn_thr = 0x3E;
 
        if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
-               aad_pdata->btn_avg = da7219_aad_fw_btn_avg(codec, fw_val32);
+               aad_pdata->btn_avg = da7219_aad_fw_btn_avg(component, fw_val32);
        else
                aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
 
        if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
                aad_pdata->adc_1bit_rpt =
-                       da7219_aad_fw_adc_1bit_rpt(codec, fw_val32);
+                       da7219_aad_fw_adc_1bit_rpt(component, fw_val32);
        else
                aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
 
        return aad_pdata;
 }
 
-static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
+static void da7219_aad_handle_pdata(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct da7219_aad_priv *da7219_aad = da7219->aad;
        struct da7219_pdata *pdata = da7219->pdata;
 
@@ -752,7 +752,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
                                DA7219_MIC_DET_THRESH_SHIFT);
                        mask |= DA7219_MIC_DET_THRESH_MASK;
                }
-               snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, mask, cfg);
+               snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg);
 
                cfg = 0;
                mask = 0;
@@ -787,15 +787,15 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
                                DA7219_JACKDET_REM_DEB_SHIFT);
                        mask |= DA7219_JACKDET_REM_DEB_MASK;
                }
-               snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_2, mask, cfg);
+               snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg);
 
-               snd_soc_write(codec, DA7219_ACCDET_CONFIG_3,
+               snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3,
                              aad_pdata->a_d_btn_thr);
-               snd_soc_write(codec, DA7219_ACCDET_CONFIG_4,
+               snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4,
                              aad_pdata->d_b_btn_thr);
-               snd_soc_write(codec, DA7219_ACCDET_CONFIG_5,
+               snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5,
                              aad_pdata->b_c_btn_thr);
-               snd_soc_write(codec, DA7219_ACCDET_CONFIG_6,
+               snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6,
                              aad_pdata->c_mic_btn_thr);
 
                cfg = 0;
@@ -818,7 +818,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
                               DA7219_ADC_1_BIT_REPEAT_SHIFT);
                        mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
                }
-               snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_7, mask, cfg);
+               snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg);
        }
 }
 
@@ -827,16 +827,16 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
  * Suspend/Resume
  */
 
-void da7219_aad_suspend(struct snd_soc_codec *codec)
+void da7219_aad_suspend(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct da7219_aad_priv *da7219_aad = da7219->aad;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        u8 micbias_ctrl;
 
        if (da7219_aad->jack) {
                /* Disable jack detection during suspend */
-               snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+               snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
                                    DA7219_ACCDET_EN_MASK, 0);
 
                /*
@@ -846,7 +846,7 @@ void da7219_aad_suspend(struct snd_soc_codec *codec)
                 * suspend then this will be dealt with through the IRQ handler.
                 */
                if (da7219_aad->jack_inserted) {
-                       micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
+                       micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
                        if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
                                snd_soc_dapm_disable_pin(dapm, "Mic Bias");
                                snd_soc_dapm_sync(dapm);
@@ -856,11 +856,11 @@ void da7219_aad_suspend(struct snd_soc_codec *codec)
        }
 }
 
-void da7219_aad_resume(struct snd_soc_codec *codec)
+void da7219_aad_resume(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct da7219_aad_priv *da7219_aad = da7219->aad;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (da7219_aad->jack) {
                /* Re-enable micbias if previously enabled for 4-pole jack */
@@ -872,7 +872,7 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
                }
 
                /* Re-enable jack detection */
-               snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+               snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
                                    DA7219_ACCDET_EN_MASK,
                                    DA7219_ACCDET_EN_MASK);
        }
@@ -883,28 +883,28 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
  * Init/Exit
  */
 
-int da7219_aad_init(struct snd_soc_codec *codec)
+int da7219_aad_init(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct da7219_aad_priv *da7219_aad;
        u8 mask[DA7219_AAD_IRQ_REG_MAX];
        int ret;
 
-       da7219_aad = devm_kzalloc(codec->dev, sizeof(*da7219_aad), GFP_KERNEL);
+       da7219_aad = devm_kzalloc(component->dev, sizeof(*da7219_aad), GFP_KERNEL);
        if (!da7219_aad)
                return -ENOMEM;
 
        da7219->aad = da7219_aad;
-       da7219_aad->codec = codec;
+       da7219_aad->component = component;
 
        /* Handle any DT/ACPI/platform data */
        if (da7219->pdata && !da7219->pdata->aad_pdata)
-               da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(codec);
+               da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(component);
 
-       da7219_aad_handle_pdata(codec);
+       da7219_aad_handle_pdata(component);
 
        /* Disable button detection */
-       snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
+       snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
                            DA7219_BUTTON_CONFIG_MASK, 0);
 
        INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
@@ -915,7 +915,7 @@ int da7219_aad_init(struct snd_soc_codec *codec)
                                   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                   "da7219-aad", da7219_aad);
        if (ret) {
-               dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
+               dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
                return ret;
        }
 
@@ -928,9 +928,9 @@ int da7219_aad_init(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(da7219_aad_init);
 
-void da7219_aad_exit(struct snd_soc_codec *codec)
+void da7219_aad_exit(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct da7219_aad_priv *da7219_aad = da7219->aad;
        u8 mask[DA7219_AAD_IRQ_REG_MAX];
 
index 117a3d7ccd31c2e772b7eeae29e8d5df79465b4f..b9c4a27e8e61df5cecd6ce0d36d4e94988257733 100644 (file)
@@ -189,7 +189,7 @@ enum da7219_aad_event_regs {
 
 /* Private data */
 struct da7219_aad_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        int irq;
 
        u8 micbias_pulse_lvl;
@@ -206,14 +206,14 @@ struct da7219_aad_priv {
 };
 
 /* AAD control */
-void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 /* Suspend/Resume */
-void da7219_aad_suspend(struct snd_soc_codec *codec);
-void da7219_aad_resume(struct snd_soc_codec *codec);
+void da7219_aad_suspend(struct snd_soc_component *component);
+void da7219_aad_resume(struct snd_soc_component *component);
 
 /* Init/Exit */
-int da7219_aad_init(struct snd_soc_codec *codec);
-void da7219_aad_exit(struct snd_soc_codec *codec);
+int da7219_aad_init(struct snd_soc_component *component);
+void da7219_aad_exit(struct snd_soc_component *component);
 
 #endif /* __DA7219_AAD_H */
index 6f088536df32ea89014abffb112c4dfefe357fe0..980a6a8bf56d38c2c54d928d3b901c76e20c66db 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <linux/acpi.h>
 #include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/i2c.h>
 #include <linux/of_device.h>
 #include <linux/property.h>
@@ -256,8 +258,8 @@ static const struct soc_enum da7219_cp_track_mode =
 static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&da7219->ctrl_lock);
@@ -270,8 +272,8 @@ static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
 static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&da7219->ctrl_lock);
@@ -284,8 +286,8 @@ static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
 static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&da7219->ctrl_lock);
@@ -298,8 +300,8 @@ static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
 static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&da7219->ctrl_lock);
@@ -310,55 +312,55 @@ static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
 }
 
 /* ALC */
-static void da7219_alc_calib(struct snd_soc_codec *codec)
+static void da7219_alc_calib(struct snd_soc_component *component)
 {
        u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl;
 
        /* Save current state of mic control register */
-       mic_ctrl = snd_soc_read(codec, DA7219_MIC_1_CTRL);
+       mic_ctrl = snd_soc_component_read32(component, DA7219_MIC_1_CTRL);
 
        /* Save current state of input mixer control register */
-       mixin_ctrl = snd_soc_read(codec, DA7219_MIXIN_L_CTRL);
+       mixin_ctrl = snd_soc_component_read32(component, DA7219_MIXIN_L_CTRL);
 
        /* Save current state of input ADC control register */
-       adc_ctrl = snd_soc_read(codec, DA7219_ADC_L_CTRL);
+       adc_ctrl = snd_soc_component_read32(component, DA7219_ADC_L_CTRL);
 
        /* Enable then Mute MIC PGAs */
-       snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
                            DA7219_MIC_1_AMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_MIC_1_CTRL,
+       snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL,
                            DA7219_MIC_1_AMP_MUTE_EN_MASK,
                            DA7219_MIC_1_AMP_MUTE_EN_MASK);
 
        /* Enable input mixers unmuted */
-       snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL,
                            DA7219_MIXIN_L_AMP_EN_MASK |
                            DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
                            DA7219_MIXIN_L_AMP_EN_MASK);
 
        /* Enable input filters unmuted */
-       snd_soc_update_bits(codec, DA7219_ADC_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL,
                            DA7219_ADC_L_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK,
                            DA7219_ADC_L_EN_MASK);
 
        /* Perform auto calibration */
-       snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
+       snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
                            DA7219_ALC_AUTO_CALIB_EN_MASK,
                            DA7219_ALC_AUTO_CALIB_EN_MASK);
        do {
-               calib_ctrl = snd_soc_read(codec, DA7219_ALC_CTRL1);
+               calib_ctrl = snd_soc_component_read32(component, DA7219_ALC_CTRL1);
        } while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK);
 
        /* If auto calibration fails, disable DC offset, hybrid ALC */
        if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
-               dev_warn(codec->dev,
+               dev_warn(component->dev,
                         "ALC auto calibration failed with overflow\n");
-               snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
+               snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
                                    DA7219_ALC_OFFSET_EN_MASK |
                                    DA7219_ALC_SYNC_MODE_MASK, 0);
        } else {
                /* Enable DC offset cancellation, hybrid mode */
-               snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
+               snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
                                    DA7219_ALC_OFFSET_EN_MASK |
                                    DA7219_ALC_SYNC_MODE_MASK,
                                    DA7219_ALC_OFFSET_EN_MASK |
@@ -366,20 +368,20 @@ static void da7219_alc_calib(struct snd_soc_codec *codec)
        }
 
        /* Restore input filter control register to original state */
-       snd_soc_write(codec, DA7219_ADC_L_CTRL, adc_ctrl);
+       snd_soc_component_write(component, DA7219_ADC_L_CTRL, adc_ctrl);
 
        /* Restore input mixer control registers to original state */
-       snd_soc_write(codec, DA7219_MIXIN_L_CTRL, mixin_ctrl);
+       snd_soc_component_write(component, DA7219_MIXIN_L_CTRL, mixin_ctrl);
 
        /* Restore MIC control registers to original states */
-       snd_soc_write(codec, DA7219_MIC_1_CTRL, mic_ctrl);
+       snd_soc_component_write(component, DA7219_MIC_1_CTRL, mic_ctrl);
 }
 
 static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_soc_put_volsw(kcontrol, ucontrol);
@@ -389,7 +391,7 @@ static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
         * make sure calibrated offsets are updated.
         */
        if ((ret == 1) && (da7219->alc_en))
-               da7219_alc_calib(codec);
+               da7219_alc_calib(component);
 
        return ret;
 }
@@ -397,13 +399,13 @@ static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
 static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
 
        /* Force ALC offset calibration if enabling ALC */
        if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
-               da7219_alc_calib(codec);
+               da7219_alc_calib(component);
                da7219->alc_en = true;
        } else {
                da7219->alc_en = false;
@@ -416,8 +418,8 @@ static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
 static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mixer_ctrl =
                (struct soc_mixer_control *) kcontrol->private_value;
        unsigned int reg = mixer_ctrl->reg;
@@ -443,8 +445,8 @@ static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
 static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mixer_ctrl =
                (struct soc_mixer_control *) kcontrol->private_value;
        unsigned int reg = mixer_ctrl->reg;
@@ -769,32 +771,43 @@ static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls[] = {
 static int da7219_dai_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        u8 pll_ctrl, pll_status;
-       int i = 0;
+       int i = 0, ret;
        bool srm_lock = false;
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               if (da7219->master)
+               if (da7219->master) {
                        /* Enable DAI clks for master mode */
-                       snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
-                                           DA7219_DAI_CLK_EN_MASK,
-                                           DA7219_DAI_CLK_EN_MASK);
+                       if (da7219->dai_clks) {
+                               ret = clk_prepare_enable(da7219->dai_clks);
+                               if (ret) {
+                                       dev_err(component->dev,
+                                               "Failed to enable dai_clks\n");
+                                       return ret;
+                               }
+                       } else {
+                               snd_soc_component_update_bits(component,
+                                                             DA7219_DAI_CLK_MODE,
+                                                             DA7219_DAI_CLK_EN_MASK,
+                                                             DA7219_DAI_CLK_EN_MASK);
+                       }
+               }
 
                /* PC synchronised to DAI */
-               snd_soc_update_bits(codec, DA7219_PC_COUNT,
+               snd_soc_component_update_bits(component, DA7219_PC_COUNT,
                                    DA7219_PC_FREERUN_MASK, 0);
 
                /* Slave mode, if SRM not enabled no need for status checks */
-               pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
+               pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL);
                if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM)
                        return 0;
 
                /* Check SRM has locked */
                do {
-                       pll_status = snd_soc_read(codec, DA7219_PLL_SRM_STS);
+                       pll_status = snd_soc_component_read32(component, DA7219_PLL_SRM_STS);
                        if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) {
                                srm_lock = true;
                        } else {
@@ -804,19 +817,26 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
                } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
 
                if (!srm_lock)
-                       dev_warn(codec->dev, "SRM failed to lock\n");
+                       dev_warn(component->dev, "SRM failed to lock\n");
 
                return 0;
        case SND_SOC_DAPM_POST_PMD:
                /* PC free-running */
-               snd_soc_update_bits(codec, DA7219_PC_COUNT,
+               snd_soc_component_update_bits(component, DA7219_PC_COUNT,
                                    DA7219_PC_FREERUN_MASK,
                                    DA7219_PC_FREERUN_MASK);
 
                /* Disable DAI clks if in master mode */
-               if (da7219->master)
-                       snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
-                                           DA7219_DAI_CLK_EN_MASK, 0);
+               if (da7219->master) {
+                       if (da7219->dai_clks)
+                               clk_disable_unprepare(da7219->dai_clks);
+                       else
+                               snd_soc_component_update_bits(component,
+                                                             DA7219_DAI_CLK_MODE,
+                                                             DA7219_DAI_CLK_EN_MASK,
+                                                             0);
+               }
+
                return 0;
        default:
                return -EINVAL;
@@ -841,7 +861,7 @@ static int da7219_settling_event(struct snd_soc_dapm_widget *w,
 static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        u8 hp_ctrl, min_gain_mask;
 
        switch (w->reg) {
@@ -860,7 +880,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_PRE_PMD:
                /* Enable minimum gain on HP to avoid pops */
-               snd_soc_update_bits(codec, hp_ctrl, min_gain_mask,
+               snd_soc_component_update_bits(component, hp_ctrl, min_gain_mask,
                                    min_gain_mask);
 
                msleep(DA7219_MIN_GAIN_DELAY);
@@ -868,7 +888,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
                break;
        case SND_SOC_DAPM_POST_PMU:
                /* Remove minimum gain on HP */
-               snd_soc_update_bits(codec, hp_ctrl, min_gain_mask, 0);
+               snd_soc_component_update_bits(component, hp_ctrl, min_gain_mask, 0);
 
                break;
        }
@@ -879,22 +899,22 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
 static int da7219_gain_ramp_event(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
        case SND_SOC_DAPM_PRE_PMD:
                /* Ensure nominal gain ramping for DAPM sequence */
                da7219->gain_ramp_ctrl =
-                       snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
-               snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
+                       snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
+               snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
                              DA7219_GAIN_RAMP_RATE_NOMINAL);
                break;
        case SND_SOC_DAPM_POST_PMU:
        case SND_SOC_DAPM_POST_PMD:
                /* Restore previous gain ramp settings */
-               snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
+               snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
                              da7219->gain_ramp_ctrl);
                break;
        }
@@ -1116,8 +1136,8 @@ static const struct snd_soc_dapm_route da7219_audio_map[] = {
 static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
@@ -1133,12 +1153,12 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
        switch (clk_id) {
        case DA7219_CLKSRC_MCLK_SQR:
-               snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
                                    DA7219_PLL_MCLK_SQR_EN_MASK,
                                    DA7219_PLL_MCLK_SQR_EN_MASK);
                break;
        case DA7219_CLKSRC_MCLK:
-               snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
                                    DA7219_PLL_MCLK_SQR_EN_MASK, 0);
                break;
        default:
@@ -1167,9 +1187,9 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
+int da7219_set_pll(struct snd_soc_component *component, int source, unsigned int fout)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
        u8 pll_ctrl, indiv_bits, indiv;
        u8 pll_frac_top, pll_frac_bot, pll_integer;
@@ -1178,7 +1198,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 
        /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
        if (da7219->mclk_rate < 2000000) {
-               dev_err(codec->dev, "PLL input clock %d below valid range\n",
+               dev_err(component->dev, "PLL input clock %d below valid range\n",
                        da7219->mclk_rate);
                return -EINVAL;
        } else if (da7219->mclk_rate <= 4500000) {
@@ -1197,7 +1217,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
                indiv_bits = DA7219_PLL_INDIV_36_TO_54_MHZ;
                indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL;
        } else {
-               dev_err(codec->dev, "PLL input clock %d above valid range\n",
+               dev_err(component->dev, "PLL input clock %d above valid range\n",
                        da7219->mclk_rate);
                return -EINVAL;
        }
@@ -1208,7 +1228,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
        switch (source) {
        case DA7219_SYSCLK_MCLK:
                pll_ctrl |= DA7219_PLL_MODE_BYPASS;
-               snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
                                    DA7219_PLL_INDIV_MASK |
                                    DA7219_PLL_MODE_MASK, pll_ctrl);
                return 0;
@@ -1219,7 +1239,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
                pll_ctrl |= DA7219_PLL_MODE_SRM;
                break;
        default:
-               dev_err(codec->dev, "Invalid PLL config\n");
+               dev_err(component->dev, "Invalid PLL config\n");
                return -EINVAL;
        }
 
@@ -1231,10 +1251,10 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
        pll_frac_bot = (frac_div) & DA7219_BYTE_MASK;
 
        /* Write PLL config & dividers */
-       snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top);
-       snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot);
-       snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer);
-       snd_soc_update_bits(codec, DA7219_PLL_CTRL,
+       snd_soc_component_write(component, DA7219_PLL_FRAC_TOP, pll_frac_top);
+       snd_soc_component_write(component, DA7219_PLL_FRAC_BOT, pll_frac_bot);
+       snd_soc_component_write(component, DA7219_PLL_INTEGER, pll_integer);
+       snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
                            DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK,
                            pll_ctrl);
 
@@ -1244,12 +1264,12 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
 static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int fref, unsigned int fout)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&da7219->pll_lock);
-       ret = da7219_set_pll(codec, source, fout);
+       ret = da7219_set_pll(component, source, fout);
        mutex_unlock(&da7219->pll_lock);
 
        return ret;
@@ -1257,8 +1277,8 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 
 static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        u8 dai_clk_mode = 0, dai_ctrl = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1335,11 +1355,11 @@ static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        /* By default 64 BCLKs per WCLK is supported */
        dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64;
 
-       snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
+       snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
                            DA7219_DAI_BCLKS_PER_WCLK_MASK |
                            DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
                            dai_clk_mode);
-       snd_soc_update_bits(codec, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
+       snd_soc_component_update_bits(component, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
                            dai_ctrl);
 
        return 0;
@@ -1349,18 +1369,18 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
                                   unsigned int tx_mask, unsigned int rx_mask,
                                   int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        u8 dai_bclks_per_wclk;
        u16 offset;
        u32 frame_size;
 
        /* No channels enabled so disable TDM, revert to 64-bit frames */
        if (!tx_mask) {
-               snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
+               snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
                                    DA7219_DAI_TDM_CH_EN_MASK |
                                    DA7219_DAI_TDM_MODE_EN_MASK, 0);
-               snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
+               snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
                                    DA7219_DAI_BCLKS_PER_WCLK_MASK,
                                    DA7219_DAI_BCLKS_PER_WCLK_64);
                return 0;
@@ -1368,14 +1388,14 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
        /* Check we have valid slots */
        if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
-               dev_err(codec->dev, "Invalid number of slots, max = %d\n",
+               dev_err(component->dev, "Invalid number of slots, max = %d\n",
                        DA7219_DAI_TDM_MAX_SLOTS);
                return -EINVAL;
        }
 
        /* Check we have a valid offset given */
        if (rx_mask > DA7219_DAI_OFFSET_MAX) {
-               dev_err(codec->dev, "Invalid slot offset, max = %d\n",
+               dev_err(component->dev, "Invalid slot offset, max = %d\n",
                        DA7219_DAI_OFFSET_MAX);
                return -EINVAL;
        }
@@ -1396,11 +1416,11 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
                dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
                break;
        default:
-               dev_err(codec->dev, "Invalid frame size %d\n", frame_size);
+               dev_err(component->dev, "Invalid frame size %d\n", frame_size);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
+       snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
                            DA7219_DAI_BCLKS_PER_WCLK_MASK,
                            dai_bclks_per_wclk);
 
@@ -1408,7 +1428,7 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
        regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
                          &offset, sizeof(offset));
 
-       snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
+       snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
                            DA7219_DAI_TDM_CH_EN_MASK |
                            DA7219_DAI_TDM_MODE_EN_MASK,
                            (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
@@ -1421,7 +1441,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 dai_ctrl = 0, fs;
        unsigned int channels;
 
@@ -1444,7 +1464,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
 
        channels = params_channels(params);
        if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Invalid number of channels, only 1 to %d supported\n",
                        DA7219_DAI_CH_NUM_MAX);
                return -EINVAL;
@@ -1489,11 +1509,11 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, DA7219_DAI_CTRL,
+       snd_soc_component_update_bits(component, DA7219_DAI_CTRL,
                            DA7219_DAI_WORD_LENGTH_MASK |
                            DA7219_DAI_CH_NUM_MASK,
                            dai_ctrl);
-       snd_soc_write(codec, DA7219_SR, fs);
+       snd_soc_component_write(component, DA7219_SR, fs);
 
        return 0;
 }
@@ -1585,9 +1605,9 @@ static enum da7219_mic_amp_in_sel
        }
 }
 
-static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
+static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_component *component)
 {
-       struct device *dev = codec->dev;
+       struct device *dev = component->dev;
        struct da7219_pdata *pdata;
        const char *of_str;
        u32 of_val32;
@@ -1598,6 +1618,12 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
 
        pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source");
 
+       pdata->dai_clks_name = "da7219-dai-clks";
+       if (device_property_read_string(dev, "clock-output-names",
+                                       &pdata->dai_clks_name))
+               dev_warn(dev, "Using default clk name: %s\n",
+                        pdata->dai_clks_name);
+
        if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0)
                pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32);
        else
@@ -1616,10 +1642,10 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
  * Codec driver functions
  */
 
-static int da7219_set_bias_level(struct snd_soc_codec *codec,
+static int da7219_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1627,11 +1653,11 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_PREPARE:
                /* Enable MCLK for transition to ON state */
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
                        if (da7219->mclk) {
                                ret = clk_prepare_enable(da7219->mclk);
                                if (ret) {
-                                       dev_err(codec->dev,
+                                       dev_err(component->dev,
                                                "Failed to enable mclk\n");
                                        return ret;
                                }
@@ -1640,13 +1666,13 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
 
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        /* Master bias */
-                       snd_soc_update_bits(codec, DA7219_REFERENCES,
+                       snd_soc_component_update_bits(component, DA7219_REFERENCES,
                                            DA7219_BIAS_EN_MASK,
                                            DA7219_BIAS_EN_MASK);
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
                        /* Remove MCLK */
                        if (da7219->mclk)
                                clk_disable_unprepare(da7219->mclk);
@@ -1655,7 +1681,7 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_OFF:
                /* Only disable master bias if we're not a wake-up source */
                if (!da7219->wakeup_source)
-                       snd_soc_update_bits(codec, DA7219_REFERENCES,
+                       snd_soc_component_update_bits(component, DA7219_REFERENCES,
                                            DA7219_BIAS_EN_MASK, 0);
 
                break;
@@ -1670,9 +1696,9 @@ static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = {
        [DA7219_SUPPLY_VDDIO] = "VDDIO",
 };
 
-static int da7219_handle_supplies(struct snd_soc_codec *codec)
+static int da7219_handle_supplies(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct regulator *vddio;
        u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
        int i, ret;
@@ -1681,10 +1707,10 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
        for (i = 0; i < DA7219_NUM_SUPPLIES; ++i)
                da7219->supplies[i].supply = da7219_supply_names[i];
 
-       ret = devm_regulator_bulk_get(codec->dev, DA7219_NUM_SUPPLIES,
+       ret = devm_regulator_bulk_get(component->dev, DA7219_NUM_SUPPLIES,
                                      da7219->supplies);
        if (ret) {
-               dev_err(codec->dev, "Failed to get supplies");
+               dev_err(component->dev, "Failed to get supplies");
                return ret;
        }
 
@@ -1692,29 +1718,111 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
        vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
        ret = regulator_get_voltage(vddio);
        if (ret < 1200000)
-               dev_warn(codec->dev, "Invalid VDDIO voltage\n");
+               dev_warn(component->dev, "Invalid VDDIO voltage\n");
        else if (ret < 2800000)
                io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
 
        /* Enable main supplies */
        ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
        if (ret) {
-               dev_err(codec->dev, "Failed to enable supplies");
+               dev_err(component->dev, "Failed to enable supplies");
                return ret;
        }
 
        /* Ensure device in active mode */
-       snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
+       snd_soc_component_write(component, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
 
        /* Update IO voltage level range */
-       snd_soc_write(codec, DA7219_IO_CTRL, io_voltage_lvl);
+       snd_soc_component_write(component, DA7219_IO_CTRL, io_voltage_lvl);
 
        return 0;
 }
 
-static void da7219_handle_pdata(struct snd_soc_codec *codec)
+#ifdef CONFIG_COMMON_CLK
+static int da7219_dai_clks_prepare(struct clk_hw *hw)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 =
+               container_of(hw, struct da7219_priv, dai_clks_hw);
+       struct snd_soc_component *component = da7219->aad->component;
+
+       snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
+                                     DA7219_DAI_CLK_EN_MASK,
+                                     DA7219_DAI_CLK_EN_MASK);
+
+       return 0;
+}
+
+static void da7219_dai_clks_unprepare(struct clk_hw *hw)
+{
+       struct da7219_priv *da7219 =
+               container_of(hw, struct da7219_priv, dai_clks_hw);
+       struct snd_soc_component *component = da7219->aad->component;
+
+       snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
+                                     DA7219_DAI_CLK_EN_MASK, 0);
+}
+
+static int da7219_dai_clks_is_prepared(struct clk_hw *hw)
+{
+       struct da7219_priv *da7219 =
+               container_of(hw, struct da7219_priv, dai_clks_hw);
+       struct snd_soc_component *component = da7219->aad->component;
+       u8 clk_reg;
+
+       clk_reg = snd_soc_component_read32(component, DA7219_DAI_CLK_MODE);
+
+       return !!(clk_reg & DA7219_DAI_CLK_EN_MASK);
+}
+
+static const struct clk_ops da7219_dai_clks_ops = {
+       .prepare = da7219_dai_clks_prepare,
+       .unprepare = da7219_dai_clks_unprepare,
+       .is_prepared = da7219_dai_clks_is_prepared,
+};
+
+static void da7219_register_dai_clks(struct snd_soc_component *component)
+{
+       struct device *dev = component->dev;
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
+       struct da7219_pdata *pdata = da7219->pdata;
+       struct clk_init_data init = {};
+       struct clk *dai_clks;
+       struct clk_lookup *dai_clks_lookup;
+
+       init.parent_names = NULL;
+       init.num_parents = 0;
+       init.name = pdata->dai_clks_name;
+       init.ops = &da7219_dai_clks_ops;
+       da7219->dai_clks_hw.init = &init;
+
+       dai_clks = devm_clk_register(dev, &da7219->dai_clks_hw);
+       if (IS_ERR(dai_clks)) {
+               dev_warn(dev, "Failed to register DAI clocks: %ld\n",
+                        PTR_ERR(dai_clks));
+               return;
+       }
+       da7219->dai_clks = dai_clks;
+
+       /* If we're using DT, then register as provider accordingly */
+       if (dev->of_node) {
+               devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+                                           &da7219->dai_clks_hw);
+       } else {
+               dai_clks_lookup = clkdev_create(dai_clks, pdata->dai_clks_name,
+                                               "%s", dev_name(dev));
+               if (!dai_clks_lookup)
+                       dev_warn(dev, "Failed to create DAI clkdev");
+               else
+                       da7219->dai_clks_lookup = dai_clks_lookup;
+       }
+}
+#else
+static inline void da7219_register_dai_clks(struct snd_soc_component *component) {}
+#endif /* CONFIG_COMMON_CLK */
+
+static void da7219_handle_pdata(struct snd_soc_component *component)
+{
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        struct da7219_pdata *pdata = da7219->pdata;
 
        if (pdata) {
@@ -1722,6 +1830,8 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
 
                da7219->wakeup_source = pdata->wakeup_source;
 
+               da7219_register_dai_clks(component);
+
                /* Mic Bias voltages */
                switch (pdata->micbias_lvl) {
                case DA7219_MICBIAS_1_6V:
@@ -1735,14 +1845,14 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
                        break;
                }
 
-               snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl);
+               snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_lvl);
 
                /* Mic */
                switch (pdata->mic_amp_in_sel) {
                case DA7219_MIC_AMP_IN_SEL_DIFF:
                case DA7219_MIC_AMP_IN_SEL_SE_P:
                case DA7219_MIC_AMP_IN_SEL_SE_N:
-                       snd_soc_write(codec, DA7219_MIC_1_SELECT,
+                       snd_soc_component_write(component, DA7219_MIC_1_SELECT,
                                      pdata->mic_amp_in_sel);
                        break;
                }
@@ -1753,9 +1863,9 @@ static struct reg_sequence da7219_rev_aa_patch[] = {
        { DA7219_REFERENCES, 0x08 },
 };
 
-static int da7219_probe(struct snd_soc_codec *codec)
+static int da7219_probe(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
        unsigned int rev;
        int ret;
 
@@ -1763,13 +1873,13 @@ static int da7219_probe(struct snd_soc_codec *codec)
        mutex_init(&da7219->pll_lock);
 
        /* Regulator configuration */
-       ret = da7219_handle_supplies(codec);
+       ret = da7219_handle_supplies(component);
        if (ret)
                return ret;
 
        ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev);
        if (ret) {
-               dev_err(codec->dev, "Failed to read chip revision: %d\n", ret);
+               dev_err(component->dev, "Failed to read chip revision: %d\n", ret);
                goto err_disable_reg;
        }
 
@@ -1778,7 +1888,7 @@ static int da7219_probe(struct snd_soc_codec *codec)
                ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch,
                                            ARRAY_SIZE(da7219_rev_aa_patch));
                if (ret) {
-                       dev_err(codec->dev, "Failed to register AA patch: %d\n",
+                       dev_err(component->dev, "Failed to register AA patch: %d\n",
                                ret);
                        goto err_disable_reg;
                }
@@ -1788,14 +1898,14 @@ static int da7219_probe(struct snd_soc_codec *codec)
        }
 
        /* Handle DT/ACPI/Platform data */
-       da7219->pdata = dev_get_platdata(codec->dev);
+       da7219->pdata = dev_get_platdata(component->dev);
        if (!da7219->pdata)
-               da7219->pdata = da7219_fw_to_pdata(codec);
+               da7219->pdata = da7219_fw_to_pdata(component);
 
-       da7219_handle_pdata(codec);
+       da7219_handle_pdata(component);
 
        /* Check if MCLK provided */
-       da7219->mclk = devm_clk_get(codec->dev, "mclk");
+       da7219->mclk = devm_clk_get(component->dev, "mclk");
        if (IS_ERR(da7219->mclk)) {
                if (PTR_ERR(da7219->mclk) != -ENOENT) {
                        ret = PTR_ERR(da7219->mclk);
@@ -1806,39 +1916,39 @@ static int da7219_probe(struct snd_soc_codec *codec)
        }
 
        /* Default PC counter to free-running */
-       snd_soc_update_bits(codec, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
+       snd_soc_component_update_bits(component, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
                            DA7219_PC_FREERUN_MASK);
 
        /* Default gain ramping */
-       snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL,
                            DA7219_MIXIN_L_AMP_RAMP_EN_MASK,
                            DA7219_MIXIN_L_AMP_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
                            DA7219_ADC_L_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
                            DA7219_DAC_L_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
+       snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
                            DA7219_DAC_R_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
                            DA7219_HP_L_AMP_RAMP_EN_MASK,
                            DA7219_HP_L_AMP_RAMP_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
                            DA7219_HP_R_AMP_RAMP_EN_MASK,
                            DA7219_HP_R_AMP_RAMP_EN_MASK);
 
        /* Default minimum gain on HP to avoid pops during DAPM sequencing */
-       snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
                            DA7219_HP_L_AMP_MIN_GAIN_EN_MASK,
                            DA7219_HP_L_AMP_MIN_GAIN_EN_MASK);
-       snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
                            DA7219_HP_R_AMP_MIN_GAIN_EN_MASK,
                            DA7219_HP_R_AMP_MIN_GAIN_EN_MASK);
 
        /* Default infinite tone gen, start/stop by Kcontrol */
-       snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
+       snd_soc_component_write(component, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
 
        /* Initialise AAD block */
-       ret = da7219_aad_init(codec);
+       ret = da7219_aad_init(component);
        if (ret)
                goto err_disable_reg;
 
@@ -1850,39 +1960,44 @@ err_disable_reg:
        return ret;
 }
 
-static int da7219_remove(struct snd_soc_codec *codec)
+static void da7219_remove(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
-       da7219_aad_exit(codec);
+       da7219_aad_exit(component);
+
+#ifdef CONFIG_COMMON_CLK
+       if (da7219->dai_clks_lookup)
+               clkdev_drop(da7219->dai_clks_lookup);
+#endif
 
        /* Supplies */
-       return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
+       regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
 }
 
 #ifdef CONFIG_PM
-static int da7219_suspend(struct snd_soc_codec *codec)
+static int da7219_suspend(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
        /* Suspend AAD if we're not a wake-up source */
        if (!da7219->wakeup_source)
-               da7219_aad_suspend(codec);
+               da7219_aad_suspend(component);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
        return 0;
 }
 
-static int da7219_resume(struct snd_soc_codec *codec)
+static int da7219_resume(struct snd_soc_component *component)
 {
-       struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
+       struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        /* Resume AAD if previously suspended */
        if (!da7219->wakeup_source)
-               da7219_aad_resume(codec);
+               da7219_aad_resume(component);
 
        return 0;
 }
@@ -1891,21 +2006,22 @@ static int da7219_resume(struct snd_soc_codec *codec)
 #define da7219_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_da7219 = {
+static const struct snd_soc_component_driver soc_component_dev_da7219 = {
        .probe                  = da7219_probe,
        .remove                 = da7219_remove,
        .suspend                = da7219_suspend,
        .resume                 = da7219_resume,
        .set_bias_level         = da7219_set_bias_level,
-
-       .component_driver = {
-               .controls               = da7219_snd_controls,
-               .num_controls           = ARRAY_SIZE(da7219_snd_controls),
-               .dapm_widgets           = da7219_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(da7219_dapm_widgets),
-               .dapm_routes            = da7219_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(da7219_audio_map),
-       },
+       .controls               = da7219_snd_controls,
+       .num_controls           = ARRAY_SIZE(da7219_snd_controls),
+       .dapm_widgets           = da7219_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(da7219_dapm_widgets),
+       .dapm_routes            = da7219_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(da7219_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 
@@ -2090,7 +2206,7 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
                }
        }
 
-       /* Soft reset codec */
+       /* Soft reset component */
        regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
                          DA7219_ACCDET_EN_MASK, 0);
        regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
@@ -2101,10 +2217,11 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
 
        regcache_cache_bypass(da7219->regmap, false);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_da7219,
                                     &da7219_dai, 1);
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register da7219 codec: %d\n",
+               dev_err(&i2c->dev, "Failed to register da7219 component: %d\n",
                        ret);
        }
        return ret;
@@ -2112,7 +2229,6 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
 
 static int da7219_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index 8d6c3c8c802639f8e1dc8b42175806b8c5c0e28d..1b00023e33cd6761c2fac0c851eb040933c4ce74 100644 (file)
@@ -14,6 +14,9 @@
 #ifndef __DA7219_H
 #define __DA7219_H
 
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <sound/da7219.h>
@@ -813,6 +816,12 @@ struct da7219_priv {
        struct mutex ctrl_lock;
        struct mutex pll_lock;
 
+#ifdef CONFIG_COMMON_CLK
+       struct clk_hw dai_clks_hw;
+#endif
+       struct clk_lookup *dai_clks_lookup;
+       struct clk *dai_clks;
+
        struct clk *mclk;
        unsigned int mclk_rate;
        int clk_src;
@@ -822,6 +831,6 @@ struct da7219_priv {
        u8 gain_ramp_ctrl;
 };
 
-int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout);
+int da7219_set_pll(struct snd_soc_component *component, int source, unsigned int fout);
 
 #endif /* __DA7219_H */
index 83db4d23c90b9590eef0723562c50f52ce0c3ee2..de275df8f4eeaa2fca1785ee87bd0e60da37e39b 100644 (file)
@@ -168,7 +168,7 @@ static const struct reg_default da732x_reg_cache[] = {
        { DA732X_REG_UNLOCK             , 0x00 },
 };
 
-static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
+static inline int da732x_get_input_div(struct snd_soc_component *component, int sysclk)
 {
        int val;
        int ret;
@@ -192,28 +192,28 @@ static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
                return -EINVAL;
        }
 
-       snd_soc_write(codec, DA732X_REG_PLL_CTRL, val);
+       snd_soc_component_write(component, DA732X_REG_PLL_CTRL, val);
 
        return ret;
 }
 
-static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state)
+static void da732x_set_charge_pump(struct snd_soc_component *component, int state)
 {
        switch (state) {
        case DA732X_ENABLE_CP:
-               snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
-               snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
+               snd_soc_component_write(component, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
+               snd_soc_component_write(component, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
                              DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP);
-               snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
+               snd_soc_component_write(component, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
                              DA732X_CP_CTRL_CPVDD1);
-               snd_soc_write(codec, DA732X_REG_CP_CTRL2,
+               snd_soc_component_write(component, DA732X_REG_CP_CTRL2,
                              DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST);
-               snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
+               snd_soc_component_write(component, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
                break;
        case DA732X_DISABLE_CP:
-               snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
-               snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
-               snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
+               snd_soc_component_write(component, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
+               snd_soc_component_write(component, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
+               snd_soc_component_write(component, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
                break;
        default:
                pr_err("Wrong charge pump state\n");
@@ -331,7 +331,7 @@ static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum,
 static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
        unsigned int reg = enum_ctrl->reg;
        unsigned int sel = ucontrol->value.enumerated.item[0];
@@ -351,7 +351,7 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits);
+       snd_soc_component_update_bits(component, reg, DA732X_HPF_MASK, bits);
 
        return 0;
 }
@@ -359,12 +359,12 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
 static int da732x_hpf_get(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
        unsigned int reg = enum_ctrl->reg;
        int val;
 
-       val = snd_soc_read(codec, reg) & DA732X_HPF_MASK;
+       val = snd_soc_component_read32(component, reg) & DA732X_HPF_MASK;
 
        switch (val) {
        case DA732X_HPF_VOICE_EN:
@@ -609,18 +609,18 @@ static const struct snd_kcontrol_new da732x_snd_controls[] = {
 static int da732x_adc_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                switch (w->reg) {
                case DA732X_REG_ADC1_PD:
-                       snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+                       snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
                                            DA732X_ADCA_BB_CLK_EN,
                                            DA732X_ADCA_BB_CLK_EN);
                        break;
                case DA732X_REG_ADC2_PD:
-                       snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+                       snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
                                            DA732X_ADCC_BB_CLK_EN,
                                            DA732X_ADCC_BB_CLK_EN);
                        break;
@@ -628,24 +628,24 @@ static int da732x_adc_event(struct snd_soc_dapm_widget *w,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
+               snd_soc_component_update_bits(component, w->reg, DA732X_ADC_RST_MASK,
                                    DA732X_ADC_SET_ACT);
-               snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
+               snd_soc_component_update_bits(component, w->reg, DA732X_ADC_PD_MASK,
                                    DA732X_ADC_ON);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
+               snd_soc_component_update_bits(component, w->reg, DA732X_ADC_PD_MASK,
                                    DA732X_ADC_OFF);
-               snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
+               snd_soc_component_update_bits(component, w->reg, DA732X_ADC_RST_MASK,
                                    DA732X_ADC_SET_RST);
 
                switch (w->reg) {
                case DA732X_REG_ADC1_PD:
-                       snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+                       snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
                                            DA732X_ADCA_BB_CLK_EN, 0);
                        break;
                case DA732X_REG_ADC2_PD:
-                       snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
+                       snd_soc_component_update_bits(component, DA732X_REG_CLK_EN3,
                                            DA732X_ADCC_BB_CLK_EN, 0);
                        break;
                default:
@@ -663,16 +663,16 @@ static int da732x_adc_event(struct snd_soc_dapm_widget *w,
 static int da732x_out_pga_event(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                                    (1 << w->shift) | DA732X_OUT_HIZ_EN,
                                    (1 << w->shift) | DA732X_OUT_HIZ_EN);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                                    (1 << w->shift) | DA732X_OUT_HIZ_EN,
                                    (1 << w->shift) | DA732X_OUT_HIZ_DIS);
                break;
@@ -949,7 +949,7 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u32 aif = 0;
        u32 reg_aif;
        u32 fs;
@@ -1011,15 +1011,15 @@ static int da732x_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif);
-       snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
+       snd_soc_component_update_bits(component, reg_aif, DA732X_AIF_WORD_MASK, aif);
+       snd_soc_component_update_bits(component, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
 
        return 0;
 }
 
 static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u32 aif_mclk, pc_count;
        u32 reg_aif1, aif1;
        u32 reg_aif3, aif3;
@@ -1107,29 +1107,29 @@ static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
                return -EINVAL;
        }
 
-       snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk);
-       snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
-       snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV |
+       snd_soc_component_write(component, DA732X_REG_AIF_MCLK, aif_mclk);
+       snd_soc_component_update_bits(component, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
+       snd_soc_component_update_bits(component, reg_aif3, DA732X_AIF_BCLK_INV |
                            DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3);
-       snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count);
+       snd_soc_component_write(component, DA732X_REG_PC_CTRL, pc_count);
 
        return 0;
 }
 
 
 
-static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
+static int da732x_set_dai_pll(struct snd_soc_component *component, int pll_id,
                              int source, unsigned int freq_in,
                              unsigned int freq_out)
 {
-       struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
+       struct da732x_priv *da732x = snd_soc_component_get_drvdata(component);
        int fref, indiv;
        u8 div_lo, div_mid, div_hi;
        u64 frac_div;
 
        /* Disable PLL */
        if (freq_out == 0) {
-               snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
+               snd_soc_component_update_bits(component, DA732X_REG_PLL_CTRL,
                                    DA732X_PLL_EN, 0);
                da732x->pll_en = false;
                return 0;
@@ -1147,17 +1147,17 @@ static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
                case 24576000:
                case 45160000:
                case 49152000:
-                       snd_soc_write(codec, DA732X_REG_PLL_CTRL,
+                       snd_soc_component_write(component, DA732X_REG_PLL_CTRL,
                                      DA732X_PLL_BYPASS);
                        return 0;
                default:
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Cannot use PLL Bypass, invalid SYSCLK rate\n");
                        return -EINVAL;
                }
        }
 
-       indiv = da732x_get_input_div(codec, da732x->sysclk);
+       indiv = da732x_get_input_div(component, da732x->sysclk);
        if (indiv < 0)
                return indiv;
 
@@ -1168,11 +1168,11 @@ static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
        div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK;
        div_lo = (frac_div) & DA732X_U8_MASK;
 
-       snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo);
-       snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid);
-       snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi);
+       snd_soc_component_write(component, DA732X_REG_PLL_DIV_LO, div_lo);
+       snd_soc_component_write(component, DA732X_REG_PLL_DIV_MID, div_mid);
+       snd_soc_component_write(component, DA732X_REG_PLL_DIV_HI, div_hi);
 
-       snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
+       snd_soc_component_update_bits(component, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
                            DA732X_PLL_EN);
 
        da732x->pll_en = true;
@@ -1183,8 +1183,8 @@ static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
 static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                                 unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct da732x_priv *da732x = snd_soc_component_get_drvdata(component);
 
        da732x->sysclk = freq;
 
@@ -1268,21 +1268,21 @@ static const struct regmap_config da732x_regmap = {
 };
 
 
-static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
+static void da732x_dac_offset_adjust(struct snd_soc_component *component)
 {
        u8 offset[DA732X_HP_DACS];
        u8 sign[DA732X_HP_DACS];
        u8 step = DA732X_DAC_OFFSET_STEP;
 
        /* Initialize DAC offset calibration circuits and registers */
-       snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
+       snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFFSET,
                      DA732X_HP_DAC_OFFSET_TRIM_VAL);
-       snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
+       snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFFSET,
                      DA732X_HP_DAC_OFFSET_TRIM_VAL);
-       snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
+       snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFF_CNTL,
                      DA732X_HP_DAC_OFF_CALIBRATION |
                      DA732X_HP_DAC_OFF_SCALE_STEPS);
-       snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
+       snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFF_CNTL,
                      DA732X_HP_DAC_OFF_CALIBRATION |
                      DA732X_HP_DAC_OFF_SCALE_STEPS);
 
@@ -1290,9 +1290,9 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
        msleep(DA732X_WAIT_FOR_STABILIZATION);
 
        /* Check DAC offset sign */
-       sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+       sign[DA732X_HPL_DAC] = (snd_soc_component_read32(component, DA732X_REG_HPL_DAC_OFF_CNTL) &
                                DA732X_HP_DAC_OFF_CNTL_COMPO);
-       sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+       sign[DA732X_HPR_DAC] = (snd_soc_component_read32(component, DA732X_REG_HPR_DAC_OFF_CNTL) &
                                DA732X_HP_DAC_OFF_CNTL_COMPO);
 
        /* Binary search DAC offset values (both channels at once) */
@@ -1302,17 +1302,17 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
        do {
                offset[DA732X_HPL_DAC] |= step;
                offset[DA732X_HPR_DAC] |= step;
-               snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
+               snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFFSET,
                              ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
-               snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
+               snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFFSET,
                              ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
 
                msleep(DA732X_WAIT_FOR_STABILIZATION);
 
-               if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+               if ((snd_soc_component_read32(component, DA732X_REG_HPL_DAC_OFF_CNTL) &
                     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
                        offset[DA732X_HPL_DAC] &= ~step;
-               if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+               if ((snd_soc_component_read32(component, DA732X_REG_HPR_DAC_OFF_CNTL) &
                     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
                        offset[DA732X_HPR_DAC] &= ~step;
 
@@ -1320,19 +1320,19 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
        } while (step);
 
        /* Write final DAC offsets to registers */
-       snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
+       snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFFSET,
                      ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
-       snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
+       snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFFSET,
                      ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
 
        /* End DAC calibration mode */
-       snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
+       snd_soc_component_write(component, DA732X_REG_HPL_DAC_OFF_CNTL,
                DA732X_HP_DAC_OFF_SCALE_STEPS);
-       snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
+       snd_soc_component_write(component, DA732X_REG_HPR_DAC_OFF_CNTL,
                DA732X_HP_DAC_OFF_SCALE_STEPS);
 }
 
-static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
+static void da732x_output_offset_adjust(struct snd_soc_component *component)
 {
        u8 offset[DA732X_HP_AMPS];
        u8 sign[DA732X_HP_AMPS];
@@ -1342,26 +1342,26 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
        offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL;
 
        /* Initialize output offset calibration circuits and registers  */
-       snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
-       snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
-       snd_soc_write(codec, DA732X_REG_HPL,
+       snd_soc_component_write(component, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
+       snd_soc_component_write(component, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
+       snd_soc_component_write(component, DA732X_REG_HPL,
                      DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
-       snd_soc_write(codec, DA732X_REG_HPR,
+       snd_soc_component_write(component, DA732X_REG_HPR,
                      DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
 
        /* Wait for voltage stabilization */
        msleep(DA732X_WAIT_FOR_STABILIZATION);
 
        /* Check output offset sign */
-       sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) &
+       sign[DA732X_HPL_AMP] = snd_soc_component_read32(component, DA732X_REG_HPL) &
                               DA732X_HP_OUT_COMPO;
-       sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) &
+       sign[DA732X_HPR_AMP] = snd_soc_component_read32(component, DA732X_REG_HPR) &
                               DA732X_HP_OUT_COMPO;
 
-       snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
+       snd_soc_component_write(component, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
                      (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
                      DA732X_HP_OUT_EN);
-       snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
+       snd_soc_component_write(component, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
                      (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
                      DA732X_HP_OUT_EN);
 
@@ -1369,17 +1369,17 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
        do {
                offset[DA732X_HPL_AMP] |= step;
                offset[DA732X_HPR_AMP] |= step;
-               snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET,
+               snd_soc_component_write(component, DA732X_REG_HPL_OUT_OFFSET,
                              offset[DA732X_HPL_AMP]);
-               snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET,
+               snd_soc_component_write(component, DA732X_REG_HPR_OUT_OFFSET,
                              offset[DA732X_HPR_AMP]);
 
                msleep(DA732X_WAIT_FOR_STABILIZATION);
 
-               if ((snd_soc_read(codec, DA732X_REG_HPL) &
+               if ((snd_soc_component_read32(component, DA732X_REG_HPL) &
                     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
                        offset[DA732X_HPL_AMP] &= ~step;
-               if ((snd_soc_read(codec, DA732X_REG_HPR) &
+               if ((snd_soc_component_read32(component, DA732X_REG_HPR) &
                     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
                        offset[DA732X_HPR_AMP] &= ~step;
 
@@ -1387,80 +1387,80 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
        } while (step);
 
        /* Write final DAC offsets to registers */
-       snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
-       snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
+       snd_soc_component_write(component, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
+       snd_soc_component_write(component, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
 }
 
-static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec)
+static void da732x_hp_dc_offset_cancellation(struct snd_soc_component *component)
 {
        /* Make sure that we have Soft Mute enabled */
-       snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
+       snd_soc_component_write(component, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
                      DA732X_GAIN_RAMPED | DA732X_16_SAMPLES);
-       snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
+       snd_soc_component_write(component, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
                      DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM |
                      DA732X_DACL_MUTE | DA732X_DACR_MUTE);
-       snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
+       snd_soc_component_write(component, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
                      DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN);
-       snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN |
+       snd_soc_component_write(component, DA732X_REG_HPR, DA732X_HP_OUT_EN |
                      DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN);
 
-       da732x_dac_offset_adjust(codec);
-       da732x_output_offset_adjust(codec);
+       da732x_dac_offset_adjust(component);
+       da732x_output_offset_adjust(component);
 
-       snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
-       snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS);
-       snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS);
+       snd_soc_component_write(component, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
+       snd_soc_component_write(component, DA732X_REG_HPL, DA732X_HP_DIS);
+       snd_soc_component_write(component, DA732X_REG_HPR, DA732X_HP_DIS);
 }
 
-static int da732x_set_bias_level(struct snd_soc_codec *codec,
+static int da732x_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
+       struct da732x_priv *da732x = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
+               snd_soc_component_update_bits(component, DA732X_REG_BIAS_EN,
                                    DA732X_BIAS_BOOST_MASK,
                                    DA732X_BIAS_BOOST_100PC);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Init Codec */
-                       snd_soc_write(codec, DA732X_REG_REF1,
+                       snd_soc_component_write(component, DA732X_REG_REF1,
                                      DA732X_VMID_FASTCHG);
-                       snd_soc_write(codec, DA732X_REG_BIAS_EN,
+                       snd_soc_component_write(component, DA732X_REG_BIAS_EN,
                                      DA732X_BIAS_EN);
 
                        mdelay(DA732X_STARTUP_DELAY);
 
                        /* Disable Fast Charge and enable DAC ref voltage */
-                       snd_soc_write(codec, DA732X_REG_REF1,
+                       snd_soc_component_write(component, DA732X_REG_REF1,
                                      DA732X_REFBUFX2_EN);
 
                        /* Enable bypass DSP routing */
-                       snd_soc_write(codec, DA732X_REG_DATA_ROUTE,
+                       snd_soc_component_write(component, DA732X_REG_DATA_ROUTE,
                                      DA732X_BYPASS_DSP);
 
                        /* Enable Digital subsystem */
-                       snd_soc_write(codec, DA732X_REG_DSP_CTRL,
+                       snd_soc_component_write(component, DA732X_REG_DSP_CTRL,
                                      DA732X_DIGITAL_EN);
 
-                       snd_soc_write(codec, DA732X_REG_SPARE1_OUT,
+                       snd_soc_component_write(component, DA732X_REG_SPARE1_OUT,
                                      DA732X_HP_DRIVER_EN |
                                      DA732X_HP_GATE_LOW |
                                      DA732X_HP_LOOP_GAIN_CTRL);
-                       snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL,
+                       snd_soc_component_write(component, DA732X_REG_HP_LIN1_GNDSEL,
                                      DA732X_HP_OUT_GNDSEL);
 
-                       da732x_set_charge_pump(codec, DA732X_ENABLE_CP);
+                       da732x_set_charge_pump(component, DA732X_ENABLE_CP);
 
-                       snd_soc_write(codec, DA732X_REG_CLK_EN1,
+                       snd_soc_component_write(component, DA732X_REG_CLK_EN1,
                              DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN);
 
                        /* Enable Zero Crossing */
-                       snd_soc_write(codec, DA732X_REG_INP_ZC_EN,
+                       snd_soc_component_write(component, DA732X_REG_INP_ZC_EN,
                                      DA732X_MIC1_PRE_ZC_EN |
                                      DA732X_MIC1_ZC_EN |
                                      DA732X_MIC2_PRE_ZC_EN |
@@ -1469,28 +1469,28 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
                                      DA732X_AUXR_ZC_EN |
                                      DA732X_MIC3_PRE_ZC_EN |
                                      DA732X_MIC3_ZC_EN);
-                       snd_soc_write(codec, DA732X_REG_OUT_ZC_EN,
+                       snd_soc_component_write(component, DA732X_REG_OUT_ZC_EN,
                                      DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN |
                                      DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN |
                                      DA732X_LIN4_ZC_EN);
 
-                       da732x_hp_dc_offset_cancellation(codec);
+                       da732x_hp_dc_offset_cancellation(component);
 
                        regcache_cache_only(da732x->regmap, false);
                        regcache_sync(da732x->regmap);
                } else {
-                       snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
+                       snd_soc_component_update_bits(component, DA732X_REG_BIAS_EN,
                                            DA732X_BIAS_BOOST_MASK,
                                            DA732X_BIAS_BOOST_50PC);
-                       snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
+                       snd_soc_component_update_bits(component, DA732X_REG_PLL_CTRL,
                                            DA732X_PLL_EN, 0);
                        da732x->pll_en = false;
                }
                break;
        case SND_SOC_BIAS_OFF:
                regcache_cache_only(da732x->regmap, true);
-               da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
-               snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
+               da732x_set_charge_pump(component, DA732X_DISABLE_CP);
+               snd_soc_component_update_bits(component, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
                                    DA732X_BIAS_DIS);
                da732x->pll_en = false;
                break;
@@ -1499,17 +1499,19 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da732x = {
+static const struct snd_soc_component_driver soc_component_dev_da732x = {
        .set_bias_level         = da732x_set_bias_level,
-       .component_driver = {
-               .controls               = da732x_snd_controls,
-               .num_controls           = ARRAY_SIZE(da732x_snd_controls),
-               .dapm_widgets           = da732x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(da732x_dapm_widgets),
-               .dapm_routes            = da732x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(da732x_dapm_routes),
-       },
+       .controls               = da732x_snd_controls,
+       .num_controls           = ARRAY_SIZE(da732x_snd_controls),
+       .dapm_widgets           = da732x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(da732x_dapm_widgets),
+       .dapm_routes            = da732x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(da732x_dapm_routes),
        .set_pll                = da732x_set_dai_pll,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int da732x_i2c_probe(struct i2c_client *i2c,
@@ -1543,10 +1545,11 @@ static int da732x_i2c_probe(struct i2c_client *i2c,
                 (reg & DA732X_ID_MAJOR_MASK) >> 4,
                 (reg & DA732X_ID_MINOR_MASK));
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_da732x,
                                     da732x_dai, ARRAY_SIZE(da732x_dai));
        if (ret != 0)
-               dev_err(&i2c->dev, "Failed to register codec.\n");
+               dev_err(&i2c->dev, "Failed to register component.\n");
 
 err:
        return ret;
@@ -1554,8 +1557,6 @@ err:
 
 static int da732x_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
-
        return 0;
 }
 
index bd7faaee5802e619ac25716f1faf7b261ea36fed..afdf90c78884d222eb9089bb8bf70b0819bf414d 100644 (file)
@@ -451,7 +451,7 @@ static const char * const da9055_hold_time_txt[] = {
 static SOC_ENUM_SINGLE_DECL(da9055_hold_time,
                            DA9055_ALC_CTRL3, 0, da9055_hold_time_txt);
 
-static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
+static int da9055_get_alc_data(struct snd_soc_component *component, u8 reg_val)
 {
        int mid_data, top_data;
        int sum = 0;
@@ -460,17 +460,17 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
        for (iteration = 0; iteration < DA9055_ALC_AVG_ITERATIONS;
             iteration++) {
                /* Select the left or right channel and capture data */
-               snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);
+               snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);
 
                /* Select middle 8 bits for read back from data register */
-               snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+               snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL,
                              reg_val | DA9055_ALC_DATA_MIDDLE);
-               mid_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+               mid_data = snd_soc_component_read32(component, DA9055_ALC_CIC_OP_LVL_DATA);
 
                /* Select top 8 bits for read back from data register */
-               snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+               snd_soc_component_write(component, DA9055_ALC_CIC_OP_LVL_CTRL,
                              reg_val | DA9055_ALC_DATA_TOP);
-               top_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+               top_data = snd_soc_component_read32(component, DA9055_ALC_CIC_OP_LVL_DATA);
 
                sum += ((mid_data << 8) | (top_data << 16));
        }
@@ -481,7 +481,7 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
 static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        u8 reg_val, adc_left, adc_right, mic_left, mic_right;
        int avg_left_data, avg_right_data, offset_l, offset_r;
 
@@ -492,31 +492,31 @@ static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
                 */
 
                /* Save current values from Mic control registers */
-               mic_left = snd_soc_read(codec, DA9055_MIC_L_CTRL);
-               mic_right = snd_soc_read(codec, DA9055_MIC_R_CTRL);
+               mic_left = snd_soc_component_read32(component, DA9055_MIC_L_CTRL);
+               mic_right = snd_soc_component_read32(component, DA9055_MIC_R_CTRL);
 
                /* Mute Mic PGA Left and Right */
-               snd_soc_update_bits(codec, DA9055_MIC_L_CTRL,
+               snd_soc_component_update_bits(component, DA9055_MIC_L_CTRL,
                                    DA9055_MIC_L_MUTE_EN, DA9055_MIC_L_MUTE_EN);
-               snd_soc_update_bits(codec, DA9055_MIC_R_CTRL,
+               snd_soc_component_update_bits(component, DA9055_MIC_R_CTRL,
                                    DA9055_MIC_R_MUTE_EN, DA9055_MIC_R_MUTE_EN);
 
                /* Save current values from ADC control registers */
-               adc_left = snd_soc_read(codec, DA9055_ADC_L_CTRL);
-               adc_right = snd_soc_read(codec, DA9055_ADC_R_CTRL);
+               adc_left = snd_soc_component_read32(component, DA9055_ADC_L_CTRL);
+               adc_right = snd_soc_component_read32(component, DA9055_ADC_R_CTRL);
 
                /* Enable ADC Left and Right */
-               snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+               snd_soc_component_update_bits(component, DA9055_ADC_L_CTRL,
                                    DA9055_ADC_L_EN, DA9055_ADC_L_EN);
-               snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+               snd_soc_component_update_bits(component, DA9055_ADC_R_CTRL,
                                    DA9055_ADC_R_EN, DA9055_ADC_R_EN);
 
                /* Calculate average for Left and Right data */
                /* Left Data */
-               avg_left_data = da9055_get_alc_data(codec,
+               avg_left_data = da9055_get_alc_data(component,
                                DA9055_ALC_CIC_OP_CHANNEL_LEFT);
                /* Right Data */
-               avg_right_data = da9055_get_alc_data(codec,
+               avg_right_data = da9055_get_alc_data(component,
                                 DA9055_ALC_CIC_OP_CHANNEL_RIGHT);
 
                /* Calculate DC offset */
@@ -524,22 +524,22 @@ static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
                offset_r = -avg_right_data;
 
                reg_val = (offset_l & DA9055_ALC_OFFSET_15_8) >> 8;
-               snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_L, reg_val);
+               snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2M_L, reg_val);
                reg_val = (offset_l & DA9055_ALC_OFFSET_17_16) >> 16;
-               snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_L, reg_val);
+               snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2U_L, reg_val);
 
                reg_val = (offset_r & DA9055_ALC_OFFSET_15_8) >> 8;
-               snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_R, reg_val);
+               snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2M_R, reg_val);
                reg_val = (offset_r & DA9055_ALC_OFFSET_17_16) >> 16;
-               snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_R, reg_val);
+               snd_soc_component_write(component, DA9055_ALC_OFFSET_OP2U_R, reg_val);
 
                /* Restore original values of ADC control registers */
-               snd_soc_write(codec, DA9055_ADC_L_CTRL, adc_left);
-               snd_soc_write(codec, DA9055_ADC_R_CTRL, adc_right);
+               snd_soc_component_write(component, DA9055_ADC_L_CTRL, adc_left);
+               snd_soc_component_write(component, DA9055_ADC_R_CTRL, adc_right);
 
                /* Restore original values of Mic control registers */
-               snd_soc_write(codec, DA9055_MIC_L_CTRL, mic_left);
-               snd_soc_write(codec, DA9055_MIC_R_CTRL, mic_right);
+               snd_soc_component_write(component, DA9055_MIC_L_CTRL, mic_left);
+               snd_soc_component_write(component, DA9055_MIC_R_CTRL, mic_right);
        }
 
        return snd_soc_put_volsw(kcontrol, ucontrol);
@@ -1052,8 +1052,8 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
        u8 aif_ctrl, fs;
        u32 sysclk;
 
@@ -1075,7 +1075,7 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* Set AIF format */
-       snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,
+       snd_soc_component_update_bits(component, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,
                            aif_ctrl);
 
        switch (params_rate(params)) {
@@ -1125,7 +1125,7 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 
        if (da9055->mclk_rate) {
                /* PLL Mode, Write actual FS */
-               snd_soc_write(codec, DA9055_SR, fs);
+               snd_soc_component_write(component, DA9055_SR, fs);
        } else {
                /*
                 * Non-PLL Mode
@@ -1134,24 +1134,24 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
                 * to derive its sys clk. As sys clk has to be 256 * Fs, we
                 * need to write constant sample rate i.e. 48KHz.
                 */
-               snd_soc_write(codec, DA9055_SR, DA9055_SR_48000);
+               snd_soc_component_write(component, DA9055_SR, DA9055_SR_48000);
        }
 
        if (da9055->mclk_rate && (da9055->mclk_rate != sysclk)) {
                /* PLL Mode */
                if (!da9055->master) {
                        /* PLL slave mode, enable PLL and also SRM */
-                       snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+                       snd_soc_component_update_bits(component, DA9055_PLL_CTRL,
                                            DA9055_PLL_EN | DA9055_PLL_SRM_EN,
                                            DA9055_PLL_EN | DA9055_PLL_SRM_EN);
                } else {
                        /* PLL master mode, only enable PLL */
-                       snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+                       snd_soc_component_update_bits(component, DA9055_PLL_CTRL,
                                            DA9055_PLL_EN, DA9055_PLL_EN);
                }
        } else {
                /* Non PLL Mode, disable PLL */
-               snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+               snd_soc_component_update_bits(component, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
        }
 
        return 0;
@@ -1160,8 +1160,8 @@ static int da9055_hw_params(struct snd_pcm_substream *substream,
 /* Set DAI mode and Format */
 static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
        u8 aif_clk_mode, aif_ctrl, mode;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1180,7 +1180,7 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        }
 
        /* Don't allow change of mode if PLL is enabled */
-       if ((snd_soc_read(codec, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&
+       if ((snd_soc_component_read32(component, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&
            (da9055->master != mode))
                return -EINVAL;
 
@@ -1207,27 +1207,27 @@ static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        /* By default only 32 BCLK per WCLK is supported */
        aif_clk_mode |= DA9055_AIF_BCLKS_PER_WCLK_32;
 
-       snd_soc_update_bits(codec, DA9055_AIF_CLK_MODE,
+       snd_soc_component_update_bits(component, DA9055_AIF_CLK_MODE,
                            (DA9055_AIF_CLK_MODE_MASK | DA9055_AIF_BCLK_MASK),
                            aif_clk_mode);
-       snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,
+       snd_soc_component_update_bits(component, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,
                            aif_ctrl);
        return 0;
 }
 
 static int da9055_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute) {
-               snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+               snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,
                                    DA9055_DAC_L_MUTE_EN, DA9055_DAC_L_MUTE_EN);
-               snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+               snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,
                                    DA9055_DAC_R_MUTE_EN, DA9055_DAC_R_MUTE_EN);
        } else {
-               snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+               snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,
                                    DA9055_DAC_L_MUTE_EN, 0);
-               snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+               snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,
                                    DA9055_DAC_R_MUTE_EN, 0);
        }
 
@@ -1240,8 +1240,8 @@ static int da9055_mute(struct snd_soc_dai *dai, int mute)
 static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case DA9055_CLKSRC_MCLK:
@@ -1283,13 +1283,13 @@ static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int fref, unsigned int fout)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 
        u8 pll_frac_top, pll_frac_bot, pll_integer, cnt;
 
        /* Disable PLL before setting the divisors */
-       snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+       snd_soc_component_update_bits(component, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
 
        /* In slave mode, there is only one set of divisors */
        if (!da9055->master && (fout != 2822400))
@@ -1312,9 +1312,9 @@ static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                goto pll_err;
 
        /* Write PLL dividers */
-       snd_soc_write(codec, DA9055_PLL_FRAC_TOP, pll_frac_top);
-       snd_soc_write(codec, DA9055_PLL_FRAC_BOT, pll_frac_bot);
-       snd_soc_write(codec, DA9055_PLL_INTEGER, pll_integer);
+       snd_soc_component_write(component, DA9055_PLL_FRAC_TOP, pll_frac_top);
+       snd_soc_component_write(component, DA9055_PLL_FRAC_BOT, pll_frac_bot);
+       snd_soc_component_write(component, DA9055_PLL_INTEGER, pll_integer);
 
        return 0;
 pll_err:
@@ -1353,7 +1353,7 @@ static struct snd_soc_dai_driver da9055_dai = {
        .symmetric_rates = 1,
 };
 
-static int da9055_set_bias_level(struct snd_soc_codec *codec,
+static int da9055_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
@@ -1361,48 +1361,48 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Enable VMID reference & master bias */
-                       snd_soc_update_bits(codec, DA9055_REFERENCES,
+                       snd_soc_component_update_bits(component, DA9055_REFERENCES,
                                            DA9055_VMID_EN | DA9055_BIAS_EN,
                                            DA9055_VMID_EN | DA9055_BIAS_EN);
                }
                break;
        case SND_SOC_BIAS_OFF:
                /* Disable VMID reference & master bias */
-               snd_soc_update_bits(codec, DA9055_REFERENCES,
+               snd_soc_component_update_bits(component, DA9055_REFERENCES,
                                    DA9055_VMID_EN | DA9055_BIAS_EN, 0);
                break;
        }
        return 0;
 }
 
-static int da9055_probe(struct snd_soc_codec *codec)
+static int da9055_probe(struct snd_soc_component *component)
 {
-       struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+       struct da9055_priv *da9055 = snd_soc_component_get_drvdata(component);
 
        /* Enable all Gain Ramps */
-       snd_soc_update_bits(codec, DA9055_AUX_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_AUX_L_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_AUX_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_AUX_R_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_MIXIN_L_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_MIXIN_R_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_ADC_L_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_ADC_R_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_DAC_L_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_DAC_R_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_HP_L_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_HP_R_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
-       snd_soc_update_bits(codec, DA9055_LINE_CTRL,
+       snd_soc_component_update_bits(component, DA9055_LINE_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
 
        /*
@@ -1412,28 +1412,28 @@ static int da9055_probe(struct snd_soc_codec *codec)
         * being managed by DAPM while other (non power related) bits are
         * enabled here
         */
-       snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_MIXIN_L_CTRL,
                            DA9055_MIXIN_L_MIX_EN, DA9055_MIXIN_L_MIX_EN);
-       snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_MIXIN_R_CTRL,
                            DA9055_MIXIN_R_MIX_EN, DA9055_MIXIN_R_MIX_EN);
 
-       snd_soc_update_bits(codec, DA9055_MIXOUT_L_CTRL,
+       snd_soc_component_update_bits(component, DA9055_MIXOUT_L_CTRL,
                            DA9055_MIXOUT_L_MIX_EN, DA9055_MIXOUT_L_MIX_EN);
-       snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL,
+       snd_soc_component_update_bits(component, DA9055_MIXOUT_R_CTRL,
                            DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN);
 
        /* Set this as per your system configuration */
-       snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
+       snd_soc_component_write(component, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
 
        /* Set platform data values */
        if (da9055->pdata) {
                /* set mic bias source */
                if (da9055->pdata->micbias_source) {
-                       snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+                       snd_soc_component_update_bits(component, DA9055_MIXIN_R_SELECT,
                                            DA9055_MICBIAS2_EN,
                                            DA9055_MICBIAS2_EN);
                } else {
-                       snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+                       snd_soc_component_update_bits(component, DA9055_MIXIN_R_SELECT,
                                            DA9055_MICBIAS2_EN, 0);
                }
                /* set mic bias voltage */
@@ -1442,7 +1442,7 @@ static int da9055_probe(struct snd_soc_codec *codec)
                case DA9055_MICBIAS_2_1V:
                case DA9055_MICBIAS_1_8V:
                case DA9055_MICBIAS_1_6V:
-                       snd_soc_update_bits(codec, DA9055_MIC_CONFIG,
+                       snd_soc_component_update_bits(component, DA9055_MIC_CONFIG,
                                            DA9055_MICBIAS_LEVEL_MASK,
                                            (da9055->pdata->micbias) << 4);
                        break;
@@ -1451,18 +1451,19 @@ static int da9055_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_da9055 = {
+static const struct snd_soc_component_driver soc_component_dev_da9055 = {
        .probe                  = da9055_probe,
        .set_bias_level         = da9055_set_bias_level,
-
-       .component_driver = {
-               .controls               = da9055_snd_controls,
-               .num_controls           = ARRAY_SIZE(da9055_snd_controls),
-               .dapm_widgets           = da9055_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(da9055_dapm_widgets),
-               .dapm_routes            = da9055_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(da9055_audio_map),
-       },
+       .controls               = da9055_snd_controls,
+       .num_controls           = ARRAY_SIZE(da9055_snd_controls),
+       .dapm_widgets           = da9055_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(da9055_dapm_widgets),
+       .dapm_routes            = da9055_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(da9055_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config da9055_regmap_config = {
@@ -1499,21 +1500,15 @@ static int da9055_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_da9055, &da9055_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_da9055, &da9055_dai, 1);
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register da9055 codec: %d\n",
+               dev_err(&i2c->dev, "Failed to register da9055 component: %d\n",
                        ret);
        }
        return ret;
 }
 
-static int da9055_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 /*
  * DO NOT change the device Ids. The naming is intentionally specific as both
  * the CODEC and PMIC parts of this chip are instantiated separately as I2C
@@ -1540,7 +1535,6 @@ static struct i2c_driver da9055_i2c_driver = {
                .of_match_table = of_match_ptr(da9055_of_match),
        },
        .probe          = da9055_i2c_probe,
-       .remove         = da9055_remove,
        .id_table       = da9055_i2c_id,
 };
 
index cf83c423394d775430e876d89721f300675365bf..8c4926df92862f4e3c0a0bd502b51cf7d4c2a37b 100644 (file)
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/platform_device.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
-static int dmic_daiops_trigger(struct snd_pcm_substream *substream,
-               int cmd, struct snd_soc_dai *dai)
-{
-       struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai);
+struct dmic {
+       struct gpio_desc *gpio_en;
+       int wakeup_delay;
+};
+
+static int dmic_aif_event(struct snd_soc_dapm_widget *w,
+                         struct snd_kcontrol *kcontrol, int event) {
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct dmic *dmic = snd_soc_component_get_drvdata(component);
 
-       if (!dmic_en)
-               return 0;
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               if (dmic->gpio_en)
+                       gpiod_set_value(dmic->gpio_en, 1);
 
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-       case SNDRV_PCM_TRIGGER_RESUME:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               gpiod_set_value(dmic_en, 1);
+               if (dmic->wakeup_delay)
+                       msleep(dmic->wakeup_delay);
                break;
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               gpiod_set_value(dmic_en, 0);
+       case SND_SOC_DAPM_POST_PMD:
+               if (dmic->gpio_en)
+                       gpiod_set_value(dmic->gpio_en, 0);
                break;
        }
 
        return 0;
 }
 
-static const struct snd_soc_dai_ops dmic_dai_ops = {
-       .trigger        = dmic_daiops_trigger,
-};
-
 static struct snd_soc_dai_driver dmic_dai = {
        .name = "dmic-hifi",
        .capture = {
@@ -68,26 +68,33 @@ static struct snd_soc_dai_driver dmic_dai = {
                        | SNDRV_PCM_FMTBIT_S24_LE
                        | SNDRV_PCM_FMTBIT_S16_LE,
        },
-       .ops    = &dmic_dai_ops,
 };
 
-static int dmic_codec_probe(struct snd_soc_codec *codec)
+static int dmic_component_probe(struct snd_soc_component *component)
 {
-       struct gpio_desc *dmic_en;
+       struct dmic *dmic;
+
+       dmic = devm_kzalloc(component->dev, sizeof(*dmic), GFP_KERNEL);
+       if (!dmic)
+               return -ENOMEM;
 
-       dmic_en = devm_gpiod_get_optional(codec->dev,
-                                       "dmicen", GPIOD_OUT_LOW);
-       if (IS_ERR(dmic_en))
-               return PTR_ERR(dmic_en);
+       dmic->gpio_en = devm_gpiod_get_optional(component->dev,
+                                               "dmicen", GPIOD_OUT_LOW);
+       if (IS_ERR(dmic->gpio_en))
+               return PTR_ERR(dmic->gpio_en);
 
-       snd_soc_codec_set_drvdata(codec, dmic_en);
+       device_property_read_u32(component->dev, "wakeup-delay-ms",
+                                &dmic->wakeup_delay);
+
+       snd_soc_component_set_drvdata(component, dmic);
 
        return 0;
 }
 
 static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
-       SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
-                            SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT_E("DMIC AIF", "Capture", 0,
+                              SND_SOC_NOPM, 0, 0, dmic_aif_event,
+                              SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_INPUT("DMic"),
 };
 
@@ -95,14 +102,16 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"DMIC AIF", NULL, "DMic"},
 };
 
-static const struct snd_soc_codec_driver soc_dmic = {
-       .probe = dmic_codec_probe,
-       .component_driver = {
-               .dapm_widgets           = dmic_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(dmic_dapm_widgets),
-               .dapm_routes            = intercon,
-               .num_dapm_routes        = ARRAY_SIZE(intercon),
-       },
+static const struct snd_soc_component_driver soc_dmic = {
+       .probe                  = dmic_component_probe,
+       .dapm_widgets           = dmic_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(dmic_dapm_widgets),
+       .dapm_routes            = intercon,
+       .num_dapm_routes        = ARRAY_SIZE(intercon),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int dmic_dev_probe(struct platform_device *pdev)
@@ -129,16 +138,10 @@ static int dmic_dev_probe(struct platform_device *pdev)
                }
        }
 
-       return snd_soc_register_codec(&pdev->dev,
+       return devm_snd_soc_register_component(&pdev->dev,
                        &soc_dmic, dai_drv, 1);
 }
 
-static int dmic_dev_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 MODULE_ALIAS("platform:dmic-codec");
 
 static const struct of_device_id dmic_dev_match[] = {
@@ -152,7 +155,6 @@ static struct platform_driver dmic_driver = {
                .of_match_table = dmic_dev_match,
        },
        .probe = dmic_dev_probe,
-       .remove = dmic_dev_remove,
 };
 
 module_platform_driver(dmic_driver);
index 3869025754d83ec3848b3b755f79c8c64eed533e..58515bb1a303655525ec2c259f4370f0868a0096 100644 (file)
@@ -69,28 +69,24 @@ static const struct snd_soc_dapm_route es7134_dapm_routes[] = {
        { "AOUTR", NULL, "DAC" },
 };
 
-static const struct snd_soc_codec_driver es7134_codec_driver = {
-       .component_driver = {
-               .dapm_widgets           = es7134_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(es7134_dapm_widgets),
-               .dapm_routes            = es7134_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(es7134_dapm_routes),
-       },
+static const struct snd_soc_component_driver es7134_component_driver = {
+       .dapm_widgets           = es7134_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(es7134_dapm_widgets),
+       .dapm_routes            = es7134_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(es7134_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int es7134_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                                     &es7134_codec_driver,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &es7134_component_driver,
                                      &es7134_dai, 1);
 }
 
-static int es7134_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id es7134_ids[] = {
        { .compatible = "everest,es7134", },
@@ -106,7 +102,6 @@ static struct platform_driver es7134_driver = {
                .of_match_table = of_match_ptr(es7134_ids),
        },
        .probe = es7134_probe,
-       .remove = es7134_remove,
 };
 
 module_platform_driver(es7134_driver);
index da2d353af5ba29a8c2018673bbddc626a56641cf..e97d12d578b00c1a287209e24fed9d29688d777e 100644 (file)
@@ -356,8 +356,8 @@ static const struct snd_soc_dapm_route es8316_dapm_routes[] = {
 static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
        int i;
        int count = 0;
 
@@ -385,19 +385,19 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 serdata1 = 0;
        u8 serdata2 = 0;
        u8 clksw;
        u8 mask;
 
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-               dev_err(codec->dev, "Codec driver only supports slave mode\n");
+               dev_err(component->dev, "Codec driver only supports slave mode\n");
                return -EINVAL;
        }
 
        if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) {
-               dev_err(codec->dev, "Codec driver only supports I2S format\n");
+               dev_err(component->dev, "Codec driver only supports I2S format\n");
                return -EINVAL;
        }
 
@@ -420,15 +420,15 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
        }
 
        mask = ES8316_SERDATA1_MASTER | ES8316_SERDATA1_BCLK_INV;
-       snd_soc_update_bits(codec, ES8316_SERDATA1, mask, serdata1);
+       snd_soc_component_update_bits(component, ES8316_SERDATA1, mask, serdata1);
 
        mask = ES8316_SERDATA2_FMT_MASK | ES8316_SERDATA2_ADCLRP;
-       snd_soc_update_bits(codec, ES8316_SERDATA_ADC, mask, serdata2);
-       snd_soc_update_bits(codec, ES8316_SERDATA_DAC, mask, serdata2);
+       snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, mask, serdata2);
+       snd_soc_component_update_bits(component, ES8316_SERDATA_DAC, mask, serdata2);
 
        /* Enable BCLK and MCLK inputs in slave mode */
        clksw = ES8316_CLKMGR_CLKSW_MCLK_ON | ES8316_CLKMGR_CLKSW_BCLK_ON;
-       snd_soc_update_bits(codec, ES8316_CLKMGR_CLKSW, clksw, clksw);
+       snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW, clksw, clksw);
 
        return 0;
 }
@@ -436,11 +436,11 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int es8316_pcm_startup(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
 
        if (es8316->sysclk == 0) {
-               dev_err(codec->dev, "No sysclk provided\n");
+               dev_err(component->dev, "No sysclk provided\n");
                return -EINVAL;
        }
 
@@ -458,13 +458,12 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
-       struct es8316_priv *es8316 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
        u8 wordlen = 0;
 
        if (!es8316->sysclk) {
-               dev_err(codec->dev, "No MCLK configured\n");
+               dev_err(component->dev, "No MCLK configured\n");
                return -EINVAL;
        }
 
@@ -485,16 +484,16 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, ES8316_SERDATA_DAC,
+       snd_soc_component_update_bits(component, ES8316_SERDATA_DAC,
                            ES8316_SERDATA2_LEN_MASK, wordlen);
-       snd_soc_update_bits(codec, ES8316_SERDATA_ADC,
+       snd_soc_component_update_bits(component, ES8316_SERDATA_ADC,
                            ES8316_SERDATA2_LEN_MASK, wordlen);
        return 0;
 }
 
 static int es8316_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, ES8316_DAC_SET1, 0x20,
+       snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20,
                            mute ? 0x20 : 0);
        return 0;
 }
@@ -530,42 +529,41 @@ static struct snd_soc_dai_driver es8316_dai = {
        .symmetric_rates = 1,
 };
 
-static int es8316_probe(struct snd_soc_codec *codec)
+static int es8316_probe(struct snd_soc_component *component)
 {
        /* Reset codec and enable current state machine */
-       snd_soc_write(codec, ES8316_RESET, 0x3f);
+       snd_soc_component_write(component, ES8316_RESET, 0x3f);
        usleep_range(5000, 5500);
-       snd_soc_write(codec, ES8316_RESET, ES8316_RESET_CSM_ON);
+       snd_soc_component_write(component, ES8316_RESET, ES8316_RESET_CSM_ON);
        msleep(30);
 
        /*
         * Documentation is unclear, but this value from the vendor driver is
         * needed otherwise audio output is silent.
         */
-       snd_soc_write(codec, ES8316_SYS_VMIDSEL, 0xff);
+       snd_soc_component_write(component, ES8316_SYS_VMIDSEL, 0xff);
 
        /*
         * Documentation for this register is unclear and incomplete,
         * but here is a vendor-provided value that improves volume
         * and quality for Intel CHT platforms.
         */
-       snd_soc_write(codec, ES8316_CLKMGR_ADCOSR, 0x32);
+       snd_soc_component_write(component, ES8316_CLKMGR_ADCOSR, 0x32);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_es8316 = {
-       .probe          = es8316_probe,
-       .idle_bias_off  = true,
-
-       .component_driver = {
-               .controls               = es8316_snd_controls,
-               .num_controls           = ARRAY_SIZE(es8316_snd_controls),
-               .dapm_widgets           = es8316_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(es8316_dapm_widgets),
-               .dapm_routes            = es8316_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(es8316_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_es8316 = {
+       .probe                  = es8316_probe,
+       .controls               = es8316_snd_controls,
+       .num_controls           = ARRAY_SIZE(es8316_snd_controls),
+       .dapm_widgets           = es8316_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(es8316_dapm_widgets),
+       .dapm_routes            = es8316_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(es8316_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config es8316_regmap = {
@@ -592,16 +590,11 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client,
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
-       return snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_es8316,
+       return devm_snd_soc_register_component(&i2c_client->dev,
+                                     &soc_component_dev_es8316,
                                      &es8316_dai, 1);
 }
 
-static int es8316_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id es8316_i2c_id[] = {
        {"es8316", 0 },
        {}
@@ -627,7 +620,6 @@ static struct i2c_driver es8316_i2c_driver = {
                .of_match_table         = of_match_ptr(es8316_of_match),
        },
        .probe          = es8316_i2c_probe,
-       .remove         = es8316_i2c_remove,
        .id_table       = es8316_i2c_id,
 };
 module_i2c_driver(es8316_i2c_driver);
index 318ab28c5351fcd198603b71b427e6972bbc43c5..19baa3260f85fb0b0d50a9562867ca1df798db08 100644 (file)
@@ -39,19 +39,12 @@ static int es8328_i2c_probe(struct i2c_client *i2c,
                        devm_regmap_init_i2c(i2c, &es8328_regmap_config));
 }
 
-static int es8328_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-       return 0;
-}
-
 static struct i2c_driver es8328_i2c_driver = {
        .driver = {
                .name           = "es8328",
                .of_match_table = es8328_of_match,
        },
        .probe    = es8328_i2c_probe,
-       .remove   = es8328_i2c_remove,
        .id_table = es8328_id,
 };
 
index 8fbd935e1c76c6bf30fae1ec7e319e038d7b48de..d242bd1f7dcc699d3d7ffd89e1dcb24aa2bcd16e 100644 (file)
@@ -28,19 +28,12 @@ static int es8328_spi_probe(struct spi_device *spi)
                        devm_regmap_init_spi(spi, &es8328_regmap_config));
 }
 
-static int es8328_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver es8328_spi_driver = {
        .driver = {
                .name           = "es8328",
                .of_match_table = es8328_of_match,
        },
        .probe  = es8328_spi_probe,
-       .remove = es8328_spi_remove,
 };
 
 module_spi_driver(es8328_spi_driver);
index bcdb8914ec16b992e26aecb718e430e6e0477e05..e9fc2fd97d2f4f6b13c46e7b0a58e03d2bc1a7ff 100644 (file)
@@ -116,9 +116,9 @@ static const struct {
        { 48000, ES8328_DACCONTROL6_DEEMPH_48k },
 };
 
-static int es8328_set_deemph(struct snd_soc_codec *codec)
+static int es8328_set_deemph(struct snd_soc_component *component)
 {
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
        int val, i, best;
 
        /*
@@ -138,17 +138,17 @@ static int es8328_set_deemph(struct snd_soc_codec *codec)
                val = ES8328_DACCONTROL6_DEEMPH_OFF;
        }
 
-       dev_dbg(codec->dev, "Set deemphasis %d\n", val);
+       dev_dbg(component->dev, "Set deemphasis %d\n", val);
 
-       return snd_soc_update_bits(codec, ES8328_DACCONTROL6,
+       return snd_soc_component_update_bits(component, ES8328_DACCONTROL6,
                        ES8328_DACCONTROL6_DEEMPH_MASK, val);
 }
 
 static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = es8328->deemph;
        return 0;
@@ -157,15 +157,15 @@ static int es8328_get_deemph(struct snd_kcontrol *kcontrol,
 static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
        unsigned int deemph = ucontrol->value.integer.value[0];
        int ret;
 
        if (deemph > 1)
                return -EINVAL;
 
-       ret = es8328_set_deemph(codec);
+       ret = es8328_set_deemph(component);
        if (ret < 0)
                return ret;
 
@@ -455,7 +455,7 @@ static const struct snd_soc_dapm_route es8328_dapm_routes[] = {
 
 static int es8328_mute(struct snd_soc_dai *dai, int mute)
 {
-       return snd_soc_update_bits(dai->codec, ES8328_DACCONTROL3,
+       return snd_soc_component_update_bits(dai->component, ES8328_DACCONTROL3,
                        ES8328_DACCONTROL3_DACMUTE,
                        mute ? ES8328_DACCONTROL3_DACMUTE : 0);
 }
@@ -463,8 +463,8 @@ static int es8328_mute(struct snd_soc_dai *dai, int mute)
 static int es8328_startup(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
 
        if (es8328->master && es8328->sysclk_constraints)
                snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -478,8 +478,8 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
        int i;
        int reg;
        int wl;
@@ -492,7 +492,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
 
        if (es8328->master) {
                if (!es8328->sysclk_constraints) {
-                       dev_err(codec->dev, "No MCLK configured\n");
+                       dev_err(component->dev, "No MCLK configured\n");
                        return -EINVAL;
                }
 
@@ -502,7 +502,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
                                break;
 
                if (i == es8328->sysclk_constraints->count) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "LRCLK %d unsupported with current clock\n",
                                params_rate(params));
                        return -EINVAL;
@@ -513,7 +513,7 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
                es8328->mclkdiv2 = 0;
        }
 
-       snd_soc_update_bits(codec, ES8328_MASTERMODE,
+       snd_soc_component_update_bits(component, ES8328_MASTERMODE,
                        ES8328_MASTERMODE_MCLKDIV2,
                        es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0);
 
@@ -538,25 +538,25 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               snd_soc_update_bits(codec, ES8328_DACCONTROL1,
+               snd_soc_component_update_bits(component, ES8328_DACCONTROL1,
                                ES8328_DACCONTROL1_DACWL_MASK,
                                wl << ES8328_DACCONTROL1_DACWL_SHIFT);
 
                es8328->playback_fs = params_rate(params);
-               es8328_set_deemph(codec);
+               es8328_set_deemph(component);
        } else
-               snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
+               snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
                                ES8328_ADCCONTROL4_ADCWL_MASK,
                                wl << ES8328_ADCCONTROL4_ADCWL_SHIFT);
 
-       return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio);
+       return snd_soc_component_update_bits(component, reg, ES8328_RATEMASK, ratio);
 }
 
 static int es8328_set_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
        int mclkdiv2 = 0;
 
        switch (freq) {
@@ -589,22 +589,22 @@ static int es8328_set_sysclk(struct snd_soc_dai *codec_dai,
 static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);
        u8 dac_mode = 0;
        u8 adc_mode = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
                /* Master serial port mode, with BCLK generated automatically */
-               snd_soc_update_bits(codec, ES8328_MASTERMODE,
+               snd_soc_component_update_bits(component, ES8328_MASTERMODE,
                                    ES8328_MASTERMODE_MSC,
                                    ES8328_MASTERMODE_MSC);
                es8328->master = true;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
                /* Slave serial port mode */
-               snd_soc_update_bits(codec, ES8328_MASTERMODE,
+               snd_soc_component_update_bits(component, ES8328_MASTERMODE,
                                    ES8328_MASTERMODE_MSC, 0);
                es8328->master = false;
                break;
@@ -634,15 +634,15 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
        if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF)
                return -EINVAL;
 
-       snd_soc_update_bits(codec, ES8328_DACCONTROL1,
+       snd_soc_component_update_bits(component, ES8328_DACCONTROL1,
                        ES8328_DACCONTROL1_DACFORMAT_MASK, dac_mode);
-       snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
+       snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,
                        ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
 
        return 0;
 }
 
-static int es8328_set_bias_level(struct snd_soc_codec *codec,
+static int es8328_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
@@ -651,8 +651,8 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_PREPARE:
                /* VREF, VMID=2x50k, digital enabled */
-               snd_soc_write(codec, ES8328_CHIPPOWER, 0);
-               snd_soc_update_bits(codec, ES8328_CONTROL1,
+               snd_soc_component_write(component, ES8328_CHIPPOWER, 0);
+               snd_soc_component_update_bits(component, ES8328_CONTROL1,
                                ES8328_CONTROL1_VMIDSEL_MASK |
                                ES8328_CONTROL1_ENREF,
                                ES8328_CONTROL1_VMIDSEL_50k |
@@ -660,8 +660,8 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_update_bits(codec, ES8328_CONTROL1,
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_update_bits(component, ES8328_CONTROL1,
                                        ES8328_CONTROL1_VMIDSEL_MASK |
                                        ES8328_CONTROL1_ENREF,
                                        ES8328_CONTROL1_VMIDSEL_5k |
@@ -671,12 +671,12 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
                        msleep(100);
                }
 
-               snd_soc_write(codec, ES8328_CONTROL2,
+               snd_soc_component_write(component, ES8328_CONTROL2,
                                ES8328_CONTROL2_OVERCURRENT_ON |
                                ES8328_CONTROL2_THERMAL_SHUTDOWN_ON);
 
                /* VREF, VMID=2*500k, digital stopped */
-               snd_soc_update_bits(codec, ES8328_CONTROL1,
+               snd_soc_component_update_bits(component, ES8328_CONTROL1,
                                ES8328_CONTROL1_VMIDSEL_MASK |
                                ES8328_CONTROL1_ENREF,
                                ES8328_CONTROL1_VMIDSEL_500k |
@@ -684,7 +684,7 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, ES8328_CONTROL1,
+               snd_soc_component_update_bits(component, ES8328_CONTROL1,
                                ES8328_CONTROL1_VMIDSEL_MASK |
                                ES8328_CONTROL1_ENREF,
                                0);
@@ -721,80 +721,80 @@ static struct snd_soc_dai_driver es8328_dai = {
        .symmetric_rates = 1,
 };
 
-static int es8328_suspend(struct snd_soc_codec *codec)
+static int es8328_suspend(struct snd_soc_component *component)
 {
        struct es8328_priv *es8328;
        int ret;
 
-       es8328 = snd_soc_codec_get_drvdata(codec);
+       es8328 = snd_soc_component_get_drvdata(component);
 
        clk_disable_unprepare(es8328->clk);
 
        ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),
                        es8328->supplies);
        if (ret) {
-               dev_err(codec->dev, "unable to disable regulators\n");
+               dev_err(component->dev, "unable to disable regulators\n");
                return ret;
        }
        return 0;
 }
 
-static int es8328_resume(struct snd_soc_codec *codec)
+static int es8328_resume(struct snd_soc_component *component)
 {
-       struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
+       struct regmap *regmap = dev_get_regmap(component->dev, NULL);
        struct es8328_priv *es8328;
        int ret;
 
-       es8328 = snd_soc_codec_get_drvdata(codec);
+       es8328 = snd_soc_component_get_drvdata(component);
 
        ret = clk_prepare_enable(es8328->clk);
        if (ret) {
-               dev_err(codec->dev, "unable to enable clock\n");
+               dev_err(component->dev, "unable to enable clock\n");
                return ret;
        }
 
        ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies),
                                        es8328->supplies);
        if (ret) {
-               dev_err(codec->dev, "unable to enable regulators\n");
+               dev_err(component->dev, "unable to enable regulators\n");
                return ret;
        }
 
        regcache_mark_dirty(regmap);
        ret = regcache_sync(regmap);
        if (ret) {
-               dev_err(codec->dev, "unable to sync regcache\n");
+               dev_err(component->dev, "unable to sync regcache\n");
                return ret;
        }
 
        return 0;
 }
 
-static int es8328_codec_probe(struct snd_soc_codec *codec)
+static int es8328_component_probe(struct snd_soc_component *component)
 {
        struct es8328_priv *es8328;
        int ret;
 
-       es8328 = snd_soc_codec_get_drvdata(codec);
+       es8328 = snd_soc_component_get_drvdata(component);
 
        ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies),
                                        es8328->supplies);
        if (ret) {
-               dev_err(codec->dev, "unable to enable regulators\n");
+               dev_err(component->dev, "unable to enable regulators\n");
                return ret;
        }
 
        /* Setup clocks */
-       es8328->clk = devm_clk_get(codec->dev, NULL);
+       es8328->clk = devm_clk_get(component->dev, NULL);
        if (IS_ERR(es8328->clk)) {
-               dev_err(codec->dev, "codec clock missing or invalid\n");
+               dev_err(component->dev, "codec clock missing or invalid\n");
                ret = PTR_ERR(es8328->clk);
                goto clk_fail;
        }
 
        ret = clk_prepare_enable(es8328->clk);
        if (ret) {
-               dev_err(codec->dev, "unable to prepare codec clk\n");
+               dev_err(component->dev, "unable to prepare codec clk\n");
                goto clk_fail;
        }
 
@@ -806,19 +806,17 @@ clk_fail:
        return ret;
 }
 
-static int es8328_remove(struct snd_soc_codec *codec)
+static void es8328_remove(struct snd_soc_component *component)
 {
        struct es8328_priv *es8328;
 
-       es8328 = snd_soc_codec_get_drvdata(codec);
+       es8328 = snd_soc_component_get_drvdata(component);
 
        if (es8328->clk)
                clk_disable_unprepare(es8328->clk);
 
        regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),
                               es8328->supplies);
-
-       return 0;
 }
 
 const struct regmap_config es8328_regmap_config = {
@@ -830,22 +828,23 @@ const struct regmap_config es8328_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(es8328_regmap_config);
 
-static const struct snd_soc_codec_driver es8328_codec_driver = {
-       .probe            = es8328_codec_probe,
-       .suspend          = es8328_suspend,
-       .resume           = es8328_resume,
-       .remove           = es8328_remove,
-       .set_bias_level   = es8328_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = es8328_snd_controls,
-               .num_controls           = ARRAY_SIZE(es8328_snd_controls),
-               .dapm_widgets           = es8328_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(es8328_dapm_widgets),
-               .dapm_routes            = es8328_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(es8328_dapm_routes),
-       },
+static const struct snd_soc_component_driver es8328_component_driver = {
+       .probe                  = es8328_component_probe,
+       .remove                 = es8328_remove,
+       .suspend                = es8328_suspend,
+       .resume                 = es8328_resume,
+       .set_bias_level         = es8328_set_bias_level,
+       .controls               = es8328_snd_controls,
+       .num_controls           = ARRAY_SIZE(es8328_snd_controls),
+       .dapm_widgets           = es8328_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(es8328_dapm_widgets),
+       .dapm_routes            = es8328_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(es8328_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 int es8328_probe(struct device *dev, struct regmap *regmap)
@@ -875,8 +874,8 @@ int es8328_probe(struct device *dev, struct regmap *regmap)
 
        dev_set_drvdata(dev, es8328);
 
-       return snd_soc_register_codec(dev,
-                       &es8328_codec_driver, &es8328_dai, 1);
+       return devm_snd_soc_register_component(dev,
+                       &es8328_component_driver, &es8328_dai, 1);
 }
 EXPORT_SYMBOL_GPL(es8328_probe);
 
index 926b1a4e37d46825a4dd3741bb7865b794245a3f..c11ed60ccefb6cab880c9c12760176e6eae30f24 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/ac97_codec.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
 
@@ -51,25 +50,21 @@ static struct snd_soc_dai_driver gtm601_dai = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_gtm601 = {
-       .component_driver = {
-               .dapm_widgets           = gtm601_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(gtm601_dapm_widgets),
-               .dapm_routes            = gtm601_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(gtm601_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_gtm601 = {
+       .dapm_widgets           = gtm601_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(gtm601_dapm_widgets),
+       .dapm_routes            = gtm601_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(gtm601_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int gtm601_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_gtm601, &gtm601_dai, 1);
-}
-
-static int gtm601_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_gtm601, &gtm601_dai, 1);
 }
 
 #if defined(CONFIG_OF)
@@ -86,7 +81,6 @@ static struct platform_driver gtm601_codec_driver = {
                .of_match_table = of_match_ptr(gtm601_codec_of_match),
        },
        .probe = gtm601_platform_probe,
-       .remove = gtm601_platform_remove,
 };
 
 module_platform_driver(gtm601_codec_driver);
index dba6f4c5074aeb09575f94f3adab20d6d7ec3f2f..84f7a7a36e4b56a7e413699e517f7287368fc179 100644 (file)
@@ -718,10 +718,22 @@ static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
 static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
                             hda_nid_t nid, unsigned int pwr_state)
 {
+       int count;
+       unsigned int state;
+
        if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) {
-               if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state))
-                       snd_hdac_codec_write(&edev->hdev, nid, 0,
-                               AC_VERB_SET_POWER_STATE, pwr_state);
+               if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state)) {
+                       for (count = 0; count < 10; count++) {
+                               snd_hdac_codec_read(&edev->hdev, nid, 0,
+                                               AC_VERB_SET_POWER_STATE,
+                                               pwr_state);
+                               state = snd_hdac_sync_power_state(&edev->hdev,
+                                               nid, pwr_state);
+                               if (!(state & AC_PWRST_ERROR))
+                                       break;
+                       }
+               }
+
        }
 }
 
@@ -1536,7 +1548,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
        struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
        struct hdac_hdmi_pin *pin = NULL;
        struct hdac_hdmi_port *hport = NULL;
-       struct snd_soc_codec *codec = edev->scodec;
+       struct snd_soc_component *component = edev->scodec;
        int i;
 
        /* Don't know how this mapping is derived */
@@ -1551,7 +1563,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
         * connection states are updated in anyway at the end of the resume,
         * we can skip it when received during PM process.
         */
-       if (snd_power_get_state(codec->component.card->snd_card) !=
+       if (snd_power_get_state(component->card->snd_card) !=
                        SNDRV_CTL_POWER_D0)
                return;
 
@@ -1609,10 +1621,10 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
        char kc_name[NAME_SIZE], xname[NAME_SIZE];
        char *name;
        int i = 0, j;
-       struct snd_soc_codec *codec = edev->scodec;
+       struct snd_soc_component *component = edev->scodec;
        struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
 
-       kc = devm_kcalloc(codec->dev, hdmi->num_ports,
+       kc = devm_kcalloc(component->dev, hdmi->num_ports,
                                sizeof(*kc), GFP_KERNEL);
 
        if (!kc)
@@ -1622,11 +1634,11 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
                for (j = 0; j < pin->num_ports; j++) {
                        snprintf(xname, sizeof(xname), "hif%d-%d Jack",
                                                pin->nid, pin->ports[j].id);
-                       name = devm_kstrdup(codec->dev, xname, GFP_KERNEL);
+                       name = devm_kstrdup(component->dev, xname, GFP_KERNEL);
                        if (!name)
                                return -ENOMEM;
                        snprintf(kc_name, sizeof(kc_name), "%s Switch", xname);
-                       kc[i].name = devm_kstrdup(codec->dev, kc_name,
+                       kc[i].name = devm_kstrdup(component->dev, kc_name,
                                                        GFP_KERNEL);
                        if (!kc[i].name)
                                return -ENOMEM;
@@ -1644,10 +1656,10 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
        return snd_soc_add_card_controls(card, kc, i);
 }
 
-int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
+int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
                        struct snd_soc_dapm_context *dapm)
 {
-       struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+       struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
        struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
        struct hdac_hdmi_pin *pin;
        struct snd_soc_dapm_widget *widgets;
@@ -1722,8 +1734,8 @@ EXPORT_SYMBOL_GPL(hdac_hdmi_jack_port_init);
 int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
                                struct snd_soc_jack *jack)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
        struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
        struct hdac_hdmi_pcm *pcm;
        struct snd_pcm *snd_pcm;
@@ -1784,16 +1796,16 @@ static void hdac_hdmi_present_sense_all_pins(struct hdac_ext_device *edev,
        }
 }
 
-static int hdmi_codec_probe(struct snd_soc_codec *codec)
+static int hdmi_codec_probe(struct snd_soc_component *component)
 {
-       struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+       struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
        struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
        struct snd_soc_dapm_context *dapm =
-               snd_soc_component_get_dapm(&codec->component);
+               snd_soc_component_get_dapm(component);
        struct hdac_ext_link *hlink = NULL;
        int ret;
 
-       edev->scodec = codec;
+       edev->scodec = component;
 
        /*
         * hold the ref while we probe, also no need to drop the ref on
@@ -1834,12 +1846,11 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int hdmi_codec_remove(struct snd_soc_codec *codec)
+static void hdmi_codec_remove(struct snd_soc_component *component)
 {
-       struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
+       struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
 
        pm_runtime_disable(&edev->hdev.dev);
-       return 0;
 }
 
 #ifdef CONFIG_PM
@@ -1891,10 +1902,12 @@ static void hdmi_codec_complete(struct device *dev)
 #define hdmi_codec_complete NULL
 #endif
 
-static const struct snd_soc_codec_driver hdmi_hda_codec = {
-       .probe          = hdmi_codec_probe,
-       .remove         = hdmi_codec_remove,
-       .idle_bias_off  = true,
+static const struct snd_soc_component_driver hdmi_hda_codec = {
+       .probe                  = hdmi_codec_probe,
+       .remove                 = hdmi_codec_remove,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,
@@ -2042,7 +2055,7 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
        snd_hdac_refresh_widgets(hdev, true);
 
        /* ASoC specific initialization */
-       ret = snd_soc_register_codec(&hdev->dev, &hdmi_hda_codec,
+       ret = devm_snd_soc_register_component(&hdev->dev, &hdmi_hda_codec,
                                        hdmi_dais, num_dais);
 
        snd_hdac_ext_bus_link_put(edev->ebus, hlink);
@@ -2059,8 +2072,6 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
        struct hdac_hdmi_port *port, *port_next;
        int i;
 
-       snd_soc_unregister_codec(&edev->hdev.dev);
-
        list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
                pcm->cvt = NULL;
                if (list_empty(&pcm->port_list))
index b5b57a5cbbfdaa3d09e689785652972c7212459d..4fa2fc9ee893142a099183f748e9a92ae2a52e2f 100644 (file)
@@ -5,6 +5,6 @@
 int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
                                struct snd_soc_jack *jack);
 
-int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
+int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
                        struct snd_soc_dapm_context *dapm);
 #endif /* __HDAC_HDMI_H__ */
index 5672e516bec378c5d5437c8e63e8dac15e515c33..6fa11888672d4ca0c60096205c45e52f647f9ab8 100644 (file)
@@ -730,14 +730,16 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
        return ret;
 }
 
-static const struct snd_soc_codec_driver hdmi_codec = {
-       .component_driver = {
-               .dapm_widgets           = hdmi_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(hdmi_widgets),
-               .dapm_routes            = hdmi_routes,
-               .num_dapm_routes        = ARRAY_SIZE(hdmi_routes),
-               .of_xlate_dai_id        = hdmi_of_xlate_dai_id,
-       },
+static const struct snd_soc_component_driver hdmi_driver = {
+       .dapm_widgets           = hdmi_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(hdmi_widgets),
+       .dapm_routes            = hdmi_routes,
+       .num_dapm_routes        = ARRAY_SIZE(hdmi_routes),
+       .of_xlate_dai_id        = hdmi_of_xlate_dai_id,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int hdmi_codec_probe(struct platform_device *pdev)
@@ -784,10 +786,10 @@ static int hdmi_codec_probe(struct platform_device *pdev)
        if (hcd->spdif)
                hcp->daidrv[i] = hdmi_spdif_dai;
 
-       ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
+       ret = devm_snd_soc_register_component(dev, &hdmi_driver, hcp->daidrv,
                                     dai_count);
        if (ret) {
-               dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n",
+               dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
                        __func__, ret);
                return ret;
        }
@@ -796,24 +798,11 @@ static int hdmi_codec_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int hdmi_codec_remove(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct hdmi_codec_priv *hcp;
-
-       hcp = dev_get_drvdata(dev);
-       kfree(hcp->chmap_info);
-       snd_soc_unregister_codec(dev);
-
-       return 0;
-}
-
 static struct platform_driver hdmi_codec_driver = {
        .driver = {
                .name = HDMI_CODEC_DRV_NAME,
        },
        .probe = hdmi_codec_probe,
-       .remove = hdmi_codec_remove,
 };
 
 module_platform_driver(hdmi_codec_driver);
index 651206273f3675bf519d0d05b4ca7313a4b504ff..148d6d6b2a2bd0a6ee2a07c7aeb47717a46ada44 100644 (file)
@@ -37,21 +37,20 @@ static struct snd_soc_dai_driver ics43432_dai = {
        },
 };
 
-static const struct snd_soc_codec_driver ics43432_codec_driver = {
+static const struct snd_soc_component_driver ics43432_component_driver = {
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int ics43432_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &ics43432_codec_driver,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &ics43432_component_driver,
                        &ics43432_dai, 1);
 }
 
-static int ics43432_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id ics43432_ids[] = {
        { .compatible = "invensense,ics43432", },
@@ -66,7 +65,6 @@ static struct platform_driver ics43432_driver = {
                .of_match_table = of_match_ptr(ics43432_ids),
        },
        .probe = ics43432_probe,
-       .remove = ics43432_remove,
 };
 
 module_platform_driver(ics43432_driver);
index 6b59b6f082983d006cb6c49acb6b03339429945e..85a336ba75f60425c7374640412b8efbe6e97224 100644 (file)
@@ -196,10 +196,10 @@ static const struct snd_soc_dapm_route rk3036_codec_dapm_routes[] = {
 
 static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int reg01_val = 0,  reg02_val = 0, reg03_val = 0;
 
-       dev_dbg(codec->dev, "rk3036_codec dai set fmt : %08x\n", fmt);
+       dev_dbg(component->dev, "rk3036_codec dai set fmt : %08x\n", fmt);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -211,7 +211,7 @@ static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                             INNO_R01_I2SMODE_MASTER;
                break;
        default:
-               dev_err(codec->dev, "invalid fmt\n");
+               dev_err(component->dev, "invalid fmt\n");
                return -EINVAL;
        }
 
@@ -229,7 +229,7 @@ static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                reg02_val |= INNO_R02_DACM_LJM;
                break;
        default:
-               dev_err(codec->dev, "set dai format failed\n");
+               dev_err(component->dev, "set dai format failed\n");
                return -EINVAL;
        }
 
@@ -251,15 +251,15 @@ static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                reg03_val |= INNO_R03_BCP_REVERSAL;
                break;
        default:
-               dev_err(codec->dev, "set dai format failed\n");
+               dev_err(component->dev, "set dai format failed\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, INNO_R01, INNO_R01_I2SMODE_MSK |
+       snd_soc_component_update_bits(component, INNO_R01, INNO_R01_I2SMODE_MSK |
                            INNO_R01_PINDIR_MSK, reg01_val);
-       snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
+       snd_soc_component_update_bits(component, INNO_R02, INNO_R02_LRCP_MSK |
                            INNO_R02_DACM_MSK, reg02_val);
-       snd_soc_update_bits(codec, INNO_R03, INNO_R03_BCP_MSK, reg03_val);
+       snd_soc_component_update_bits(component, INNO_R03, INNO_R03_BCP_MSK, reg03_val);
 
        return 0;
 }
@@ -268,7 +268,7 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
                                      struct snd_pcm_hw_params *hw_params,
                                      struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int reg02_val = 0, reg03_val = 0;
 
        switch (params_format(hw_params)) {
@@ -291,9 +291,9 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
        reg02_val |= INNO_R02_LRCP_NORMAL;
        reg03_val |= INNO_R03_FWL_32BIT | INNO_R03_DACR_WORK;
 
-       snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
+       snd_soc_component_update_bits(component, INNO_R02, INNO_R02_LRCP_MSK |
                            INNO_R02_VWL_MSK, reg02_val);
-       snd_soc_update_bits(codec, INNO_R03, INNO_R03_DACR_MSK |
+       snd_soc_component_update_bits(component, INNO_R03, INNO_R03_DACR_MSK |
                            INNO_R03_FWL_MSK, reg03_val);
        return 0;
 }
@@ -330,43 +330,42 @@ static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = {
        },
 };
 
-static void rk3036_codec_reset(struct snd_soc_codec *codec)
+static void rk3036_codec_reset(struct snd_soc_component *component)
 {
-       snd_soc_write(codec, INNO_R00,
+       snd_soc_component_write(component, INNO_R00,
                      INNO_R00_CSR_RESET | INNO_R00_CDCR_RESET);
-       snd_soc_write(codec, INNO_R00,
+       snd_soc_component_write(component, INNO_R00,
                      INNO_R00_CSR_WORK | INNO_R00_CDCR_WORK);
 }
 
-static int rk3036_codec_probe(struct snd_soc_codec *codec)
+static int rk3036_codec_probe(struct snd_soc_component *component)
 {
-       rk3036_codec_reset(codec);
+       rk3036_codec_reset(component);
        return 0;
 }
 
-static int rk3036_codec_remove(struct snd_soc_codec *codec)
+static void rk3036_codec_remove(struct snd_soc_component *component)
 {
-       rk3036_codec_reset(codec);
-       return 0;
+       rk3036_codec_reset(component);
 }
 
-static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
+static int rk3036_codec_set_bias_level(struct snd_soc_component *component,
                                       enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_STANDBY:
                /* set a big current for capacitor charging. */
-               snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
+               snd_soc_component_write(component, INNO_R10, INNO_R10_MAX_CUR);
                /* start precharge */
-               snd_soc_write(codec, INNO_R06, INNO_R06_DAC_PRECHARGE);
+               snd_soc_component_write(component, INNO_R06, INNO_R06_DAC_PRECHARGE);
 
                break;
 
        case SND_SOC_BIAS_OFF:
                /* set a big current for capacitor discharging. */
-               snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
+               snd_soc_component_write(component, INNO_R10, INNO_R10_MAX_CUR);
                /* start discharge. */
-               snd_soc_write(codec, INNO_R06, INNO_R06_DAC_DISCHARGE);
+               snd_soc_component_write(component, INNO_R06, INNO_R06_DAC_DISCHARGE);
 
                break;
        default:
@@ -376,18 +375,20 @@ static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static const struct snd_soc_codec_driver rk3036_codec_driver = {
+static const struct snd_soc_component_driver rk3036_codec_driver = {
        .probe                  = rk3036_codec_probe,
        .remove                 = rk3036_codec_remove,
        .set_bias_level         = rk3036_codec_set_bias_level,
-       .component_driver = {
-               .controls               = rk3036_codec_dapm_controls,
-               .num_controls           = ARRAY_SIZE(rk3036_codec_dapm_controls),
-               .dapm_routes            = rk3036_codec_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rk3036_codec_dapm_routes),
-               .dapm_widgets           = rk3036_codec_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rk3036_codec_dapm_widgets),
-       },
+       .controls               = rk3036_codec_dapm_controls,
+       .num_controls           = ARRAY_SIZE(rk3036_codec_dapm_controls),
+       .dapm_routes            = rk3036_codec_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rk3036_codec_dapm_routes),
+       .dapm_widgets           = rk3036_codec_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rk3036_codec_dapm_widgets),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rk3036_codec_regmap_config = {
@@ -449,7 +450,7 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
        priv->dev = &pdev->dev;
        dev_set_drvdata(&pdev->dev, priv);
 
-       ret = snd_soc_register_codec(&pdev->dev, &rk3036_codec_driver,
+       ret = devm_snd_soc_register_component(&pdev->dev, &rk3036_codec_driver,
                                     rk3036_codec_dai_driver,
                                     ARRAY_SIZE(rk3036_codec_dai_driver));
        if (ret) {
@@ -464,7 +465,6 @@ static int rk3036_codec_platform_remove(struct platform_device *pdev)
 {
        struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_codec(&pdev->dev);
        clk_disable_unprepare(priv->pclk);
 
        return 0;
index 5ca99280ae0097bd59a36df4f6fc1c44ab8427fe..166420376e67efa12c49902453e0375ef2c5a1df 100644 (file)
@@ -867,7 +867,7 @@ static const struct snd_soc_dapm_route isabelle_intercon[] = {
 
 static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, ISABELLE_DAC1_SOFTRAMP_REG,
+       snd_soc_component_update_bits(dai->component, ISABELLE_DAC1_SOFTRAMP_REG,
                        BIT(4), (mute ? BIT(4) : 0));
 
        return 0;
@@ -875,7 +875,7 @@ static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute)
 
 static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, ISABELLE_DAC2_SOFTRAMP_REG,
+       snd_soc_component_update_bits(dai->component, ISABELLE_DAC2_SOFTRAMP_REG,
                        BIT(4), (mute ? BIT(4) : 0));
 
        return 0;
@@ -883,13 +883,13 @@ static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute)
 
 static int isabelle_line_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, ISABELLE_DAC3_SOFTRAMP_REG,
+       snd_soc_component_update_bits(dai->component, ISABELLE_DAC3_SOFTRAMP_REG,
                        BIT(4), (mute ? BIT(4) : 0));
 
        return 0;
 }
 
-static int isabelle_set_bias_level(struct snd_soc_codec *codec,
+static int isabelle_set_bias_level(struct snd_soc_component *component,
                                enum snd_soc_bias_level level)
 {
        switch (level) {
@@ -899,12 +899,12 @@ static int isabelle_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
+               snd_soc_component_update_bits(component, ISABELLE_PWR_EN_REG,
                                ISABELLE_CHIP_EN, BIT(0));
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
+               snd_soc_component_update_bits(component, ISABELLE_PWR_EN_REG,
                                ISABELLE_CHIP_EN, 0);
                break;
        }
@@ -916,7 +916,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
                              struct snd_pcm_hw_params *params,
                              struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 aif = 0;
        unsigned int fs_val = 0;
 
@@ -952,7 +952,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, ISABELLE_FS_RATE_CFG_REG,
+       snd_soc_component_update_bits(component, ISABELLE_FS_RATE_CFG_REG,
                        ISABELLE_FS_RATE_MASK, fs_val);
 
        /* bit size */
@@ -967,7 +967,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
+       snd_soc_component_update_bits(component, ISABELLE_INTF_CFG_REG,
                        ISABELLE_AIF_LENGTH_MASK, aif);
 
        return 0;
@@ -975,7 +975,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
 
 static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        unsigned int aif_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1003,7 +1003,7 @@ static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
+       snd_soc_component_update_bits(component, ISABELLE_INTF_CFG_REG,
                        (ISABELLE_AIF_MS | ISABELLE_AIF_FMT_MASK), aif_val);
 
        return 0;
@@ -1087,17 +1087,17 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_isabelle = {
-       .set_bias_level = isabelle_set_bias_level,
-       .component_driver = {
-               .controls               = isabelle_snd_controls,
-               .num_controls           = ARRAY_SIZE(isabelle_snd_controls),
-               .dapm_widgets           = isabelle_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(isabelle_dapm_widgets),
-               .dapm_routes            = isabelle_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(isabelle_intercon),
-       },
-       .idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_isabelle = {
+       .set_bias_level         = isabelle_set_bias_level,
+       .controls               = isabelle_snd_controls,
+       .num_controls           = ARRAY_SIZE(isabelle_snd_controls),
+       .dapm_widgets           = isabelle_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(isabelle_dapm_widgets),
+       .dapm_routes            = isabelle_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(isabelle_intercon),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config isabelle_regmap_config = {
@@ -1125,23 +1125,17 @@ static int isabelle_i2c_probe(struct i2c_client *i2c,
        }
        i2c_set_clientdata(i2c, isabelle_regmap);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                               &soc_codec_dev_isabelle, isabelle_dai,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                               &soc_component_dev_isabelle, isabelle_dai,
                                ARRAY_SIZE(isabelle_dai));
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
                return ret;
        }
 
        return ret;
 }
 
-static int isabelle_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id isabelle_i2c_id[] = {
        { "isabelle", 0 },
        { }
@@ -1153,7 +1147,6 @@ static struct i2c_driver isabelle_i2c_driver = {
                .name = "isabelle",
        },
        .probe = isabelle_i2c_probe,
-       .remove = isabelle_i2c_remove,
        .id_table = isabelle_i2c_id,
 };
 
index 6324ccdc8a5c556b00d3d80b81f8fe626743ca41..9395b583432ce482e76681bbbcf529cea8b7dadd 100644 (file)
@@ -157,7 +157,7 @@ static const struct snd_soc_dapm_route jz4740_codec_dapm_routes[] = {
 static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(dai->codec);
+       struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(dai->component);
        uint32_t val;
 
        switch (params_rate(params)) {
@@ -236,10 +236,10 @@ static void jz4740_codec_wakeup(struct regmap *regmap)
        regcache_sync(regmap);
 }
 
-static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
+static int jz4740_codec_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+       struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(component);
        struct regmap *regmap = jz4740_codec->regmap;
        unsigned int mask;
        unsigned int value;
@@ -257,7 +257,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_STANDBY:
                /* The only way to clear the suspend flag is to reset the codec */
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        jz4740_codec_wakeup(regmap);
 
                mask = JZ4740_CODEC_1_VREF_DISABLE |
@@ -283,9 +283,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
+static int jz4740_codec_dev_probe(struct snd_soc_component *component)
 {
-       struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+       struct jz4740_codec *jz4740_codec = snd_soc_component_get_drvdata(component);
 
        regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1,
                        JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
@@ -293,19 +293,21 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
-       .probe = jz4740_codec_dev_probe,
-       .set_bias_level = jz4740_codec_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = jz4740_codec_controls,
-               .num_controls           = ARRAY_SIZE(jz4740_codec_controls),
-               .dapm_widgets           = jz4740_codec_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(jz4740_codec_dapm_widgets),
-               .dapm_routes            = jz4740_codec_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(jz4740_codec_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_codec_dev_jz4740_codec = {
+       .probe                  = jz4740_codec_dev_probe,
+       .set_bias_level         = jz4740_codec_set_bias_level,
+       .controls               = jz4740_codec_controls,
+       .num_controls           = ARRAY_SIZE(jz4740_codec_controls),
+       .dapm_widgets           = jz4740_codec_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(jz4740_codec_dapm_widgets),
+       .dapm_routes            = jz4740_codec_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(jz4740_codec_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+
 };
 
 static const struct regmap_config jz4740_codec_regmap_config = {
@@ -343,7 +345,7 @@ static int jz4740_codec_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, jz4740_codec);
 
-       ret = snd_soc_register_codec(&pdev->dev,
+       ret = devm_snd_soc_register_component(&pdev->dev,
                        &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
        if (ret)
                dev_err(&pdev->dev, "Failed to register codec\n");
@@ -351,16 +353,8 @@ static int jz4740_codec_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int jz4740_codec_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-
-       return 0;
-}
-
 static struct platform_driver jz4740_codec_driver = {
        .probe = jz4740_codec_probe,
-       .remove = jz4740_codec_remove,
        .driver = {
                .name = "jz4740-codec",
        },
index 41e09d1287b8583479b4df23c3db83ddc465ef2e..59a646cc03d4a38d327ad4e3d74ee11de4635be9 100644 (file)
@@ -1110,7 +1110,7 @@ static int lm49453_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 clk_div = 0;
 
        /* Setting DAC clock dividers based on substream sample rate. */
@@ -1134,15 +1134,15 @@ static int lm49453_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, LM49453_P0_ADC_CLK_DIV_REG, clk_div);
-       snd_soc_write(codec, LM49453_P0_DAC_HP_CLK_DIV_REG, clk_div);
+       snd_soc_component_write(component, LM49453_P0_ADC_CLK_DIV_REG, clk_div);
+       snd_soc_component_write(component, LM49453_P0_DAC_HP_CLK_DIV_REG, clk_div);
 
        return 0;
 }
 
 static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        u16 aif_val;
        int mode = 0;
@@ -1185,11 +1185,11 @@ static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, LM49453_P0_AUDIO_PORT1_BASIC_REG,
+       snd_soc_component_update_bits(component, LM49453_P0_AUDIO_PORT1_BASIC_REG,
                            LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(0)|BIT(5),
                            (aif_val | mode | clk_phase));
 
-       snd_soc_write(codec, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift);
+       snd_soc_component_write(component, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift);
 
        return 0;
 }
@@ -1197,7 +1197,7 @@ static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 static int lm49453_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                                  unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 pll_clk = 0;
 
        switch (freq) {
@@ -1216,50 +1216,50 @@ static int lm49453_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG, BIT(4), pll_clk);
+       snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG, BIT(4), pll_clk);
 
        return 0;
 }
 
 static int lm49453_hp_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(1)|BIT(0),
+       snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(1)|BIT(0),
                            (mute ? (BIT(1)|BIT(0)) : 0));
        return 0;
 }
 
 static int lm49453_lo_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(3)|BIT(2),
+       snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(3)|BIT(2),
                            (mute ? (BIT(3)|BIT(2)) : 0));
        return 0;
 }
 
 static int lm49453_ls_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(5)|BIT(4),
+       snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(5)|BIT(4),
                            (mute ? (BIT(5)|BIT(4)) : 0));
        return 0;
 }
 
 static int lm49453_ep_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(4),
+       snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(4),
                            (mute ? BIT(4) : 0));
        return 0;
 }
 
 static int lm49453_ha_mute(struct snd_soc_dai *dai, int mute)
 {
-       snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(7)|BIT(6),
+       snd_soc_component_update_bits(dai->component, LM49453_P0_DAC_DSP_REG, BIT(7)|BIT(6),
                            (mute ? (BIT(7)|BIT(6)) : 0));
        return 0;
 }
 
-static int lm49453_set_bias_level(struct snd_soc_codec *codec,
+static int lm49453_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
+       struct lm49453_priv *lm49453 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -1267,15 +1267,15 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        regcache_sync(lm49453->regmap);
 
-               snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
+               snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG,
                                    LM49453_PMC_SETUP_CHIP_EN, LM49453_CHIP_EN);
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
+               snd_soc_component_update_bits(component, LM49453_P0_PMC_SETUP_REG,
                                    LM49453_PMC_SETUP_CHIP_EN, 0);
                break;
        }
@@ -1389,17 +1389,17 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
-       .set_bias_level = lm49453_set_bias_level,
-       .component_driver = {
-               .controls               = lm49453_snd_controls,
-               .num_controls           = ARRAY_SIZE(lm49453_snd_controls),
-               .dapm_widgets           = lm49453_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(lm49453_dapm_widgets),
-               .dapm_routes            = lm49453_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(lm49453_audio_map),
-       },
-       .idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_lm49453 = {
+       .set_bias_level         = lm49453_set_bias_level,
+       .controls               = lm49453_snd_controls,
+       .num_controls           = ARRAY_SIZE(lm49453_snd_controls),
+       .dapm_widgets           = lm49453_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(lm49453_dapm_widgets),
+       .dapm_routes            = lm49453_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(lm49453_audio_map),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config lm49453_regmap_config = {
@@ -1434,18 +1434,17 @@ static int lm49453_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                                     &soc_codec_dev_lm49453,
+       ret =  devm_snd_soc_register_component(&i2c->dev,
+                                     &soc_component_dev_lm49453,
                                      lm49453_dai, ARRAY_SIZE(lm49453_dai));
        if (ret < 0)
-               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 
        return ret;
 }
 
 static int lm49453_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
diff --git a/sound/soc/codecs/max9759.c b/sound/soc/codecs/max9759.c
new file mode 100644 (file)
index 0000000..ecfb4a8
--- /dev/null
@@ -0,0 +1,207 @@
+// SPDX-Licence-Identifier: GPL-2.0
+/*
+ * MAX9759 Amplifier Driver
+ *
+ * Copyright (c) 2017 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+#define DRV_NAME "max9759"
+
+struct max9759 {
+       struct gpio_desc *gpiod_shutdown;
+       struct gpio_desc *gpiod_mute;
+       struct gpio_descs *gpiod_gain;
+       bool is_mute;
+       unsigned int gain;
+};
+
+static int pga_event(struct snd_soc_dapm_widget *w,
+                    struct snd_kcontrol *control, int event)
+{
+       struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
+       struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+       if (SND_SOC_DAPM_EVENT_ON(event))
+               gpiod_set_value_cansleep(priv->gpiod_shutdown, 0);
+       else
+               gpiod_set_value_cansleep(priv->gpiod_shutdown, 1);
+
+       return 0;
+}
+
+/* From 6dB to 24dB in steps of 6dB */
+static const DECLARE_TLV_DB_SCALE(speaker_gain_tlv, 600, 600, 0);
+
+static int speaker_gain_control_get(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+       struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+       ucontrol->value.integer.value[0] = priv->gain;
+
+       return 0;
+}
+
+static const bool speaker_gain_table[4][2] = {
+       /* G1, G2 */
+       {true, true},   /* +6dB */
+       {false, true},  /* +12dB */
+       {true, false},  /* +18dB */
+       {false, false}, /* +24dB */
+};
+
+static int speaker_gain_control_put(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+       struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+       if (ucontrol->value.integer.value[0] > 3)
+               return -EINVAL;
+
+       priv->gain = ucontrol->value.integer.value[0];
+
+       /* G1 */
+       gpiod_set_value_cansleep(priv->gpiod_gain->desc[0],
+                                speaker_gain_table[priv->gain][0]);
+       /* G2 */
+       gpiod_set_value_cansleep(priv->gpiod_gain->desc[1],
+                                speaker_gain_table[priv->gain][1]);
+
+       return 1;
+}
+
+static int speaker_mute_get(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+       struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+       ucontrol->value.integer.value[0] = !priv->is_mute;
+
+       return 0;
+}
+
+static int speaker_mute_put(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
+       struct max9759 *priv = snd_soc_component_get_drvdata(c);
+
+       priv->is_mute = !ucontrol->value.integer.value[0];
+
+       gpiod_set_value_cansleep(priv->gpiod_mute, priv->is_mute);
+
+       return 1;
+}
+
+static const struct snd_kcontrol_new max9759_dapm_controls[] = {
+       SOC_SINGLE_EXT_TLV("Speaker Gain Volume", 0, 0, 3, 0,
+                          speaker_gain_control_get, speaker_gain_control_put,
+                          speaker_gain_tlv),
+       SOC_SINGLE_BOOL_EXT("Playback Switch", 0,
+                           speaker_mute_get, speaker_mute_put),
+};
+
+static const struct snd_soc_dapm_widget max9759_dapm_widgets[] = {
+       SND_SOC_DAPM_INPUT("INL"),
+       SND_SOC_DAPM_INPUT("INR"),
+       SND_SOC_DAPM_PGA_E("PGA", SND_SOC_NOPM, 0, 0, NULL, 0, pga_event,
+                          (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)),
+       SND_SOC_DAPM_OUTPUT("OUTL"),
+       SND_SOC_DAPM_OUTPUT("OUTR"),
+};
+
+static const struct snd_soc_dapm_route max9759_dapm_routes[] = {
+       { "PGA", NULL, "INL" },
+       { "PGA", NULL, "INR" },
+       { "OUTL", NULL, "PGA" },
+       { "OUTR", NULL, "PGA" },
+};
+
+static const struct snd_soc_component_driver max9759_component_driver = {
+       .controls               = max9759_dapm_controls,
+       .num_controls           = ARRAY_SIZE(max9759_dapm_controls),
+       .dapm_widgets           = max9759_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max9759_dapm_widgets),
+       .dapm_routes            = max9759_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(max9759_dapm_routes),
+};
+
+static int max9759_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct max9759 *priv;
+       int err;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, priv);
+
+       priv->gpiod_shutdown = devm_gpiod_get(dev, "shutdown", GPIOD_OUT_HIGH);
+       if (IS_ERR(priv->gpiod_shutdown)) {
+               err = PTR_ERR(priv->gpiod_shutdown);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'shutdown' gpio: %d", err);
+               return err;
+       }
+
+       priv->gpiod_mute = devm_gpiod_get(dev, "mute", GPIOD_OUT_HIGH);
+       if (IS_ERR(priv->gpiod_mute)) {
+               err = PTR_ERR(priv->gpiod_mute);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'mute' gpio: %d", err);
+               return err;
+       }
+       priv->is_mute = true;
+
+       priv->gpiod_gain = devm_gpiod_get_array(dev, "gain", GPIOD_OUT_HIGH);
+       if (IS_ERR(priv->gpiod_gain)) {
+               err = PTR_ERR(priv->gpiod_gain);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'gain' gpios: %d", err);
+               return err;
+       }
+       priv->gain = 0;
+
+       if (priv->gpiod_gain->ndescs != 2) {
+               dev_err(dev, "Invalid 'gain' gpios count: %d",
+                       priv->gpiod_gain->ndescs);
+               return -EINVAL;
+       }
+
+       return devm_snd_soc_register_component(dev, &max9759_component_driver,
+                                              NULL, 0);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id max9759_ids[] = {
+       { .compatible = "maxim,max9759", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, max9759_ids);
+#endif
+
+static struct platform_driver max9759_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .of_match_table = of_match_ptr(max9759_ids),
+       },
+       .probe = max9759_probe,
+};
+
+module_platform_driver(max9759_driver);
+
+MODULE_DESCRIPTION("ASoC MAX9759 amplifier driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL");
index f0bb830874e59ab9c2b544e961143c0a4515c6ce..865f64c40b79fe7cc1edaaefcb3ef47f3871f3f0 100644 (file)
@@ -307,7 +307,7 @@ static const struct regmap_config max98088_regmap = {
 /*
  * Load equalizer DSP coefficient configurations registers
  */
-static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai,
+static void m98088_eq_band(struct snd_soc_component *component, unsigned int dai,
                    unsigned int band, u16 *coefs)
 {
        unsigned int eq_reg;
@@ -325,8 +325,8 @@ static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai,
 
        /* Step through the registers and coefs */
        for (i = 0; i < M98088_COEFS_PER_BAND; i++) {
-               snd_soc_write(codec, eq_reg++, M98088_BYTE1(coefs[i]));
-               snd_soc_write(codec, eq_reg++, M98088_BYTE0(coefs[i]));
+               snd_soc_component_write(component, eq_reg++, M98088_BYTE1(coefs[i]));
+               snd_soc_component_write(component, eq_reg++, M98088_BYTE0(coefs[i]));
        }
 }
 
@@ -380,12 +380,12 @@ static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum,
 static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        unsigned int sel = ucontrol->value.integer.value[0];
 
        max98088->mic1pre = sel;
-       snd_soc_update_bits(codec, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,
+       snd_soc_component_update_bits(component, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,
                (1+sel)<<M98088_MICPRE_SHIFT);
 
        return 0;
@@ -394,8 +394,8 @@ static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
 static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = max98088->mic1pre;
        return 0;
@@ -404,12 +404,12 @@ static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,
 static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        unsigned int sel = ucontrol->value.integer.value[0];
 
        max98088->mic2pre = sel;
-       snd_soc_update_bits(codec, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,
+       snd_soc_component_update_bits(component, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,
                (1+sel)<<M98088_MICPRE_SHIFT);
 
        return 0;
@@ -418,8 +418,8 @@ static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,
 static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = max98088->mic2pre;
        return 0;
@@ -617,21 +617,21 @@ static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = {
 static int max98088_mic_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                if (w->reg == M98088_REG_35_LVL_MIC1) {
-                       snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
+                       snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK,
                                (1+max98088->mic1pre)<<M98088_MICPRE_SHIFT);
                } else {
-                       snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
+                       snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK,
                                (1+max98088->mic2pre)<<M98088_MICPRE_SHIFT);
                }
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, 0);
+               snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK, 0);
                break;
        default:
                return -EINVAL;
@@ -647,8 +647,8 @@ static int max98088_mic_event(struct snd_soc_dapm_widget *w,
 static int max98088_line_pga(struct snd_soc_dapm_widget *w,
                             int event, int line, u8 channel)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        u8 *state;
 
        if (WARN_ON(!(channel == 1 || channel == 2)))
@@ -668,13 +668,13 @@ static int max98088_line_pga(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                *state |= channel;
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                        (1 << w->shift), (1 << w->shift));
                break;
        case SND_SOC_DAPM_POST_PMD:
                *state &= ~channel;
                if (*state == 0) {
-                       snd_soc_update_bits(codec, w->reg,
+                       snd_soc_component_update_bits(component, w->reg,
                                (1 << w->shift), 0);
                }
                break;
@@ -963,8 +963,8 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -976,51 +976,51 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,
                        M98088_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,
                        M98088_DAI_WS, M98088_DAI_WS);
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
 
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98088_REG_11_DAI1_CLKMODE,
+       snd_soc_component_update_bits(component, M98088_REG_11_DAI1_CLKMODE,
                M98088_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98088_REG_14_DAI1_FORMAT)
+       if (snd_soc_component_read32(component, M98088_REG_14_DAI1_FORMAT)
                & M98088_DAI_MAS) {
                if (max98088->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98088->sysclk);
-               snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
+               snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
+               snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_18_DAI1_FILTERS,
                        M98088_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_18_DAI1_FILTERS,
                        M98088_DAI_DHF, M98088_DAI_DHF);
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
                M98088_SHDNRUN);
 
        return 0;
@@ -1030,8 +1030,8 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -1043,51 +1043,51 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,
                        M98088_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,
                        M98088_DAI_WS, M98088_DAI_WS);
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
 
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98088_REG_19_DAI2_CLKMODE,
+       snd_soc_component_update_bits(component, M98088_REG_19_DAI2_CLKMODE,
                M98088_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98088_REG_1C_DAI2_FORMAT)
+       if (snd_soc_component_read32(component, M98088_REG_1C_DAI2_FORMAT)
                & M98088_DAI_MAS) {
                if (max98088->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98088->sysclk);
-               snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
+               snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
+               snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_20_DAI2_FILTERS,
                        M98088_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
+               snd_soc_component_update_bits(component, M98088_REG_20_DAI2_FILTERS,
                        M98088_DAI_DHF, M98088_DAI_DHF);
 
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
+       snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
                M98088_SHDNRUN);
 
        return 0;
@@ -1096,8 +1096,8 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
 static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
                                   int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        /* Requested clock frequency is already setup */
        if (freq == max98088->sysclk)
@@ -1108,18 +1108,18 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
         *         0x02 (when master clk is 20MHz to 30MHz)..
         */
        if ((freq >= 10000000) && (freq < 20000000)) {
-               snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x10);
+               snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x10);
        } else if ((freq >= 20000000) && (freq < 30000000)) {
-               snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x20);
+               snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x20);
        } else {
-               dev_err(codec->dev, "Invalid master clock frequency\n");
+               dev_err(component->dev, "Invalid master clock frequency\n");
                return -EINVAL;
        }
 
-       if (snd_soc_read(codec, M98088_REG_51_PWR_SYS)  & M98088_SHDNRUN) {
-               snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
+       if (snd_soc_component_read32(component, M98088_REG_51_PWR_SYS)  & M98088_SHDNRUN) {
+               snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS,
                        M98088_SHDNRUN, 0);
-               snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
+               snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS,
                        M98088_SHDNRUN, M98088_SHDNRUN);
        }
 
@@ -1132,8 +1132,8 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
 static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        u8 reg15val;
        u8 reg14val = 0;
@@ -1146,9 +1146,9 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
+                       snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
+                       snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1158,7 +1158,7 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1188,14 +1188,14 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,
                        M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
                        M98088_DAI_WCI, reg14val);
 
                reg15val = M98088_DAI_BSEL64;
                if (max98088->digmic)
                        reg15val |= M98088_DAI_OSR64;
-               snd_soc_write(codec, M98088_REG_15_DAI1_CLOCK, reg15val);
+               snd_soc_component_write(component, M98088_REG_15_DAI1_CLOCK, reg15val);
        }
 
        return 0;
@@ -1204,8 +1204,8 @@ static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        u8 reg1Cval = 0;
 
@@ -1217,9 +1217,9 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
+                       snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
+                       snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1229,7 +1229,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1259,11 +1259,11 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,
                        M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
                        M98088_DAI_WCI, reg1Cval);
 
-               snd_soc_write(codec, M98088_REG_1D_DAI2_CLOCK,
+               snd_soc_component_write(component, M98088_REG_1D_DAI2_CLOCK,
                        M98088_DAI_BSEL64);
        }
 
@@ -1272,7 +1272,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 
 static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int reg;
 
        if (mute)
@@ -1280,14 +1280,14 @@ static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
        else
                reg = 0;
 
-       snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
+       snd_soc_component_update_bits(component, M98088_REG_2F_LVL_DAI1_PLAY,
                            M98088_DAI_MUTE_MASK, reg);
        return 0;
 }
 
 static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int reg;
 
        if (mute)
@@ -1295,15 +1295,15 @@ static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
        else
                reg = 0;
 
-       snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
+       snd_soc_component_update_bits(component, M98088_REG_31_LVL_DAI2_PLAY,
                            M98088_DAI_MUTE_MASK, reg);
        return 0;
 }
 
-static int max98088_set_bias_level(struct snd_soc_codec *codec,
+static int max98088_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -1313,15 +1313,15 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        regcache_sync(max98088->regmap);
 
-               snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
+               snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN,
                                   M98088_MBEN, M98088_MBEN);
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
+               snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN,
                                    M98088_MBEN, 0);
                regcache_mark_dirty(max98088->regmap);
                break;
@@ -1380,7 +1380,7 @@ static struct snd_soc_dai_driver max98088_dai[] = {
 
 static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};
 
-static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
+static int max98088_get_channel(struct snd_soc_component *component, const char *name)
 {
        int i;
 
@@ -1389,13 +1389,13 @@ static int max98088_get_channel(struct snd_soc_codec *codec, const char *name)
                        return i;
 
        /* Shouldn't happen */
-       dev_err(codec->dev, "Bad EQ channel name '%s'\n", name);
+       dev_err(component->dev, "Bad EQ channel name '%s'\n", name);
        return -EINVAL;
 }
 
-static void max98088_setup_eq1(struct snd_soc_codec *codec)
+static void max98088_setup_eq1(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        struct max98088_eq_cfg *coef_set;
        int best, best_val, save, i, sel, fs;
@@ -1420,29 +1420,29 @@ static void max98088_setup_eq1(struct snd_soc_codec *codec)
                }
        }
 
-       dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+       dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
                pdata->eq_cfg[best].name,
                pdata->eq_cfg[best].rate, fs);
 
        /* Disable EQ while configuring, and save current on/off state */
-       save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);
+       save = snd_soc_component_read32(component, M98088_REG_49_CFG_LEVEL);
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);
 
        coef_set = &pdata->eq_cfg[sel];
 
-       m98088_eq_band(codec, 0, 0, coef_set->band1);
-       m98088_eq_band(codec, 0, 1, coef_set->band2);
-       m98088_eq_band(codec, 0, 2, coef_set->band3);
-       m98088_eq_band(codec, 0, 3, coef_set->band4);
-       m98088_eq_band(codec, 0, 4, coef_set->band5);
+       m98088_eq_band(component, 0, 0, coef_set->band1);
+       m98088_eq_band(component, 0, 1, coef_set->band2);
+       m98088_eq_band(component, 0, 2, coef_set->band3);
+       m98088_eq_band(component, 0, 3, coef_set->band4);
+       m98088_eq_band(component, 0, 4, coef_set->band5);
 
        /* Restore the original on/off state */
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);
 }
 
-static void max98088_setup_eq2(struct snd_soc_codec *codec)
+static void max98088_setup_eq2(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        struct max98088_eq_cfg *coef_set;
        int best, best_val, save, i, sel, fs;
@@ -1467,34 +1467,34 @@ static void max98088_setup_eq2(struct snd_soc_codec *codec)
                }
        }
 
-       dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+       dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
                pdata->eq_cfg[best].name,
                pdata->eq_cfg[best].rate, fs);
 
        /* Disable EQ while configuring, and save current on/off state */
-       save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);
+       save = snd_soc_component_read32(component, M98088_REG_49_CFG_LEVEL);
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);
 
        coef_set = &pdata->eq_cfg[sel];
 
-       m98088_eq_band(codec, 1, 0, coef_set->band1);
-       m98088_eq_band(codec, 1, 1, coef_set->band2);
-       m98088_eq_band(codec, 1, 2, coef_set->band3);
-       m98088_eq_band(codec, 1, 3, coef_set->band4);
-       m98088_eq_band(codec, 1, 4, coef_set->band5);
+       m98088_eq_band(component, 1, 0, coef_set->band1);
+       m98088_eq_band(component, 1, 1, coef_set->band2);
+       m98088_eq_band(component, 1, 2, coef_set->band3);
+       m98088_eq_band(component, 1, 3, coef_set->band4);
+       m98088_eq_band(component, 1, 4, coef_set->band5);
 
        /* Restore the original on/off state */
-       snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,
+       snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,
                save);
 }
 
 static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
-       int channel = max98088_get_channel(codec, kcontrol->id.name);
+       int channel = max98088_get_channel(component, kcontrol->id.name);
        struct max98088_cdata *cdata;
        int sel = ucontrol->value.enumerated.item[0];
 
@@ -1510,10 +1510,10 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
 
        switch (channel) {
        case 0:
-               max98088_setup_eq1(codec);
+               max98088_setup_eq1(component);
                break;
        case 1:
-               max98088_setup_eq2(codec);
+               max98088_setup_eq2(component);
                break;
        }
 
@@ -1523,9 +1523,9 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
 static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-       int channel = max98088_get_channel(codec, kcontrol->id.name);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
+       int channel = max98088_get_channel(component, kcontrol->id.name);
        struct max98088_cdata *cdata;
 
        if (channel < 0)
@@ -1536,9 +1536,9 @@ static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
+static void max98088_handle_eq_pdata(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        struct max98088_eq_cfg *cfg;
        unsigned int cfgcnt;
@@ -1591,19 +1591,19 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
        max98088->eq_enum.texts = max98088->eq_texts;
        max98088->eq_enum.items = max98088->eq_textcnt;
 
-       ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+       ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
+               dev_err(component->dev, "Failed to add EQ control: %d\n", ret);
 }
 
-static void max98088_handle_pdata(struct snd_soc_codec *codec)
+static void max98088_handle_pdata(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_pdata *pdata = max98088->pdata;
        u8 regval = 0;
 
        if (!pdata) {
-               dev_dbg(codec->dev, "No platform data\n");
+               dev_dbg(component->dev, "No platform data\n");
                return;
        }
 
@@ -1616,21 +1616,21 @@ static void max98088_handle_pdata(struct snd_soc_codec *codec)
 
        max98088->digmic = (regval ? 1 : 0);
 
-       snd_soc_write(codec, M98088_REG_48_CFG_MIC, regval);
+       snd_soc_component_write(component, M98088_REG_48_CFG_MIC, regval);
 
        /* Configure receiver output */
        regval = ((pdata->receiver_mode) ? M98088_REC_LINEMODE : 0);
-       snd_soc_update_bits(codec, M98088_REG_2A_MIC_REC_CNTL,
+       snd_soc_component_update_bits(component, M98088_REG_2A_MIC_REC_CNTL,
                M98088_REC_LINEMODE_MASK, regval);
 
        /* Configure equalizers */
        if (pdata->eq_cfgcnt)
-               max98088_handle_eq_pdata(codec);
+               max98088_handle_eq_pdata(component);
 }
 
-static int max98088_probe(struct snd_soc_codec *codec)
+static int max98088_probe(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
        struct max98088_cdata *cdata;
        int ret = 0;
 
@@ -1658,60 +1658,59 @@ static int max98088_probe(struct snd_soc_codec *codec)
        max98088->mic1pre = 0;
        max98088->mic2pre = 0;
 
-       ret = snd_soc_read(codec, M98088_REG_FF_REV_ID);
+       ret = snd_soc_component_read32(component, M98088_REG_FF_REV_ID);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to read device revision: %d\n",
+               dev_err(component->dev, "Failed to read device revision: %d\n",
                        ret);
                goto err_access;
        }
-       dev_info(codec->dev, "revision %c\n", ret - 0x40 + 'A');
+       dev_info(component->dev, "revision %c\n", ret - 0x40 + 'A');
 
-       snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV);
+       snd_soc_component_write(component, M98088_REG_51_PWR_SYS, M98088_PWRSV);
 
-       snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00);
+       snd_soc_component_write(component, M98088_REG_0F_IRQ_ENABLE, 0x00);
 
-       snd_soc_write(codec, M98088_REG_22_MIX_DAC,
+       snd_soc_component_write(component, M98088_REG_22_MIX_DAC,
                M98088_DAI1L_TO_DACL|M98088_DAI2L_TO_DACL|
                M98088_DAI1R_TO_DACR|M98088_DAI2R_TO_DACR);
 
-       snd_soc_write(codec, M98088_REG_4E_BIAS_CNTL, 0xF0);
-       snd_soc_write(codec, M98088_REG_50_DAC_BIAS2, 0x0F);
+       snd_soc_component_write(component, M98088_REG_4E_BIAS_CNTL, 0xF0);
+       snd_soc_component_write(component, M98088_REG_50_DAC_BIAS2, 0x0F);
 
-       snd_soc_write(codec, M98088_REG_16_DAI1_IOCFG,
+       snd_soc_component_write(component, M98088_REG_16_DAI1_IOCFG,
                M98088_S1NORMAL|M98088_SDATA);
 
-       snd_soc_write(codec, M98088_REG_1E_DAI2_IOCFG,
+       snd_soc_component_write(component, M98088_REG_1E_DAI2_IOCFG,
                M98088_S2NORMAL|M98088_SDATA);
 
-       max98088_handle_pdata(codec);
+       max98088_handle_pdata(component);
 
 err_access:
        return ret;
 }
 
-static int max98088_remove(struct snd_soc_codec *codec)
+static void max98088_remove(struct snd_soc_component *component)
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);
 
        kfree(max98088->eq_texts);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98088 = {
-       .probe   = max98088_probe,
-       .remove  = max98088_remove,
-       .set_bias_level = max98088_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = max98088_snd_controls,
-               .num_controls           = ARRAY_SIZE(max98088_snd_controls),
-               .dapm_widgets           = max98088_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max98088_dapm_widgets),
-               .dapm_routes            = max98088_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(max98088_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_max98088 = {
+       .probe                  = max98088_probe,
+       .remove                 = max98088_remove,
+       .set_bias_level         = max98088_set_bias_level,
+       .controls               = max98088_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98088_snd_controls),
+       .dapm_widgets           = max98088_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98088_dapm_widgets),
+       .dapm_routes            = max98088_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98088_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int max98088_i2c_probe(struct i2c_client *i2c,
@@ -1734,17 +1733,11 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
        i2c_set_clientdata(i2c, max98088);
        max98088->pdata = i2c->dev.platform_data;
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_max98088, &max98088_dai[0], 2);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_max98088, &max98088_dai[0], 2);
        return ret;
 }
 
-static int max98088_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98088_i2c_id[] = {
        { "max98088", MAX98088 },
        { "max98089", MAX98089 },
@@ -1757,7 +1750,6 @@ static struct i2c_driver max98088_i2c_driver = {
                .name = "max98088",
        },
        .probe  = max98088_i2c_probe,
-       .remove = max98088_i2c_remove,
        .id_table = max98088_i2c_id,
 };
 
index f5075d1f79e6360abef58526908f351b341546b1..c97f21836c66a241e4119e6a7cc2a22a171f6097 100644 (file)
@@ -284,7 +284,7 @@ static int max98090_reset(struct max98090_priv *max98090)
        ret = regmap_write(max98090->regmap, M98090_REG_SOFTWARE_RESET,
                M98090_SWRESET_MASK);
        if (ret < 0) {
-               dev_err(max98090->codec->dev,
+               dev_err(max98090->component->dev,
                        "Failed to reset codec: %d\n", ret);
                return ret;
        }
@@ -354,12 +354,12 @@ static const DECLARE_TLV_DB_RANGE(max98090_rcv_lout_tlv,
 static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int mask = (1 << fls(mc->max)) - 1;
-       unsigned int val = snd_soc_read(codec, mc->reg);
+       unsigned int val = snd_soc_component_read32(component, mc->reg);
        unsigned int *select;
 
        switch (mc->reg) {
@@ -394,13 +394,13 @@ static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
 static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int mask = (1 << fls(mc->max)) - 1;
        unsigned int sel = ucontrol->value.integer.value[0];
-       unsigned int val = snd_soc_read(codec, mc->reg);
+       unsigned int val = snd_soc_component_read32(component, mc->reg);
        unsigned int *select;
 
        switch (mc->reg) {
@@ -429,7 +429,7 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
                sel = val;
        }
 
-       snd_soc_update_bits(codec, mc->reg,
+       snd_soc_component_update_bits(component, mc->reg,
                mask << mc->shift,
                sel << mc->shift);
 
@@ -733,10 +733,10 @@ static const struct snd_kcontrol_new max98091_snd_controls[] = {
 static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
                                 struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
-       unsigned int val = snd_soc_read(codec, w->reg);
+       unsigned int val = snd_soc_component_read32(component, w->reg);
 
        if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
                val = (val & M98090_MIC_PA1EN_MASK) >> M98090_MIC_PA1EN_SHIFT;
@@ -768,10 +768,10 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
        }
 
        if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
-               snd_soc_update_bits(codec, w->reg, M98090_MIC_PA1EN_MASK,
+               snd_soc_component_update_bits(component, w->reg, M98090_MIC_PA1EN_MASK,
                        val << M98090_MIC_PA1EN_SHIFT);
        else
-               snd_soc_update_bits(codec, w->reg, M98090_MIC_PA2EN_MASK,
+               snd_soc_component_update_bits(component, w->reg, M98090_MIC_PA2EN_MASK,
                        val << M98090_MIC_PA2EN_SHIFT);
 
        return 0;
@@ -780,8 +780,8 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
 static int max98090_shdn_event(struct snd_soc_dapm_widget *w,
                                 struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
        if (event & SND_SOC_DAPM_POST_PMU)
                max98090->shdn_pending = true;
@@ -1441,16 +1441,16 @@ static const struct snd_soc_dapm_route max98091_dapm_routes[] = {
        {"DMIC4", NULL, "AHPF"},
 };
 
-static int max98090_add_widgets(struct snd_soc_codec *codec)
+static int max98090_add_widgets(struct snd_soc_component *component)
 {
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-       snd_soc_add_codec_controls(codec, max98090_snd_controls,
+       snd_soc_add_component_controls(component, max98090_snd_controls,
                ARRAY_SIZE(max98090_snd_controls));
 
        if (max98090->devtype == MAX98091) {
-               snd_soc_add_codec_controls(codec, max98091_snd_controls,
+               snd_soc_add_component_controls(component, max98091_snd_controls,
                        ARRAY_SIZE(max98091_snd_controls));
        }
 
@@ -1497,24 +1497,24 @@ static const unsigned long long mi_value[] = {
        8125, 1625, 1500, 25
 };
 
-static void max98090_configure_bclk(struct snd_soc_codec *codec)
+static void max98090_configure_bclk(struct snd_soc_component *component)
 {
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        unsigned long long ni;
        int i;
 
        if (!max98090->sysclk) {
-               dev_err(codec->dev, "No SYSCLK configured\n");
+               dev_err(component->dev, "No SYSCLK configured\n");
                return;
        }
 
        if (!max98090->bclk || !max98090->lrclk) {
-               dev_err(codec->dev, "No audio clocks configured\n");
+               dev_err(component->dev, "No audio clocks configured\n");
                return;
        }
 
        /* Skip configuration when operating as slave */
-       if (!(snd_soc_read(codec, M98090_REG_MASTER_MODE) &
+       if (!(snd_soc_component_read32(component, M98090_REG_MASTER_MODE) &
                M98090_MAS_MASK)) {
                return;
        }
@@ -1523,14 +1523,14 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
        for (i = 0; i < ARRAY_SIZE(pclk_rates); i++) {
                if ((pclk_rates[i] == max98090->sysclk) &&
                        (lrclk_rates[i] == max98090->lrclk)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Found supported PCLK to LRCLK rates 0x%x\n",
                                i + 0x8);
 
-                       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+                       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                                M98090_FREQ_MASK,
                                (i + 0x8) << M98090_FREQ_SHIFT);
-                       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+                       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                                M98090_USE_M1_MASK, 0);
                        return;
                }
@@ -1540,24 +1540,24 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
        for (i = 0; i < ARRAY_SIZE(user_pclk_rates); i++) {
                if ((user_pclk_rates[i] == max98090->sysclk) &&
                        (user_lrclk_rates[i] == max98090->lrclk)) {
-                       dev_dbg(codec->dev,
+                       dev_dbg(component->dev,
                                "Found user supported PCLK to LRCLK rates\n");
-                       dev_dbg(codec->dev, "i %d ni %lld mi %lld\n",
+                       dev_dbg(component->dev, "i %d ni %lld mi %lld\n",
                                i, ni_value[i], mi_value[i]);
 
-                       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+                       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                                M98090_FREQ_MASK, 0);
-                       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+                       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                                M98090_USE_M1_MASK,
                                        1 << M98090_USE_M1_SHIFT);
 
-                       snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_MSB,
+                       snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_MSB,
                                (ni_value[i] >> 8) & 0x7F);
-                       snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_LSB,
+                       snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_LSB,
                                ni_value[i] & 0xFF);
-                       snd_soc_write(codec, M98090_REG_CLOCK_RATIO_MI_MSB,
+                       snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_MI_MSB,
                                (mi_value[i] >> 8) & 0x7F);
-                       snd_soc_write(codec, M98090_REG_CLOCK_RATIO_MI_LSB,
+                       snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_MI_LSB,
                                mi_value[i] & 0xFF);
 
                        return;
@@ -1567,9 +1567,9 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
        /*
         * Calculate based on MI = 65536 (not as good as either method above)
         */
-       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                M98090_FREQ_MASK, 0);
-       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                M98090_USE_M1_MASK, 0);
 
        /*
@@ -1580,18 +1580,18 @@ static void max98090_configure_bclk(struct snd_soc_codec *codec)
        ni = 65536ULL * (max98090->lrclk < 50000 ? 96ULL : 48ULL)
                        * (unsigned long long int)max98090->lrclk;
        do_div(ni, (unsigned long long int)max98090->sysclk);
-       dev_info(codec->dev, "No better method found\n");
-       dev_info(codec->dev, "Calculating ni %lld with mi 65536\n", ni);
-       snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_MSB,
+       dev_info(component->dev, "No better method found\n");
+       dev_info(component->dev, "Calculating ni %lld with mi 65536\n", ni);
+       snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_MSB,
                (ni >> 8) & 0x7F);
-       snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_LSB, ni & 0xFF);
+       snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_LSB, ni & 0xFF);
 }
 
 static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        struct max98090_cdata *cdata;
        u8 regval;
 
@@ -1605,11 +1605,11 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Set to slave mode PLL - MAS mode off */
-                       snd_soc_write(codec,
+                       snd_soc_component_write(component,
                                M98090_REG_CLOCK_RATIO_NI_MSB, 0x00);
-                       snd_soc_write(codec,
+                       snd_soc_component_write(component,
                                M98090_REG_CLOCK_RATIO_NI_LSB, 0x00);
-                       snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
+                       snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
                                M98090_USE_M1_MASK, 0);
                        max98090->master = false;
                        break;
@@ -1633,10 +1633,10 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "DAI clock mode unsupported");
+                       dev_err(component->dev, "DAI clock mode unsupported");
                        return -EINVAL;
                }
-               snd_soc_write(codec, M98090_REG_MASTER_MODE, regval);
+               snd_soc_component_write(component, M98090_REG_MASTER_MODE, regval);
 
                regval = 0;
                switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1651,7 +1651,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_DSP_A:
                        /* Not supported mode */
                default:
-                       dev_err(codec->dev, "DAI format unsupported");
+                       dev_err(component->dev, "DAI format unsupported");
                        return -EINVAL;
                }
 
@@ -1668,7 +1668,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
                        regval |= M98090_BCI_MASK|M98090_WCI_MASK;
                        break;
                default:
-                       dev_err(codec->dev, "DAI invert mode unsupported");
+                       dev_err(component->dev, "DAI invert mode unsupported");
                        return -EINVAL;
                }
 
@@ -1681,7 +1681,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
                if (max98090->tdm_slots > 1)
                        regval ^= M98090_BCI_MASK;
 
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        M98090_REG_INTERFACE_FORMAT, regval);
        }
 
@@ -1691,8 +1691,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        struct max98090_cdata *cdata;
        cdata = &max98090->dai[0];
 
@@ -1704,13 +1704,13 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
 
        if (max98090->tdm_slots > 1) {
                /* SLOTL SLOTR SLOTDLY */
-               snd_soc_write(codec, M98090_REG_TDM_FORMAT,
+               snd_soc_component_write(component, M98090_REG_TDM_FORMAT,
                        0 << M98090_TDM_SLOTL_SHIFT |
                        1 << M98090_TDM_SLOTR_SHIFT |
                        0 << M98090_TDM_SLOTDLY_SHIFT);
 
                /* FSW TDM */
-               snd_soc_update_bits(codec, M98090_REG_TDM_CONTROL,
+               snd_soc_component_update_bits(component, M98090_REG_TDM_CONTROL,
                        M98090_TDM_MASK,
                        M98090_TDM_MASK);
        }
@@ -1724,10 +1724,10 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int max98090_set_bias_level(struct snd_soc_codec *codec,
+static int max98090_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1745,7 +1745,7 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
                if (IS_ERR(max98090->mclk))
                        break;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
                        clk_disable_unprepare(max98090->mclk);
                } else {
                        ret = clk_prepare_enable(max98090->mclk);
@@ -1755,10 +1755,10 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regcache_sync(max98090->regmap);
                        if (ret != 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to sync cache: %d\n", ret);
                                return ret;
                        }
@@ -1767,7 +1767,7 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_OFF:
                /* Set internal pull-up to lowest power mode */
-               snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
+               snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
                        M98090_JDWK_MASK, M98090_JDWK_MASK);
                regcache_mark_dirty(max98090->regmap);
                break;
@@ -1928,8 +1928,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        struct max98090_cdata *cdata;
 
        cdata = &max98090->dai[0];
@@ -1941,7 +1941,7 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
+               snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
                        M98090_WS_MASK, 0);
                break;
        default:
@@ -1949,24 +1949,24 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (max98090->master)
-               max98090_configure_bclk(codec);
+               max98090_configure_bclk(component);
 
        cdata->rate = max98090->lrclk;
 
        /* Update filter mode */
        if (max98090->lrclk < 24000)
-               snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+               snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
                        M98090_MODE_MASK, 0);
        else
-               snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+               snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
                        M98090_MODE_MASK, M98090_MODE_MASK);
 
        /* Update sample rate mode */
        if (max98090->lrclk < 50000)
-               snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+               snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
                        M98090_DHF_MASK, 0);
        else
-               snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
+               snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
                        M98090_DHF_MASK, M98090_DHF_MASK);
 
        max98090_configure_dmic(max98090, max98090->dmic_freq, max98090->pclk,
@@ -1981,8 +1981,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
 static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
                                   int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
        /* Requested clock frequency is already setup */
        if (freq == max98090->sysclk)
@@ -1999,19 +1999,19 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
         *               0x03 (when master clk is 40MHz to 60MHz)..
         */
        if ((freq >= 10000000) && (freq <= 20000000)) {
-               snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
+               snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV1);
                max98090->pclk = freq;
        } else if ((freq > 20000000) && (freq <= 40000000)) {
-               snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
+               snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV2);
                max98090->pclk = freq >> 1;
        } else if ((freq > 40000000) && (freq <= 60000000)) {
-               snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
+               snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV4);
                max98090->pclk = freq >> 2;
        } else {
-               dev_err(codec->dev, "Invalid master clock frequency\n");
+               dev_err(component->dev, "Invalid master clock frequency\n");
                return -EINVAL;
        }
 
@@ -2022,11 +2022,11 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
 
 static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int regval;
 
        regval = mute ? M98090_DVM_MASK : 0;
-       snd_soc_update_bits(codec, M98090_REG_DAI_PLAYBACK_LEVEL,
+       snd_soc_component_update_bits(component, M98090_REG_DAI_PLAYBACK_LEVEL,
                M98090_DVM_MASK, regval);
 
        return 0;
@@ -2035,8 +2035,8 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -2065,7 +2065,7 @@ static void max98090_pll_det_enable_work(struct work_struct *work)
        struct max98090_priv *max98090 =
                container_of(work, struct max98090_priv,
                             pll_det_enable_work.work);
-       struct snd_soc_codec *codec = max98090->codec;
+       struct snd_soc_component *component = max98090->component;
        unsigned int status, mask;
 
        /*
@@ -2088,7 +2088,7 @@ static void max98090_pll_det_enable_work(struct work_struct *work)
                                   msecs_to_jiffies(100));
 
        /* Enable PLL unlock interrupt */
-       snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+       snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
                            M98090_IULK_MASK,
                            1 << M98090_IULK_SHIFT);
 }
@@ -2097,12 +2097,12 @@ static void max98090_pll_det_disable_work(struct work_struct *work)
 {
        struct max98090_priv *max98090 =
                container_of(work, struct max98090_priv, pll_det_disable_work);
-       struct snd_soc_codec *codec = max98090->codec;
+       struct snd_soc_component *component = max98090->component;
 
        cancel_delayed_work_sync(&max98090->pll_det_enable_work);
 
        /* Disable PLL unlock interrupt */
-       snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+       snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
                            M98090_IULK_MASK, 0);
 }
 
@@ -2110,18 +2110,18 @@ static void max98090_pll_work(struct work_struct *work)
 {
        struct max98090_priv *max98090 =
                container_of(work, struct max98090_priv, pll_work);
-       struct snd_soc_codec *codec = max98090->codec;
+       struct snd_soc_component *component = max98090->component;
 
-       if (!snd_soc_codec_is_active(codec))
+       if (!snd_soc_component_is_active(component))
                return;
 
-       dev_info_ratelimited(codec->dev, "PLL unlocked\n");
+       dev_info_ratelimited(component->dev, "PLL unlocked\n");
 
        /* Toggle shutdown OFF then ON */
-       snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+       snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
                            M98090_SHDNN_MASK, 0);
        msleep(10);
-       snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+       snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
                            M98090_SHDNN_MASK, M98090_SHDNN_MASK);
 
        /* Give PLL time to lock */
@@ -2133,7 +2133,7 @@ static void max98090_jack_work(struct work_struct *work)
        struct max98090_priv *max98090 = container_of(work,
                struct max98090_priv,
                jack_work.work);
-       struct snd_soc_codec *codec = max98090->codec;
+       struct snd_soc_component *component = max98090->component;
        int status = 0;
        int reg;
 
@@ -2141,25 +2141,25 @@ static void max98090_jack_work(struct work_struct *work)
        if (max98090->jack_state == M98090_JACK_STATE_NO_HEADSET) {
 
                /* Strong pull up allows mic detection */
-               snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
+               snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
                        M98090_JDWK_MASK, 0);
 
                msleep(50);
 
-               reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
+               reg = snd_soc_component_read32(component, M98090_REG_JACK_STATUS);
 
                /* Weak pull up allows only insertion detection */
-               snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
+               snd_soc_component_update_bits(component, M98090_REG_JACK_DETECT,
                        M98090_JDWK_MASK, M98090_JDWK_MASK);
        } else {
-               reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
+               reg = snd_soc_component_read32(component, M98090_REG_JACK_STATUS);
        }
 
-       reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
+       reg = snd_soc_component_read32(component, M98090_REG_JACK_STATUS);
 
        switch (reg & (M98090_LSNS_MASK | M98090_JKSNS_MASK)) {
                case M98090_LSNS_MASK | M98090_JKSNS_MASK:
-                       dev_dbg(codec->dev, "No Headset Detected\n");
+                       dev_dbg(component->dev, "No Headset Detected\n");
 
                        max98090->jack_state = M98090_JACK_STATE_NO_HEADSET;
 
@@ -2171,7 +2171,7 @@ static void max98090_jack_work(struct work_struct *work)
                        if (max98090->jack_state ==
                                M98090_JACK_STATE_HEADSET) {
 
-                               dev_dbg(codec->dev,
+                               dev_dbg(component->dev,
                                        "Headset Button Down Detected\n");
 
                                /*
@@ -2188,7 +2188,7 @@ static void max98090_jack_work(struct work_struct *work)
                        /* Line is reported as Headphone */
                        /* Nokia Headset is reported as Headphone */
                        /* Mono Headphone is reported as Headphone */
-                       dev_dbg(codec->dev, "Headphone Detected\n");
+                       dev_dbg(component->dev, "Headphone Detected\n");
 
                        max98090->jack_state = M98090_JACK_STATE_HEADPHONE;
 
@@ -2197,7 +2197,7 @@ static void max98090_jack_work(struct work_struct *work)
                        break;
 
                case M98090_JKSNS_MASK:
-                       dev_dbg(codec->dev, "Headset Detected\n");
+                       dev_dbg(component->dev, "Headset Detected\n");
 
                        max98090->jack_state = M98090_JACK_STATE_HEADSET;
 
@@ -2206,7 +2206,7 @@ static void max98090_jack_work(struct work_struct *work)
                        break;
 
                default:
-                       dev_dbg(codec->dev, "Unrecognized Jack Status\n");
+                       dev_dbg(component->dev, "Unrecognized Jack Status\n");
                        break;
        }
 
@@ -2217,21 +2217,21 @@ static void max98090_jack_work(struct work_struct *work)
 static irqreturn_t max98090_interrupt(int irq, void *data)
 {
        struct max98090_priv *max98090 = data;
-       struct snd_soc_codec *codec = max98090->codec;
+       struct snd_soc_component *component = max98090->component;
        int ret;
        unsigned int mask;
        unsigned int active;
 
        /* Treat interrupt before codec is initialized as spurious */
-       if (codec == NULL)
+       if (component == NULL)
                return IRQ_NONE;
 
-       dev_dbg(codec->dev, "***** max98090_interrupt *****\n");
+       dev_dbg(component->dev, "***** max98090_interrupt *****\n");
 
        ret = regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask);
 
        if (ret != 0) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "failed to read M98090_REG_INTERRUPT_S: %d\n",
                        ret);
                return IRQ_NONE;
@@ -2240,13 +2240,13 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
        ret = regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &active);
 
        if (ret != 0) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "failed to read M98090_REG_DEVICE_STATUS: %d\n",
                        ret);
                return IRQ_NONE;
        }
 
-       dev_dbg(codec->dev, "active=0x%02x mask=0x%02x -> active=0x%02x\n",
+       dev_dbg(component->dev, "active=0x%02x mask=0x%02x -> active=0x%02x\n",
                active, mask, active & mask);
 
        active &= mask;
@@ -2255,20 +2255,20 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
                return IRQ_NONE;
 
        if (active & M98090_CLD_MASK)
-               dev_err(codec->dev, "M98090_CLD_MASK\n");
+               dev_err(component->dev, "M98090_CLD_MASK\n");
 
        if (active & M98090_SLD_MASK)
-               dev_dbg(codec->dev, "M98090_SLD_MASK\n");
+               dev_dbg(component->dev, "M98090_SLD_MASK\n");
 
        if (active & M98090_ULK_MASK) {
-               dev_dbg(codec->dev, "M98090_ULK_MASK\n");
+               dev_dbg(component->dev, "M98090_ULK_MASK\n");
                schedule_work(&max98090->pll_work);
        }
 
        if (active & M98090_JDET_MASK) {
-               dev_dbg(codec->dev, "M98090_JDET_MASK\n");
+               dev_dbg(component->dev, "M98090_JDET_MASK\n");
 
-               pm_wakeup_event(codec->dev, 100);
+               pm_wakeup_event(component->dev, 100);
 
                queue_delayed_work(system_power_efficient_wq,
                                   &max98090->jack_work,
@@ -2276,10 +2276,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
        }
 
        if (active & M98090_DRCACT_MASK)
-               dev_dbg(codec->dev, "M98090_DRCACT_MASK\n");
+               dev_dbg(component->dev, "M98090_DRCACT_MASK\n");
 
        if (active & M98090_DRCCLP_MASK)
-               dev_err(codec->dev, "M98090_DRCCLP_MASK\n");
+               dev_err(component->dev, "M98090_DRCCLP_MASK\n");
 
        return IRQ_HANDLED;
 }
@@ -2287,7 +2287,7 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
 /**
  * max98090_mic_detect - Enable microphone detection via the MAX98090 IRQ
  *
- * @codec:  MAX98090 codec
+ * @component:  MAX98090 component
  * @jack:   jack to report detection events on
  *
  * Enable microphone detection via IRQ on the MAX98090.  If GPIOs are
@@ -2297,20 +2297,20 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
  *
  * If no jack is supplied detection will be disabled.
  */
-int max98090_mic_detect(struct snd_soc_codec *codec,
+int max98090_mic_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack)
 {
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "max98090_mic_detect\n");
+       dev_dbg(component->dev, "max98090_mic_detect\n");
 
        max98090->jack = jack;
        if (jack) {
-               snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+               snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
                        M98090_IJDET_MASK,
                        1 << M98090_IJDET_SHIFT);
        } else {
-               snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
+               snd_soc_component_update_bits(component, M98090_REG_INTERRUPT_S,
                        M98090_IJDET_MASK,
                        0);
        }
@@ -2360,22 +2360,22 @@ static struct snd_soc_dai_driver max98090_dai[] = {
 }
 };
 
-static int max98090_probe(struct snd_soc_codec *codec)
+static int max98090_probe(struct snd_soc_component *component)
 {
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
        struct max98090_cdata *cdata;
        enum max98090_type devtype;
        int ret = 0;
        int err;
        unsigned int micbias;
 
-       dev_dbg(codec->dev, "max98090_probe\n");
+       dev_dbg(component->dev, "max98090_probe\n");
 
-       max98090->mclk = devm_clk_get(codec->dev, "mclk");
+       max98090->mclk = devm_clk_get(component->dev, "mclk");
        if (PTR_ERR(max98090->mclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
-       max98090->codec = codec;
+       max98090->component = component;
 
        /* Reset the codec, the DSP core, and disable all interrupts */
        max98090_reset(max98090);
@@ -2394,26 +2394,26 @@ static int max98090_probe(struct snd_soc_codec *codec)
        max98090->pa1en = 0;
        max98090->pa2en = 0;
 
-       ret = snd_soc_read(codec, M98090_REG_REVISION_ID);
+       ret = snd_soc_component_read32(component, M98090_REG_REVISION_ID);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to read device revision: %d\n",
+               dev_err(component->dev, "Failed to read device revision: %d\n",
                        ret);
                goto err_access;
        }
 
        if ((ret >= M98090_REVA) && (ret <= M98090_REVA + 0x0f)) {
                devtype = MAX98090;
-               dev_info(codec->dev, "MAX98090 REVID=0x%02x\n", ret);
+               dev_info(component->dev, "MAX98090 REVID=0x%02x\n", ret);
        } else if ((ret >= M98091_REVA) && (ret <= M98091_REVA + 0x0f)) {
                devtype = MAX98091;
-               dev_info(codec->dev, "MAX98091 REVID=0x%02x\n", ret);
+               dev_info(component->dev, "MAX98091 REVID=0x%02x\n", ret);
        } else {
                devtype = MAX98090;
-               dev_err(codec->dev, "Unrecognized revision 0x%02x\n", ret);
+               dev_err(component->dev, "Unrecognized revision 0x%02x\n", ret);
        }
 
        if (max98090->devtype != devtype) {
-               dev_warn(codec->dev, "Mismatch in DT specified CODEC type.\n");
+               dev_warn(component->dev, "Mismatch in DT specified CODEC type.\n");
                max98090->devtype = devtype;
        }
 
@@ -2427,7 +2427,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
        INIT_WORK(&max98090->pll_work, max98090_pll_work);
 
        /* Enable jack detection */
-       snd_soc_write(codec, M98090_REG_JACK_DETECT,
+       snd_soc_component_write(component, M98090_REG_JACK_DETECT,
                M98090_JDETEN_MASK | M98090_JDEB_25MS);
 
        /*
@@ -2435,75 +2435,76 @@ static int max98090_probe(struct snd_soc_codec *codec)
         * An old interrupt ocurring prior to installing the ISR
         * can keep a new interrupt from generating a trigger.
         */
-       snd_soc_read(codec, M98090_REG_DEVICE_STATUS);
+       snd_soc_component_read32(component, M98090_REG_DEVICE_STATUS);
 
        /* High Performance is default */
-       snd_soc_update_bits(codec, M98090_REG_DAC_CONTROL,
+       snd_soc_component_update_bits(component, M98090_REG_DAC_CONTROL,
                M98090_DACHP_MASK,
                1 << M98090_DACHP_SHIFT);
-       snd_soc_update_bits(codec, M98090_REG_DAC_CONTROL,
+       snd_soc_component_update_bits(component, M98090_REG_DAC_CONTROL,
                M98090_PERFMODE_MASK,
                0 << M98090_PERFMODE_SHIFT);
-       snd_soc_update_bits(codec, M98090_REG_ADC_CONTROL,
+       snd_soc_component_update_bits(component, M98090_REG_ADC_CONTROL,
                M98090_ADCHP_MASK,
                1 << M98090_ADCHP_SHIFT);
 
        /* Turn on VCM bandgap reference */
-       snd_soc_write(codec, M98090_REG_BIAS_CONTROL,
+       snd_soc_component_write(component, M98090_REG_BIAS_CONTROL,
                M98090_VCM_MODE_MASK);
 
-       err = device_property_read_u32(codec->dev, "maxim,micbias", &micbias);
+       err = device_property_read_u32(component->dev, "maxim,micbias", &micbias);
        if (err) {
                micbias = M98090_MBVSEL_2V8;
-               dev_info(codec->dev, "use default 2.8v micbias\n");
+               dev_info(component->dev, "use default 2.8v micbias\n");
        } else if (micbias > M98090_MBVSEL_2V8) {
-               dev_err(codec->dev, "micbias out of range 0x%x\n", micbias);
+               dev_err(component->dev, "micbias out of range 0x%x\n", micbias);
                micbias = M98090_MBVSEL_2V8;
        }
 
-       snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
+       snd_soc_component_update_bits(component, M98090_REG_MIC_BIAS_VOLTAGE,
                M98090_MBVSEL_MASK, micbias);
 
-       max98090_add_widgets(codec);
+       max98090_add_widgets(component);
 
 err_access:
        return ret;
 }
 
-static int max98090_remove(struct snd_soc_codec *codec)
+static void max98090_remove(struct snd_soc_component *component)
 {
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
        cancel_delayed_work_sync(&max98090->jack_work);
        cancel_delayed_work_sync(&max98090->pll_det_enable_work);
        cancel_work_sync(&max98090->pll_det_disable_work);
        cancel_work_sync(&max98090->pll_work);
-       max98090->codec = NULL;
-
-       return 0;
+       max98090->component = NULL;
 }
 
-static void max98090_seq_notifier(struct snd_soc_dapm_context *dapm,
+static void max98090_seq_notifier(struct snd_soc_component *component,
        enum snd_soc_dapm_type event, int subseq)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
+       struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
 
        if (max98090->shdn_pending) {
-               snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+               snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
                                M98090_SHDNN_MASK, 0);
                msleep(40);
-               snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
+               snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
                                M98090_SHDNN_MASK, M98090_SHDNN_MASK);
                max98090->shdn_pending = false;
        }
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98090 = {
-       .probe   = max98090_probe,
-       .remove  = max98090_remove,
-       .seq_notifier = max98090_seq_notifier,
-       .set_bias_level = max98090_set_bias_level,
+static const struct snd_soc_component_driver soc_component_dev_max98090 = {
+       .probe                  = max98090_probe,
+       .remove                 = max98090_remove,
+       .seq_notifier           = max98090_seq_notifier,
+       .set_bias_level         = max98090_set_bias_level,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config max98090_regmap = {
@@ -2570,8 +2571,8 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_max98090, max98090_dai,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_max98090, max98090_dai,
                        ARRAY_SIZE(max98090_dai));
 err_enable:
        return ret;
@@ -2595,7 +2596,7 @@ static void max98090_i2c_shutdown(struct i2c_client *i2c)
 static int max98090_i2c_remove(struct i2c_client *client)
 {
        max98090_i2c_shutdown(client);
-       snd_soc_unregister_codec(&client->dev);
+
        return 0;
 }
 
index bc610d9a9ecb73fd61be71c4c6dfb5af030ad588..b1572a2d19da3def48b8fc398afbb6b5f1aab6ea 100644 (file)
@@ -1519,7 +1519,7 @@ struct max98090_cdata {
 
 struct max98090_priv {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        enum max98090_type devtype;
        struct max98090_pdata *pdata;
        struct clk *mclk;
@@ -1546,7 +1546,7 @@ struct max98090_priv {
        bool shdn_pending;
 };
 
-int max98090_mic_detect(struct snd_soc_codec *codec,
+int max98090_mic_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack);
 
 #endif
index 5ead87d2ab1df95cfc8245a3b07aae5fb49b9f83..6bf2d0ba864f9f222ffbc1d50cba365660dc986f 100644 (file)
@@ -251,7 +251,7 @@ static const struct regmap_config max98095_regmap = {
 /*
  * Load equalizer DSP coefficient configurations registers
  */
-static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
+static void m98095_eq_band(struct snd_soc_component *component, unsigned int dai,
                    unsigned int band, u16 *coefs)
 {
        unsigned int eq_reg;
@@ -269,15 +269,15 @@ static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
 
        /* Step through the registers and coefs */
        for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
-               snd_soc_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
-               snd_soc_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
+               snd_soc_component_write(component, eq_reg++, M98095_BYTE1(coefs[i]));
+               snd_soc_component_write(component, eq_reg++, M98095_BYTE0(coefs[i]));
        }
 }
 
 /*
  * Load biquad filter coefficient configurations registers
  */
-static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
+static void m98095_biquad_band(struct snd_soc_component *component, unsigned int dai,
                    unsigned int band, u16 *coefs)
 {
        unsigned int bq_reg;
@@ -295,8 +295,8 @@ static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
 
        /* Step through the registers and coefs */
        for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
-               snd_soc_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
-               snd_soc_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
+               snd_soc_component_write(component, bq_reg++, M98095_BYTE1(coefs[i]));
+               snd_soc_component_write(component, bq_reg++, M98095_BYTE0(coefs[i]));
        }
 }
 
@@ -353,12 +353,12 @@ static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum,
 static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        unsigned int sel = ucontrol->value.integer.value[0];
 
        max98095->mic1pre = sel;
-       snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
+       snd_soc_component_update_bits(component, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
                (1+sel)<<M98095_MICPRE_SHIFT);
 
        return 0;
@@ -367,8 +367,8 @@ static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
 static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = max98095->mic1pre;
        return 0;
@@ -377,12 +377,12 @@ static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
 static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        unsigned int sel = ucontrol->value.integer.value[0];
 
        max98095->mic2pre = sel;
-       snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
+       snd_soc_component_update_bits(component, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
                (1+sel)<<M98095_MICPRE_SHIFT);
 
        return 0;
@@ -391,8 +391,8 @@ static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
 static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = max98095->mic2pre;
        return 0;
@@ -598,21 +598,21 @@ static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
 static int max98095_mic_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                if (w->reg == M98095_05F_LVL_MIC1) {
-                       snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
+                       snd_soc_component_update_bits(component, w->reg, M98095_MICPRE_MASK,
                                (1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
                } else {
-                       snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
+                       snd_soc_component_update_bits(component, w->reg, M98095_MICPRE_MASK,
                                (1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
                }
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
+               snd_soc_component_update_bits(component, w->reg, M98095_MICPRE_MASK, 0);
                break;
        default:
                return -EINVAL;
@@ -628,8 +628,8 @@ static int max98095_mic_event(struct snd_soc_dapm_widget *w,
 static int max98095_line_pga(struct snd_soc_dapm_widget *w,
                             int event, u8 channel)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        u8 *state;
 
        if (WARN_ON(!(channel == 1 || channel == 2)))
@@ -640,13 +640,13 @@ static int max98095_line_pga(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                *state |= channel;
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                        (1 << w->shift), (1 << w->shift));
                break;
        case SND_SOC_DAPM_POST_PMD:
                *state &= ~channel;
                if (*state == 0) {
-                       snd_soc_update_bits(codec, w->reg,
+                       snd_soc_component_update_bits(component, w->reg,
                                (1 << w->shift), 0);
                }
                break;
@@ -676,15 +676,15 @@ static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
 static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                        (1 << (w->shift+2)), (1 << (w->shift+2)));
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                        (1 << (w->shift+2)), 0);
                break;
        default:
@@ -942,8 +942,8 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -955,11 +955,11 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98095_02A_DAI1_FORMAT,
                        M98095_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98095_02A_DAI1_FORMAT,
                        M98095_DAI_WS, M98095_DAI_WS);
                break;
        default:
@@ -969,31 +969,31 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
+       snd_soc_component_update_bits(component, M98095_027_DAI1_CLKMODE,
                M98095_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
+       if (snd_soc_component_read32(component, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
                if (max98095->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98095->sysclk);
-               snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
+               snd_soc_component_write(component, M98095_028_DAI1_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
+               snd_soc_component_write(component, M98095_029_DAI1_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
+               snd_soc_component_update_bits(component, M98095_02E_DAI1_FILTERS,
                        M98095_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
+               snd_soc_component_update_bits(component, M98095_02E_DAI1_FILTERS,
                        M98095_DAI_DHF, M98095_DAI_DHF);
 
        return 0;
@@ -1003,8 +1003,8 @@ static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -1016,11 +1016,11 @@ static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98095_034_DAI2_FORMAT,
                        M98095_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98095_034_DAI2_FORMAT,
                        M98095_DAI_WS, M98095_DAI_WS);
                break;
        default:
@@ -1030,31 +1030,31 @@ static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
+       snd_soc_component_update_bits(component, M98095_031_DAI2_CLKMODE,
                M98095_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
+       if (snd_soc_component_read32(component, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
                if (max98095->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98095->sysclk);
-               snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
+               snd_soc_component_write(component, M98095_032_DAI2_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
+               snd_soc_component_write(component, M98095_033_DAI2_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
+               snd_soc_component_update_bits(component, M98095_038_DAI2_FILTERS,
                        M98095_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
+               snd_soc_component_update_bits(component, M98095_038_DAI2_FILTERS,
                        M98095_DAI_DHF, M98095_DAI_DHF);
 
        return 0;
@@ -1064,8 +1064,8 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        unsigned long long ni;
        unsigned int rate;
@@ -1077,11 +1077,11 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 16:
-               snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
+               snd_soc_component_update_bits(component, M98095_03E_DAI3_FORMAT,
                        M98095_DAI_WS, 0);
                break;
        case 24:
-               snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
+               snd_soc_component_update_bits(component, M98095_03E_DAI3_FORMAT,
                        M98095_DAI_WS, M98095_DAI_WS);
                break;
        default:
@@ -1091,31 +1091,31 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
        if (rate_value(rate, &regval))
                return -EINVAL;
 
-       snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
+       snd_soc_component_update_bits(component, M98095_03B_DAI3_CLKMODE,
                M98095_CLKMODE_MASK, regval);
        cdata->rate = rate;
 
        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
+       if (snd_soc_component_read32(component, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
                if (max98095->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock frequency\n");
+                       dev_err(component->dev, "Invalid system clock frequency\n");
                        return -EINVAL;
                }
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98095->sysclk);
-               snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
+               snd_soc_component_write(component, M98095_03C_DAI3_CLKCFG_HI,
                        (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
+               snd_soc_component_write(component, M98095_03D_DAI3_CLKCFG_LO,
                        ni & 0xFF);
        }
 
        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
+               snd_soc_component_update_bits(component, M98095_042_DAI3_FILTERS,
                        M98095_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
+               snd_soc_component_update_bits(component, M98095_042_DAI3_FILTERS,
                        M98095_DAI_DHF, M98095_DAI_DHF);
 
        return 0;
@@ -1124,8 +1124,8 @@ static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
 static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
                                   int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
        /* Requested clock frequency is already setup */
        if (freq == max98095->sysclk)
@@ -1142,13 +1142,13 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
         *         0x03 (when master clk is 40MHz to 60MHz)..
         */
        if ((freq >= 10000000) && (freq < 20000000)) {
-               snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
+               snd_soc_component_write(component, M98095_026_SYS_CLK, 0x10);
        } else if ((freq >= 20000000) && (freq < 40000000)) {
-               snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
+               snd_soc_component_write(component, M98095_026_SYS_CLK, 0x20);
        } else if ((freq >= 40000000) && (freq < 60000000)) {
-               snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
+               snd_soc_component_write(component, M98095_026_SYS_CLK, 0x30);
        } else {
-               dev_err(codec->dev, "Invalid master clock frequency\n");
+               dev_err(component->dev, "Invalid master clock frequency\n");
                return -EINVAL;
        }
 
@@ -1161,8 +1161,8 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
 static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        u8 regval = 0;
 
@@ -1174,9 +1174,9 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
+                       snd_soc_component_write(component, M98095_028_DAI1_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
+                       snd_soc_component_write(component, M98095_029_DAI1_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1186,7 +1186,7 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1216,11 +1216,11 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
+               snd_soc_component_update_bits(component, M98095_02A_DAI1_FORMAT,
                        M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
                        M98095_DAI_WCI, regval);
 
-               snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
+               snd_soc_component_write(component, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
        }
 
        return 0;
@@ -1229,8 +1229,8 @@ static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        u8 regval = 0;
 
@@ -1242,9 +1242,9 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
+                       snd_soc_component_write(component, M98095_032_DAI2_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
+                       snd_soc_component_write(component, M98095_033_DAI2_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1254,7 +1254,7 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1284,11 +1284,11 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
+               snd_soc_component_update_bits(component, M98095_034_DAI2_FORMAT,
                        M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
                        M98095_DAI_WCI, regval);
 
-               snd_soc_write(codec, M98095_035_DAI2_CLOCK,
+               snd_soc_component_write(component, M98095_035_DAI2_CLOCK,
                        M98095_DAI_BSEL64);
        }
 
@@ -1298,8 +1298,8 @@ static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        u8 regval = 0;
 
@@ -1311,9 +1311,9 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
+                       snd_soc_component_write(component, M98095_03C_DAI3_CLKCFG_HI,
                                0x80);
-                       snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
+                       snd_soc_component_write(component, M98095_03D_DAI3_CLKCFG_LO,
                                0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -1323,7 +1323,7 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
                default:
-                       dev_err(codec->dev, "Clock mode unsupported");
+                       dev_err(component->dev, "Clock mode unsupported");
                        return -EINVAL;
                }
 
@@ -1353,21 +1353,21 @@ static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
+               snd_soc_component_update_bits(component, M98095_03E_DAI3_FORMAT,
                        M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
                        M98095_DAI_WCI, regval);
 
-               snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
+               snd_soc_component_write(component, M98095_03F_DAI3_CLOCK,
                        M98095_DAI_BSEL64);
        }
 
        return 0;
 }
 
-static int max98095_set_bias_level(struct snd_soc_codec *codec,
+static int max98095_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1385,7 +1385,7 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
                if (IS_ERR(max98095->mclk))
                        break;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
                        clk_disable_unprepare(max98095->mclk);
                } else {
                        ret = clk_prepare_enable(max98095->mclk);
@@ -1395,21 +1395,21 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regcache_sync(max98095->regmap);
 
                        if (ret != 0) {
-                               dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
+                               dev_err(component->dev, "Failed to sync cache: %d\n", ret);
                                return ret;
                        }
                }
 
-               snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
+               snd_soc_component_update_bits(component, M98095_090_PWR_EN_IN,
                                M98095_MBEN, M98095_MBEN);
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
+               snd_soc_component_update_bits(component, M98095_090_PWR_EN_IN,
                                M98095_MBEN, 0);
                regcache_mark_dirty(max98095->regmap);
                break;
@@ -1494,8 +1494,8 @@ static int max98095_get_eq_channel(const char *name)
 static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_pdata *pdata = max98095->pdata;
        int channel = max98095_get_eq_channel(kcontrol->id.name);
        struct max98095_cdata *cdata;
@@ -1528,7 +1528,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
                }
        }
 
-       dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+       dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
                pdata->eq_cfg[best].name,
                pdata->eq_cfg[best].rate, fs);
 
@@ -1537,29 +1537,29 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
        regmask = (channel == 0) ? M98095_EQ1EN : M98095_EQ2EN;
 
        /* Disable filter while configuring, and save current on/off state */
-       regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
-       snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
+       regsave = snd_soc_component_read32(component, M98095_088_CFG_LEVEL);
+       snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, 0);
 
        mutex_lock(&max98095->lock);
-       snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
-       m98095_eq_band(codec, channel, 0, coef_set->band1);
-       m98095_eq_band(codec, channel, 1, coef_set->band2);
-       m98095_eq_band(codec, channel, 2, coef_set->band3);
-       m98095_eq_band(codec, channel, 3, coef_set->band4);
-       m98095_eq_band(codec, channel, 4, coef_set->band5);
-       snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
+       snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
+       m98095_eq_band(component, channel, 0, coef_set->band1);
+       m98095_eq_band(component, channel, 1, coef_set->band2);
+       m98095_eq_band(component, channel, 2, coef_set->band3);
+       m98095_eq_band(component, channel, 3, coef_set->band4);
+       m98095_eq_band(component, channel, 4, coef_set->band5);
+       snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, 0);
        mutex_unlock(&max98095->lock);
 
        /* Restore the original on/off state */
-       snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
+       snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, regsave);
        return 0;
 }
 
 static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        int channel = max98095_get_eq_channel(kcontrol->id.name);
        struct max98095_cdata *cdata;
 
@@ -1569,9 +1569,9 @@ static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
+static void max98095_handle_eq_pdata(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_pdata *pdata = max98095->pdata;
        struct max98095_eq_cfg *cfg;
        unsigned int cfgcnt;
@@ -1624,14 +1624,14 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
        max98095->eq_enum.texts = max98095->eq_texts;
        max98095->eq_enum.items = max98095->eq_textcnt;
 
-       ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+       ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
+               dev_err(component->dev, "Failed to add EQ control: %d\n", ret);
 }
 
 static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"};
 
-static int max98095_get_bq_channel(struct snd_soc_codec *codec,
+static int max98095_get_bq_channel(struct snd_soc_component *component,
                                   const char *name)
 {
        int i;
@@ -1641,17 +1641,17 @@ static int max98095_get_bq_channel(struct snd_soc_codec *codec,
                        return i;
 
        /* Shouldn't happen */
-       dev_err(codec->dev, "Bad biquad channel name '%s'\n", name);
+       dev_err(component->dev, "Bad biquad channel name '%s'\n", name);
        return -EINVAL;
 }
 
 static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_pdata *pdata = max98095->pdata;
-       int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
+       int channel = max98095_get_bq_channel(component, kcontrol->id.name);
        struct max98095_cdata *cdata;
        unsigned int sel = ucontrol->value.enumerated.item[0];
        struct max98095_biquad_cfg *coef_set;
@@ -1682,7 +1682,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
                }
        }
 
-       dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
+       dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",
                pdata->bq_cfg[best].name,
                pdata->bq_cfg[best].rate, fs);
 
@@ -1691,27 +1691,27 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
        regmask = (channel == 0) ? M98095_BQ1EN : M98095_BQ2EN;
 
        /* Disable filter while configuring, and save current on/off state */
-       regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
-       snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
+       regsave = snd_soc_component_read32(component, M98095_088_CFG_LEVEL);
+       snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, 0);
 
        mutex_lock(&max98095->lock);
-       snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
-       m98095_biquad_band(codec, channel, 0, coef_set->band1);
-       m98095_biquad_band(codec, channel, 1, coef_set->band2);
-       snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
+       snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
+       m98095_biquad_band(component, channel, 0, coef_set->band1);
+       m98095_biquad_band(component, channel, 1, coef_set->band2);
+       snd_soc_component_update_bits(component, M98095_00F_HOST_CFG, M98095_SEG, 0);
        mutex_unlock(&max98095->lock);
 
        /* Restore the original on/off state */
-       snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
+       snd_soc_component_update_bits(component, M98095_088_CFG_LEVEL, regmask, regsave);
        return 0;
 }
 
 static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
                                 struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-       int channel = max98095_get_bq_channel(codec, kcontrol->id.name);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+       int channel = max98095_get_bq_channel(component, kcontrol->id.name);
        struct max98095_cdata *cdata;
 
        if (channel < 0)
@@ -1723,9 +1723,9 @@ static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
+static void max98095_handle_bq_pdata(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_pdata *pdata = max98095->pdata;
        struct max98095_biquad_cfg *cfg;
        unsigned int cfgcnt;
@@ -1779,19 +1779,19 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
        max98095->bq_enum.texts = max98095->bq_texts;
        max98095->bq_enum.items = max98095->bq_textcnt;
 
-       ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
+       ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
+               dev_err(component->dev, "Failed to add Biquad control: %d\n", ret);
 }
 
-static void max98095_handle_pdata(struct snd_soc_codec *codec)
+static void max98095_handle_pdata(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_pdata *pdata = max98095->pdata;
        u8 regval = 0;
 
        if (!pdata) {
-               dev_dbg(codec->dev, "No platform data\n");
+               dev_dbg(component->dev, "No platform data\n");
                return;
        }
 
@@ -1802,27 +1802,27 @@ static void max98095_handle_pdata(struct snd_soc_codec *codec)
        if (pdata->digmic_right_mode)
                regval |= M98095_DIGMIC_R;
 
-       snd_soc_write(codec, M98095_087_CFG_MIC, regval);
+       snd_soc_component_write(component, M98095_087_CFG_MIC, regval);
 
        /* Configure equalizers */
        if (pdata->eq_cfgcnt)
-               max98095_handle_eq_pdata(codec);
+               max98095_handle_eq_pdata(component);
 
        /* Configure bi-quad filters */
        if (pdata->bq_cfgcnt)
-               max98095_handle_bq_pdata(codec);
+               max98095_handle_bq_pdata(component);
 }
 
 static irqreturn_t max98095_report_jack(int irq, void *data)
 {
-       struct snd_soc_codec *codec = data;
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = data;
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        unsigned int value;
        int hp_report = 0;
        int mic_report = 0;
 
        /* Read the Jack Status Register */
-       value = snd_soc_read(codec, M98095_007_JACK_AUTO_STS);
+       value = snd_soc_component_read32(component, M98095_007_JACK_AUTO_STS);
 
        /* If ddone is not set, then detection isn't finished yet */
        if ((value & M98095_DDONE) == 0)
@@ -1853,9 +1853,9 @@ static irqreturn_t max98095_report_jack(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int max98095_jack_detect_enable(struct snd_soc_codec *codec)
+static int max98095_jack_detect_enable(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        int ret = 0;
        int detect_enable = M98095_JDEN;
        unsigned int slew = M98095_DEFAULT_SLEW_DELAY;
@@ -1866,41 +1866,41 @@ static int max98095_jack_detect_enable(struct snd_soc_codec *codec)
        if (max98095->pdata->jack_detect_delay)
                slew = max98095->pdata->jack_detect_delay;
 
-       ret = snd_soc_write(codec, M98095_08E_JACK_DC_SLEW, slew);
+       ret = snd_soc_component_write(component, M98095_08E_JACK_DC_SLEW, slew);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
+               dev_err(component->dev, "Failed to cfg auto detect %d\n", ret);
                return ret;
        }
 
        /* configure auto detection to be enabled */
-       ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, detect_enable);
+       ret = snd_soc_component_write(component, M98095_089_JACK_DET_AUTO, detect_enable);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
+               dev_err(component->dev, "Failed to cfg auto detect %d\n", ret);
                return ret;
        }
 
        return ret;
 }
 
-static int max98095_jack_detect_disable(struct snd_soc_codec *codec)
+static int max98095_jack_detect_disable(struct snd_soc_component *component)
 {
        int ret = 0;
 
        /* configure auto detection to be disabled */
-       ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, 0x0);
+       ret = snd_soc_component_write(component, M98095_089_JACK_DET_AUTO, 0x0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
+               dev_err(component->dev, "Failed to cfg auto detect %d\n", ret);
                return ret;
        }
 
        return ret;
 }
 
-int max98095_jack_detect(struct snd_soc_codec *codec,
+int max98095_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-       struct i2c_client *client = to_i2c_client(codec->dev);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+       struct i2c_client *client = to_i2c_client(component->dev);
        int ret = 0;
 
        max98095->headphone_jack = hp_jack;
@@ -1910,44 +1910,44 @@ int max98095_jack_detect(struct snd_soc_codec *codec,
        if (!hp_jack && !mic_jack)
                return -EINVAL;
 
-       max98095_jack_detect_enable(codec);
+       max98095_jack_detect_enable(component);
 
        /* enable interrupts for headphone jack detection */
-       ret = snd_soc_update_bits(codec, M98095_013_JACK_INT_EN,
+       ret = snd_soc_component_update_bits(component, M98095_013_JACK_INT_EN,
                M98095_IDDONE, M98095_IDDONE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to cfg jack irqs %d\n", ret);
+               dev_err(component->dev, "Failed to cfg jack irqs %d\n", ret);
                return ret;
        }
 
-       max98095_report_jack(client->irq, codec);
+       max98095_report_jack(client->irq, component);
        return 0;
 }
 EXPORT_SYMBOL_GPL(max98095_jack_detect);
 
 #ifdef CONFIG_PM
-static int max98095_suspend(struct snd_soc_codec *codec)
+static int max98095_suspend(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
 
        if (max98095->headphone_jack || max98095->mic_jack)
-               max98095_jack_detect_disable(codec);
+               max98095_jack_detect_disable(component);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
        return 0;
 }
 
-static int max98095_resume(struct snd_soc_codec *codec)
+static int max98095_resume(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-       struct i2c_client *client = to_i2c_client(codec->dev);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+       struct i2c_client *client = to_i2c_client(component->dev);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        if (max98095->headphone_jack || max98095->mic_jack) {
-               max98095_jack_detect_enable(codec);
-               max98095_report_jack(client->irq, codec);
+               max98095_jack_detect_enable(component);
+               max98095_report_jack(client->irq, component);
        }
 
        return 0;
@@ -1957,30 +1957,30 @@ static int max98095_resume(struct snd_soc_codec *codec)
 #define max98095_resume NULL
 #endif
 
-static int max98095_reset(struct snd_soc_codec *codec)
+static int max98095_reset(struct snd_soc_component *component)
 {
        int i, ret;
 
        /* Gracefully reset the DSP core and the codec hardware
         * in a proper sequence */
-       ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
+       ret = snd_soc_component_write(component, M98095_00F_HOST_CFG, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
+               dev_err(component->dev, "Failed to reset DSP: %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
+       ret = snd_soc_component_write(component, M98095_097_PWR_SYS, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
+               dev_err(component->dev, "Failed to reset component: %d\n", ret);
                return ret;
        }
 
        /* Reset to hardware default for registers, as there is not
         * a soft reset hardware control register */
        for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
-               ret = snd_soc_write(codec, i, snd_soc_read(codec, i));
+               ret = snd_soc_component_write(component, i, snd_soc_component_read32(component, i));
                if (ret < 0) {
-                       dev_err(codec->dev, "Failed to reset: %d\n", ret);
+                       dev_err(component->dev, "Failed to reset: %d\n", ret);
                        return ret;
                }
        }
@@ -1988,21 +1988,21 @@ static int max98095_reset(struct snd_soc_codec *codec)
        return ret;
 }
 
-static int max98095_probe(struct snd_soc_codec *codec)
+static int max98095_probe(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
        struct max98095_cdata *cdata;
        struct i2c_client *client;
        int ret = 0;
 
-       max98095->mclk = devm_clk_get(codec->dev, "mclk");
+       max98095->mclk = devm_clk_get(component->dev, "mclk");
        if (PTR_ERR(max98095->mclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        /* reset the codec, the DSP core, and disable all interrupts */
-       max98095_reset(codec);
+       max98095_reset(component);
 
-       client = to_i2c_client(codec->dev);
+       client = to_i2c_client(component->dev);
 
        /* initialize private data */
 
@@ -2037,85 +2037,85 @@ static int max98095_probe(struct snd_soc_codec *codec)
                ret = request_threaded_irq(client->irq, NULL,
                        max98095_report_jack,
                        IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
-                       IRQF_ONESHOT, "max98095", codec);
+                       IRQF_ONESHOT, "max98095", component);
                if (ret) {
-                       dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
+                       dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
                        goto err_access;
                }
        }
 
-       ret = snd_soc_read(codec, M98095_0FF_REV_ID);
+       ret = snd_soc_component_read32(component, M98095_0FF_REV_ID);
        if (ret < 0) {
-               dev_err(codec->dev, "Failure reading hardware revision: %d\n",
+               dev_err(component->dev, "Failure reading hardware revision: %d\n",
                        ret);
                goto err_irq;
        }
-       dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
+       dev_info(component->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
 
-       snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
+       snd_soc_component_write(component, M98095_097_PWR_SYS, M98095_PWRSV);
 
-       snd_soc_write(codec, M98095_048_MIX_DAC_LR,
+       snd_soc_component_write(component, M98095_048_MIX_DAC_LR,
                M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
 
-       snd_soc_write(codec, M98095_049_MIX_DAC_M,
+       snd_soc_component_write(component, M98095_049_MIX_DAC_M,
                M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
 
-       snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
-       snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
-       snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
+       snd_soc_component_write(component, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
+       snd_soc_component_write(component, M98095_045_CFG_DSP, M98095_DSPNORMAL);
+       snd_soc_component_write(component, M98095_04E_CFG_HP, M98095_HPNORMAL);
 
-       snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
+       snd_soc_component_write(component, M98095_02C_DAI1_IOCFG,
                M98095_S1NORMAL|M98095_SDATA);
 
-       snd_soc_write(codec, M98095_036_DAI2_IOCFG,
+       snd_soc_component_write(component, M98095_036_DAI2_IOCFG,
                M98095_S2NORMAL|M98095_SDATA);
 
-       snd_soc_write(codec, M98095_040_DAI3_IOCFG,
+       snd_soc_component_write(component, M98095_040_DAI3_IOCFG,
                M98095_S3NORMAL|M98095_SDATA);
 
-       max98095_handle_pdata(codec);
+       max98095_handle_pdata(component);
 
        /* take the codec out of the shut down */
-       snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
+       snd_soc_component_update_bits(component, M98095_097_PWR_SYS, M98095_SHDNRUN,
                M98095_SHDNRUN);
 
        return 0;
 
 err_irq:
        if (client->irq)
-               free_irq(client->irq, codec);
+               free_irq(client->irq, component);
 err_access:
        return ret;
 }
 
-static int max98095_remove(struct snd_soc_codec *codec)
+static void max98095_remove(struct snd_soc_component *component)
 {
-       struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
-       struct i2c_client *client = to_i2c_client(codec->dev);
+       struct max98095_priv *max98095 = snd_soc_component_get_drvdata(component);
+       struct i2c_client *client = to_i2c_client(component->dev);
 
        if (max98095->headphone_jack || max98095->mic_jack)
-               max98095_jack_detect_disable(codec);
+               max98095_jack_detect_disable(component);
 
        if (client->irq)
-               free_irq(client->irq, codec);
-
-       return 0;
+               free_irq(client->irq, component);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98095 = {
-       .probe   = max98095_probe,
-       .remove  = max98095_remove,
-       .suspend = max98095_suspend,
-       .resume  = max98095_resume,
-       .set_bias_level = max98095_set_bias_level,
-       .component_driver = {
-               .controls               = max98095_snd_controls,
-               .num_controls           = ARRAY_SIZE(max98095_snd_controls),
-               .dapm_widgets           = max98095_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max98095_dapm_widgets),
-               .dapm_routes            = max98095_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(max98095_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_max98095 = {
+       .probe                  = max98095_probe,
+       .remove                 = max98095_remove,
+       .suspend                = max98095_suspend,
+       .resume                 = max98095_resume,
+       .set_bias_level         = max98095_set_bias_level,
+       .controls               = max98095_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98095_snd_controls),
+       .dapm_widgets           = max98095_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98095_dapm_widgets),
+       .dapm_routes            = max98095_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98095_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int max98095_i2c_probe(struct i2c_client *i2c,
@@ -2142,17 +2142,12 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
        i2c_set_clientdata(i2c, max98095);
        max98095->pdata = i2c->dev.platform_data;
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_max98095,
                                     max98095_dai, ARRAY_SIZE(max98095_dai));
        return ret;
 }
 
-static int max98095_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98095_i2c_id[] = {
        { "max98095", MAX98095 },
        { }
@@ -2171,7 +2166,6 @@ static struct i2c_driver max98095_i2c_driver = {
                .of_match_table = of_match_ptr(max98095_of_match),
        },
        .probe  = max98095_i2c_probe,
-       .remove = max98095_i2c_remove,
        .id_table = max98095_i2c_id,
 };
 
index 2ebbe4e894bf090636a641ee704849a5f25e7068..67886cacddb2a9c1b77446bfd79f9835768120eb 100644 (file)
 /* Default Delay used in Slew Rate Calculation for Jack detection */
 #define M98095_DEFAULT_SLEW_DELAY              0x18
 
-extern int max98095_jack_detect(struct snd_soc_codec *codec,
+extern int max98095_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack);
 
 #endif
index 426ed2dae6ca292bcfd08a283a5b0703717b78e6..d469576b5a7bb4a75ea5f26289f2e5a9fbe14eb0 100644 (file)
@@ -59,27 +59,29 @@ static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
        {"Speaker", NULL, "HiFi Playback"},
 };
 
-static int max98357a_codec_probe(struct snd_soc_codec *codec)
+static int max98357a_component_probe(struct snd_soc_component *component)
 {
        struct gpio_desc *sdmode;
 
-       sdmode = devm_gpiod_get_optional(codec->dev, "sdmode", GPIOD_OUT_LOW);
+       sdmode = devm_gpiod_get_optional(component->dev, "sdmode", GPIOD_OUT_LOW);
        if (IS_ERR(sdmode))
                return PTR_ERR(sdmode);
 
-       snd_soc_codec_set_drvdata(codec, sdmode);
+       snd_soc_component_set_drvdata(component, sdmode);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver max98357a_codec_driver = {
-       .probe                  = max98357a_codec_probe,
-       .component_driver = {
-               .dapm_widgets           = max98357a_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max98357a_dapm_widgets),
-               .dapm_routes            = max98357a_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(max98357a_dapm_routes),
-       },
+static const struct snd_soc_component_driver max98357a_component_driver = {
+       .probe                  = max98357a_component_probe,
+       .dapm_widgets           = max98357a_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98357a_dapm_widgets),
+       .dapm_routes            = max98357a_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(max98357a_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct snd_soc_dai_ops max98357a_dai_ops = {
@@ -107,14 +109,13 @@ static struct snd_soc_dai_driver max98357a_dai_driver = {
 
 static int max98357a_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &max98357a_codec_driver,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &max98357a_component_driver,
                        &max98357a_dai_driver, 1);
 }
 
 static int max98357a_platform_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
-
        return 0;
 }
 
index 7bc2a17c1e94087389a04d26c982ec628d795d1b..d4ba1392aaf8025ce1748f147df881da6d1e8625 100644 (file)
@@ -187,15 +187,15 @@ static const struct snd_kcontrol_new max98371_snd_controls[] = {
 static int max98371_dai_set_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98371_priv *max98371 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
                break;
        default:
-               dev_err(codec->dev, "DAI clock mode unsupported");
+               dev_err(component->dev, "DAI clock mode unsupported");
                return -EINVAL;
        }
 
@@ -210,7 +210,7 @@ static int max98371_dai_set_fmt(struct snd_soc_dai *codec_dai,
                val |= MAX98371_DAI_LEFT;
                break;
        default:
-               dev_err(codec->dev, "DAI wrong mode unsupported");
+               dev_err(component->dev, "DAI wrong mode unsupported");
                return -EINVAL;
        }
        regmap_update_bits(max98371->regmap, MAX98371_FMT,
@@ -222,8 +222,8 @@ static int max98371_dai_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98371_priv *max98371 = snd_soc_component_get_drvdata(component);
        int blr_clk_ratio, ch_size, channels = params_channels(params);
        int rate = params_rate(params);
 
@@ -348,15 +348,17 @@ static struct snd_soc_dai_driver max98371_dai[] = {
        }
 };
 
-static const struct snd_soc_codec_driver max98371_codec = {
-       .component_driver = {
-               .controls = max98371_snd_controls,
-               .num_controls = ARRAY_SIZE(max98371_snd_controls),
-               .dapm_routes = max98371_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(max98371_audio_map),
-               .dapm_widgets = max98371_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets),
-       },
+static const struct snd_soc_component_driver max98371_component = {
+       .controls               = max98371_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98371_snd_controls),
+       .dapm_routes            = max98371_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98371_audio_map),
+       .dapm_widgets           = max98371_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98371_dapm_widgets),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config max98371_regmap = {
@@ -397,21 +399,15 @@ static int max98371_i2c_probe(struct i2c_client *i2c,
        }
        dev_info(&i2c->dev, "device version %x\n", reg);
 
-       ret = snd_soc_register_codec(&i2c->dev, &max98371_codec,
+       ret = devm_snd_soc_register_component(&i2c->dev, &max98371_component,
                        max98371_dai, ARRAY_SIZE(max98371_dai));
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
                return ret;
        }
        return ret;
 }
 
-static int max98371_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98371_i2c_id[] = {
        { "max98371", 0 },
        { }
@@ -432,7 +428,6 @@ static struct i2c_driver max98371_i2c_driver = {
                .of_match_table = of_match_ptr(max98371_of_match),
        },
        .probe  = max98371_i2c_probe,
-       .remove = max98371_i2c_remove,
        .id_table = max98371_i2c_id,
 };
 
index 9f6330964d98aeb51d8d534d994a3d3861d06980..06e9ba784e0bf6fa24bcb9330895984afd0a7f00 100644 (file)
@@ -62,6 +62,5 @@
 
 struct max98371_priv {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
 };
 #endif
index 562e887651291816c05c6585f17b4664fabfb2c3..a92586106932f848a8aaeaa465f794287742b449 100644 (file)
@@ -112,12 +112,12 @@ static struct reg_default max98373_reg[] = {
 
 static int max98373_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
        unsigned int format = 0;
        unsigned int invert = 0;
 
-       dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+       dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF:
@@ -126,7 +126,7 @@ static int max98373_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                invert = MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE;
                break;
        default:
-               dev_err(codec->dev, "DAI invert mode unsupported\n");
+               dev_err(component->dev, "DAI invert mode unsupported\n");
                return -EINVAL;
        }
 
@@ -177,10 +177,10 @@ static int max98373_get_bclk_sel(int bclk)
        return 0;
 }
 
-static int max98373_set_clock(struct snd_soc_codec *codec,
+static int max98373_set_clock(struct snd_soc_component *component,
        struct snd_pcm_hw_params *params)
 {
-       struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+       struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
        /* BCLK/LRCLK ratio calculation */
        int blr_clk_ratio = params_channels(params) * max98373->ch_size;
        int value;
@@ -189,7 +189,7 @@ static int max98373_set_clock(struct snd_soc_codec *codec,
                /* BCLK configuration */
                value = max98373_get_bclk_sel(blr_clk_ratio);
                if (!value) {
-                       dev_err(codec->dev, "format unsupported %d\n",
+                       dev_err(component->dev, "format unsupported %d\n",
                                params_format(params));
                        return -EINVAL;
                }
@@ -206,8 +206,8 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
        unsigned int sampling_rate = 0;
        unsigned int chan_sz = 0;
 
@@ -223,7 +223,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
                chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32;
                break;
        default:
-               dev_err(codec->dev, "format unsupported %d\n",
+               dev_err(component->dev, "format unsupported %d\n",
                        params_format(params));
                goto err;
        }
@@ -234,7 +234,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
                MAX98373_R2024_PCM_DATA_FMT_CFG,
                MAX98373_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
 
-       dev_dbg(codec->dev, "format supported %d",
+       dev_dbg(component->dev, "format supported %d",
                params_format(params));
 
        /* sampling rate configuration */
@@ -267,7 +267,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
                sampling_rate = MAX98373_PCM_SR_SET1_SR_48000;
                break;
        default:
-               dev_err(codec->dev, "rate %d not supported\n",
+               dev_err(component->dev, "rate %d not supported\n",
                        params_rate(params));
                goto err;
        }
@@ -295,7 +295,7 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
                        MAX98373_PCM_SR_SET2_IVADC_SR_MASK,
                        sampling_rate);
 
-       return max98373_set_clock(codec, params);
+       return max98373_set_clock(component, params);
 err:
        return -EINVAL;
 }
@@ -304,8 +304,8 @@ static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask,
        int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
        int bsel = 0;
        unsigned int chan_sz = 0;
        unsigned int mask;
@@ -319,7 +319,7 @@ static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
        /* BCLK configuration */
        bsel = max98373_get_bclk_sel(slots * slot_width);
        if (bsel == 0) {
-               dev_err(codec->dev, "BCLK %d not supported\n",
+               dev_err(component->dev, "BCLK %d not supported\n",
                        slots * slot_width);
                return -EINVAL;
        }
@@ -341,7 +341,7 @@ static int max98373_dai_tdm_slot(struct snd_soc_dai *dai,
                chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32;
                break;
        default:
-               dev_err(codec->dev, "format unsupported %d\n",
+               dev_err(component->dev, "format unsupported %d\n",
                        slot_width);
                return -EINVAL;
        }
@@ -394,8 +394,8 @@ static const struct snd_soc_dai_ops max98373_dai_ops = {
 static int max98373_dac_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -721,11 +721,9 @@ static struct snd_soc_dai_driver max98373_dai[] = {
        }
 };
 
-static int max98373_probe(struct snd_soc_codec *codec)
+static int max98373_probe(struct snd_soc_component *component)
 {
-       struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec);
-
-       codec->control_data = max98373->regmap;
+       struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
 
        /* Software Reset */
        regmap_write(max98373->regmap,
@@ -828,16 +826,18 @@ static const struct dev_pm_ops max98373_pm = {
        SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume)
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98373 = {
-       .probe = max98373_probe,
-       .component_driver = {
-               .controls = max98373_snd_controls,
-               .num_controls = ARRAY_SIZE(max98373_snd_controls),
-               .dapm_widgets = max98373_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets),
-               .dapm_routes = max98373_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(max98373_audio_map),
-       },
+static const struct snd_soc_component_driver soc_codec_dev_max98373 = {
+       .probe                  = max98373_probe,
+       .controls               = max98373_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98373_snd_controls),
+       .dapm_widgets           = max98373_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98373_dapm_widgets),
+       .dapm_routes            = max98373_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98373_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config max98373_regmap = {
@@ -920,7 +920,7 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
        max98373_slot_config(i2c, max98373);
 
        /* codec registeration */
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98373,
+       ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373,
                max98373_dai, ARRAY_SIZE(max98373_dai));
        if (ret < 0)
                dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
@@ -928,12 +928,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
        return ret;
 }
 
-static int max98373_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98373_i2c_id[] = {
        { "max98373", 0},
        { },
@@ -965,7 +959,6 @@ static struct i2c_driver max98373_i2c_driver = {
                .pm = &max98373_pm,
        },
        .probe = max98373_i2c_probe,
-       .remove = max98373_i2c_remove,
        .id_table = max98373_i2c_id,
 };
 
index a3dfc918c278bda4b41a972c204daa031baed106..74d7f52c7e73b21f5293e942573037ff75c61160 100644 (file)
@@ -130,8 +130,8 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component);
        u64 lrclk_div;
        u8 sf, da;
 
@@ -139,14 +139,14 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
 
        /* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
-       sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
+       sf = (snd_soc_component_read32(component, MAX9850_CLOCK) >> 2) + 1;
        lrclk_div = (1 << 22);
        lrclk_div *= params_rate(params);
        lrclk_div *= sf;
        do_div(lrclk_div, max9850->sysclk);
 
-       snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
-       snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
+       snd_soc_component_write(component, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
+       snd_soc_component_write(component, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
 
        switch (params_width(params)) {
        case 16:
@@ -161,7 +161,7 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
+       snd_soc_component_update_bits(component, MAX9850_DIGITAL_AUDIO, 0x3, da);
 
        return 0;
 }
@@ -169,16 +169,16 @@ static int max9850_hw_params(struct snd_pcm_substream *substream,
 static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component);
 
        /* calculate mclk -> iclk divider */
        if (freq <= 13000000)
-               snd_soc_write(codec, MAX9850_CLOCK, 0x0);
+               snd_soc_component_write(component, MAX9850_CLOCK, 0x0);
        else if (freq <= 26000000)
-               snd_soc_write(codec, MAX9850_CLOCK, 0x4);
+               snd_soc_component_write(component, MAX9850_CLOCK, 0x4);
        else if (freq <= 40000000)
-               snd_soc_write(codec, MAX9850_CLOCK, 0x8);
+               snd_soc_component_write(component, MAX9850_CLOCK, 0x8);
        else
                return -EINVAL;
 
@@ -188,7 +188,7 @@ static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 da = 0;
 
        /* set master/slave audio interface */
@@ -234,15 +234,15 @@ static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        }
 
        /* set da */
-       snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
+       snd_soc_component_write(component, MAX9850_DIGITAL_AUDIO, da);
 
        return 0;
 }
 
-static int max9850_set_bias_level(struct snd_soc_codec *codec,
+static int max9850_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
+       struct max9850_priv *max9850 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -251,10 +251,10 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regcache_sync(max9850->regmap);
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to sync cache: %d\n", ret);
                                return ret;
                        }
@@ -289,31 +289,32 @@ static struct snd_soc_dai_driver max9850_dai = {
        .ops = &max9850_dai_ops,
 };
 
-static int max9850_probe(struct snd_soc_codec *codec)
+static int max9850_probe(struct snd_soc_component *component)
 {
        /* enable zero-detect */
-       snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
+       snd_soc_component_update_bits(component, MAX9850_GENERAL_PURPOSE, 1, 1);
        /* enable slew-rate control */
-       snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
+       snd_soc_component_update_bits(component, MAX9850_VOLUME, 0x40, 0x40);
        /* set slew-rate 125ms */
-       snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
+       snd_soc_component_update_bits(component, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max9850 = {
-       .probe =        max9850_probe,
-       .set_bias_level = max9850_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = max9850_controls,
-               .num_controls           = ARRAY_SIZE(max9850_controls),
-               .dapm_widgets           = max9850_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max9850_dapm_widgets),
-               .dapm_routes            = max9850_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(max9850_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_max9850 = {
+       .probe                  = max9850_probe,
+       .set_bias_level         = max9850_set_bias_level,
+       .controls               = max9850_controls,
+       .num_controls           = ARRAY_SIZE(max9850_controls),
+       .dapm_widgets           = max9850_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max9850_dapm_widgets),
+       .dapm_routes            = max9850_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(max9850_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int max9850_i2c_probe(struct i2c_client *i2c,
@@ -333,17 +334,11 @@ static int max9850_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, max9850);
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_max9850, &max9850_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_max9850, &max9850_dai, 1);
        return ret;
 }
 
-static int max9850_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max9850_i2c_id[] = {
        { "max9850", 0 },
        { }
@@ -355,7 +350,6 @@ static struct i2c_driver max9850_i2c_driver = {
                .name = "max9850",
        },
        .probe = max9850_i2c_probe,
-       .remove = max9850_i2c_remove,
        .id_table = max9850_i2c_id,
 };
 
index a2dc6a47f4664637bef5c302c18758d9b421c954..5bbf889ad98eb6189702f6751cc161e211f00d47 100644 (file)
@@ -261,8 +261,8 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max9860_priv *max9860 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component);
        u8 master;
        u8 ifc1a = 0;
        u8 ifc1b = 0;
@@ -270,7 +270,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
        unsigned long n;
        int ret;
 
-       dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
+       dev_dbg(component->dev, "hw_params %u Hz, %u channels\n",
                params_rate(params),
                params_channels(params));
 
@@ -306,7 +306,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
                break;
        case SND_SOC_DAIFMT_DSP_A:
                if (params_width(params) != 16) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "DSP_A works for 16 bits per sample only.\n");
                        return -EINVAL;
                }
@@ -315,7 +315,7 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
                break;
        case SND_SOC_DAIFMT_DSP_B:
                if (params_width(params) != 16) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "DSP_B works for 16 bits per sample only.\n");
                        return -EINVAL;
                }
@@ -352,16 +352,16 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev, "IFC1A  %02x\n", ifc1a);
+       dev_dbg(component->dev, "IFC1A  %02x\n", ifc1a);
        ret = regmap_write(max9860->regmap, MAX9860_IFC1A, ifc1a);
        if (ret) {
-               dev_err(codec->dev, "Failed to set IFC1A: %d\n", ret);
+               dev_err(component->dev, "Failed to set IFC1A: %d\n", ret);
                return ret;
        }
-       dev_dbg(codec->dev, "IFC1B  %02x\n", ifc1b);
+       dev_dbg(component->dev, "IFC1B  %02x\n", ifc1b);
        ret = regmap_write(max9860->regmap, MAX9860_IFC1B, ifc1b);
        if (ret) {
-               dev_err(codec->dev, "Failed to set IFC1B: %d\n", ret);
+               dev_err(component->dev, "Failed to set IFC1B: %d\n", ret);
                return ret;
        }
 
@@ -417,33 +417,33 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
        }
 
        sysclk |= max9860->psclk;
-       dev_dbg(codec->dev, "SYSCLK %02x\n", sysclk);
+       dev_dbg(component->dev, "SYSCLK %02x\n", sysclk);
        ret = regmap_write(max9860->regmap,
                           MAX9860_SYSCLK, sysclk);
        if (ret) {
-               dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
+               dev_err(component->dev, "Failed to set SYSCLK: %d\n", ret);
                return ret;
        }
-       dev_dbg(codec->dev, "N %lu\n", n);
+       dev_dbg(component->dev, "N %lu\n", n);
        ret = regmap_write(max9860->regmap,
                           MAX9860_AUDIOCLKHIGH, n >> 8);
        if (ret) {
-               dev_err(codec->dev, "Failed to set NHI: %d\n", ret);
+               dev_err(component->dev, "Failed to set NHI: %d\n", ret);
                return ret;
        }
        ret = regmap_write(max9860->regmap,
                           MAX9860_AUDIOCLKLOW, n & 0xff);
        if (ret) {
-               dev_err(codec->dev, "Failed to set NLO: %d\n", ret);
+               dev_err(component->dev, "Failed to set NLO: %d\n", ret);
                return ret;
        }
 
        if (!master) {
-               dev_dbg(codec->dev, "Enable PLL\n");
+               dev_dbg(component->dev, "Enable PLL\n");
                ret = regmap_update_bits(max9860->regmap, MAX9860_AUDIOCLKHIGH,
                                         MAX9860_PLL, MAX9860_PLL);
                if (ret) {
-                       dev_err(codec->dev, "Failed to enable PLL: %d\n", ret);
+                       dev_err(component->dev, "Failed to enable PLL: %d\n", ret);
                        return ret;
                }
        }
@@ -453,8 +453,8 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
 
 static int max9860_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max9860_priv *max9860 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -500,10 +500,10 @@ static struct snd_soc_dai_driver max9860_dai = {
        .symmetric_rates = 1,
 };
 
-static int max9860_set_bias_level(struct snd_soc_codec *codec,
+static int max9860_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct max9860_priv *max9860 = dev_get_drvdata(codec->dev);
+       struct max9860_priv *max9860 = dev_get_drvdata(component->dev);
        int ret;
 
        switch (level) {
@@ -515,7 +515,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
                ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
                                         MAX9860_SHDN, MAX9860_SHDN);
                if (ret) {
-                       dev_err(codec->dev, "Failed to remove SHDN: %d\n", ret);
+                       dev_err(component->dev, "Failed to remove SHDN: %d\n", ret);
                        return ret;
                }
                break;
@@ -524,7 +524,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
                ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
                                         MAX9860_SHDN, 0);
                if (ret) {
-                       dev_err(codec->dev, "Failed to request SHDN: %d\n",
+                       dev_err(component->dev, "Failed to request SHDN: %d\n",
                                ret);
                        return ret;
                }
@@ -534,18 +534,17 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static const struct snd_soc_codec_driver max9860_codec_driver = {
-       .set_bias_level = max9860_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = max9860_controls,
-               .num_controls           = ARRAY_SIZE(max9860_controls),
-               .dapm_widgets           = max9860_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max9860_dapm_widgets),
-               .dapm_routes            = max9860_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(max9860_dapm_routes),
-       },
+static const struct snd_soc_component_driver max9860_component_driver = {
+       .set_bias_level         = max9860_set_bias_level,
+       .controls               = max9860_controls,
+       .num_controls           = ARRAY_SIZE(max9860_controls),
+       .dapm_widgets           = max9860_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max9860_dapm_widgets),
+       .dapm_routes            = max9860_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(max9860_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 #ifdef CONFIG_PM
@@ -698,7 +697,7 @@ static int max9860_probe(struct i2c_client *i2c,
        pm_runtime_enable(dev);
        pm_runtime_idle(dev);
 
-       ret = snd_soc_register_codec(dev, &max9860_codec_driver,
+       ret = devm_snd_soc_register_component(dev, &max9860_component_driver,
                                     &max9860_dai, 1);
        if (ret) {
                dev_err(dev, "Failed to register CODEC: %d\n", ret);
@@ -719,7 +718,6 @@ static int max9860_remove(struct i2c_client *i2c)
        struct device *dev = &i2c->dev;
        struct max9860_priv *max9860 = dev_get_drvdata(dev);
 
-       snd_soc_unregister_codec(dev);
        pm_runtime_disable(dev);
        regulator_disable(max9860->dvddio);
        return 0;
index 2f60924fe9196861391ed7a8234c8aab41449b10..4ea3287162ad2356721116176cb33a81b258073f 100644 (file)
@@ -179,8 +179,8 @@ static inline int get_ni_value(int mclk, int rate)
 static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
        unsigned int ni_h, ni_l;
        int value;
 
@@ -227,7 +227,7 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
                                bclk_value = MAX9867_IFC1B_PCLK_16;
                                break;
                        default:
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "unsupported sampling rate\n");
                                return -EINVAL;
                        }
@@ -239,7 +239,7 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
                        bclk_value = MAX9867_IFC1B_32BIT;
                        break;
                default:
-                       dev_err(codec->dev, "unsupported sampling rate\n");
+                       dev_err(component->dev, "unsupported sampling rate\n");
                        return -EINVAL;
                }
                regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
@@ -251,8 +251,8 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
 static int max9867_prepare(struct snd_pcm_substream *substream,
                         struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 
        regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
                MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
@@ -261,8 +261,8 @@ static int max9867_prepare(struct snd_pcm_substream *substream,
 
 static int max9867_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
 
        if (mute)
                regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
@@ -276,8 +276,8 @@ static int max9867_mute(struct snd_soc_dai *dai, int mute)
 static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
        int value = 0;
 
        /* Set the prescaler based on the master clock frequency*/
@@ -291,7 +291,9 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                value |= MAX9867_PSCLK_40_60;
                max9867->pclk =  freq/4;
        } else {
-               pr_err("bad clock frequency %d", freq);
+               dev_err(component->dev,
+                       "Invalid clock frequency %uHz (required 10-60MHz)\n",
+                       freq);
                return -EINVAL;
        }
        value = value << MAX9867_PSCLK_SHIFT;
@@ -306,8 +308,8 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
        u8 iface1A = 0, iface1B = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -323,10 +325,16 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       /* for i2s compatible mode */
-       iface1A |= MAX9867_I2S_DLY;
-       /* SDOUT goes to hiz state after all data is transferred */
-       iface1A |= MAX9867_SDOUT_HIZ;
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               iface1A |= MAX9867_I2S_DLY;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ;
+               break;
+       default:
+               return -EINVAL;
+       }
 
        /* Clock inversion bits, BCI and WCI */
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -367,19 +375,20 @@ static struct snd_soc_dai_driver max9867_dai[] = {
        .name = "max9867-aif1",
        .playback = {
                .stream_name = "HiFi Playback",
-               .channels_min = 1,
+               .channels_min = 2,
                .channels_max = 2,
                .rates = MAX9867_RATES,
                .formats = MAX9867_FORMATS,
        },
        .capture = {
                .stream_name = "HiFi Capture",
-               .channels_min = 1,
+               .channels_min = 2,
                .channels_max = 2,
                .rates = MAX9867_RATES,
                .formats = MAX9867_FORMATS,
        },
        .ops = &max9867_dai_ops,
+       .symmetric_rates = 1,
        }
 };
 
@@ -404,25 +413,17 @@ static int max9867_resume(struct device *dev)
 }
 #endif
 
-static int max9867_probe(struct snd_soc_codec *codec)
-{
-       struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
-
-       dev_dbg(codec->dev, "max98090_probe\n");
-       max9867->codec = codec;
-       return 0;
-}
-
-static const struct snd_soc_codec_driver max9867_codec = {
-       .probe = max9867_probe,
-       .component_driver = {
-               .controls               = max9867_snd_controls,
-               .num_controls           = ARRAY_SIZE(max9867_snd_controls),
-               .dapm_routes            = max9867_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(max9867_audio_map),
-               .dapm_widgets           = max9867_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max9867_dapm_widgets),
-       },
+static const struct snd_soc_component_driver max9867_component = {
+       .controls               = max9867_snd_controls,
+       .num_controls           = ARRAY_SIZE(max9867_snd_controls),
+       .dapm_routes            = max9867_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max9867_audio_map),
+       .dapm_widgets           = max9867_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max9867_dapm_widgets),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static bool max9867_volatile_register(struct device *dev, unsigned int reg)
@@ -486,8 +487,7 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
        max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
        if (IS_ERR(max9867->regmap)) {
                ret = PTR_ERR(max9867->regmap);
-               dev_err(&i2c->dev,
-                               "Failed to allocate regmap: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
                return ret;
        }
        ret = regmap_read(max9867->regmap,
@@ -497,21 +497,15 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
        dev_info(&i2c->dev, "device revision: %x\n", reg);
-       ret = snd_soc_register_codec(&i2c->dev, &max9867_codec,
+       ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component,
                        max9867_dai, ARRAY_SIZE(max9867_dai));
        if (ret < 0) {
-               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
                return ret;
        }
        return ret;
 }
 
-static int max9867_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max9867_i2c_id[] = {
        { "max9867", 0 },
        { }
@@ -535,7 +529,6 @@ static struct i2c_driver max9867_i2c_driver = {
                .pm = &max9867_pm_ops,
        },
        .probe  = max9867_i2c_probe,
-       .remove = max9867_i2c_remove,
        .id_table = max9867_i2c_id,
 };
 
index 65590b4ad62a15e10101a63c24b3da316637424e..55cd9976ff47d3ca10e1d12f8f6f6e6119e3f2d3 100644 (file)
@@ -75,7 +75,6 @@
 /* codec private data */
 struct max9867_priv {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
        unsigned int sysclk;
        unsigned int pclk;
        unsigned int master;
index 921f95fc396dbc04e2cc4f8fbe7a6b7dcd6abdd6..29877730a2b042b7d30466fe88d73f81708336db 100644 (file)
@@ -99,8 +99,8 @@ static const struct snd_kcontrol_new max98925_dai_sel_mux =
 static int max98925_dac_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -256,7 +256,7 @@ static const struct {
        },
 };
 
-static inline int max98925_rate_value(struct snd_soc_codec *codec,
+static inline int max98925_rate_value(struct snd_soc_component *component,
                int rate, int clock, int *value, int *n, int *m)
 {
        int ret = -EINVAL;
@@ -297,11 +297,11 @@ static void max98925_set_sense_data(struct max98925_priv *max98925)
 static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
                                 unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
        unsigned int invert = 0;
 
-       dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+       dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
                /* set DAI to slave mode */
@@ -322,7 +322,7 @@ static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
        case SND_SOC_DAIFMT_CBS_CFM:
        case SND_SOC_DAIFMT_CBM_CFS:
        default:
-               dev_err(codec->dev, "DAI clock mode unsupported");
+               dev_err(component->dev, "DAI clock mode unsupported");
                return -EINVAL;
        }
 
@@ -339,7 +339,7 @@ static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
                invert = M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK;
                break;
        default:
-               dev_err(codec->dev, "DAI invert mode unsupported");
+               dev_err(component->dev, "DAI invert mode unsupported");
                return -EINVAL;
        }
 
@@ -352,7 +352,7 @@ static int max98925_set_clock(struct max98925_priv *max98925,
                struct snd_pcm_hw_params *params)
 {
        unsigned int dai_sr = 0, clock, mdll, n, m;
-       struct snd_soc_codec *codec = max98925->codec;
+       struct snd_soc_component *component = max98925->component;
        int rate = params_rate(params);
        /* BCLK/LRCLK ratio calculation */
        int blr_clk_ratio = params_channels(params) * max98925->ch_size;
@@ -395,12 +395,12 @@ static int max98925_set_clock(struct max98925_priv *max98925,
                mdll  = M98925_MDLL_MULT_MCLKx8;
                break;
        default:
-               dev_info(max98925->codec->dev, "unsupported sysclk %d\n",
+               dev_info(max98925->component->dev, "unsupported sysclk %d\n",
                                        max98925->sysclk);
                return -EINVAL;
        }
 
-       if (max98925_rate_value(codec, rate, clock, &dai_sr, &n, &m))
+       if (max98925_rate_value(component, rate, clock, &dai_sr, &n, &m))
                return -EINVAL;
 
        /* set DAI_SR to correct LRCLK frequency */
@@ -427,8 +427,8 @@ static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
        switch (params_width(params)) {
        case 16:
@@ -454,7 +454,7 @@ static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
                                __func__, params_format(params));
                return -EINVAL;
        }
-       dev_dbg(codec->dev, "%s: format supported %d",
+       dev_dbg(component->dev, "%s: format supported %d",
                                __func__, params_format(params));
        return max98925_set_clock(max98925, params);
 }
@@ -462,8 +462,8 @@ static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
 static int max98925_dai_set_sysclk(struct snd_soc_dai *dai,
                                   int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case 0:
@@ -516,11 +516,11 @@ static struct snd_soc_dai_driver max98925_dai[] = {
        }
 };
 
-static int max98925_probe(struct snd_soc_codec *codec)
+static int max98925_probe(struct snd_soc_component *component)
 {
-       struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
+       struct max98925_priv *max98925 = snd_soc_component_get_drvdata(component);
 
-       max98925->codec = codec;
+       max98925->component = component;
        regmap_write(max98925->regmap, MAX98925_GLOBAL_ENABLE, 0x00);
        /* It's not the default but we need to set DAI_DLY */
        regmap_write(max98925->regmap,
@@ -538,16 +538,18 @@ static int max98925_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98925 = {
-       .probe            = max98925_probe,
-       .component_driver = {
-               .controls               = max98925_snd_controls,
-               .num_controls           = ARRAY_SIZE(max98925_snd_controls),
-               .dapm_routes            = max98925_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(max98925_audio_map),
-               .dapm_widgets           = max98925_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max98925_dapm_widgets),
-       },
+static const struct snd_soc_component_driver soc_component_dev_max98925 = {
+       .probe                  = max98925_probe,
+       .controls               = max98925_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98925_snd_controls),
+       .dapm_routes            = max98925_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98925_audio_map),
+       .dapm_widgets           = max98925_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98925_dapm_widgets),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config max98925_regmap = {
@@ -612,20 +614,15 @@ static int max98925_i2c_probe(struct i2c_client *i2c,
 
        dev_info(&i2c->dev, "device version 0x%02X\n", reg);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98925,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_max98925,
                        max98925_dai, ARRAY_SIZE(max98925_dai));
        if (ret < 0)
                dev_err(&i2c->dev,
-                               "Failed to register codec: %d\n", ret);
+                               "Failed to register component: %d\n", ret);
        return ret;
 }
 
-static int max98925_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98925_i2c_id[] = {
        { "max98925", 0 },
        { }
@@ -645,7 +642,6 @@ static struct i2c_driver max98925_i2c_driver = {
                .pm = NULL,
        },
        .probe  = max98925_i2c_probe,
-       .remove = max98925_i2c_remove,
        .id_table = max98925_i2c_id,
 };
 
index 3783248f2780f3ac61dc2c29acc57941bc9cff87..96f97085328dbdc29f60a0313bd97765fa7a1e12 100644 (file)
 
 struct max98925_priv {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct max98925_pdata *pdata;
        unsigned int sysclk;
        unsigned int v_slot;
index 7b1d1b0fa8796d379e650cbdf6c0eda623c6aac7..d9b1f68f243dd837cf55116cccd732697685679b 100644 (file)
@@ -336,18 +336,18 @@ static void max98926_set_sense_data(struct max98926_priv *max98926)
 static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
        unsigned int invert = 0;
 
-       dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+       dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
                max98926_set_sense_data(max98926);
                break;
        default:
-               dev_err(codec->dev, "DAI clock mode unsupported\n");
+               dev_err(component->dev, "DAI clock mode unsupported\n");
                return -EINVAL;
        }
 
@@ -364,7 +364,7 @@ static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
                invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK;
                break;
        default:
-               dev_err(codec->dev, "DAI invert mode unsupported\n");
+               dev_err(component->dev, "DAI invert mode unsupported\n");
                return -EINVAL;
        }
 
@@ -381,8 +381,8 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
 {
        int dai_sr = -EINVAL;
        int rate = params_rate(params), i;
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
        int blr_clk_ratio;
 
        switch (params_format(params)) {
@@ -408,7 +408,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
                max98926->ch_size = 32;
                break;
        default:
-               dev_dbg(codec->dev, "format unsupported %d\n",
+               dev_dbg(component->dev, "format unsupported %d\n",
                        params_format(params));
                return -EINVAL;
        }
@@ -485,27 +485,29 @@ static struct snd_soc_dai_driver max98926_dai[] = {
 }
 };
 
-static int max98926_probe(struct snd_soc_codec *codec)
+static int max98926_probe(struct snd_soc_component *component)
 {
-       struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
+       struct max98926_priv *max98926 = snd_soc_component_get_drvdata(component);
 
-       max98926->codec = codec;
+       max98926->component = component;
 
        /* Hi-Z all the slots */
        regmap_write(max98926->regmap, MAX98926_DOUT_HIZ_CFG4, 0xF0);
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98926 = {
-       .probe  = max98926_probe,
-       .component_driver = {
-               .controls               = max98926_snd_controls,
-               .num_controls           = ARRAY_SIZE(max98926_snd_controls),
-               .dapm_routes            = max98926_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(max98926_audio_map),
-               .dapm_widgets           = max98926_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(max98926_dapm_widgets),
-       },
+static const struct snd_soc_component_driver soc_component_dev_max98926 = {
+       .probe                  = max98926_probe,
+       .controls               = max98926_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98926_snd_controls),
+       .dapm_routes            = max98926_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98926_audio_map),
+       .dapm_widgets           = max98926_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98926_dapm_widgets),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config max98926_regmap = {
@@ -563,22 +565,17 @@ static int max98926_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98926,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_max98926,
                        max98926_dai, ARRAY_SIZE(max98926_dai));
        if (ret < 0)
                dev_err(&i2c->dev,
-                               "Failed to register codec: %d\n", ret);
+                               "Failed to register component: %d\n", ret);
        dev_info(&i2c->dev, "device version: %x\n", reg);
 err_out:
        return ret;
 }
 
-static int max98926_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98926_i2c_id[] = {
        { "max98926", 0 },
        { }
@@ -598,7 +595,6 @@ static struct i2c_driver max98926_i2c_driver = {
                .pm = NULL,
        },
        .probe  = max98926_i2c_probe,
-       .remove = max98926_i2c_remove,
        .id_table = max98926_i2c_id,
 };
 
index 9d7ab6df79ca27054bde7a2b7314a0721cc52c3b..ccf2c3f66c07355cf16c34f77af2df380ef43ca4 100644 (file)
 
 struct max98926_priv {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        unsigned int sysclk;
        unsigned int v_slot;
        unsigned int i_slot;
index f701fdc81175fca40a55d3a0f24d5a74171f150b..065303a465359b09e0f28e64867fcd9524d86582 100644 (file)
@@ -142,14 +142,14 @@ static struct reg_default max98927_reg[] = {
 
 static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
        unsigned int mode = 0;
        unsigned int format = 0;
        bool use_pdm = false;
        unsigned int invert = 0;
 
-       dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
+       dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -160,7 +160,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                mode = MAX98927_PCM_MASTER_MODE_MASTER;
                break;
        default:
-               dev_err(codec->dev, "DAI clock mode unsupported\n");
+               dev_err(component->dev, "DAI clock mode unsupported\n");
                return -EINVAL;
        }
 
@@ -176,7 +176,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
                break;
        default:
-               dev_err(codec->dev, "DAI invert mode unsupported\n");
+               dev_err(component->dev, "DAI invert mode unsupported\n");
                return -EINVAL;
        }
 
@@ -268,7 +268,7 @@ static int max98927_get_bclk_sel(int bclk)
 static int max98927_set_clock(struct max98927_priv *max98927,
        struct snd_pcm_hw_params *params)
 {
-       struct snd_soc_codec *codec = max98927->codec;
+       struct snd_soc_component *component = max98927->component;
        /* BCLK/LRCLK ratio calculation */
        int blr_clk_ratio = params_channels(params) * max98927->ch_size;
        int value;
@@ -281,7 +281,7 @@ static int max98927_set_clock(struct max98927_priv *max98927,
                                break;
                }
                if (i == ARRAY_SIZE(rate_table)) {
-                       dev_err(codec->dev, "failed to find proper clock rate.\n");
+                       dev_err(component->dev, "failed to find proper clock rate.\n");
                        return -EINVAL;
                }
                regmap_update_bits(max98927->regmap,
@@ -294,7 +294,7 @@ static int max98927_set_clock(struct max98927_priv *max98927,
                /* BCLK configuration */
                value = max98927_get_bclk_sel(blr_clk_ratio);
                if (!value) {
-                       dev_err(codec->dev, "format unsupported %d\n",
+                       dev_err(component->dev, "format unsupported %d\n",
                                params_format(params));
                        return -EINVAL;
                }
@@ -311,8 +311,8 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
        unsigned int sampling_rate = 0;
        unsigned int chan_sz = 0;
 
@@ -328,7 +328,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
                chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
                break;
        default:
-               dev_err(codec->dev, "format unsupported %d\n",
+               dev_err(component->dev, "format unsupported %d\n",
                        params_format(params));
                goto err;
        }
@@ -339,7 +339,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
                MAX98927_R0020_PCM_MODE_CFG,
                MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
 
-       dev_dbg(codec->dev, "format supported %d",
+       dev_dbg(component->dev, "format supported %d",
                params_format(params));
 
        /* sampling rate configuration */
@@ -372,7 +372,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
                sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
                break;
        default:
-               dev_err(codec->dev, "rate %d not supported\n",
+               dev_err(component->dev, "rate %d not supported\n",
                        params_rate(params));
                goto err;
        }
@@ -407,8 +407,8 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask,
        int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
        int bsel = 0;
        unsigned int chan_sz = 0;
 
@@ -417,7 +417,7 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
        /* BCLK configuration */
        bsel = max98927_get_bclk_sel(slots * slot_width);
        if (bsel == 0) {
-               dev_err(codec->dev, "BCLK %d not supported\n",
+               dev_err(component->dev, "BCLK %d not supported\n",
                        slots * slot_width);
                return -EINVAL;
        }
@@ -439,7 +439,7 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
                chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
                break;
        default:
-               dev_err(codec->dev, "format unsupported %d\n",
+               dev_err(component->dev, "format unsupported %d\n",
                        slot_width);
                return -EINVAL;
        }
@@ -483,8 +483,8 @@ static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
 static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 
        max98927->sysclk = freq;
        return 0;
@@ -500,8 +500,8 @@ static const struct snd_soc_dai_ops max98927_dai_ops = {
 static int max98927_dac_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -677,11 +677,11 @@ static struct snd_soc_dai_driver max98927_dai[] = {
        }
 };
 
-static int max98927_probe(struct snd_soc_codec *codec)
+static int max98927_probe(struct snd_soc_component *component)
 {
-       struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+       struct max98927_priv *max98927 = snd_soc_component_get_drvdata(component);
 
-       max98927->codec = codec;
+       max98927->component = component;
 
        /* Software Reset */
        regmap_write(max98927->regmap,
@@ -823,16 +823,18 @@ static const struct dev_pm_ops max98927_pm = {
        SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume)
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
-       .probe = max98927_probe,
-       .component_driver = {
-               .controls = max98927_snd_controls,
-               .num_controls = ARRAY_SIZE(max98927_snd_controls),
-               .dapm_widgets = max98927_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
-               .dapm_routes = max98927_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_max98927 = {
+       .probe                  = max98927_probe,
+       .controls               = max98927_snd_controls,
+       .num_controls           = ARRAY_SIZE(max98927_snd_controls),
+       .dapm_widgets           = max98927_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(max98927_dapm_widgets),
+       .dapm_routes            = max98927_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(max98927_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config max98927_regmap = {
@@ -914,20 +916,15 @@ static int max98927_i2c_probe(struct i2c_client *i2c,
        max98927_slot_config(i2c, max98927);
 
        /* codec registeration */
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+               &soc_component_dev_max98927,
                max98927_dai, ARRAY_SIZE(max98927_dai));
        if (ret < 0)
-               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
 
        return ret;
 }
 
-static int max98927_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id max98927_i2c_id[] = {
        { "max98927", 0},
        { },
@@ -959,7 +956,6 @@ static struct i2c_driver max98927_i2c_driver = {
                .pm = &max98927_pm,
        },
        .probe  = max98927_i2c_probe,
-       .remove = max98927_i2c_remove,
        .id_table = max98927_i2c_id,
 };
 
index 9ea839735433d2c22d6cab24f9caf9d1478a10b2..42a9a244a9dbef6546fd83dbac3e38401fb4f40f 100644 (file)
 
 struct max98927_priv {
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct max98927_pdata *pdata;
        unsigned int spk_gain;
        unsigned int sysclk;
index be7a45f05bbffdaa861495f20834a8de03032304..7b0d2610cd27bc7da32e999ac22675579b493dbf 100644 (file)
@@ -107,13 +107,13 @@ static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int rate = params_rate(params);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(mc13783_rates); i++) {
                if (rate == mc13783_rates[i]) {
-                       snd_soc_update_bits(codec, MC13783_AUDIO_DAC,
+                       snd_soc_component_update_bits(component, MC13783_AUDIO_DAC,
                                        0xf << 17, i << 17);
                        return 0;
                }
@@ -126,7 +126,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int rate = params_rate(params);
        unsigned int val;
 
@@ -141,7 +141,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, MC13783_AUDIO_CODEC, AUDIO_CODEC_CDCFS8K16K,
+       snd_soc_component_update_bits(component, MC13783_AUDIO_CODEC, AUDIO_CODEC_CDCFS8K16K,
                        val);
 
        return 0;
@@ -160,7 +160,7 @@ static int mc13783_pcm_hw_params_sync(struct snd_pcm_substream *substream,
 static int mc13783_set_fmt(struct snd_soc_dai *dai, unsigned int fmt,
                        unsigned int reg)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val = 0;
        unsigned int mask = AUDIO_CFS(3) | AUDIO_BCL_INV | AUDIO_CFS_INV |
                                AUDIO_CSM | AUDIO_C_CLK_EN | AUDIO_C_RESET;
@@ -208,7 +208,7 @@ static int mc13783_set_fmt(struct snd_soc_dai *dai, unsigned int fmt,
 
        val |= AUDIO_C_RESET;
 
-       snd_soc_update_bits(codec, reg, mask, val);
+       snd_soc_component_update_bits(component, reg, mask, val);
 
        return 0;
 }
@@ -255,7 +255,7 @@ static int mc13783_set_sysclk(struct snd_soc_dai *dai,
                                  int clk_id, unsigned int freq, int dir,
                                  unsigned int reg)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int clk;
        unsigned int val = 0;
        unsigned int mask = AUDIO_CLK(0x7) | AUDIO_CLK_SEL;
@@ -275,7 +275,7 @@ static int mc13783_set_sysclk(struct snd_soc_dai *dai,
 
        val |= AUDIO_CLK(clk);
 
-       snd_soc_update_bits(codec, reg, mask, val);
+       snd_soc_component_update_bits(component, reg, mask, val);
 
        return 0;
 }
@@ -308,7 +308,7 @@ static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots,
        int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val = 0;
        unsigned int mask = SSI_NETWORK_DAC_SLOT_MASK |
                                SSI_NETWORK_DAC_RXSLOT_MASK;
@@ -344,7 +344,7 @@ static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
+       snd_soc_component_update_bits(component, MC13783_SSI_NETWORK, mask, val);
 
        return 0;
 }
@@ -353,7 +353,7 @@ static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots,
        int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val = 0;
        unsigned int mask = 0x3f;
 
@@ -366,7 +366,7 @@ static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
        val |= (0x00 << 2);     /* primary timeslot RX/TX(?) is 0 */
        val |= (0x01 << 4);     /* secondary timeslot TX is 1 */
 
-       snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
+       snd_soc_component_update_bits(component, MC13783_SSI_NETWORK, mask, val);
 
        return 0;
 }
@@ -606,12 +606,12 @@ static struct snd_kcontrol_new mc13783_control_list[] = {
        SOC_SINGLE("MC2 Capture Bias Switch", MC13783_AUDIO_TX, 1, 1, 0),
 };
 
-static int mc13783_probe(struct snd_soc_codec *codec)
+static int mc13783_probe(struct snd_soc_component *component)
 {
-       struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct mc13783_priv *priv = snd_soc_component_get_drvdata(component);
 
-       snd_soc_codec_init_regmap(codec,
-                                 dev_get_regmap(codec->dev->parent, NULL));
+       snd_soc_component_init_regmap(component,
+                                 dev_get_regmap(component->dev->parent, NULL));
 
        /* these are the reset values */
        mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
@@ -638,14 +638,12 @@ static int mc13783_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int mc13783_remove(struct snd_soc_codec *codec)
+static void mc13783_remove(struct snd_soc_component *component)
 {
-       struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct mc13783_priv *priv = snd_soc_component_get_drvdata(component);
 
        /* Make sure VAUDIOON is off */
        mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
-
-       return 0;
 }
 
 #define MC13783_RATES_RECORD (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
@@ -731,17 +729,19 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
        }
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
-       .probe          = mc13783_probe,
-       .remove         = mc13783_remove,
-       .component_driver = {
-               .controls               = mc13783_control_list,
-               .num_controls           = ARRAY_SIZE(mc13783_control_list),
-               .dapm_widgets           = mc13783_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(mc13783_dapm_widgets),
-               .dapm_routes            = mc13783_routes,
-               .num_dapm_routes        = ARRAY_SIZE(mc13783_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_mc13783 = {
+       .probe                  = mc13783_probe,
+       .remove                 = mc13783_remove,
+       .controls               = mc13783_control_list,
+       .num_controls           = ARRAY_SIZE(mc13783_control_list),
+       .dapm_widgets           = mc13783_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(mc13783_dapm_widgets),
+       .dapm_routes            = mc13783_routes,
+       .num_dapm_routes        = ARRAY_SIZE(mc13783_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int __init mc13783_codec_probe(struct platform_device *pdev)
@@ -782,10 +782,10 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
        priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
 
        if (priv->adc_ssi_port == priv->dac_ssi_port)
-               ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
+               ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_mc13783,
                        mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
        else
-               ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
+               ret = devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_mc13783,
                        mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
 
        return ret;
@@ -793,8 +793,6 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
 
 static int mc13783_codec_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
-
        return 0;
 }
 
index 5cc960d8211e3c6f8608900456210fe715d3bac5..a5fa490dc145e85b71b449c2f811a81828cdce85 100644 (file)
@@ -338,8 +338,8 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *hw_params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
        int i = get_coeff(priv->mclk, params_rate(hw_params));
        int srate;
 
@@ -351,23 +351,23 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
        if (priv->clk_in) {
                switch (priv->mclk / params_rate(hw_params)) {
                case 256:
-                       snd_soc_update_bits(codec, ML26124_CLK_CTL,
+                       snd_soc_component_update_bits(component, ML26124_CLK_CTL,
                                            BIT(0) | BIT(1), 1);
                        break;
                case 512:
-                       snd_soc_update_bits(codec, ML26124_CLK_CTL,
+                       snd_soc_component_update_bits(component, ML26124_CLK_CTL,
                                            BIT(0) | BIT(1), 2);
                        break;
                case 1024:
-                       snd_soc_update_bits(codec, ML26124_CLK_CTL,
+                       snd_soc_component_update_bits(component, ML26124_CLK_CTL,
                                            BIT(0) | BIT(1), 3);
                        break;
                default:
-                       dev_err(codec->dev, "Unsupported MCLKI\n");
+                       dev_err(component->dev, "Unsupported MCLKI\n");
                        break;
                }
        } else {
-               snd_soc_update_bits(codec, ML26124_CLK_CTL,
+               snd_soc_component_update_bits(component, ML26124_CLK_CTL,
                                    BIT(0) | BIT(1), 0);
        }
 
@@ -375,35 +375,35 @@ static int ml26124_hw_params(struct snd_pcm_substream *substream,
        if (srate < 0)
                return srate;
 
-       snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf, srate);
-       snd_soc_update_bits(codec, ML26124_PLLNL, 0xff, coeff_div[i].pllnl);
-       snd_soc_update_bits(codec, ML26124_PLLNH, 0x1, coeff_div[i].pllnh);
-       snd_soc_update_bits(codec, ML26124_PLLML, 0xff, coeff_div[i].pllml);
-       snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh);
-       snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv);
+       snd_soc_component_update_bits(component, ML26124_SMPLING_RATE, 0xf, srate);
+       snd_soc_component_update_bits(component, ML26124_PLLNL, 0xff, coeff_div[i].pllnl);
+       snd_soc_component_update_bits(component, ML26124_PLLNH, 0x1, coeff_div[i].pllnh);
+       snd_soc_component_update_bits(component, ML26124_PLLML, 0xff, coeff_div[i].pllml);
+       snd_soc_component_update_bits(component, ML26124_PLLMH, 0x3f, coeff_div[i].pllmh);
+       snd_soc_component_update_bits(component, ML26124_PLLDIV, 0x1f, coeff_div[i].plldiv);
 
        return 0;
 }
 
 static int ml26124_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 
        switch (priv->substream->stream) {
        case SNDRV_PCM_STREAM_CAPTURE:
-               snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
+               snd_soc_component_update_bits(component, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
                break;
        case SNDRV_PCM_STREAM_PLAYBACK:
-               snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
+               snd_soc_component_update_bits(component, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
                break;
        }
 
        if (mute)
-               snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
+               snd_soc_component_update_bits(component, ML26124_DVOL_CTL, BIT(4),
                                    DVOL_CTL_DVMUTE_ON);
        else
-               snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
+               snd_soc_component_update_bits(component, ML26124_DVOL_CTL, BIT(4),
                                    DVOL_CTL_DVMUTE_OFF);
 
        return 0;
@@ -413,7 +413,7 @@ static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
        unsigned char mode;
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -426,7 +426,7 @@ static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
        default:
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, ML26124_SAI_MODE_SEL, BIT(0), mode);
+       snd_soc_component_update_bits(component, ML26124_SAI_MODE_SEL, BIT(0), mode);
 
        /* interface format */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -450,8 +450,8 @@ static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case ML26124_USE_PLLOUT:
@@ -469,17 +469,17 @@ static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int ml26124_set_bias_level(struct snd_soc_codec *codec,
+static int ml26124_set_bias_level(struct snd_soc_component *component,
                enum snd_soc_bias_level level)
 {
-       struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct ml26124_priv *priv = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
+               snd_soc_component_update_bits(component, ML26124_PW_SPAMP_PW_MNG,
                                    ML26124_R26_MASK, ML26124_BLT_PREAMP_ON);
                msleep(100);
-               snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
+               snd_soc_component_update_bits(component, ML26124_PW_SPAMP_PW_MNG,
                                    ML26124_R26_MASK,
                                    ML26124_MICBEN_ON | ML26124_BLT_ALL_ON);
                break;
@@ -487,8 +487,8 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_STANDBY:
                /* VMID ON */
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG,
                                            ML26124_VMID, ML26124_VMID);
                        msleep(500);
                        regcache_sync(priv->regmap);
@@ -496,7 +496,7 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
                break;
        case SND_SOC_BIAS_OFF:
                /* VMID OFF */
-               snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
+               snd_soc_component_update_bits(component, ML26124_PW_REF_PW_MNG,
                                    ML26124_VMID, 0);
                break;
        }
@@ -528,27 +528,29 @@ static struct snd_soc_dai_driver ml26124_dai = {
        .symmetric_rates = 1,
 };
 
-static int ml26124_probe(struct snd_soc_codec *codec)
+static int ml26124_probe(struct snd_soc_component *component)
 {
        /* Software Reset */
-       snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
-       snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
+       snd_soc_component_update_bits(component, ML26124_SW_RST, 0x01, 1);
+       snd_soc_component_update_bits(component, ML26124_SW_RST, 0x01, 0);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
-       .probe =        ml26124_probe,
-       .set_bias_level = ml26124_set_bias_level,
-       .suspend_bias_off = true,
-       .component_driver = {
-               .controls               = ml26124_snd_controls,
-               .num_controls           = ARRAY_SIZE(ml26124_snd_controls),
-               .dapm_widgets           = ml26124_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ml26124_dapm_widgets),
-               .dapm_routes            = ml26124_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(ml26124_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ml26124 = {
+       .probe                  = ml26124_probe,
+       .set_bias_level         = ml26124_set_bias_level,
+       .controls               = ml26124_snd_controls,
+       .num_controls           = ARRAY_SIZE(ml26124_snd_controls),
+       .dapm_widgets           = ml26124_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ml26124_dapm_widgets),
+       .dapm_routes            = ml26124_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ml26124_intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ml26124_i2c_regmap = {
@@ -580,14 +582,8 @@ static int ml26124_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       return snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_ml26124, &ml26124_dai, 1);
-}
-
-static int ml26124_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
+       return devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_ml26124, &ml26124_dai, 1);
 }
 
 static const struct i2c_device_id ml26124_i2c_id[] = {
@@ -601,7 +597,6 @@ static struct i2c_driver ml26124_i2c_driver = {
                .name = "ml26124",
        },
        .probe = ml26124_i2c_probe,
-       .remove = ml26124_i2c_remove,
        .id_table = ml26124_i2c_id,
 };
 
index 44062bb7bf2fc1a3ff797b00314662fbaa591ba6..12ee83d52405d06a72c8cd5a67485c69bf2ddeb1 100644 (file)
@@ -288,7 +288,7 @@ struct pm8916_wcd_analog_priv {
        int     mbhc_btn0_released;
        bool    detect_accessory_type;
        struct clk *mclk;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
        struct snd_soc_jack *jack;
        bool hphl_jack_type_normally_open;
@@ -338,18 +338,18 @@ static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = {
        SOC_SINGLE_TLV("ADC3 Volume", CDC_A_TX_3_EN, 3, 8, 0, analog_gain),
 };
 
-static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
+static void pm8916_wcd_analog_micbias_enable(struct snd_soc_component *component)
 {
-       struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+       struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-       snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+       snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
                            MICB_1_CTL_EXT_PRECHARG_EN_MASK |
                            MICB_1_CTL_INT_PRECHARG_BYP_MASK,
                            MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL
                            | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
 
        if (wcd->micbias_mv) {
-               snd_soc_update_bits(codec, CDC_A_MICB_1_VAL,
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_VAL,
                                    MICB_1_VAL_MICB_OUT_VAL_MASK,
                                    MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
                /*
@@ -360,20 +360,20 @@ static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
                        msleep(50);
        }
 
-       snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+       snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
                            MICB_1_CTL_EXT_PRECHARG_EN_MASK |
                            MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0);
 
 }
 
-static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_codec
-                                                *codec, int event,
+static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_component
+                                                *component, int event,
                                                 int reg, unsigned int cap_mode)
 {
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               pm8916_wcd_analog_micbias_enable(codec);
-               snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
+               pm8916_wcd_analog_micbias_enable(component);
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
                                    MICB_1_EN_BYP_CAP_MASK, cap_mode);
                break;
        }
@@ -381,25 +381,25 @@ static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_codec
        return 0;
 }
 
-static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_codec
-                                                *codec, int event,
+static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_component
+                                                *component, int event,
                                                 int reg, u32 cap_mode)
 {
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS,
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
                                    MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
                                    MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
-               snd_soc_update_bits(codec, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0);
-               snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
+               snd_soc_component_update_bits(component, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0);
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
                                    MICB_1_EN_OPA_STG2_TAIL_CURR_MASK,
                                    MICB_1_EN_OPA_STG2_TAIL_CURR_1_60UA);
 
                break;
        case SND_SOC_DAPM_POST_PMU:
-               pm8916_wcd_analog_micbias_enable(codec);
-               snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
+               pm8916_wcd_analog_micbias_enable(component);
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
                                    MICB_1_EN_BYP_CAP_MASK, cap_mode);
                break;
        }
@@ -412,10 +412,10 @@ static int pm8916_wcd_analog_enable_micbias_ext1(struct
                                                  *w, struct snd_kcontrol
                                                  *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-       return pm8916_wcd_analog_enable_micbias_ext(codec, event, w->reg,
+       return pm8916_wcd_analog_enable_micbias_ext(component, event, w->reg,
                                                     wcd->micbias1_cap_mode);
 }
 
@@ -424,10 +424,10 @@ static int pm8916_wcd_analog_enable_micbias_ext2(struct
                                                  *w, struct snd_kcontrol
                                                  *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-       return pm8916_wcd_analog_enable_micbias_ext(codec, event, w->reg,
+       return pm8916_wcd_analog_enable_micbias_ext(component, event, w->reg,
                                                     wcd->micbias2_cap_mode);
 
 }
@@ -437,35 +437,35 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct
                                                  *w, struct snd_kcontrol
                                                  *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
-       return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
+       return pm8916_wcd_analog_enable_micbias_int(component, event, w->reg,
                                                     wcd->micbias1_cap_mode);
 }
 
 static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
                                      bool micbias2_enabled)
 {
-       struct snd_soc_codec *codec = priv->codec;
+       struct snd_soc_component *component = priv->component;
        u32 coarse, fine, reg_val, reg_addr;
        int *vrefs, i;
 
        if (!micbias2_enabled) { /* use internal 100uA Current source */
                /* Enable internal 2.2k Internal Rbias Resistor */
-               snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS,
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
                                    MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
                                    MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
                /* Remove pull down on MIC BIAS2 */
-               snd_soc_update_bits(codec, CDC_A_MICB_2_EN,
+               snd_soc_component_update_bits(component, CDC_A_MICB_2_EN,
                                   CDC_A_MICB_2_PULL_DOWN_EN_MASK,
                                   0);
                /* enable 100uA internal current source */
-               snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL,
+               snd_soc_component_update_bits(component, CDC_A_MBHC_FSM_CTL,
                                    CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK,
                                    CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA);
        }
-       snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL,
+       snd_soc_component_update_bits(component, CDC_A_MBHC_FSM_CTL,
                        CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK,
                        CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN);
 
@@ -482,7 +482,7 @@ static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
                fine = ((vrefs[i] % 100) / 12);
                reg_val = (coarse << CDC_A_MBHC_BTN_VREF_COARSE_SHIFT) |
                         (fine << CDC_A_MBHC_BTN_VREF_FINE_SHIFT);
-               snd_soc_update_bits(codec, reg_addr,
+               snd_soc_component_update_bits(component, reg_addr,
                               CDC_A_MBHC_BTN_VREF_MASK,
                               reg_val);
                reg_addr++;
@@ -493,12 +493,12 @@ static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
 
 static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
 {
-       struct snd_soc_codec *codec = wcd->codec;
+       struct snd_soc_component *component = wcd->component;
        bool micbias_enabled = false;
        u32 plug_type = 0;
        u32 int_en_mask;
 
-       snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
+       snd_soc_component_write(component, CDC_A_MBHC_DET_CTL_1,
                      CDC_A_MBHC_DET_CTL_L_DET_EN |
                      CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
                      CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
@@ -510,23 +510,23 @@ static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
        if (wcd->gnd_jack_type_normally_open)
                plug_type |= CDC_A_GND_PLUG_TYPE_NO;
 
-       snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
+       snd_soc_component_write(component, CDC_A_MBHC_DET_CTL_2,
                      CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
                      CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
                      plug_type |
                      CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
 
 
-       snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
+       snd_soc_component_write(component, CDC_A_MBHC_DBNC_TIMER,
                      CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
                      CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
 
        /* enable MBHC clock */
-       snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
+       snd_soc_component_update_bits(component, CDC_D_CDC_DIG_CLK_CTL,
                            DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
                            DIG_CLK_CTL_D_MBHC_CLK_EN);
 
-       if (snd_soc_read(codec, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
+       if (snd_soc_component_read32(component, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
                micbias_enabled = true;
 
        pm8916_mbhc_configure_bias(wcd, micbias_enabled);
@@ -535,8 +535,8 @@ static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
        if (wcd->mbhc_btn_enabled)
                int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
 
-       snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
-       snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
+       snd_soc_component_update_bits(component, CDC_D_INT_EN_CLR, int_en_mask, 0);
+       snd_soc_component_update_bits(component, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
        wcd->mbhc_btn0_released = false;
        wcd->detect_accessory_type = true;
 }
@@ -546,8 +546,8 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct
                                                  *w, struct snd_kcontrol
                                                  *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -558,7 +558,7 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct
                break;
        }
 
-       return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
+       return pm8916_wcd_analog_enable_micbias_int(component, event, w->reg,
                                                     wcd->micbias2_cap_mode);
 }
 
@@ -566,7 +566,7 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
                                         struct snd_kcontrol *kcontrol,
                                         int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        u16 adc_reg = CDC_A_TX_1_2_TEST_CTL_2;
        u8 init_bit_shift;
 
@@ -578,7 +578,7 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                if (w->reg == CDC_A_TX_2_EN)
-                       snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+                       snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
                                            MICB_1_CTL_CFILT_REF_SEL_MASK,
                                            MICB_1_CTL_CFILT_REF_SEL_HPF_REF);
                /*
@@ -587,17 +587,17 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
                 * happen when the input voltage is changing too much.
                 */
                usleep_range(10000, 10010);
-               snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
+               snd_soc_component_update_bits(component, adc_reg, 1 << init_bit_shift,
                                    1 << init_bit_shift);
                switch (w->reg) {
                case CDC_A_TX_1_EN:
-                       snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX1_CTL,
+                       snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX1_CTL,
                                            CONN_TX1_SERIAL_TX1_MUX,
                                            CONN_TX1_SERIAL_TX1_ADC_1);
                        break;
                case CDC_A_TX_2_EN:
                case CDC_A_TX_3_EN:
-                       snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
+                       snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL,
                                            CONN_TX2_SERIAL_TX2_MUX,
                                            CONN_TX2_SERIAL_TX2_ADC_2);
                        break;
@@ -609,21 +609,21 @@ static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
                 * to reduce the tx pop
                 */
                usleep_range(12000, 12010);
-               snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
+               snd_soc_component_update_bits(component, adc_reg, 1 << init_bit_shift, 0x00);
                break;
        case SND_SOC_DAPM_POST_PMD:
                switch (w->reg) {
                case CDC_A_TX_1_EN:
-                       snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX1_CTL,
+                       snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX1_CTL,
                                            CONN_TX1_SERIAL_TX1_MUX,
                                            CONN_TX1_SERIAL_TX1_ZERO);
                        break;
                case CDC_A_TX_2_EN:
-                       snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
+                       snd_soc_component_update_bits(component, CDC_A_MICB_1_CTL,
                                            MICB_1_CTL_CFILT_REF_SEL_MASK, 0);
                        /* fall through */
                case CDC_A_TX_3_EN:
-                       snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
+                       snd_soc_component_update_bits(component, CDC_D_CDC_CONN_TX2_CTL,
                                            CONN_TX2_SERIAL_TX2_MUX,
                                            CONN_TX2_SERIAL_TX2_ZERO);
                        break;
@@ -639,11 +639,11 @@ static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
                                            struct snd_kcontrol *kcontrol,
                                            int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
+               snd_soc_component_update_bits(component, CDC_A_SPKR_PWRSTG_CTL,
                                    SPKR_PWRSTG_CTL_DAC_EN_MASK |
                                    SPKR_PWRSTG_CTL_BBM_MASK |
                                    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
@@ -653,29 +653,29 @@ static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
                                    SPKR_PWRSTG_CTL_HBRDGE_EN |
                                    SPKR_PWRSTG_CTL_CLAMP_EN);
 
-               snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
+               snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
                                    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK,
                                    RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE);
                break;
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, CDC_A_SPKR_DRV_CTL,
+               snd_soc_component_update_bits(component, CDC_A_SPKR_DRV_CTL,
                                    SPKR_DRV_CTL_DEF_MASK,
                                    SPKR_DRV_CTL_DEF_VAL);
-               snd_soc_update_bits(codec, w->reg,
+               snd_soc_component_update_bits(component, w->reg,
                                    SPKR_DRV_CLASSD_PA_EN_MASK,
                                    SPKR_DRV_CLASSD_PA_EN_ENABLE);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
+               snd_soc_component_update_bits(component, CDC_A_SPKR_PWRSTG_CTL,
                                    SPKR_PWRSTG_CTL_DAC_EN_MASK|
                                    SPKR_PWRSTG_CTL_BBM_MASK |
                                    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
                                    SPKR_PWRSTG_CTL_CLAMP_EN_MASK, 0);
 
-               snd_soc_update_bits(codec, CDC_A_SPKR_DAC_CTL,
+               snd_soc_component_update_bits(component, CDC_A_SPKR_DAC_CTL,
                                    SPKR_DAC_CTL_DAC_RESET_MASK,
                                    SPKR_DAC_CTL_DAC_RESET_NORMAL);
-               snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
+               snd_soc_component_update_bits(component, CDC_A_RX_EAR_CTL,
                                    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK, 0);
                break;
        }
@@ -701,36 +701,36 @@ static const struct reg_default wcd_reg_defaults_2_0[] = {
        {CDC_A_MASTER_BIAS_CTL, 0x30},
 };
 
-static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec)
+static int pm8916_wcd_analog_probe(struct snd_soc_component *component)
 {
-       struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
+       struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
        int err, reg;
 
        err = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
        if (err != 0) {
-               dev_err(codec->dev, "failed to enable regulators (%d)\n", err);
+               dev_err(component->dev, "failed to enable regulators (%d)\n", err);
                return err;
        }
 
-       snd_soc_codec_init_regmap(codec,
-                                 dev_get_regmap(codec->dev->parent, NULL));
-       snd_soc_codec_set_drvdata(codec, priv);
-       priv->pmic_rev = snd_soc_read(codec, CDC_D_REVISION1);
-       priv->codec_version = snd_soc_read(codec, CDC_D_PERPH_SUBTYPE);
+       snd_soc_component_init_regmap(component,
+                                 dev_get_regmap(component->dev->parent, NULL));
+       snd_soc_component_set_drvdata(component, priv);
+       priv->pmic_rev = snd_soc_component_read32(component, CDC_D_REVISION1);
+       priv->codec_version = snd_soc_component_read32(component, CDC_D_PERPH_SUBTYPE);
 
-       dev_info(codec->dev, "PMIC REV: %d\t CODEC Version: %d\n",
+       dev_info(component->dev, "PMIC REV: %d\t CODEC Version: %d\n",
                 priv->pmic_rev, priv->codec_version);
 
-       snd_soc_write(codec, CDC_D_PERPH_RESET_CTL4, 0x01);
-       snd_soc_write(codec, CDC_A_PERPH_RESET_CTL4, 0x01);
+       snd_soc_component_write(component, CDC_D_PERPH_RESET_CTL4, 0x01);
+       snd_soc_component_write(component, CDC_A_PERPH_RESET_CTL4, 0x01);
 
        for (reg = 0; reg < ARRAY_SIZE(wcd_reg_defaults_2_0); reg++)
-               snd_soc_write(codec, wcd_reg_defaults_2_0[reg].reg,
+               snd_soc_component_write(component, wcd_reg_defaults_2_0[reg].reg,
                              wcd_reg_defaults_2_0[reg].def);
 
-       priv->codec = codec;
+       priv->component = component;
 
-       snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL,
+       snd_soc_component_update_bits(component, CDC_D_CDC_RST_CTL,
                            RST_CTL_DIG_SW_RST_N_MASK,
                            RST_CTL_DIG_SW_RST_N_REMOVE_RESET);
 
@@ -739,14 +739,14 @@ static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int pm8916_wcd_analog_remove(struct snd_soc_codec *codec)
+static void pm8916_wcd_analog_remove(struct snd_soc_component *component)
 {
-       struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
+       struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
 
-       snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL,
+       snd_soc_component_update_bits(component, CDC_D_CDC_RST_CTL,
                            RST_CTL_DIG_SW_RST_N_MASK, 0);
 
-       return regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
+       regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
                                      priv->supplies);
 }
 
@@ -934,11 +934,11 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0),
 };
 
-static int pm8916_wcd_analog_set_jack(struct snd_soc_codec *codec,
+static int pm8916_wcd_analog_set_jack(struct snd_soc_component *component,
                                      struct snd_soc_jack *jack,
                                      void *data)
 {
-       struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+       struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
        wcd->jack = jack;
 
@@ -950,8 +950,8 @@ static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
        struct pm8916_wcd_analog_priv *priv = arg;
 
        if (priv->detect_accessory_type) {
-               struct snd_soc_codec *codec = priv->codec;
-               u32 val = snd_soc_read(codec, CDC_A_MBHC_RESULT_1);
+               struct snd_soc_component *component = priv->component;
+               u32 val = snd_soc_component_read32(component, CDC_A_MBHC_RESULT_1);
 
                /* check if its BTN0 thats released */
                if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK))
@@ -967,10 +967,10 @@ static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
 static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
 {
        struct pm8916_wcd_analog_priv *priv = arg;
-       struct snd_soc_codec *codec = priv->codec;
+       struct snd_soc_component *component = priv->component;
        u32 btn_result;
 
-       btn_result = snd_soc_read(codec, CDC_A_MBHC_RESULT_1) &
+       btn_result = snd_soc_component_read32(component, CDC_A_MBHC_RESULT_1) &
                                  CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK;
 
        switch (btn_result) {
@@ -993,7 +993,7 @@ static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
                                            SND_JACK_BTN_0, btn_mask);
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Unexpected button press result (%x)", btn_result);
                break;
        }
@@ -1004,15 +1004,15 @@ static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
 static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
 {
        struct pm8916_wcd_analog_priv *priv = arg;
-       struct snd_soc_codec *codec = priv->codec;
+       struct snd_soc_component *component = priv->component;
        bool ins = false;
 
-       if (snd_soc_read(codec, CDC_A_MBHC_DET_CTL_1) &
+       if (snd_soc_component_read32(component, CDC_A_MBHC_DET_CTL_1) &
                                CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK)
                ins = true;
 
        /* Set the detection type appropriately */
-       snd_soc_update_bits(codec, CDC_A_MBHC_DET_CTL_1,
+       snd_soc_component_update_bits(component, CDC_A_MBHC_DET_CTL_1,
                            CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK,
                            (!ins << CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT));
 
@@ -1020,7 +1020,7 @@ static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
        if (ins) { /* hs insertion */
                bool micbias_enabled = false;
 
-               if (snd_soc_read(codec, CDC_A_MICB_2_EN) &
+               if (snd_soc_component_read32(component, CDC_A_MICB_2_EN) &
                                CDC_A_MICB_2_EN_ENABLE)
                        micbias_enabled = true;
 
@@ -1075,18 +1075,20 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
               },
 };
 
-static const struct snd_soc_codec_driver pm8916_wcd_analog = {
-       .probe = pm8916_wcd_analog_probe,
-       .remove = pm8916_wcd_analog_remove,
-       .set_jack = pm8916_wcd_analog_set_jack,
-       .component_driver = {
-               .controls = pm8916_wcd_analog_snd_controls,
-               .num_controls = ARRAY_SIZE(pm8916_wcd_analog_snd_controls),
-               .dapm_widgets = pm8916_wcd_analog_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(pm8916_wcd_analog_dapm_widgets),
-               .dapm_routes = pm8916_wcd_analog_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(pm8916_wcd_analog_audio_map),
-       },
+static const struct snd_soc_component_driver pm8916_wcd_analog = {
+       .probe                  = pm8916_wcd_analog_probe,
+       .remove                 = pm8916_wcd_analog_remove,
+       .set_jack               = pm8916_wcd_analog_set_jack,
+       .controls               = pm8916_wcd_analog_snd_controls,
+       .num_controls           = ARRAY_SIZE(pm8916_wcd_analog_snd_controls),
+       .dapm_widgets           = pm8916_wcd_analog_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pm8916_wcd_analog_dapm_widgets),
+       .dapm_routes            = pm8916_wcd_analog_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(pm8916_wcd_analog_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int pm8916_wcd_analog_parse_dt(struct device *dev,
@@ -1223,7 +1225,7 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, priv);
 
-       return snd_soc_register_codec(dev, &pm8916_wcd_analog,
+       return devm_snd_soc_register_component(dev, &pm8916_wcd_analog,
                                      pm8916_wcd_analog_dai,
                                      ARRAY_SIZE(pm8916_wcd_analog_dai));
 }
@@ -1232,7 +1234,6 @@ static int pm8916_wcd_analog_spmi_remove(struct platform_device *pdev)
 {
        struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_codec(&pdev->dev);
        clk_disable_unprepare(priv->mclk);
 
        return 0;
index 13354d6304a848759433122e124d83119321bd71..3063dedd21cff7255c7f437405a9595902352e57 100644 (file)
@@ -348,14 +348,14 @@ static int msm8916_wcd_digital_enable_interpolator(
                                                struct snd_kcontrol *kcontrol,
                                                int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* apply the digital gain after the interpolator is enabled */
                usleep_range(10000, 10100);
-               snd_soc_write(codec, rx_gain_reg[w->shift],
-                             snd_soc_read(codec, rx_gain_reg[w->shift]));
+               snd_soc_component_write(component, rx_gain_reg[w->shift],
+                             snd_soc_component_read32(component, rx_gain_reg[w->shift]));
                break;
        }
        return 0;
@@ -365,7 +365,7 @@ static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w,
                                          struct snd_kcontrol *kcontrol,
                                          int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int decimator = w->shift + 1;
        u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg;
        u8 dec_hpf_cut_of_freq;
@@ -377,46 +377,46 @@ static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                /* Enable TX digital mute */
-               snd_soc_update_bits(codec, tx_vol_ctl_reg,
+               snd_soc_component_update_bits(component, tx_vol_ctl_reg,
                                    TX_VOL_CTL_CFG_MUTE_EN_MASK,
                                    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
-               dec_hpf_cut_of_freq = snd_soc_read(codec, tx_mux_ctl_reg) &
+               dec_hpf_cut_of_freq = snd_soc_component_read32(component, tx_mux_ctl_reg) &
                                        TX_MUX_CTL_CUT_OFF_FREQ_MASK;
                dec_hpf_cut_of_freq >>= TX_MUX_CTL_CUT_OFF_FREQ_SHIFT;
                if (dec_hpf_cut_of_freq != TX_MUX_CTL_CF_NEG_3DB_150HZ) {
                        /* set cut of freq to CF_MIN_3DB_150HZ (0x1) */
-                       snd_soc_update_bits(codec, tx_mux_ctl_reg,
+                       snd_soc_component_update_bits(component, tx_mux_ctl_reg,
                                            TX_MUX_CTL_CUT_OFF_FREQ_MASK,
                                            TX_MUX_CTL_CF_NEG_3DB_150HZ);
                }
                break;
        case SND_SOC_DAPM_POST_PMU:
                /* enable HPF */
-               snd_soc_update_bits(codec, tx_mux_ctl_reg,
+               snd_soc_component_update_bits(component, tx_mux_ctl_reg,
                                    TX_MUX_CTL_HPF_BP_SEL_MASK,
                                    TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS);
                /* apply the digital gain after the decimator is enabled */
-               snd_soc_write(codec, tx_gain_reg[w->shift],
-                             snd_soc_read(codec, tx_gain_reg[w->shift]));
-               snd_soc_update_bits(codec, tx_vol_ctl_reg,
+               snd_soc_component_write(component, tx_gain_reg[w->shift],
+                             snd_soc_component_read32(component, tx_gain_reg[w->shift]));
+               snd_soc_component_update_bits(component, tx_vol_ctl_reg,
                                    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, tx_vol_ctl_reg,
+               snd_soc_component_update_bits(component, tx_vol_ctl_reg,
                                    TX_VOL_CTL_CFG_MUTE_EN_MASK,
                                    TX_VOL_CTL_CFG_MUTE_EN_ENABLE);
-               snd_soc_update_bits(codec, tx_mux_ctl_reg,
+               snd_soc_component_update_bits(component, tx_mux_ctl_reg,
                                    TX_MUX_CTL_HPF_BP_SEL_MASK,
                                    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift,
+               snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift,
                                    1 << w->shift);
-               snd_soc_update_bits(codec, dec_reset_reg, 1 << w->shift, 0x0);
-               snd_soc_update_bits(codec, tx_mux_ctl_reg,
+               snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift, 0x0);
+               snd_soc_component_update_bits(component, tx_mux_ctl_reg,
                                    TX_MUX_CTL_HPF_BP_SEL_MASK,
                                    TX_MUX_CTL_HPF_BP_SEL_BYPASS);
-               snd_soc_update_bits(codec, tx_vol_ctl_reg,
+               snd_soc_component_update_bits(component, tx_vol_ctl_reg,
                                    TX_VOL_CTL_CFG_MUTE_EN_MASK, 0);
                break;
        }
@@ -428,35 +428,35 @@ static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w,
                                           struct snd_kcontrol *kcontrol,
                                           int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int dmic;
        int ret;
        /* get dmic number out of widget name */
        char *dmic_num = strpbrk(w->name, "12");
 
        if (dmic_num == NULL) {
-               dev_err(codec->dev, "Invalid DMIC\n");
+               dev_err(component->dev, "Invalid DMIC\n");
                return -EINVAL;
        }
        ret = kstrtouint(dmic_num, 10, &dmic);
        if (ret < 0 || dmic > 2) {
-               dev_err(codec->dev, "Invalid DMIC line on the codec\n");
+               dev_err(component->dev, "Invalid DMIC line on the component\n");
                return -EINVAL;
        }
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, LPASS_CDC_CLK_DMIC_B1_CTL,
+               snd_soc_component_update_bits(component, LPASS_CDC_CLK_DMIC_B1_CTL,
                                    DMIC_B1_CTL_DMIC0_CLK_SEL_MASK,
                                    DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3);
                switch (dmic) {
                case 1:
-                       snd_soc_update_bits(codec, LPASS_CDC_TX1_DMIC_CTL,
+                       snd_soc_component_update_bits(component, LPASS_CDC_TX1_DMIC_CTL,
                                            TXN_DMIC_CTL_CLK_SEL_MASK,
                                            TXN_DMIC_CTL_CLK_SEL_DIV3);
                        break;
                case 2:
-                       snd_soc_update_bits(codec, LPASS_CDC_TX2_DMIC_CTL,
+                       snd_soc_component_update_bits(component, LPASS_CDC_TX2_DMIC_CTL,
                                            TXN_DMIC_CTL_CLK_SEL_MASK,
                                            TXN_DMIC_CTL_CLK_SEL_DIV3);
                        break;
@@ -575,20 +575,20 @@ static int msm8916_wcd_digital_get_clks(struct platform_device *pdev,
        return 0;
 }
 
-static int msm8916_wcd_digital_codec_probe(struct snd_soc_codec *codec)
+static int msm8916_wcd_digital_component_probe(struct snd_soc_component *component)
 {
-       struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(codec->dev);
+       struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(component->dev);
 
-       snd_soc_codec_set_drvdata(codec, priv);
+       snd_soc_component_set_drvdata(component, priv);
 
        return 0;
 }
 
-static int msm8916_wcd_digital_codec_set_sysclk(struct snd_soc_codec *codec,
+static int msm8916_wcd_digital_component_set_sysclk(struct snd_soc_component *component,
                                                int clk_id, int source,
                                                unsigned int freq, int dir)
 {
-       struct msm8916_wcd_digital_priv *p = dev_get_drvdata(codec->dev);
+       struct msm8916_wcd_digital_priv *p = dev_get_drvdata(component->dev);
 
        return clk_set_rate(p->mclk, freq);
 }
@@ -618,18 +618,18 @@ static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
                rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ;
                break;
        default:
-               dev_err(dai->codec->dev, "Invalid sampling rate %d\n",
+               dev_err(dai->component->dev, "Invalid sampling rate %d\n",
                        params_rate(params));
                return -EINVAL;
        }
 
        switch (substream->stream) {
        case SNDRV_PCM_STREAM_CAPTURE:
-               snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL,
+               snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
                                    TX_I2S_CTL_TX_I2S_FS_RATE_MASK, tx_fs_rate);
                break;
        case SNDRV_PCM_STREAM_PLAYBACK:
-               snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_RX_I2S_CTL,
+               snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
                                    RX_I2S_CTL_RX_I2S_FS_RATE_MASK, rx_fs_rate);
                break;
        default:
@@ -638,18 +638,19 @@ static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
-               snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL,
+               snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
                                    TX_I2S_CTL_TX_I2S_MODE_MASK,
                                    TX_I2S_CTL_TX_I2S_MODE_16);
-               snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_RX_I2S_CTL,
+               snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
                                    RX_I2S_CTL_RX_I2S_MODE_MASK,
                                    RX_I2S_CTL_RX_I2S_MODE_16);
                break;
+
        case SNDRV_PCM_FORMAT_S32_LE:
-               snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_TX_I2S_CTL,
+               snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL,
                                    TX_I2S_CTL_TX_I2S_MODE_MASK,
                                    TX_I2S_CTL_TX_I2S_MODE_32);
-               snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_RX_I2S_CTL,
+               snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL,
                                    RX_I2S_CTL_RX_I2S_MODE_MASK,
                                    RX_I2S_CTL_RX_I2S_MODE_32);
                break;
@@ -780,32 +781,32 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
 static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream,
                                       struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct msm8916_wcd_digital_priv *msm8916_wcd;
        unsigned long mclk_rate;
 
-       msm8916_wcd = snd_soc_codec_get_drvdata(codec);
-       snd_soc_update_bits(codec, LPASS_CDC_CLK_MCLK_CTL,
+       msm8916_wcd = snd_soc_component_get_drvdata(component);
+       snd_soc_component_update_bits(component, LPASS_CDC_CLK_MCLK_CTL,
                            MCLK_CTL_MCLK_EN_MASK,
                            MCLK_CTL_MCLK_EN_ENABLE);
-       snd_soc_update_bits(codec, LPASS_CDC_CLK_PDM_CTL,
+       snd_soc_component_update_bits(component, LPASS_CDC_CLK_PDM_CTL,
                            LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK,
                            LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB);
 
        mclk_rate = clk_get_rate(msm8916_wcd->mclk);
        switch (mclk_rate) {
        case 12288000:
-               snd_soc_update_bits(codec, LPASS_CDC_TOP_CTL,
+               snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
                                    TOP_CTL_DIG_MCLK_FREQ_MASK,
                                    TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ);
                break;
        case 9600000:
-               snd_soc_update_bits(codec, LPASS_CDC_TOP_CTL,
+               snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL,
                                    TOP_CTL_DIG_MCLK_FREQ_MASK,
                                    TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ);
                break;
        default:
-               dev_err(codec->dev, "Invalid mclk rate %ld\n", mclk_rate);
+               dev_err(component->dev, "Invalid mclk rate %ld\n", mclk_rate);
                break;
        }
        return 0;
@@ -814,7 +815,7 @@ static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream,
 static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream,
                                         struct snd_soc_dai *dai)
 {
-       snd_soc_update_bits(dai->codec, LPASS_CDC_CLK_PDM_CTL,
+       snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_PDM_CTL,
                            LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0);
 }
 
@@ -851,18 +852,19 @@ static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = {
               },
 };
 
-static const struct snd_soc_codec_driver msm8916_wcd_digital = {
-       .probe = msm8916_wcd_digital_codec_probe,
-       .set_sysclk = msm8916_wcd_digital_codec_set_sysclk,
-       .component_driver = {
-               .controls = msm8916_wcd_digital_snd_controls,
-               .num_controls = ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
-               .dapm_widgets = msm8916_wcd_digital_dapm_widgets,
-               .num_dapm_widgets =
-                                ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets),
-               .dapm_routes = msm8916_wcd_digital_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(msm8916_wcd_digital_audio_map),
-       },
+static const struct snd_soc_component_driver msm8916_wcd_digital = {
+       .probe                  = msm8916_wcd_digital_component_probe,
+       .set_sysclk             = msm8916_wcd_digital_component_set_sysclk,
+       .controls               = msm8916_wcd_digital_snd_controls,
+       .num_controls           = ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
+       .dapm_widgets           = msm8916_wcd_digital_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets),
+       .dapm_routes            = msm8916_wcd_digital_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(msm8916_wcd_digital_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config msm8916_codec_regmap_config = {
@@ -915,7 +917,7 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev)
 
        dev_set_drvdata(dev, priv);
 
-       return snd_soc_register_codec(dev, &msm8916_wcd_digital,
+       return devm_snd_soc_register_component(dev, &msm8916_wcd_digital,
                                      msm8916_wcd_digital_dai,
                                      ARRAY_SIZE(msm8916_wcd_digital_dai));
 }
@@ -924,7 +926,6 @@ static int msm8916_wcd_digital_remove(struct platform_device *pdev)
 {
        struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_codec(&pdev->dev);
        clk_disable_unprepare(priv->mclk);
        clk_disable_unprepare(priv->ahbclk);
 
index b08fb7e243c3ce3ca75d08a78f79a4e7ce6b8e4f..17104f8dc1a9ef0db2e7321b23ec196b4400ba5a 100644 (file)
@@ -236,8 +236,8 @@ static const struct snd_kcontrol_new digital_ch1_mux =
 static int adc_power_control(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
        if (SND_SOC_DAPM_EVENT_ON(event)) {
                msleep(300);
@@ -258,8 +258,8 @@ static int adc_power_control(struct snd_soc_dapm_widget *w,
 static int aiftx_power_control(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
        if (SND_SOC_DAPM_EVENT_OFF(event)) {
                regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0001);
@@ -379,8 +379,8 @@ static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr)
 static int nau8540_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, osr;
 
        /* CLK_ADC = OSR * FS
@@ -422,8 +422,8 @@ static int nau8540_hw_params(struct snd_pcm_substream *substream,
 
 static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
        unsigned int ctrl1_val = 0, ctrl2_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -493,8 +493,8 @@ static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
        unsigned int ctrl2_val = 0, ctrl4_val = 0;
 
        if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)))
@@ -649,10 +649,10 @@ static void nau8540_fll_apply(struct regmap *regmap,
 }
 
 /* freq_out must be 256*Fs in order to achieve the best performance */
-static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int nau8540_set_pll(struct snd_soc_component *component, int pll_id, int source,
                unsigned int freq_in, unsigned int freq_out)
 {
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
        struct nau8540_fll fll_param;
        int ret, fs;
 
@@ -702,10 +702,10 @@ static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
        return 0;
 }
 
-static int nau8540_set_sysclk(struct snd_soc_codec *codec,
+static int nau8540_set_sysclk(struct snd_soc_component *component,
        int clk_id, int source, unsigned int freq, int dir)
 {
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case NAU8540_CLK_DIS:
@@ -777,9 +777,9 @@ static void nau8540_init_regs(struct nau8540 *nau8540)
                NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI);
 }
 
-static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec)
+static int __maybe_unused nau8540_suspend(struct snd_soc_component *component)
 {
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(nau8540->regmap, true);
        regcache_mark_dirty(nau8540->regmap);
@@ -787,9 +787,9 @@ static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
+static int __maybe_unused nau8540_resume(struct snd_soc_component *component)
 {
-       struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
+       struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(nau8540->regmap, false);
        regcache_sync(nau8540->regmap);
@@ -797,21 +797,22 @@ static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver nau8540_codec_driver = {
-       .set_sysclk = nau8540_set_sysclk,
-       .set_pll = nau8540_set_pll,
-       .suspend = nau8540_suspend,
-       .resume = nau8540_resume,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls = nau8540_snd_controls,
-               .num_controls = ARRAY_SIZE(nau8540_snd_controls),
-               .dapm_widgets = nau8540_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(nau8540_dapm_widgets),
-               .dapm_routes = nau8540_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(nau8540_dapm_routes),
-       },
+static const struct snd_soc_component_driver nau8540_component_driver = {
+       .set_sysclk             = nau8540_set_sysclk,
+       .set_pll                = nau8540_set_pll,
+       .suspend                = nau8540_suspend,
+       .resume                 = nau8540_resume,
+       .controls               = nau8540_snd_controls,
+       .num_controls           = ARRAY_SIZE(nau8540_snd_controls),
+       .dapm_widgets           = nau8540_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(nau8540_dapm_widgets),
+       .dapm_routes            = nau8540_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(nau8540_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config nau8540_regmap_config = {
@@ -856,17 +857,10 @@ static int nau8540_i2c_probe(struct i2c_client *i2c,
        nau8540_reset_chip(nau8540->regmap);
        nau8540_init_regs(nau8540);
 
-       return snd_soc_register_codec(dev,
-               &nau8540_codec_driver, &nau8540_dai, 1);
-}
-
-static int nau8540_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
+       return devm_snd_soc_register_component(dev,
+               &nau8540_component_driver, &nau8540_dai, 1);
 }
 
-
 static const struct i2c_device_id nau8540_i2c_ids[] = {
        { "nau8540", 0 },
        { }
@@ -887,7 +881,6 @@ static struct i2c_driver nau8540_i2c_driver = {
                .of_match_table = of_match_ptr(nau8540_of_ids),
        },
        .probe = nau8540_i2c_probe,
-       .remove = nau8540_i2c_remove,
        .id_table = nau8540_i2c_ids,
 };
 module_i2c_driver(nau8540_i2c_driver);
index c8e2451ae0a3700a52d111afaebb7482e53957d9..ca2ba1c7bb9a863662d75cb4197d14fb30a66e03 100644 (file)
@@ -167,8 +167,8 @@ static bool nau8810_volatile_reg(struct device *dev, unsigned int reg)
 static int nau8810_eq_get(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        struct soc_bytes_ext *params = (void *)kcontrol->private_value;
        int i, reg, reg_val;
        u16 *val;
@@ -198,8 +198,8 @@ static int nau8810_eq_get(struct snd_kcontrol *kcontrol,
 static int nau8810_eq_put(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        struct soc_bytes_ext *params = (void *)kcontrol->private_value;
        void *data;
        u16 *val, value;
@@ -219,7 +219,7 @@ static int nau8810_eq_put(struct snd_kcontrol *kcontrol,
                value = be16_to_cpu(*(val + i));
                ret = regmap_write(nau8810->regmap, reg + i, value);
                if (ret) {
-                       dev_err(codec->dev, "EQ configuration fail, register: %x ret: %d\n",
+                       dev_err(component->dev, "EQ configuration fail, register: %x ret: %d\n",
                                reg + i, ret);
                        kfree(data);
                        return ret;
@@ -399,8 +399,8 @@ static const struct snd_kcontrol_new nau8810_loopback =
 static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        unsigned int value;
 
        regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value);
@@ -485,8 +485,8 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
 static int nau8810_set_sysclk(struct snd_soc_dai *dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
 
        nau8810->clk_id = clk_id;
        nau8810->sysclk = freq;
@@ -538,8 +538,8 @@ static int nau88l0_calc_pll(unsigned int pll_in,
 static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id,
        int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        struct regmap *map = nau8810->regmap;
        struct nau8810_pll *pll_param = &nau8810->pll;
        int ret, fs;
@@ -577,8 +577,8 @@ static int nau8810_set_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int nau8810_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        u16 ctrl1_val = 0, ctrl2_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -667,8 +667,8 @@ static int nau8810_mclk_clkdiv(struct nau8810 *nau8810, int rate)
 static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        int val_len = 0, val_rate = 0, ret = 0;
 
        switch (params_width(params)) {
@@ -723,10 +723,10 @@ static int nau8810_pcm_hw_params(struct snd_pcm_substream *substream,
        return ret;
 }
 
-static int nau8810_set_bias_level(struct snd_soc_codec *codec,
+static int nau8810_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct nau8810 *nau8810 = snd_soc_codec_get_drvdata(codec);
+       struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
        struct regmap *map = nau8810->regmap;
 
        switch (level) {
@@ -741,7 +741,7 @@ static int nau8810_set_bias_level(struct snd_soc_codec *codec,
                        NAU8810_IOBUF_EN | NAU8810_ABIAS_EN,
                        NAU8810_IOBUF_EN | NAU8810_ABIAS_EN);
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        regcache_sync(map);
                        regmap_update_bits(map, NAU8810_REG_POWER1,
                                NAU8810_REFIMP_MASK, NAU8810_REFIMP_3K);
@@ -808,18 +808,19 @@ static const struct regmap_config nau8810_regmap_config = {
        .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults),
 };
 
-static const struct snd_soc_codec_driver nau8810_codec_driver = {
-       .set_bias_level = nau8810_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls = nau8810_snd_controls,
-               .num_controls = ARRAY_SIZE(nau8810_snd_controls),
-               .dapm_widgets = nau8810_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(nau8810_dapm_widgets),
-               .dapm_routes = nau8810_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(nau8810_dapm_routes),
-       },
+static const struct snd_soc_component_driver nau8810_component_driver = {
+       .set_bias_level         = nau8810_set_bias_level,
+       .controls               = nau8810_snd_controls,
+       .num_controls           = ARRAY_SIZE(nau8810_snd_controls),
+       .dapm_widgets           = nau8810_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(nau8810_dapm_widgets),
+       .dapm_routes            = nau8810_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(nau8810_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int nau8810_i2c_probe(struct i2c_client *i2c,
@@ -842,15 +843,8 @@ static int nau8810_i2c_probe(struct i2c_client *i2c,
 
        regmap_write(nau8810->regmap, NAU8810_REG_RESET, 0x00);
 
-       return snd_soc_register_codec(dev,
-               &nau8810_codec_driver, &nau8810_dai, 1);
-}
-
-static int nau8810_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-
-       return 0;
+       return devm_snd_soc_register_component(dev,
+               &nau8810_component_driver, &nau8810_dai, 1);
 }
 
 static const struct i2c_device_id nau8810_i2c_id[] = {
@@ -873,7 +867,6 @@ static struct i2c_driver nau8810_i2c_driver = {
                .of_match_table = of_match_ptr(nau8810_of_match),
        },
        .probe =    nau8810_i2c_probe,
-       .remove =   nau8810_i2c_remove,
        .id_table = nau8810_i2c_id,
 };
 
index 088e0cef4cb8d469f17c24f22941e045fbc5f1a8..637e9527805f4d7e8c5d2d0b7802976e9fc5919f 100644 (file)
@@ -414,8 +414,8 @@ static const struct snd_kcontrol_new nau8824_snd_controls[] = {
 static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -437,8 +437,8 @@ static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
 static int nau8824_spk_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -461,8 +461,8 @@ static int nau8824_spk_event(struct snd_soc_dapm_widget *w,
 static int nau8824_pump_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -487,10 +487,14 @@ static int nau8824_pump_event(struct snd_soc_dapm_widget *w,
 static int system_clock_control(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
+       struct regmap *regmap = nau8824->regmap;
+       unsigned int value;
+       bool clk_fll, error;
 
        if (SND_SOC_DAPM_EVENT_OFF(event)) {
+               dev_dbg(nau8824->dev, "system clock control : POWER OFF\n");
                /* Set clock source to disable or internal clock before the
                 * playback or capture end. Codec needs clock for Jack
                 * detection and button press if jack inserted; otherwise,
@@ -502,15 +506,48 @@ static int system_clock_control(struct snd_soc_dapm_widget *w,
                } else {
                        nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
                }
+       } else {
+               dev_dbg(nau8824->dev, "system clock control : POWER ON\n");
+               /* Check the clock source setting is proper or not
+                * no matter the source is from FLL or MCLK.
+                */
+               regmap_read(regmap, NAU8824_REG_FLL1, &value);
+               clk_fll = value & NAU8824_FLL_RATIO_MASK;
+               /* It's error to use internal clock when playback */
+               regmap_read(regmap, NAU8824_REG_FLL6, &value);
+               error = value & NAU8824_DCO_EN;
+               if (!error) {
+                       /* Check error depending on source is FLL or MCLK. */
+                       regmap_read(regmap, NAU8824_REG_CLK_DIVIDER, &value);
+                       if (clk_fll)
+                               error = !(value & NAU8824_CLK_SRC_VCO);
+                       else
+                               error = value & NAU8824_CLK_SRC_VCO;
+               }
+               /* Recover the clock source setting if error. */
+               if (error) {
+                       if (clk_fll) {
+                               regmap_update_bits(regmap,
+                                       NAU8824_REG_FLL6, NAU8824_DCO_EN, 0);
+                               regmap_update_bits(regmap,
+                                       NAU8824_REG_CLK_DIVIDER,
+                                       NAU8824_CLK_SRC_MASK,
+                                       NAU8824_CLK_SRC_VCO);
+                       } else {
+                               nau8824_config_sysclk(nau8824,
+                                       NAU8824_CLK_MCLK, 0);
+                       }
+               }
        }
+
        return 0;
 }
 
 static int dmic_clock_control(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
        int src;
 
        /* The DMIC clock is gotten from system clock (256fs) divided by
@@ -591,7 +628,8 @@ static const struct snd_kcontrol_new nau8824_dacr_mux =
 
 static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0,
-                       system_clock_control, SND_SOC_DAPM_POST_PMD),
+               system_clock_control, SND_SOC_DAPM_POST_PMD |
+               SND_SOC_DAPM_POST_PMU),
 
        SND_SOC_DAPM_INPUT("HSMIC1"),
        SND_SOC_DAPM_INPUT("HSMIC2"),
@@ -988,8 +1026,8 @@ static int nau8824_clock_check(struct nau8824 *nau8824,
 static int nau8824_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
 
        nau8824_sema_acquire(nau8824, HZ);
@@ -1072,8 +1110,8 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
 
 static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
        unsigned int ctrl1_val = 0, ctrl2_val = 0;
 
        nau8824_sema_acquire(nau8824, HZ);
@@ -1149,8 +1187,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int nau8824_set_tdm_slot(struct snd_soc_dai *dai,
        unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
        unsigned int tslot_l = 0, ctrl_val = 0;
 
        if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)) ||
@@ -1288,10 +1326,10 @@ static void nau8824_fll_apply(struct regmap *regmap,
 }
 
 /* freq_out must be 256*Fs in order to achieve the best performance */
-static int nau8824_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int nau8824_set_pll(struct snd_soc_component *component, int pll_id, int source,
                unsigned int freq_in, unsigned int freq_out)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
        struct nau8824_fll fll_param;
        int ret, fs;
 
@@ -1374,10 +1412,10 @@ static int nau8824_config_sysclk(struct nau8824 *nau8824,
        return 0;
 }
 
-static int nau8824_set_sysclk(struct snd_soc_codec *codec,
+static int nau8824_set_sysclk(struct snd_soc_component *component,
        int clk_id, int source, unsigned int freq, int dir)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        return nau8824_config_sysclk(nau8824, clk_id, freq);
 }
@@ -1403,10 +1441,10 @@ static void nau8824_resume_setup(struct nau8824 *nau8824)
        }
 }
 
-static int nau8824_set_bias_level(struct snd_soc_codec *codec,
+static int nau8824_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -1416,7 +1454,7 @@ static int nau8824_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Setup codec configuration after resume */
                        nau8824_resume_setup(nau8824);
                }
@@ -1434,23 +1472,23 @@ static int nau8824_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int nau8824_codec_probe(struct snd_soc_codec *codec)
+static int nau8824_component_probe(struct snd_soc_component *component)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        nau8824->dapm = dapm;
 
        return 0;
 }
 
-static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec)
+static int __maybe_unused nau8824_suspend(struct snd_soc_component *component)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        if (nau8824->irq) {
                disable_irq(nau8824->irq);
-               snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+               snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
        }
        regcache_cache_only(nau8824->regmap, true);
        regcache_mark_dirty(nau8824->regmap);
@@ -1458,9 +1496,9 @@ static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
+static int __maybe_unused nau8824_resume(struct snd_soc_component *component)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(nau8824->regmap, false);
        regcache_sync(nau8824->regmap);
@@ -1475,23 +1513,24 @@ static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver nau8824_codec_driver = {
-       .probe = nau8824_codec_probe,
-       .set_sysclk = nau8824_set_sysclk,
-       .set_pll = nau8824_set_pll,
-       .set_bias_level = nau8824_set_bias_level,
-       .suspend = nau8824_suspend,
-       .resume = nau8824_resume,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls = nau8824_snd_controls,
-               .num_controls = ARRAY_SIZE(nau8824_snd_controls),
-               .dapm_widgets = nau8824_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(nau8824_dapm_widgets),
-               .dapm_routes = nau8824_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(nau8824_dapm_routes),
-       },
+static const struct snd_soc_component_driver nau8824_component_driver = {
+       .probe                  = nau8824_component_probe,
+       .set_sysclk             = nau8824_set_sysclk,
+       .set_pll                = nau8824_set_pll,
+       .set_bias_level         = nau8824_set_bias_level,
+       .suspend                = nau8824_suspend,
+       .resume                 = nau8824_resume,
+       .controls               = nau8824_snd_controls,
+       .num_controls           = ARRAY_SIZE(nau8824_snd_controls),
+       .dapm_widgets           = nau8824_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(nau8824_dapm_widgets),
+       .dapm_routes            = nau8824_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(nau8824_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct snd_soc_dai_ops nau8824_dai_ops = {
@@ -1547,10 +1586,10 @@ static const struct regmap_config nau8824_regmap_config = {
  * events will be routed to the given jack.  Jack can be null to stop
  * reporting.
  */
-int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8824_enable_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack)
 {
-       struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
+       struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
        int ret;
 
        nau8824->jack = jack;
@@ -1838,15 +1877,8 @@ static int nau8824_i2c_probe(struct i2c_client *i2c,
        if (i2c->irq)
                nau8824_setup_irq(nau8824);
 
-       return snd_soc_register_codec(dev,
-               &nau8824_codec_driver, &nau8824_dai, 1);
-}
-
-
-static int nau8824_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
+       return devm_snd_soc_register_component(dev,
+               &nau8824_component_driver, &nau8824_dai, 1);
 }
 
 static const struct i2c_device_id nau8824_i2c_ids[] = {
@@ -1878,7 +1910,6 @@ static struct i2c_driver nau8824_i2c_driver = {
                .acpi_match_table = ACPI_PTR(nau8824_acpi_match),
        },
        .probe = nau8824_i2c_probe,
-       .remove = nau8824_i2c_remove,
        .id_table = nau8824_i2c_ids,
 };
 module_i2c_driver(nau8824_i2c_driver);
index 21eae2431c83a4d8db8ffe77761e3a460aa208e7..6184a2b5c9414e6e73e61f25c0100c8a993d3b10 100644 (file)
@@ -471,7 +471,7 @@ struct nau8824_osr_attr {
 };
 
 
-int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8824_enable_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack);
 
 #endif                         /* _NAU8824_H */
index a1b697b6fb6483a357f68efa5818725a2a6e62e8..dc6ea4987b7d9a4fb132d41902dd6c0bf75e39f8 100644 (file)
@@ -914,8 +914,8 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
 static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -938,8 +938,8 @@ static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
 static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -962,8 +962,8 @@ static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
 static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -1244,8 +1244,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
 
        nau8825_sema_acquire(nau8825, 3 * HZ);
@@ -1329,8 +1329,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
 
 static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
        unsigned int ctrl1_val = 0, ctrl2_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1427,10 +1427,10 @@ static struct snd_soc_dai_driver nau8825_dai = {
  * events will be routed to the given jack.  Jack can be null to stop
  * reporting.
  */
-int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8825_enable_jack_detect(struct snd_soc_component *component,
                                struct snd_soc_jack *jack)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
        struct regmap *regmap = nau8825->regmap;
 
        nau8825->jack = jack;
@@ -1952,24 +1952,22 @@ static const struct regmap_config nau8825_regmap_config = {
        .num_reg_defaults = ARRAY_SIZE(nau8825_reg_defaults),
 };
 
-static int nau8825_codec_probe(struct snd_soc_codec *codec)
+static int nau8825_component_probe(struct snd_soc_component *component)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        nau8825->dapm = dapm;
 
        return 0;
 }
 
-static int nau8825_codec_remove(struct snd_soc_codec *codec)
+static void nau8825_component_remove(struct snd_soc_component *component)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
        /* Cancel and reset cross tak suppresstion detection funciton */
        nau8825_xtalk_cancel(nau8825);
-
-       return 0;
 }
 
 /**
@@ -2084,20 +2082,20 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
 }
 
 /* freq_out must be 256*Fs in order to achieve the best performance */
-static int nau8825_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+static int nau8825_set_pll(struct snd_soc_component *component, int pll_id, int source,
                unsigned int freq_in, unsigned int freq_out)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
        struct nau8825_fll fll_param;
        int ret, fs;
 
        fs = freq_out / 256;
        ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupported input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupported input clock %d\n", freq_in);
                return ret;
        }
-       dev_dbg(codec->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
+       dev_dbg(component->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
                fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
                fll_param.fll_int, fll_param.clk_ref_div);
 
@@ -2298,10 +2296,10 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
        return 0;
 }
 
-static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int nau8825_set_sysclk(struct snd_soc_component *component, int clk_id,
        int source, unsigned int freq, int dir)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
        return nau8825_configure_sysclk(nau8825, clk_id, freq);
 }
@@ -2331,10 +2329,10 @@ static int nau8825_resume_setup(struct nau8825 *nau8825)
        return 0;
 }
 
-static int nau8825_set_bias_level(struct snd_soc_codec *codec,
+static int nau8825_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -2345,11 +2343,11 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        if (nau8825->mclk_freq) {
                                ret = clk_prepare_enable(nau8825->mclk);
                                if (ret) {
-                                       dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
+                                       dev_err(nau8825->dev, "Unable to prepare component mclk\n");
                                        return ret;
                                }
                        }
@@ -2383,12 +2381,12 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
+static int __maybe_unused nau8825_suspend(struct snd_soc_component *component)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
 
        disable_irq(nau8825->irq);
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
        /* Power down codec power; don't suppoet button wakeup */
        snd_soc_dapm_disable_pin(nau8825->dapm, "SAR");
        snd_soc_dapm_disable_pin(nau8825->dapm, "MICBIAS");
@@ -2399,9 +2397,9 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
+static int __maybe_unused nau8825_resume(struct snd_soc_component *component)
 {
-       struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
+       struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
        int ret;
 
        regcache_cache_only(nau8825->regmap, false);
@@ -2415,24 +2413,25 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver nau8825_codec_driver = {
-       .probe = nau8825_codec_probe,
-       .remove = nau8825_codec_remove,
-       .set_sysclk = nau8825_set_sysclk,
-       .set_pll = nau8825_set_pll,
-       .set_bias_level = nau8825_set_bias_level,
-       .suspend_bias_off = true,
-       .suspend = nau8825_suspend,
-       .resume = nau8825_resume,
-
-       .component_driver = {
-               .controls               = nau8825_controls,
-               .num_controls           = ARRAY_SIZE(nau8825_controls),
-               .dapm_widgets           = nau8825_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(nau8825_dapm_widgets),
-               .dapm_routes            = nau8825_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(nau8825_dapm_routes),
-       },
+static const struct snd_soc_component_driver nau8825_component_driver = {
+       .probe                  = nau8825_component_probe,
+       .remove                 = nau8825_component_remove,
+       .set_sysclk             = nau8825_set_sysclk,
+       .set_pll                = nau8825_set_pll,
+       .set_bias_level         = nau8825_set_bias_level,
+       .suspend                = nau8825_suspend,
+       .resume                 = nau8825_resume,
+       .controls               = nau8825_controls,
+       .num_controls           = ARRAY_SIZE(nau8825_controls),
+       .dapm_widgets           = nau8825_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(nau8825_dapm_widgets),
+       .dapm_routes            = nau8825_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(nau8825_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static void nau8825_reset_chip(struct regmap *regmap)
@@ -2619,13 +2618,13 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
        if (i2c->irq)
                nau8825_setup_irq(nau8825);
 
-       return snd_soc_register_codec(&i2c->dev, &nau8825_codec_driver,
+       return devm_snd_soc_register_component(&i2c->dev,
+               &nau8825_component_driver,
                &nau8825_dai, 1);
 }
 
 static int nau8825_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index f7e7321258825759d2adad0db15e84ced34f698e..f6074c6185691c618590065db541fac900d309b5 100644 (file)
@@ -480,7 +480,7 @@ struct nau8825 {
        bool xtalk_baktab_initialized; /* True if initialized. */
 };
 
-int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
+int nau8825_enable_jack_detect(struct snd_soc_component *component,
                                struct snd_soc_jack *jack);
 
 
index c7e28dd2e8153bc359494bdd9cb87728dcb1d0a0..84777d3fa4642266b9a6be54c2517981d6efe67d 100644 (file)
@@ -90,9 +90,9 @@ struct pcm1681_private {
 
 static const int pcm1681_deemph[] = { 44100, 48000, 32000 };
 
-static int pcm1681_set_deemph(struct snd_soc_codec *codec)
+static int pcm1681_set_deemph(struct snd_soc_component *component)
 {
-       struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
        int i = 0, val = -1, enable = 0;
 
        if (priv->deemph) {
@@ -120,8 +120,8 @@ static int pcm1681_set_deemph(struct snd_soc_codec *codec)
 static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = priv->deemph;
 
@@ -131,23 +131,23 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
 static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 
        priv->deemph = ucontrol->value.integer.value[0];
 
-       return pcm1681_set_deemph(codec);
+       return pcm1681_set_deemph(component);
 }
 
 static int pcm1681_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
 
        /* The PCM1681 can only be slave to all clocks */
        if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-               dev_err(codec->dev, "Invalid clocking mode\n");
+               dev_err(component->dev, "Invalid clocking mode\n");
                return -EINVAL;
        }
 
@@ -158,8 +158,8 @@ static int pcm1681_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int pcm1681_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
        int val;
 
        if (mute)
@@ -174,8 +174,8 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm1681_private *priv = snd_soc_component_get_drvdata(component);
        int val = 0, ret;
 
        priv->rate = params_rate(params);
@@ -200,7 +200,7 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
                val = 0x05;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -208,7 +208,7 @@ static int pcm1681_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       return pcm1681_set_deemph(codec);
+       return pcm1681_set_deemph(component);
 }
 
 static const struct snd_soc_dai_ops pcm1681_dai_ops = {
@@ -288,15 +288,17 @@ static const struct regmap_config pcm1681_regmap = {
        .readable_reg           = pcm1681_accessible_reg,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
-       .component_driver = {
-               .controls               = pcm1681_controls,
-               .num_controls           = ARRAY_SIZE(pcm1681_controls),
-               .dapm_widgets           = pcm1681_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pcm1681_dapm_widgets),
-               .dapm_routes            = pcm1681_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pcm1681_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_pcm1681 = {
+       .controls               = pcm1681_controls,
+       .num_controls           = ARRAY_SIZE(pcm1681_controls),
+       .dapm_widgets           = pcm1681_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm1681_dapm_widgets),
+       .dapm_routes            = pcm1681_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm1681_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct i2c_device_id pcm1681_i2c_id[] = {
@@ -324,16 +326,11 @@ static int pcm1681_i2c_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, priv);
 
-       return snd_soc_register_codec(&client->dev, &soc_codec_dev_pcm1681,
+       return devm_snd_soc_register_component(&client->dev,
+               &soc_component_dev_pcm1681,
                &pcm1681_dai, 1);
 }
 
-static int pcm1681_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static struct i2c_driver pcm1681_i2c_driver = {
        .driver = {
                .name   = "pcm1681",
@@ -341,7 +338,6 @@ static struct i2c_driver pcm1681_i2c_driver = {
        },
        .id_table       = pcm1681_i2c_id,
        .probe          = pcm1681_i2c_probe,
-       .remove         = pcm1681_i2c_remove,
 };
 
 module_i2c_driver(pcm1681_i2c_driver);
diff --git a/sound/soc/codecs/pcm1789-i2c.c b/sound/soc/codecs/pcm1789-i2c.c
new file mode 100644 (file)
index 0000000..327ec58
--- /dev/null
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+// Audio driver for PCM1789 I2C
+// Copyright (C) 2018 Bootlin
+// Mylène Josserand <mylene.josserand@bootlin.com>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include "pcm1789.h"
+
+static int pcm1789_i2c_probe(struct i2c_client *client,
+                            const struct i2c_device_id *id)
+{
+       struct regmap *regmap;
+       int ret;
+
+       regmap = devm_regmap_init_i2c(client, &pcm1789_regmap_config);
+       if (IS_ERR(regmap)) {
+               ret = PTR_ERR(regmap);
+               dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
+               return ret;
+       }
+
+       return pcm1789_common_init(&client->dev, regmap);
+}
+
+static int pcm1789_i2c_remove(struct i2c_client *client)
+{
+       return pcm1789_common_exit(&client->dev);
+}
+
+static const struct of_device_id pcm1789_of_match[] = {
+       { .compatible = "ti,pcm1789", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, pcm1789_of_match);
+
+static const struct i2c_device_id pcm1789_i2c_ids[] = {
+       { "pcm1789", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, pcm1789_i2c_ids);
+
+static struct i2c_driver pcm1789_i2c_driver = {
+       .driver = {
+               .name   = "pcm1789",
+               .of_match_table = of_match_ptr(pcm1789_of_match),
+       },
+       .id_table       = pcm1789_i2c_ids,
+       .probe          = pcm1789_i2c_probe,
+       .remove = pcm1789_i2c_remove,
+};
+
+module_i2c_driver(pcm1789_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC PCM1789 I2C driver");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@bootlin.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c
new file mode 100644 (file)
index 0000000..507ac94
--- /dev/null
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+// Audio driver for PCM1789
+// Copyright (C) 2018 Bootlin
+// Mylène Josserand <mylene.josserand@bootlin.com>
+
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "pcm1789.h"
+
+#define PCM1789_MUTE_CONTROL   0x10
+#define PCM1789_FMT_CONTROL    0x11
+#define PCM1789_SOFT_MUTE      0x14
+#define PCM1789_DAC_VOL_LEFT   0x18
+#define PCM1789_DAC_VOL_RIGHT  0x19
+
+#define PCM1789_FMT_MASK       0x07
+#define PCM1789_MUTE_MASK      0x03
+#define PCM1789_MUTE_SRET      0x06
+
+struct pcm1789_private {
+       struct regmap *regmap;
+       unsigned int format;
+       unsigned int rate;
+       struct gpio_desc *reset;
+       struct work_struct work;
+       struct device *dev;
+};
+
+static const struct reg_default pcm1789_reg_defaults[] = {
+       { PCM1789_FMT_CONTROL, 0x00 },
+       { PCM1789_SOFT_MUTE, 0x00 },
+       { PCM1789_DAC_VOL_LEFT, 0xff },
+       { PCM1789_DAC_VOL_RIGHT, 0xff },
+};
+
+static bool pcm1789_accessible_reg(struct device *dev, unsigned int reg)
+{
+       return reg >= PCM1789_MUTE_CONTROL && reg <= PCM1789_DAC_VOL_RIGHT;
+}
+
+static bool pcm1789_writeable_reg(struct device *dev, unsigned int reg)
+{
+       return pcm1789_accessible_reg(dev, reg);
+}
+
+static int pcm1789_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                              unsigned int format)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+
+       priv->format = format;
+
+       return 0;
+}
+
+static int pcm1789_digital_mute(struct snd_soc_dai *codec_dai, int mute)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+
+       return regmap_update_bits(priv->regmap, PCM1789_SOFT_MUTE,
+                                 PCM1789_MUTE_MASK,
+                                 mute ? 0 : PCM1789_MUTE_MASK);
+}
+
+static int pcm1789_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params,
+                            struct snd_soc_dai *codec_dai)
+{
+       struct snd_soc_component *component = codec_dai->component;
+       struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+       int val = 0, ret;
+
+       priv->rate = params_rate(params);
+
+       switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_RIGHT_J:
+               switch (params_width(params)) {
+               case 24:
+                       val = 2;
+                       break;
+               case 16:
+                       val = 3;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       case SND_SOC_DAIFMT_I2S:
+               switch (params_width(params)) {
+               case 16:
+               case 24:
+               case 32:
+                       val = 0;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               switch (params_width(params)) {
+               case 16:
+               case 24:
+               case 32:
+                       val = 1;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               dev_err(component->dev, "Invalid DAI format\n");
+               return -EINVAL;
+       }
+
+       ret = regmap_update_bits(priv->regmap, PCM1789_FMT_CONTROL,
+                                PCM1789_FMT_MASK, val);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static void pcm1789_work_queue(struct work_struct *work)
+{
+       struct pcm1789_private *priv = container_of(work,
+                                                   struct pcm1789_private,
+                                                   work);
+
+       /* Perform a software reset to remove codec from desynchronized state */
+       if (regmap_update_bits(priv->regmap, PCM1789_MUTE_CONTROL,
+                              0x3 << PCM1789_MUTE_SRET, 0) < 0)
+               dev_err(priv->dev, "Error while setting SRET");
+}
+
+static int pcm1789_trigger(struct snd_pcm_substream *substream, int cmd,
+                          struct snd_soc_dai *dai)
+{
+       struct snd_soc_component *component = dai->component;
+       struct pcm1789_private *priv = snd_soc_component_get_drvdata(component);
+       int ret = 0;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               schedule_work(&priv->work);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct snd_soc_dai_ops pcm1789_dai_ops = {
+       .set_fmt        = pcm1789_set_dai_fmt,
+       .hw_params      = pcm1789_hw_params,
+       .digital_mute   = pcm1789_digital_mute,
+       .trigger        = pcm1789_trigger,
+};
+
+static const DECLARE_TLV_DB_SCALE(pcm1789_dac_tlv, -12000, 50, 1);
+
+static const struct snd_kcontrol_new pcm1789_controls[] = {
+       SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1789_DAC_VOL_LEFT,
+                              PCM1789_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0,
+                              pcm1789_dac_tlv),
+};
+
+static const struct snd_soc_dapm_widget pcm1789_dapm_widgets[] = {
+       SND_SOC_DAPM_OUTPUT("IOUTL+"),
+       SND_SOC_DAPM_OUTPUT("IOUTL-"),
+       SND_SOC_DAPM_OUTPUT("IOUTR+"),
+       SND_SOC_DAPM_OUTPUT("IOUTR-"),
+};
+
+static const struct snd_soc_dapm_route pcm1789_dapm_routes[] = {
+       { "IOUTL+", NULL, "Playback" },
+       { "IOUTL-", NULL, "Playback" },
+       { "IOUTR+", NULL, "Playback" },
+       { "IOUTR-", NULL, "Playback" },
+};
+
+static struct snd_soc_dai_driver pcm1789_dai = {
+       .name = "pcm1789-hifi",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_CONTINUOUS,
+               .rate_min = 10000,
+               .rate_max = 200000,
+               .formats = PCM1789_FORMATS,
+       },
+       .ops = &pcm1789_dai_ops,
+};
+
+const struct regmap_config pcm1789_regmap_config = {
+       .reg_bits               = 8,
+       .val_bits               = 8,
+       .max_register           = PCM1789_DAC_VOL_RIGHT,
+       .reg_defaults           = pcm1789_reg_defaults,
+       .num_reg_defaults       = ARRAY_SIZE(pcm1789_reg_defaults),
+       .writeable_reg          = pcm1789_writeable_reg,
+       .readable_reg           = pcm1789_accessible_reg,
+};
+EXPORT_SYMBOL_GPL(pcm1789_regmap_config);
+
+static const struct snd_soc_component_driver soc_component_dev_pcm1789 = {
+       .controls               = pcm1789_controls,
+       .num_controls           = ARRAY_SIZE(pcm1789_controls),
+       .dapm_widgets           = pcm1789_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm1789_dapm_widgets),
+       .dapm_routes            = pcm1789_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm1789_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
+
+int pcm1789_common_init(struct device *dev, struct regmap *regmap)
+{
+       struct pcm1789_private *pcm1789;
+
+       pcm1789 = devm_kzalloc(dev, sizeof(struct pcm1789_private),
+                              GFP_KERNEL);
+       if (!pcm1789)
+               return -ENOMEM;
+
+       pcm1789->regmap = regmap;
+       pcm1789->dev = dev;
+       dev_set_drvdata(dev, pcm1789);
+
+       pcm1789->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+       if (IS_ERR(pcm1789->reset))
+               return PTR_ERR(pcm1789->reset);
+
+       gpiod_set_value_cansleep(pcm1789->reset, 0);
+       msleep(300);
+
+       INIT_WORK(&pcm1789->work, pcm1789_work_queue);
+
+       return devm_snd_soc_register_component(dev, &soc_component_dev_pcm1789,
+                                              &pcm1789_dai, 1);
+}
+EXPORT_SYMBOL_GPL(pcm1789_common_init);
+
+int pcm1789_common_exit(struct device *dev)
+{
+       struct pcm1789_private *priv = dev_get_drvdata(dev);
+
+       if (&priv->work)
+               flush_work(&priv->work);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(pcm1789_common_exit);
+
+MODULE_DESCRIPTION("ASoC PCM1789 driver");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1789.h b/sound/soc/codecs/pcm1789.h
new file mode 100644 (file)
index 0000000..c446d78
--- /dev/null
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+// Definitions for PCM1789 audio driver
+// Copyright (C) 2018 Bootlin
+// Mylène Josserand <mylene.josserand@bootlin.com>
+
+#ifndef __PCM1789_H__
+#define __PCM1789_H__
+
+#define PCM1789_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
+                        SNDRV_PCM_FMTBIT_S16_LE)
+
+extern const struct regmap_config pcm1789_regmap_config;
+
+int pcm1789_common_init(struct device *dev, struct regmap *regmap);
+int pcm1789_common_exit(struct device *dev);
+
+#endif
index 4118106abb8d9a9a456c5a1f5155c6cfc1de07ea..03747966c6bc6ced7f24d53b05506639ad2f304e 100644 (file)
@@ -39,11 +39,6 @@ static int pcm179x_i2c_probe(struct i2c_client *client,
        return pcm179x_common_init(&client->dev, regmap);
 }
 
-static int pcm179x_i2c_remove(struct i2c_client *client)
-{
-       return pcm179x_common_exit(&client->dev);
-}
-
 static const struct of_device_id pcm179x_of_match[] = {
        { .compatible = "ti,pcm1792a", },
        { }
@@ -63,7 +58,6 @@ static struct i2c_driver pcm179x_i2c_driver = {
        },
        .id_table       = pcm179x_i2c_ids,
        .probe          = pcm179x_i2c_probe,
-       .remove         = pcm179x_i2c_remove,
 };
 
 module_i2c_driver(pcm179x_i2c_driver);
index da924d44408301da6bff49cce9305209fe7ee8e1..89ad715676fc3549514f25af74bd78afc405181f 100644 (file)
@@ -38,11 +38,6 @@ static int pcm179x_spi_probe(struct spi_device *spi)
        return pcm179x_common_init(&spi->dev, regmap);
 }
 
-static int pcm179x_spi_remove(struct spi_device *spi)
-{
-       return pcm179x_common_exit(&spi->dev);
-}
-
 static const struct of_device_id pcm179x_of_match[] = {
        { .compatible = "ti,pcm1792a", },
        { }
@@ -62,7 +57,6 @@ static struct spi_driver pcm179x_spi_driver = {
        },
        .id_table = pcm179x_spi_ids,
        .probe = pcm179x_spi_probe,
-       .remove = pcm179x_spi_remove,
 };
 
 module_spi_driver(pcm179x_spi_driver);
index 82a3d9db32cb87b84b78cb07d40b3a34a636a59e..4b311c06f97da1cf666e860848debd76250d4356 100644 (file)
@@ -77,8 +77,8 @@ struct pcm179x_private {
 static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct pcm179x_private *priv = snd_soc_component_get_drvdata(component);
 
        priv->format = format;
 
@@ -87,8 +87,8 @@ static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm179x_private *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE,
@@ -103,8 +103,8 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm179x_private *priv = snd_soc_component_get_drvdata(component);
        int val = 0, ret;
 
        priv->rate = params_rate(params);
@@ -137,7 +137,7 @@ static int pcm179x_hw_params(struct snd_pcm_substream *substream,
                }
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -205,15 +205,17 @@ const struct regmap_config pcm179x_regmap_config = {
 };
 EXPORT_SYMBOL_GPL(pcm179x_regmap_config);
 
-static const struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
-       .component_driver = {
-               .controls               = pcm179x_controls,
-               .num_controls           = ARRAY_SIZE(pcm179x_controls),
-               .dapm_widgets           = pcm179x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pcm179x_dapm_widgets),
-               .dapm_routes            = pcm179x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pcm179x_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_pcm179x = {
+       .controls               = pcm179x_controls,
+       .num_controls           = ARRAY_SIZE(pcm179x_controls),
+       .dapm_widgets           = pcm179x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm179x_dapm_widgets),
+       .dapm_routes            = pcm179x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm179x_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 int pcm179x_common_init(struct device *dev, struct regmap *regmap)
@@ -228,18 +230,11 @@ int pcm179x_common_init(struct device *dev, struct regmap *regmap)
        pcm179x->regmap = regmap;
        dev_set_drvdata(dev, pcm179x);
 
-       return snd_soc_register_codec(dev,
-                       &soc_codec_dev_pcm179x, &pcm179x_dai, 1);
+       return devm_snd_soc_register_component(dev,
+                       &soc_component_dev_pcm179x, &pcm179x_dai, 1);
 }
 EXPORT_SYMBOL_GPL(pcm179x_common_init);
 
-int pcm179x_common_exit(struct device *dev)
-{
-       snd_soc_unregister_codec(dev);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(pcm179x_common_exit);
-
 MODULE_DESCRIPTION("ASoC PCM179X driver");
 MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
 MODULE_LICENSE("GPL");
index 11e331268aae27c2523a9e12dfb4c44ce3967dd0..cf8681c9a37390e3b73a7f1296c28ec21dd0e2a3 100644 (file)
@@ -23,6 +23,5 @@
 extern const struct regmap_config pcm179x_regmap_config;
 
 int pcm179x_common_init(struct device *dev, struct regmap *regmap);
-int pcm179x_common_exit(struct device *dev);
 
 #endif
index 543621232d604a4227f8df988c34dbc249dfb4fa..0214dc6d84d049d04a0ae1bfdbf0361ced357f24 100644 (file)
@@ -36,13 +36,6 @@ static int pcm186x_i2c_probe(struct i2c_client *i2c,
        return pcm186x_probe(&i2c->dev, type, irq, regmap);
 }
 
-static int pcm186x_i2c_remove(struct i2c_client *i2c)
-{
-       pcm186x_remove(&i2c->dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id pcm186x_i2c_id[] = {
        { "pcm1862", PCM1862 },
        { "pcm1863", PCM1863 },
@@ -54,7 +47,6 @@ MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id);
 
 static struct i2c_driver pcm186x_i2c_driver = {
        .probe          = pcm186x_i2c_probe,
-       .remove         = pcm186x_i2c_remove,
        .id_table       = pcm186x_i2c_id,
        .driver         = {
                .name   = "pcm186x",
index 2366f8e4d4d46c5cbcabd1a17e66f2e1e9336545..b56e198274979a8fa3403992e05d0089c0f243c4 100644 (file)
@@ -36,13 +36,6 @@ static int pcm186x_spi_probe(struct spi_device *spi)
        return pcm186x_probe(&spi->dev, type, irq, regmap);
 }
 
-static int pcm186x_spi_remove(struct spi_device *spi)
-{
-       pcm186x_remove(&spi->dev);
-
-       return 0;
-}
-
 static const struct spi_device_id pcm186x_spi_id[] = {
        { "pcm1862", PCM1862 },
        { "pcm1863", PCM1863 },
@@ -54,7 +47,6 @@ MODULE_DEVICE_TABLE(spi, pcm186x_spi_id);
 
 static struct spi_driver pcm186x_spi_driver = {
        .probe          = pcm186x_spi_probe,
-       .remove         = pcm186x_spi_remove,
        .id_table       = pcm186x_spi_id,
        .driver         = {
                .name   = "pcm186x",
index cdb51427facc4e162e2d0f709f80bbd6c00f3721..88fde70b1e9ef775c1c263fe36c5a613a93546c0 100644 (file)
@@ -262,9 +262,8 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-
-       struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int rate = params_rate(params);
        unsigned int format = params_format(params);
        unsigned int width = params_width(params);
@@ -274,7 +273,7 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
        u8 tdm_tx_sel = 0;
        u8 pcm_cfg = 0;
 
-       dev_dbg(codec->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n",
+       dev_dbg(component->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n",
                __func__, rate, format, width, channels);
 
        switch (width) {
@@ -306,7 +305,7 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, PCM186X_PCM_CFG,
+       snd_soc_component_update_bits(component, PCM186X_PCM_CFG,
                            PCM186X_PCM_CFG_RX_WLEN_MASK |
                            PCM186X_PCM_CFG_TX_WLEN_MASK,
                            pcm_cfg);
@@ -329,14 +328,14 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
                        return -EINVAL;
                }
 
-               snd_soc_update_bits(codec, PCM186X_TDM_TX_SEL,
+               snd_soc_component_update_bits(component, PCM186X_TDM_TX_SEL,
                                    PCM186X_TDM_TX_SEL_MASK, tdm_tx_sel);
 
                /* In DSP/TDM mode, the LRCLK divider must be 256 */
                div_lrck = 256;
 
                /* Configure 1/256 duty cycle for LRCK */
-               snd_soc_update_bits(codec, PCM186X_PCM_CFG,
+               snd_soc_component_update_bits(component, PCM186X_PCM_CFG,
                                    PCM186X_PCM_CFG_TDM_LRCK_MODE,
                                    PCM186X_PCM_CFG_TDM_LRCK_MODE);
        }
@@ -345,12 +344,12 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
        if (priv->is_master_mode) {
                div_bck = priv->sysclk / (div_lrck * rate);
 
-               dev_dbg(codec->dev,
+               dev_dbg(component->dev,
                        "%s() master_clk=%u div_bck=%u div_lrck=%u\n",
                        __func__, priv->sysclk, div_bck, div_lrck);
 
-               snd_soc_write(codec, PCM186X_BCK_DIV, div_bck - 1);
-               snd_soc_write(codec, PCM186X_LRK_DIV, div_lrck - 1);
+               snd_soc_component_write(component, PCM186X_BCK_DIV, div_bck - 1);
+               snd_soc_component_write(component, PCM186X_LRK_DIV, div_lrck - 1);
        }
 
        return 0;
@@ -358,18 +357,18 @@ static int pcm186x_hw_params(struct snd_pcm_substream *substream,
 
 static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
        u8 clk_ctrl = 0;
        u8 pcm_cfg = 0;
 
-       dev_dbg(codec->dev, "%s() format=0x%x\n", __func__, format);
+       dev_dbg(component->dev, "%s() format=0x%x\n", __func__, format);
 
        /* set master/slave audio interface */
        switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
                if (!priv->sysclk) {
-                       dev_err(codec->dev, "operating in master mode requires sysclock to be configured\n");
+                       dev_err(component->dev, "operating in master mode requires sysclock to be configured\n");
                        return -EINVAL;
                }
                clk_ctrl |= PCM186X_CLK_CTRL_MST_MODE;
@@ -379,7 +378,7 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
                priv->is_master_mode = false;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI master/slave interface\n");
+               dev_err(component->dev, "Invalid DAI master/slave interface\n");
                return -EINVAL;
        }
 
@@ -388,7 +387,7 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
        case SND_SOC_DAIFMT_NB_NF:
                break;
        default:
-               dev_err(codec->dev, "Inverted DAI clocks not supported\n");
+               dev_err(component->dev, "Inverted DAI clocks not supported\n");
                return -EINVAL;
        }
 
@@ -410,16 +409,16 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
                pcm_cfg = PCM186X_PCM_CFG_FMT_TDM;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, PCM186X_CLK_CTRL,
+       snd_soc_component_update_bits(component, PCM186X_CLK_CTRL,
                            PCM186X_CLK_CTRL_MST_MODE, clk_ctrl);
 
-       snd_soc_write(codec, PCM186X_TDM_TX_OFFSET, priv->tdm_offset);
+       snd_soc_component_write(component, PCM186X_TDM_TX_OFFSET, priv->tdm_offset);
 
-       snd_soc_update_bits(codec, PCM186X_PCM_CFG,
+       snd_soc_component_update_bits(component, PCM186X_PCM_CFG,
                            PCM186X_PCM_CFG_FMT_MASK, pcm_cfg);
 
        return 0;
@@ -428,16 +427,16 @@ static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format)
 static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                                unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
        unsigned int first_slot, last_slot, tdm_offset;
 
-       dev_dbg(codec->dev,
+       dev_dbg(component->dev,
                "%s() tx_mask=0x%x rx_mask=0x%x slots=%d slot_width=%d\n",
                __func__, tx_mask, rx_mask, slots, slot_width);
 
        if (!tx_mask) {
-               dev_err(codec->dev, "tdm tx mask must not be 0\n");
+               dev_err(component->dev, "tdm tx mask must not be 0\n");
                return -EINVAL;
        }
 
@@ -445,14 +444,14 @@ static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        last_slot = __fls(tx_mask);
 
        if (last_slot - first_slot != hweight32(tx_mask) - 1) {
-               dev_err(codec->dev, "tdm tx mask must be contiguous\n");
+               dev_err(component->dev, "tdm tx mask must be contiguous\n");
                return -EINVAL;
        }
 
        tdm_offset = first_slot * slot_width;
 
        if (tdm_offset > 255) {
-               dev_err(codec->dev, "tdm tx slot selection out of bounds\n");
+               dev_err(component->dev, "tdm tx slot selection out of bounds\n");
                return -EINVAL;
        }
 
@@ -464,10 +463,10 @@ static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int pcm186x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                                  unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s() clk_id=%d freq=%u dir=%d\n",
+       dev_dbg(component->dev, "%s() clk_id=%d freq=%u dir=%d\n",
                __func__, clk_id, freq, dir);
 
        priv->sysclk = freq;
@@ -506,9 +505,9 @@ static struct snd_soc_dai_driver pcm1865_dai = {
        .ops = &pcm186x_dai_ops,
 };
 
-static int pcm186x_power_on(struct snd_soc_codec *codec)
+static int pcm186x_power_on(struct snd_soc_component *component)
 {
-       struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
@@ -519,25 +518,25 @@ static int pcm186x_power_on(struct snd_soc_codec *codec)
        regcache_cache_only(priv->regmap, false);
        ret = regcache_sync(priv->regmap);
        if (ret) {
-               dev_err(codec->dev, "Failed to restore cache\n");
+               dev_err(component->dev, "Failed to restore cache\n");
                regcache_cache_only(priv->regmap, true);
                regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
                                       priv->supplies);
                return ret;
        }
 
-       snd_soc_update_bits(codec, PCM186X_POWER_CTRL,
+       snd_soc_component_update_bits(component, PCM186X_POWER_CTRL,
                            PCM186X_PWR_CTRL_PWRDN, 0);
 
        return 0;
 }
 
-static int pcm186x_power_off(struct snd_soc_codec *codec)
+static int pcm186x_power_off(struct snd_soc_component *component)
 {
-       struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct pcm186x_priv *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
-       snd_soc_update_bits(codec, PCM186X_POWER_CTRL,
+       snd_soc_component_update_bits(component, PCM186X_POWER_CTRL,
                            PCM186X_PWR_CTRL_PWRDN, PCM186X_PWR_CTRL_PWRDN);
 
        regcache_cache_only(priv->regmap, true);
@@ -550,11 +549,11 @@ static int pcm186x_power_off(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int pcm186x_set_bias_level(struct snd_soc_codec *codec,
+static int pcm186x_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
-               snd_soc_codec_get_bias_level(codec), level);
+       dev_dbg(component->dev, "## %s: %d -> %d\n", __func__,
+               snd_soc_component_get_bias_level(component), level);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -562,42 +561,44 @@ static int pcm186x_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-                       pcm186x_power_on(codec);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+                       pcm186x_power_on(component);
                break;
        case SND_SOC_BIAS_OFF:
-               pcm186x_power_off(codec);
+               pcm186x_power_off(component);
                break;
        }
 
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_pcm1863 = {
-       .set_bias_level = pcm186x_set_bias_level,
-
-       .component_driver = {
-               .controls = pcm1863_snd_controls,
-               .num_controls = ARRAY_SIZE(pcm1863_snd_controls),
-               .dapm_widgets = pcm1863_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(pcm1863_dapm_widgets),
-               .dapm_routes = pcm1863_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(pcm1863_dapm_routes),
-       },
+static struct snd_soc_component_driver soc_codec_dev_pcm1863 = {
+       .set_bias_level         = pcm186x_set_bias_level,
+       .controls               = pcm1863_snd_controls,
+       .num_controls           = ARRAY_SIZE(pcm1863_snd_controls),
+       .dapm_widgets           = pcm1863_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm1863_dapm_widgets),
+       .dapm_routes            = pcm1863_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm1863_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_pcm1865 = {
-       .set_bias_level = pcm186x_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls = pcm1865_snd_controls,
-               .num_controls = ARRAY_SIZE(pcm1865_snd_controls),
-               .dapm_widgets = pcm1865_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(pcm1865_dapm_widgets),
-               .dapm_routes = pcm1865_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(pcm1865_dapm_routes),
-       },
+static struct snd_soc_component_driver soc_codec_dev_pcm1865 = {
+       .set_bias_level         = pcm186x_set_bias_level,
+       .controls               = pcm1865_snd_controls,
+       .num_controls           = ARRAY_SIZE(pcm1865_snd_controls),
+       .dapm_widgets           = pcm1865_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm1865_dapm_widgets),
+       .dapm_routes            = pcm1865_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm1865_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static bool pcm186x_volatile(struct device *dev, unsigned int reg)
@@ -687,13 +688,13 @@ int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq,
        switch (type) {
        case PCM1865:
        case PCM1864:
-               ret = snd_soc_register_codec(dev, &soc_codec_dev_pcm1865,
+               ret = devm_snd_soc_register_component(dev, &soc_codec_dev_pcm1865,
                                             &pcm1865_dai, 1);
                break;
        case PCM1863:
        case PCM1862:
        default:
-               ret = snd_soc_register_codec(dev, &soc_codec_dev_pcm1863,
+               ret = devm_snd_soc_register_component(dev, &soc_codec_dev_pcm1863,
                                             &pcm1863_dai, 1);
        }
        if (ret) {
@@ -705,14 +706,6 @@ int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq,
 }
 EXPORT_SYMBOL_GPL(pcm186x_probe);
 
-int pcm186x_remove(struct device *dev)
-{
-       snd_soc_unregister_codec(dev);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(pcm186x_remove);
-
 MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>");
 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 MODULE_DESCRIPTION("PCM186x Universal Audio ADC driver");
index b630111bb3c4fb3f4d455676685f72cd75ae0289..2c6ba55bf394eb0f2ad4a2a4ce2f2fc21291a541 100644 (file)
@@ -215,6 +215,5 @@ extern const struct regmap_config pcm186x_regmap;
 
 int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq,
                  struct regmap *regmap);
-int pcm186x_remove(struct device *dev);
 
 #endif /* _PCM186X_H_ */
index e59d8ffb93bd65a2a6319aa3c24e7dc4d603a708..c6ce9bd77c5ef76bfbb7c197b40745ae02914c23 100644 (file)
@@ -32,8 +32,8 @@ static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol,
                          int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct pcm3008_setup_data *setup = codec->dev->platform_data;
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct pcm3008_setup_data *setup = component->dev->platform_data;
 
        gpio_set_value_cansleep(setup->pdda_pin,
                                SND_SOC_DAPM_EVENT_ON(event));
@@ -45,8 +45,8 @@ static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol,
                          int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct pcm3008_setup_data *setup = codec->dev->platform_data;
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct pcm3008_setup_data *setup = component->dev->platform_data;
 
        gpio_set_value_cansleep(setup->pdad_pin,
                                SND_SOC_DAPM_EVENT_ON(event));
@@ -98,13 +98,15 @@ static struct snd_soc_dai_driver pcm3008_dai = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
-       .component_driver = {
-               .dapm_widgets           = pcm3008_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pcm3008_dapm_widgets),
-               .dapm_routes            = pcm3008_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pcm3008_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_pcm3008 = {
+       .dapm_widgets           = pcm3008_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm3008_dapm_widgets),
+       .dapm_routes            = pcm3008_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm3008_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int pcm3008_codec_probe(struct platform_device *pdev)
@@ -146,22 +148,14 @@ static int pcm3008_codec_probe(struct platform_device *pdev)
        if (ret != 0)
                return ret;
 
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_pcm3008, &pcm3008_dai, 1);
-}
-
-static int pcm3008_codec_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_pcm3008, &pcm3008_dai, 1);
 }
 
 MODULE_ALIAS("platform:pcm3008-codec");
 
 static struct platform_driver pcm3008_codec_driver = {
        .probe          = pcm3008_codec_probe,
-       .remove         = pcm3008_codec_remove,
        .driver         = {
                .name   = "pcm3008-codec",
        },
index b9d1207ccef26fdc684324a0038771b609749e69..3356c91f55b0ab3d4e91bdbb1399862a3ce94a52 100644 (file)
@@ -287,8 +287,8 @@ static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
 
 static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
 
        regmap_write(pcm3168a->regmap, PCM3168A_DAC_MUTE, mute ? 0xff : 0);
 
@@ -298,7 +298,7 @@ static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
 static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(dai->codec);
+       struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
        int ret;
 
        if (freq > PCM1368A_MAX_SYSCLK)
@@ -316,8 +316,8 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
 static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
                               unsigned int format, bool dac)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
        u32 fmt, reg, mask, shift;
        bool master_mode;
 
@@ -338,7 +338,7 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
                fmt = PCM3168A_FMT_DSP_B;
                break;
        default:
-               dev_err(codec->dev, "unsupported dai format\n");
+               dev_err(component->dev, "unsupported dai format\n");
                return -EINVAL;
        }
 
@@ -350,7 +350,7 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
                master_mode = true;
                break;
        default:
-               dev_err(codec->dev, "unsupported master/slave mode\n");
+               dev_err(component->dev, "unsupported master/slave mode\n");
                return -EINVAL;
        }
 
@@ -396,8 +396,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
        bool tx, master_mode;
        u32 val, mask, shift, reg;
        unsigned int rate, fmt, ratio, max_ratio;
@@ -430,7 +430,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (i == max_ratio) {
-               dev_err(codec->dev, "unsupported sysclk ratio\n");
+               dev_err(component->dev, "unsupported sysclk ratio\n");
                return -EINVAL;
        }
 
@@ -438,21 +438,21 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
        switch (min_frame_size) {
        case 32:
                if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
-                       dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
+                       dev_err(component->dev, "32-bit frames are supported only for slave mode using right justified\n");
                        return -EINVAL;
                }
                fmt = PCM3168A_FMT_RIGHT_J_16;
                break;
        case 48:
                if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
-                       dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
+                       dev_err(component->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
                        return -EINVAL;
                }
                break;
        case 64:
                break;
        default:
-               dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
+               dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size);
                return -EINVAL;
        }
 
@@ -595,16 +595,16 @@ const struct regmap_config pcm3168a_regmap = {
 };
 EXPORT_SYMBOL_GPL(pcm3168a_regmap);
 
-static const struct snd_soc_codec_driver pcm3168a_driver = {
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = pcm3168a_snd_controls,
-               .num_controls           = ARRAY_SIZE(pcm3168a_snd_controls),
-               .dapm_widgets           = pcm3168a_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pcm3168a_dapm_widgets),
-               .dapm_routes            = pcm3168a_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pcm3168a_dapm_routes)
-       },
+static const struct snd_soc_component_driver pcm3168a_driver = {
+       .controls               = pcm3168a_snd_controls,
+       .num_controls           = ARRAY_SIZE(pcm3168a_snd_controls),
+       .dapm_widgets           = pcm3168a_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm3168a_dapm_widgets),
+       .dapm_routes            = pcm3168a_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm3168a_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 int pcm3168a_probe(struct device *dev, struct regmap *regmap)
@@ -669,10 +669,10 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap)
        pm_runtime_enable(dev);
        pm_runtime_idle(dev);
 
-       ret = snd_soc_register_codec(dev, &pcm3168a_driver, pcm3168a_dais,
+       ret = devm_snd_soc_register_component(dev, &pcm3168a_driver, pcm3168a_dais,
                        ARRAY_SIZE(pcm3168a_dais));
        if (ret) {
-               dev_err(dev, "failed to register codec: %d\n", ret);
+               dev_err(dev, "failed to register component: %d\n", ret);
                goto err_regulator;
        }
 
@@ -692,7 +692,6 @@ void pcm3168a_remove(struct device *dev)
 {
        struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
 
-       snd_soc_unregister_codec(dev);
        pm_runtime_disable(dev);
        regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
                                pcm3168a->supplies);
index 8ba322a00363cf107cbb364634740655681b8e25..39ac2857a5545e7d437f097a878d6a7c24284b1b 100644 (file)
@@ -32,20 +32,19 @@ static struct snd_soc_dai_driver pcm5102a_dai = {
        },
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_pcm5102a;
+static struct snd_soc_component_driver soc_component_dev_pcm5102a = {
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
 
 static int pcm5102a_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a,
+       return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_pcm5102a,
                        &pcm5102a_dai, 1);
 }
 
-static int pcm5102a_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static const struct of_device_id pcm5102a_of_match[] = {
        { .compatible = "ti,pcm5102a", },
        { }
@@ -54,7 +53,6 @@ MODULE_DEVICE_TABLE(of, pcm5102a_of_match);
 
 static struct platform_driver pcm5102a_codec_driver = {
        .probe          = pcm5102a_probe,
-       .remove         = pcm5102a_remove,
        .driver         = {
                .name   = "pcm5102a-codec",
                .of_match_table = pcm5102a_of_match,
index e0f3556d38729486fe937022cc271dd136a8c0eb..f0f2d4fd3769f5785c55d42a613697a6682042b6 100644 (file)
@@ -226,8 +226,8 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg)
 static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = pcm512x->overclock_pll;
        return 0;
@@ -236,10 +236,10 @@ static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
-       switch (snd_soc_codec_get_bias_level(codec)) {
+       switch (snd_soc_component_get_bias_level(component)) {
        case SND_SOC_BIAS_OFF:
        case SND_SOC_BIAS_STANDBY:
                break;
@@ -254,8 +254,8 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = pcm512x->overclock_dsp;
        return 0;
@@ -264,10 +264,10 @@ static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
-       switch (snd_soc_codec_get_bias_level(codec)) {
+       switch (snd_soc_component_get_bias_level(component)) {
        case SND_SOC_BIAS_OFF:
        case SND_SOC_BIAS_STANDBY:
                break;
@@ -282,8 +282,8 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = pcm512x->overclock_dac;
        return 0;
@@ -292,10 +292,10 @@ static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
 static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
-       switch (snd_soc_codec_get_bias_level(codec)) {
+       switch (snd_soc_component_get_bias_level(component)) {
        case SND_SOC_BIAS_OFF:
        case SND_SOC_BIAS_STANDBY:
                break;
@@ -522,8 +522,8 @@ static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
 static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
                                      struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        struct device *dev = dai->dev;
        struct snd_pcm_hw_constraint_ratnums *constraints_no_pll;
        struct snd_ratnum *rats_no_pll;
@@ -564,8 +564,8 @@ static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
 static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream,
                                     struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        struct device *dev = dai->dev;
        struct regmap *regmap = pcm512x->regmap;
 
@@ -590,8 +590,8 @@ static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream,
 static int pcm512x_dai_startup(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
        switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -606,10 +606,10 @@ static int pcm512x_dai_startup(struct snd_pcm_substream *substream,
        }
 }
 
-static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
+static int pcm512x_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
+       struct pcm512x_priv *pcm512x = dev_get_drvdata(component->dev);
        int ret;
 
        switch (level) {
@@ -621,7 +621,7 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
                                         PCM512x_RQST, 0);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to remove standby: %d\n",
+                       dev_err(component->dev, "Failed to remove standby: %d\n",
                                ret);
                        return ret;
                }
@@ -631,7 +631,7 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
                                         PCM512x_RQST, PCM512x_RQST);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to request standby: %d\n",
+                       dev_err(component->dev, "Failed to request standby: %d\n",
                                ret);
                        return ret;
                }
@@ -645,8 +645,8 @@ static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
                                      unsigned long bclk_rate)
 {
        struct device *dev = dai->dev;
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        unsigned long sck_rate;
        int pow2;
 
@@ -691,8 +691,8 @@ static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai,
                                  unsigned long pll_rate)
 {
        struct device *dev = dai->dev;
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        unsigned long common;
        int R, J, D, P;
        unsigned long K; /* 10000 * J.D */
@@ -798,8 +798,8 @@ static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai,
                                            unsigned long osr_rate,
                                            unsigned long pllin_rate)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        unsigned long dac_rate;
 
        if (!pcm512x->pll_out)
@@ -829,8 +829,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
                                struct snd_pcm_hw_params *params)
 {
        struct device *dev = dai->dev;
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        unsigned long pllin_rate = 0;
        unsigned long pll_rate;
        unsigned long sck_rate;
@@ -949,7 +949,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
                                         PCM512x_SDAC, PCM512x_SDAC_GPIO);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set gpio as dacref: %d\n", ret);
                        return ret;
                }
@@ -958,7 +958,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_DACIN,
                                         PCM512x_GREF, gpio);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set gpio %d as dacin: %d\n",
                                pcm512x->pll_in, ret);
                        return ret;
@@ -987,7 +987,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
                                         PCM512x_SDAC, PCM512x_SDAC_SCK);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set sck as dacref: %d\n", ret);
                        return ret;
                }
@@ -1082,18 +1082,18 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
        ret = regmap_update_bits(pcm512x->regmap, PCM512x_FS_SPEED_MODE,
                                 PCM512x_FSSP, fssp);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to set fs speed: %d\n", ret);
+               dev_err(component->dev, "Failed to set fs speed: %d\n", ret);
                return ret;
        }
 
-       dev_dbg(codec->dev, "DSP divider %d\n", dsp_div);
-       dev_dbg(codec->dev, "DAC divider %d\n", dac_div);
-       dev_dbg(codec->dev, "NCP divider %d\n", ncp_div);
-       dev_dbg(codec->dev, "OSR divider %d\n", osr_div);
-       dev_dbg(codec->dev, "BCK divider %d\n", bclk_div);
-       dev_dbg(codec->dev, "LRCK divider %d\n", lrclk_div);
-       dev_dbg(codec->dev, "IDAC %d\n", idac);
-       dev_dbg(codec->dev, "1<<FSSP %d\n", 1 << fssp);
+       dev_dbg(component->dev, "DSP divider %d\n", dsp_div);
+       dev_dbg(component->dev, "DAC divider %d\n", dac_div);
+       dev_dbg(component->dev, "NCP divider %d\n", ncp_div);
+       dev_dbg(component->dev, "OSR divider %d\n", osr_div);
+       dev_dbg(component->dev, "BCK divider %d\n", bclk_div);
+       dev_dbg(component->dev, "LRCK divider %d\n", lrclk_div);
+       dev_dbg(component->dev, "IDAC %d\n", idac);
+       dev_dbg(component->dev, "1<<FSSP %d\n", 1 << fssp);
 
        return 0;
 }
@@ -1102,15 +1102,15 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
        int alen;
        int gpio;
        int clock_output;
        int master_mode;
        int ret;
 
-       dev_dbg(codec->dev, "hw_params %u Hz, %u channels\n",
+       dev_dbg(component->dev, "hw_params %u Hz, %u channels\n",
                params_rate(params),
                params_channels(params));
 
@@ -1128,7 +1128,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                alen = PCM512x_ALEN_32;
                break;
        default:
-               dev_err(codec->dev, "Bad frame size: %d\n",
+               dev_err(component->dev, "Bad frame size: %d\n",
                        params_width(params));
                return -EINVAL;
        }
@@ -1141,7 +1141,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                                         | PCM512x_BCKO | PCM512x_LRKO,
                                         0);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to enable slave mode: %d\n", ret);
                        return ret;
                }
@@ -1149,7 +1149,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
                                         PCM512x_DCAS, 0);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to enable clock divider autoset: %d\n",
                                ret);
                        return ret;
@@ -1170,20 +1170,20 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
        ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1,
                                 PCM512x_ALEN, alen);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to set frame size: %d\n", ret);
+               dev_err(component->dev, "Failed to set frame size: %d\n", ret);
                return ret;
        }
 
        if (pcm512x->pll_out) {
                ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to set FLEX_A: %d\n", ret);
+                       dev_err(component->dev, "Failed to set FLEX_A: %d\n", ret);
                        return ret;
                }
 
                ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to set FLEX_B: %d\n", ret);
+                       dev_err(component->dev, "Failed to set FLEX_B: %d\n", ret);
                        return ret;
                }
 
@@ -1196,7 +1196,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                                         | PCM512x_IDSK | PCM512x_IDCH
                                         | PCM512x_DCAS);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to ignore auto-clock failures: %d\n",
                                ret);
                        return ret;
@@ -1211,7 +1211,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                                         | PCM512x_IDSK | PCM512x_IDCH
                                         | PCM512x_DCAS | PCM512x_IPLK);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to ignore auto-clock failures: %d\n",
                                ret);
                        return ret;
@@ -1220,7 +1220,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
                                         PCM512x_PLLE, 0);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to disable pll: %d\n", ret);
+                       dev_err(component->dev, "Failed to disable pll: %d\n", ret);
                        return ret;
                }
        }
@@ -1233,7 +1233,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_REF,
                                         PCM512x_SREF, PCM512x_SREF_GPIO);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set gpio as pllref: %d\n", ret);
                        return ret;
                }
@@ -1242,7 +1242,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_PLLIN,
                                         PCM512x_GREF, gpio);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set gpio %d as pllin: %d\n",
                                pcm512x->pll_in, ret);
                        return ret;
@@ -1251,7 +1251,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
                                         PCM512x_PLLE, PCM512x_PLLE);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to enable pll: %d\n", ret);
+                       dev_err(component->dev, "Failed to enable pll: %d\n", ret);
                        return ret;
                }
        }
@@ -1260,7 +1260,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                                 PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO,
                                 clock_output);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable clock output: %d\n", ret);
+               dev_err(component->dev, "Failed to enable clock output: %d\n", ret);
                return ret;
        }
 
@@ -1268,7 +1268,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                                 PCM512x_RLRK | PCM512x_RBCK,
                                 master_mode);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable master mode: %d\n", ret);
+               dev_err(component->dev, "Failed to enable master mode: %d\n", ret);
                return ret;
        }
 
@@ -1277,7 +1277,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN,
                                         gpio, gpio);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to enable gpio %d: %d\n",
+                       dev_err(component->dev, "Failed to enable gpio %d: %d\n",
                                pcm512x->pll_out, ret);
                        return ret;
                }
@@ -1286,7 +1286,7 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
                ret = regmap_update_bits(pcm512x->regmap, gpio,
                                         PCM512x_GxSL, PCM512x_GxSL_PLLCK);
                if (ret != 0) {
-                       dev_err(codec->dev, "Failed to output pll on %d: %d\n",
+                       dev_err(component->dev, "Failed to output pll on %d: %d\n",
                                ret, pcm512x->pll_out);
                        return ret;
                }
@@ -1295,14 +1295,14 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
        ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
                                 PCM512x_RQSY, PCM512x_RQSY_HALT);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to halt clocks: %d\n", ret);
+               dev_err(component->dev, "Failed to halt clocks: %d\n", ret);
                return ret;
        }
 
        ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
                                 PCM512x_RQSY, PCM512x_RQSY_RESUME);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to resume clocks: %d\n", ret);
+               dev_err(component->dev, "Failed to resume clocks: %d\n", ret);
                return ret;
        }
 
@@ -1311,8 +1311,8 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
 
 static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
 
        pcm512x->fmt = fmt;
 
@@ -1341,18 +1341,17 @@ static struct snd_soc_dai_driver pcm512x_dai = {
        .ops = &pcm512x_dai_ops,
 };
 
-static const struct snd_soc_codec_driver pcm512x_codec_driver = {
-       .set_bias_level = pcm512x_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = pcm512x_controls,
-               .num_controls           = ARRAY_SIZE(pcm512x_controls),
-               .dapm_widgets           = pcm512x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pcm512x_dapm_widgets),
-               .dapm_routes            = pcm512x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pcm512x_dapm_routes),
-       },
+static const struct snd_soc_component_driver pcm512x_component_driver = {
+       .set_bias_level         = pcm512x_set_bias_level,
+       .controls               = pcm512x_controls,
+       .num_controls           = ARRAY_SIZE(pcm512x_controls),
+       .dapm_widgets           = pcm512x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pcm512x_dapm_widgets),
+       .dapm_routes            = pcm512x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pcm512x_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_range_cfg pcm512x_range = {
@@ -1498,7 +1497,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
        }
 #endif
 
-       ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
+       ret = devm_snd_soc_register_component(dev, &pcm512x_component_driver,
                                    &pcm512x_dai, 1);
        if (ret != 0) {
                dev_err(dev, "Failed to register CODEC: %d\n", ret);
@@ -1523,7 +1522,6 @@ void pcm512x_remove(struct device *dev)
 {
        struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
 
-       snd_soc_unregister_codec(dev);
        pm_runtime_disable(dev);
        if (!IS_ERR(pcm512x->sclk))
                clk_disable_unprepare(pcm512x->sclk);
index 8f92e5c4dd9d7b34dc2b9e0ff34ec9d045f9f5d9..d88e673410835205f2a4a0ae7e30717335dbb679 100644 (file)
@@ -38,7 +38,7 @@ struct rt274_priv {
        struct reg_default *index_cache;
        int index_cache_size;
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct i2c_client *i2c;
        struct snd_soc_jack *jack;
        struct delayed_work jack_detect_work;
@@ -338,13 +338,13 @@ static bool rt274_readable_register(struct device *dev, unsigned int reg)
 }
 
 #ifdef CONFIG_PM
-static void rt274_index_sync(struct snd_soc_codec *codec)
+static void rt274_index_sync(struct snd_soc_component *component)
 {
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-               snd_soc_write(codec, rt274->index_cache[i].reg,
+               snd_soc_component_write(component, rt274->index_cache[i].reg,
                                  rt274->index_cache[i].def);
        }
 }
@@ -357,7 +357,7 @@ static int rt274_jack_detect(struct rt274_priv *rt274, bool *hp, bool *mic)
        *hp = false;
        *mic = false;
 
-       if (!rt274->codec)
+       if (!rt274->component)
                return -EINVAL;
 
        regmap_read(rt274->regmap, RT274_GET_HP_SENSE, &buf);
@@ -393,10 +393,10 @@ static void rt274_jack_detect_work(struct work_struct *work)
 
 static irqreturn_t rt274_irq(int irq, void *data);
 
-static int rt274_mic_detect(struct snd_soc_codec *codec,
+static int rt274_mic_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack,  void *data)
 {
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
        if (jack == NULL) {
                /* Disable jack detection */
@@ -609,8 +609,8 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
        int d_len_code = 0, c_len_code = 0;
 
@@ -620,7 +620,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
        case 48000:
                break;
        default:
-               dev_err(codec->dev, "Unsupported sample rate %d\n",
+               dev_err(component->dev, "Unsupported sample rate %d\n",
                                        params_rate(params));
                return -EINVAL;
        }
@@ -628,7 +628,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
        case 12288000:
        case 24576000:
                if (params_rate(params) != 48000) {
-                       dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+                       dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
                                        params_rate(params), rt274->sys_clk);
                        return -EINVAL;
                }
@@ -636,7 +636,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
        case 11289600:
        case 22579200:
                if (params_rate(params) != 44100) {
-                       dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+                       dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
                                        params_rate(params), rt274->sys_clk);
                        return -EINVAL;
                }
@@ -647,7 +647,7 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
                /* bit 3:0 Number of Channel */
                val |= (params_channels(params) - 1);
        } else {
-               dev_err(codec->dev, "Unsupported channels %d\n",
+               dev_err(component->dev, "Unsupported channels %d\n",
                                        params_channels(params));
                return -EINVAL;
        }
@@ -685,29 +685,29 @@ static int rt274_hw_params(struct snd_pcm_substream *substream,
        if (rt274->master)
                c_len_code = 0x3;
 
-       snd_soc_update_bits(codec,
+       snd_soc_component_update_bits(component,
                RT274_I2S_CTRL1, 0xc018, d_len_code << 3 | c_len_code << 14);
-       dev_dbg(codec->dev, "format val = 0x%x\n", val);
+       dev_dbg(component->dev, "format val = 0x%x\n", val);
 
-       snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x407f, val);
-       snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x407f, val);
+       snd_soc_component_update_bits(component, RT274_DAC_FORMAT, 0x407f, val);
+       snd_soc_component_update_bits(component, RT274_ADC_FORMAT, 0x407f, val);
 
        return 0;
 }
 
 static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M);
                rt274->master = true;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S);
                rt274->master = false;
                break;
@@ -717,27 +717,27 @@ static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+               snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
                                        RT274_I2S_FMT_MASK, RT274_I2S_FMT_I2S);
                break;
        case SND_SOC_DAIFMT_LEFT_J:
-               snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+               snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
                                        RT274_I2S_FMT_MASK, RT274_I2S_FMT_LJ);
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+               snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
                                        RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMA);
                break;
        case SND_SOC_DAIFMT_DSP_B:
-               snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+               snd_soc_component_update_bits(component, RT274_I2S_CTRL1,
                                        RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMB);
                break;
        default:
                return -EINVAL;
        }
        /* bit 15 Stream Type 0:PCM 1:Non-PCM */
-       snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x8000, 0);
-       snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x8000, 0);
+       snd_soc_component_update_bits(component, RT274_DAC_FORMAT, 0x8000, 0);
+       snd_soc_component_update_bits(component, RT274_ADC_FORMAT, 0x8000, 0);
 
        return 0;
 }
@@ -745,47 +745,47 @@ static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
        switch (source) {
        case RT274_PLL2_S_MCLK:
-               snd_soc_update_bits(codec, RT274_PLL2_CTRL,
+               snd_soc_component_update_bits(component, RT274_PLL2_CTRL,
                                RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_MCLK);
                break;
        default:
-               dev_warn(codec->dev, "invalid pll source, use BCLK\n");
+               dev_warn(component->dev, "invalid pll source, use BCLK\n");
        case RT274_PLL2_S_BCLK:
-               snd_soc_update_bits(codec, RT274_PLL2_CTRL,
+               snd_soc_component_update_bits(component, RT274_PLL2_CTRL,
                                RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK);
                break;
        }
 
        if (source == RT274_PLL2_S_BCLK) {
-               snd_soc_update_bits(codec, RT274_MCLK_CTRL,
+               snd_soc_component_update_bits(component, RT274_MCLK_CTRL,
                                (0x3 << 12), (0x3 << 12));
                switch (rt274->fs) {
                case 50:
-                       snd_soc_write(codec, 0x7a, 0xaab6);
-                       snd_soc_write(codec, 0x7b, 0x0301);
-                       snd_soc_write(codec, 0x7c, 0x04fe);
+                       snd_soc_component_write(component, 0x7a, 0xaab6);
+                       snd_soc_component_write(component, 0x7b, 0x0301);
+                       snd_soc_component_write(component, 0x7c, 0x04fe);
                        break;
                case 64:
-                       snd_soc_write(codec, 0x7a, 0xaa96);
-                       snd_soc_write(codec, 0x7b, 0x8003);
-                       snd_soc_write(codec, 0x7c, 0x081e);
+                       snd_soc_component_write(component, 0x7a, 0xaa96);
+                       snd_soc_component_write(component, 0x7b, 0x8003);
+                       snd_soc_component_write(component, 0x7c, 0x081e);
                        break;
                case 128:
-                       snd_soc_write(codec, 0x7a, 0xaa96);
-                       snd_soc_write(codec, 0x7b, 0x8003);
-                       snd_soc_write(codec, 0x7c, 0x080e);
+                       snd_soc_component_write(component, 0x7a, 0xaa96);
+                       snd_soc_component_write(component, 0x7b, 0x8003);
+                       snd_soc_component_write(component, 0x7c, 0x080e);
                        break;
                default:
-                       dev_warn(codec->dev, "invalid freq_in, assume 4.8M\n");
+                       dev_warn(component->dev, "invalid freq_in, assume 4.8M\n");
                case 100:
-                       snd_soc_write(codec, 0x7a, 0xaab6);
-                       snd_soc_write(codec, 0x7b, 0x0301);
-                       snd_soc_write(codec, 0x7c, 0x047e);
+                       snd_soc_component_write(component, 0x7a, 0xaab6);
+                       snd_soc_component_write(component, 0x7b, 0x0301);
+                       snd_soc_component_write(component, 0x7c, 0x047e);
                        break;
                }
        }
@@ -796,11 +796,11 @@ static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
        unsigned int clk_src, mclk_en;
 
-       dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+       dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
 
        switch (clk_id) {
        case RT274_SCLK_S_MCLK:
@@ -818,43 +818,43 @@ static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
        default:
                mclk_en = RT274_MCLK_MODE_DIS;
                clk_src = RT274_CLK_SRC_MCLK;
-               dev_warn(codec->dev, "invalid sysclk source, use PLL1\n");
+               dev_warn(component->dev, "invalid sysclk source, use PLL1\n");
                break;
        }
-       snd_soc_update_bits(codec, RT274_MCLK_CTRL,
+       snd_soc_component_update_bits(component, RT274_MCLK_CTRL,
                        RT274_MCLK_MODE_MASK, mclk_en);
-       snd_soc_update_bits(codec, RT274_CLK_CTRL,
+       snd_soc_component_update_bits(component, RT274_CLK_CTRL,
                        RT274_CLK_SRC_MASK, clk_src);
 
        switch (freq) {
        case 19200000:
                if (clk_id == RT274_SCLK_S_MCLK) {
-                       dev_err(codec->dev, "Should not use MCLK\n");
+                       dev_err(component->dev, "Should not use MCLK\n");
                        return -EINVAL;
                }
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL2, 0x40, 0x40);
                break;
        case 24000000:
                if (clk_id == RT274_SCLK_S_MCLK) {
-                       dev_err(codec->dev, "Should not use MCLK\n");
+                       dev_err(component->dev, "Should not use MCLK\n");
                        return -EINVAL;
                }
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL2, 0x40, 0x0);
                break;
        case 12288000:
        case 11289600:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_MCLK_CTRL, 0x1fcf, 0x0008);
                break;
        case 24576000:
        case 22579200:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_MCLK_CTRL, 0x1fcf, 0x1543);
                break;
        default:
-               dev_err(codec->dev, "Unsupported system clock\n");
+               dev_err(component->dev, "Unsupported system clock\n");
                return -EINVAL;
        }
 
@@ -866,16 +866,16 @@ static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
 
 static int rt274_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
        rt274->fs = ratio;
        if ((ratio / 50) == 0)
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, 0x1000, 0x1000);
        else
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, 0x1000, 0x0);
 
 
@@ -886,28 +886,28 @@ static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (rx_mask || tx_mask) {
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_EN);
        } else {
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_DIS);
                return 0;
        }
 
        switch (slots) {
        case 4:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_4CH);
                break;
        case 2:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_2CH);
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Support 2 or 4 slots TDM only\n");
                return -EINVAL;
        }
@@ -915,20 +915,20 @@ static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        return 0;
 }
 
-static int rt274_set_bias_level(struct snd_soc_codec *codec,
+static int rt274_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
                if (SND_SOC_BIAS_STANDBY ==
-                       snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_write(codec,
+                       snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_write(component,
                                RT274_SET_AUDIO_POWER, AC_PWRST_D0);
                }
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT274_SET_AUDIO_POWER, AC_PWRST_D3);
                break;
 
@@ -968,11 +968,11 @@ static irqreturn_t rt274_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int rt274_probe(struct snd_soc_codec *codec)
+static int rt274_probe(struct snd_soc_component *component)
 {
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
-       rt274->codec = codec;
+       rt274->component = component;
 
        if (rt274->i2c->irq) {
                INIT_DELAYED_WORK(&rt274->jack_detect_work,
@@ -984,19 +984,17 @@ static int rt274_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt274_remove(struct snd_soc_codec *codec)
+static void rt274_remove(struct snd_soc_component *component)
 {
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
        cancel_delayed_work_sync(&rt274->jack_detect_work);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt274_suspend(struct snd_soc_codec *codec)
+static int rt274_suspend(struct snd_soc_component *component)
 {
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt274->regmap, true);
        regcache_mark_dirty(rt274->regmap);
@@ -1004,12 +1002,12 @@ static int rt274_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt274_resume(struct snd_soc_codec *codec)
+static int rt274_resume(struct snd_soc_component *component)
 {
-       struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+       struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt274->regmap, false);
-       rt274_index_sync(codec);
+       rt274_index_sync(component);
        regcache_sync(rt274->regmap);
 
        return 0;
@@ -1055,22 +1053,22 @@ static struct snd_soc_dai_driver rt274_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt274 = {
-       .probe = rt274_probe,
-       .remove = rt274_remove,
-       .suspend = rt274_suspend,
-       .resume = rt274_resume,
-       .set_bias_level = rt274_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt274_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt274_snd_controls),
-               .dapm_widgets           = rt274_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt274_dapm_widgets),
-               .dapm_routes            = rt274_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt274_dapm_routes),
-       },
-       .set_jack = rt274_mic_detect,
+static const struct snd_soc_component_driver soc_component_dev_rt274 = {
+       .probe                  = rt274_probe,
+       .remove                 = rt274_remove,
+       .suspend                = rt274_suspend,
+       .resume                 = rt274_resume,
+       .set_bias_level         = rt274_set_bias_level,
+       .set_jack               = rt274_mic_detect,
+       .controls               = rt274_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt274_snd_controls),
+       .dapm_widgets           = rt274_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt274_dapm_widgets),
+       .dapm_routes            = rt274_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt274_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt274_regmap = {
@@ -1191,7 +1189,8 @@ static int rt274_i2c_probe(struct i2c_client *i2c,
                }
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt274,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_rt274,
                                     rt274_dai, ARRAY_SIZE(rt274_dai));
 
        return ret;
@@ -1203,7 +1202,6 @@ static int rt274_i2c_remove(struct i2c_client *i2c)
 
        if (i2c->irq)
                free_irq(i2c->irq, rt274);
-       snd_soc_unregister_codec(&i2c->dev);
 
        return 0;
 }
index af6325c78292d2e49eae9021887d437b9aac9e22..0b0f748bffbe7015430b25c9333d734a4488537c 100644 (file)
@@ -40,7 +40,7 @@ struct rt286_priv {
        struct reg_default *index_cache;
        int index_cache_size;
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt286_platform_data pdata;
        struct i2c_client *i2c;
        struct snd_soc_jack *jack;
@@ -187,13 +187,13 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
 }
 
 #ifdef CONFIG_PM
-static void rt286_index_sync(struct snd_soc_codec *codec)
+static void rt286_index_sync(struct snd_soc_component *component)
 {
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-               snd_soc_write(codec, rt286->index_cache[i].reg,
+               snd_soc_component_write(component, rt286->index_cache[i].reg,
                                  rt286->index_cache[i].def);
        }
 }
@@ -220,10 +220,10 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
        *hp = false;
        *mic = false;
 
-       if (!rt286->codec)
+       if (!rt286->component)
                return -EINVAL;
 
-       dapm = snd_soc_codec_get_dapm(rt286->codec);
+       dapm = snd_soc_component_get_dapm(rt286->component);
 
        if (rt286->pdata.cbj_en) {
                regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
@@ -275,9 +275,10 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
                regmap_read(rt286->regmap, RT286_GET_MIC1_SENSE, &buf);
                *mic = buf & 0x80000000;
        }
-
-       snd_soc_dapm_disable_pin(dapm, "HV");
-       snd_soc_dapm_disable_pin(dapm, "VREF");
+       if (!*mic) {
+               snd_soc_dapm_disable_pin(dapm, "HV");
+               snd_soc_dapm_disable_pin(dapm, "VREF");
+       }
        if (!*hp)
                snd_soc_dapm_disable_pin(dapm, "LDO1");
        snd_soc_dapm_sync(dapm);
@@ -305,10 +306,10 @@ static void rt286_jack_detect_work(struct work_struct *work)
                SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
 }
 
-int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
        rt286->jack = jack;
 
@@ -334,8 +335,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect);
 static int is_mclk_mode(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
        if (rt286->clk_id == RT286_SCLK_S_MCLK)
                return 1;
@@ -434,15 +435,15 @@ SOC_DAPM_ENUM("SPO source", rt286_spo_enum);
 static int rt286_spk_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT286_SPK_EAPD, RT286_SET_EAPD_HIGH);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT286_SPK_EAPD, RT286_SET_EAPD_LOW);
                break;
 
@@ -456,14 +457,14 @@ static int rt286_spk_event(struct snd_soc_dapm_widget *w,
 static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0x20);
+               snd_soc_component_write(component, RT286_SET_PIN_DMIC1, 0x20);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0);
+               snd_soc_component_write(component, RT286_SET_PIN_DMIC1, 0);
                break;
        default:
                return 0;
@@ -475,14 +476,14 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
 static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08);
+               snd_soc_component_update_bits(component, RT286_POWER_CTRL2, 0x38, 0x08);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30);
+               snd_soc_component_update_bits(component, RT286_POWER_CTRL2, 0x38, 0x30);
                break;
        default:
                return 0;
@@ -494,19 +495,19 @@ static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
 static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
                break;
        default:
@@ -674,8 +675,8 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
        int d_len_code;
 
@@ -687,7 +688,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
        case 48000:
                break;
        default:
-               dev_err(codec->dev, "Unsupported sample rate %d\n",
+               dev_err(component->dev, "Unsupported sample rate %d\n",
                                        params_rate(params));
                return -EINVAL;
        }
@@ -695,7 +696,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
        case 12288000:
        case 24576000:
                if (params_rate(params) != 48000) {
-                       dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+                       dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
                                        params_rate(params), rt286->sys_clk);
                        return -EINVAL;
                }
@@ -703,7 +704,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
        case 11289600:
        case 22579200:
                if (params_rate(params) != 44100) {
-                       dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+                       dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
                                        params_rate(params), rt286->sys_clk);
                        return -EINVAL;
                }
@@ -714,7 +715,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
                /* bit 3:0 Number of Channel */
                val |= (params_channels(params) - 1);
        } else {
-               dev_err(codec->dev, "Unsupported channels %d\n",
+               dev_err(component->dev, "Unsupported channels %d\n",
                                        params_channels(params));
                return -EINVAL;
        }
@@ -745,27 +746,27 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec,
+       snd_soc_component_update_bits(component,
                RT286_I2S_CTRL1, 0x0018, d_len_code << 3);
-       dev_dbg(codec->dev, "format val = 0x%x\n", val);
+       dev_dbg(component->dev, "format val = 0x%x\n", val);
 
-       snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val);
-       snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val);
+       snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x407f, val);
+       snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x407f, val);
 
        return 0;
 }
 
 static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x800, 0x800);
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x800, 0x0);
                break;
        default:
@@ -774,27 +775,27 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x300, 0x0);
                break;
        case SND_SOC_DAIFMT_LEFT_J:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x300, 0x1 << 8);
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x300, 0x2 << 8);
                break;
        case SND_SOC_DAIFMT_DSP_B:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x300, 0x3 << 8);
                break;
        default:
                return -EINVAL;
        }
        /* bit 15 Stream Type 0:PCM 1:Non-PCM */
-       snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x8000, 0);
-       snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x8000, 0);
+       snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x8000, 0);
+       snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x8000, 0);
 
        return 0;
 }
@@ -802,58 +803,58 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+       dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
 
        if (RT286_SCLK_S_MCLK == clk_id) {
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL2, 0x0100, 0x0);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_PLL_CTRL1, 0x20, 0x20);
        } else {
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL2, 0x0100, 0x0100);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_PLL_CTRL, 0x4, 0x4);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_PLL_CTRL1, 0x20, 0x0);
        }
 
        switch (freq) {
        case 19200000:
                if (RT286_SCLK_S_MCLK == clk_id) {
-                       dev_err(codec->dev, "Should not use MCLK\n");
+                       dev_err(component->dev, "Should not use MCLK\n");
                        return -EINVAL;
                }
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL2, 0x40, 0x40);
                break;
        case 24000000:
                if (RT286_SCLK_S_MCLK == clk_id) {
-                       dev_err(codec->dev, "Should not use MCLK\n");
+                       dev_err(component->dev, "Should not use MCLK\n");
                        return -EINVAL;
                }
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL2, 0x40, 0x0);
                break;
        case 12288000:
        case 11289600:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL2, 0x8, 0x0);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_CLK_DIV, 0xfc1e, 0x0004);
                break;
        case 24576000:
        case 22579200:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL2, 0x8, 0x8);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_CLK_DIV, 0xfc1e, 0x5406);
                break;
        default:
-               dev_err(codec->dev, "Unsupported system clock\n");
+               dev_err(component->dev, "Unsupported system clock\n");
                return -EINVAL;
        }
 
@@ -865,42 +866,42 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
 
 static int rt286_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
        if (50 == ratio)
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x1000, 0x1000);
        else
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_I2S_CTRL1, 0x1000, 0x0);
 
 
        return 0;
 }
 
-static int rt286_set_bias_level(struct snd_soc_codec *codec,
+static int rt286_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
-               if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_write(codec,
+               if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_write(component,
                                RT286_SET_AUDIO_POWER, AC_PWRST_D0);
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                RT286_DC_GAIN, 0x200, 0x200);
                }
                break;
 
        case SND_SOC_BIAS_ON:
                mdelay(10);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT286_DC_GAIN, 0x200, 0x0);
 
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT286_SET_AUDIO_POWER, AC_PWRST_D3);
                break;
 
@@ -937,11 +938,11 @@ static irqreturn_t rt286_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int rt286_probe(struct snd_soc_codec *codec)
+static int rt286_probe(struct snd_soc_component *component)
 {
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
-       rt286->codec = codec;
+       rt286->component = component;
 
        if (rt286->i2c->irq) {
                regmap_update_bits(rt286->regmap,
@@ -956,19 +957,17 @@ static int rt286_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt286_remove(struct snd_soc_codec *codec)
+static void rt286_remove(struct snd_soc_component *component)
 {
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
        cancel_delayed_work_sync(&rt286->jack_detect_work);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt286_suspend(struct snd_soc_codec *codec)
+static int rt286_suspend(struct snd_soc_component *component)
 {
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt286->regmap, true);
        regcache_mark_dirty(rt286->regmap);
@@ -976,12 +975,12 @@ static int rt286_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt286_resume(struct snd_soc_codec *codec)
+static int rt286_resume(struct snd_soc_component *component)
 {
-       struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
+       struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt286->regmap, false);
-       rt286_index_sync(codec);
+       rt286_index_sync(component);
        regcache_sync(rt286->regmap);
 
        return 0;
@@ -1046,21 +1045,21 @@ static struct snd_soc_dai_driver rt286_dai[] = {
 
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt286 = {
-       .probe = rt286_probe,
-       .remove = rt286_remove,
-       .suspend = rt286_suspend,
-       .resume = rt286_resume,
-       .set_bias_level = rt286_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt286_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt286_snd_controls),
-               .dapm_widgets           = rt286_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt286_dapm_widgets),
-               .dapm_routes            = rt286_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt286_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt286 = {
+       .probe                  = rt286_probe,
+       .remove                 = rt286_remove,
+       .suspend                = rt286_suspend,
+       .resume                 = rt286_resume,
+       .set_bias_level         = rt286_set_bias_level,
+       .controls               = rt286_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt286_snd_controls),
+       .dapm_widgets           = rt286_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt286_dapm_widgets),
+       .dapm_routes            = rt286_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt286_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt286_regmap = {
@@ -1243,7 +1242,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
                }
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt286,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_rt286,
                                     rt286_dai, ARRAY_SIZE(rt286_dai));
 
        return ret;
@@ -1255,7 +1255,6 @@ static int rt286_i2c_remove(struct i2c_client *i2c)
 
        if (i2c->irq)
                free_irq(i2c->irq, rt286);
-       snd_soc_unregister_codec(&i2c->dev);
 
        return 0;
 }
index 7130edb152efb42db071bcb9ca706d59c894e61e..c63d0e79ba86e2788f162c0dca86e28b6ce5e015 100644 (file)
@@ -199,7 +199,7 @@ enum {
        RT286_AIFS,
 };
 
-int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif /* __RT286_H__ */
 
index ce963768449f188a804ad86136650b5afd540024..06cdba4edfe2cdf5accc6ad54f82efbfe1d5eaa8 100644 (file)
@@ -39,7 +39,7 @@ struct rt298_priv {
        struct reg_default *index_cache;
        int index_cache_size;
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt298_platform_data pdata;
        struct i2c_client *i2c;
        struct snd_soc_jack *jack;
@@ -194,13 +194,13 @@ static bool rt298_readable_register(struct device *dev, unsigned int reg)
 }
 
 #ifdef CONFIG_PM
-static void rt298_index_sync(struct snd_soc_codec *codec)
+static void rt298_index_sync(struct snd_soc_component *component)
 {
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-               snd_soc_write(codec, rt298->index_cache[i].reg,
+               snd_soc_component_write(component, rt298->index_cache[i].reg,
                                  rt298->index_cache[i].def);
        }
 }
@@ -227,10 +227,10 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
        *hp = false;
        *mic = false;
 
-       if (!rt298->codec)
+       if (!rt298->component)
                return -EINVAL;
 
-       dapm = snd_soc_codec_get_dapm(rt298->codec);
+       dapm = snd_soc_component_get_dapm(rt298->component);
 
        if (rt298->pdata.cbj_en) {
                regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf);
@@ -290,9 +290,10 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
                regmap_read(rt298->regmap, RT298_GET_MIC1_SENSE, &buf);
                *mic = buf & 0x80000000;
        }
-
-       snd_soc_dapm_disable_pin(dapm, "HV");
-       snd_soc_dapm_disable_pin(dapm, "VREF");
+       if (!*mic) {
+               snd_soc_dapm_disable_pin(dapm, "HV");
+               snd_soc_dapm_disable_pin(dapm, "VREF");
+       }
        if (!*hp)
                snd_soc_dapm_disable_pin(dapm, "LDO1");
        snd_soc_dapm_sync(dapm);
@@ -323,9 +324,9 @@ static void rt298_jack_detect_work(struct work_struct *work)
                SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
 }
 
-int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
        struct snd_soc_dapm_context *dapm;
        bool hp = false;
        bool mic = false;
@@ -334,7 +335,7 @@ int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
        /* If jack in NULL, disable HS jack */
        if (!jack) {
                regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0);
-               dapm = snd_soc_codec_get_dapm(codec);
+               dapm = snd_soc_component_get_dapm(component);
                snd_soc_dapm_disable_pin(dapm, "LDO1");
                snd_soc_dapm_sync(dapm);
                return 0;
@@ -360,8 +361,8 @@ EXPORT_SYMBOL_GPL(rt298_mic_detect);
 static int is_mclk_mode(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
        if (rt298->clk_id == RT298_SCLK_S_MCLK)
                return 1;
@@ -458,15 +459,15 @@ SOC_DAPM_ENUM("SPO source", rt298_spo_enum);
 static int rt298_spk_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT298_SPK_EAPD, RT298_SET_EAPD_HIGH);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT298_SPK_EAPD, RT298_SET_EAPD_LOW);
                break;
 
@@ -480,14 +481,14 @@ static int rt298_spk_event(struct snd_soc_dapm_widget *w,
 static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0x20);
+               snd_soc_component_write(component, RT298_SET_PIN_DMIC1, 0x20);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0);
+               snd_soc_component_write(component, RT298_SET_PIN_DMIC1, 0);
                break;
        default:
                return 0;
@@ -499,39 +500,39 @@ static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
 static int rt298_adc_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int nid;
 
        nid = (w->reg >> 20) & 0xff;
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
                        0x7080, 0x7000);
                 /* If MCLK doesn't exist, reset AD filter */
-               if (!(snd_soc_read(codec, RT298_VAD_CTRL) & 0x200)) {
+               if (!(snd_soc_component_read32(component, RT298_VAD_CTRL) & 0x200)) {
                        pr_info("NO MCLK\n");
                        switch (nid) {
                        case RT298_ADC_IN1:
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        RT298_D_FILTER_CTRL, 0x2, 0x2);
                                mdelay(10);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        RT298_D_FILTER_CTRL, 0x2, 0x0);
                                break;
                        case RT298_ADC_IN2:
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        RT298_D_FILTER_CTRL, 0x4, 0x4);
                                mdelay(10);
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        RT298_D_FILTER_CTRL, 0x4, 0x0);
                                break;
                        }
                }
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
                        0x7080, 0x7080);
                break;
@@ -545,19 +546,19 @@ static int rt298_adc_event(struct snd_soc_dapm_widget *w,
 static int rt298_mic1_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_A_BIAS_CTRL3, 0xc000, 0x8000);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_A_BIAS_CTRL2, 0xc000, 0x8000);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_A_BIAS_CTRL3, 0xc000, 0x0000);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_A_BIAS_CTRL2, 0xc000, 0x0000);
                break;
        default:
@@ -745,8 +746,8 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
        int d_len_code;
 
@@ -756,7 +757,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
        case 48000:
                break;
        default:
-               dev_err(codec->dev, "Unsupported sample rate %d\n",
+               dev_err(component->dev, "Unsupported sample rate %d\n",
                                        params_rate(params));
                return -EINVAL;
        }
@@ -764,7 +765,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
        case 12288000:
        case 24576000:
                if (params_rate(params) != 48000) {
-                       dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+                       dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
                                        params_rate(params), rt298->sys_clk);
                        return -EINVAL;
                }
@@ -772,7 +773,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
        case 11289600:
        case 22579200:
                if (params_rate(params) != 44100) {
-                       dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+                       dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
                                        params_rate(params), rt298->sys_clk);
                        return -EINVAL;
                }
@@ -783,7 +784,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
                /* bit 3:0 Number of Channel */
                val |= (params_channels(params) - 1);
        } else {
-               dev_err(codec->dev, "Unsupported channels %d\n",
+               dev_err(component->dev, "Unsupported channels %d\n",
                                        params_channels(params));
                return -EINVAL;
        }
@@ -814,27 +815,27 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec,
+       snd_soc_component_update_bits(component,
                RT298_I2S_CTRL1, 0x0018, d_len_code << 3);
-       dev_dbg(codec->dev, "format val = 0x%x\n", val);
+       dev_dbg(component->dev, "format val = 0x%x\n", val);
 
-       snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x407f, val);
-       snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x407f, val);
+       snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x407f, val);
+       snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x407f, val);
 
        return 0;
 }
 
 static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x800, 0x800);
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x800, 0x0);
                break;
        default:
@@ -843,27 +844,27 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x300, 0x0);
                break;
        case SND_SOC_DAIFMT_LEFT_J:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x300, 0x1 << 8);
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x300, 0x2 << 8);
                break;
        case SND_SOC_DAIFMT_DSP_B:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x300, 0x3 << 8);
                break;
        default:
                return -EINVAL;
        }
        /* bit 15 Stream Type 0:PCM 1:Non-PCM */
-       snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x8000, 0);
-       snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x8000, 0);
+       snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x8000, 0);
+       snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x8000, 0);
 
        return 0;
 }
@@ -871,56 +872,56 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+       dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
 
        if (RT298_SCLK_S_MCLK == clk_id) {
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL2, 0x0100, 0x0);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_PLL_CTRL1, 0x20, 0x20);
        } else {
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL2, 0x0100, 0x0100);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_PLL_CTRL1, 0x20, 0x0);
        }
 
        switch (freq) {
        case 19200000:
                if (RT298_SCLK_S_MCLK == clk_id) {
-                       dev_err(codec->dev, "Should not use MCLK\n");
+                       dev_err(component->dev, "Should not use MCLK\n");
                        return -EINVAL;
                }
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL2, 0x40, 0x40);
                break;
        case 24000000:
                if (RT298_SCLK_S_MCLK == clk_id) {
-                       dev_err(codec->dev, "Should not use MCLK\n");
+                       dev_err(component->dev, "Should not use MCLK\n");
                        return -EINVAL;
                }
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL2, 0x40, 0x0);
                break;
        case 12288000:
        case 11289600:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL2, 0x8, 0x0);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_CLK_DIV, 0xfc1e, 0x0004);
                break;
        case 24576000:
        case 22579200:
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL2, 0x8, 0x8);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_CLK_DIV, 0xfc1e, 0x5406);
                break;
        default:
-               dev_err(codec->dev, "Unsupported system clock\n");
+               dev_err(component->dev, "Unsupported system clock\n");
                return -EINVAL;
        }
 
@@ -932,39 +933,39 @@ static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
 
 static int rt298_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
        if (50 == ratio)
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x1000, 0x1000);
        else
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                        RT298_I2S_CTRL1, 0x1000, 0x0);
 
 
        return 0;
 }
 
-static int rt298_set_bias_level(struct snd_soc_codec *codec,
+static int rt298_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
                if (SND_SOC_BIAS_STANDBY ==
-                       snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_write(codec,
+                       snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_write(component,
                                RT298_SET_AUDIO_POWER, AC_PWRST_D0);
-                       snd_soc_update_bits(codec, 0x0d, 0x200, 0x200);
-                       snd_soc_update_bits(codec, 0x52, 0x80, 0x0);
+                       snd_soc_component_update_bits(component, 0x0d, 0x200, 0x200);
+                       snd_soc_component_update_bits(component, 0x52, 0x80, 0x0);
                        mdelay(20);
-                       snd_soc_update_bits(codec, 0x0d, 0x200, 0x0);
-                       snd_soc_update_bits(codec, 0x52, 0x80, 0x80);
+                       snd_soc_component_update_bits(component, 0x0d, 0x200, 0x0);
+                       snd_soc_component_update_bits(component, 0x52, 0x80, 0x80);
                }
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_write(codec,
+               snd_soc_component_write(component,
                        RT298_SET_AUDIO_POWER, AC_PWRST_D3);
                break;
 
@@ -1003,11 +1004,11 @@ static irqreturn_t rt298_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int rt298_probe(struct snd_soc_codec *codec)
+static int rt298_probe(struct snd_soc_component *component)
 {
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
-       rt298->codec = codec;
+       rt298->component = component;
 
        if (rt298->i2c->irq) {
                regmap_update_bits(rt298->regmap,
@@ -1022,19 +1023,17 @@ static int rt298_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt298_remove(struct snd_soc_codec *codec)
+static void rt298_remove(struct snd_soc_component *component)
 {
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
        cancel_delayed_work_sync(&rt298->jack_detect_work);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt298_suspend(struct snd_soc_codec *codec)
+static int rt298_suspend(struct snd_soc_component *component)
 {
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
        rt298->is_hp_in = -1;
        regcache_cache_only(rt298->regmap, true);
@@ -1043,12 +1042,12 @@ static int rt298_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt298_resume(struct snd_soc_codec *codec)
+static int rt298_resume(struct snd_soc_component *component)
 {
-       struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
+       struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt298->regmap, false);
-       rt298_index_sync(codec);
+       rt298_index_sync(component);
        regcache_sync(rt298->regmap);
 
        return 0;
@@ -1113,21 +1112,21 @@ static struct snd_soc_dai_driver rt298_dai[] = {
 
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt298 = {
-       .probe = rt298_probe,
-       .remove = rt298_remove,
-       .suspend = rt298_suspend,
-       .resume = rt298_resume,
-       .set_bias_level = rt298_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt298_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt298_snd_controls),
-               .dapm_widgets           = rt298_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt298_dapm_widgets),
-               .dapm_routes            = rt298_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt298_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt298 = {
+       .probe                  = rt298_probe,
+       .remove                 = rt298_remove,
+       .suspend                = rt298_suspend,
+       .resume                 = rt298_resume,
+       .set_bias_level         = rt298_set_bias_level,
+       .controls               = rt298_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt298_snd_controls),
+       .dapm_widgets           = rt298_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt298_dapm_widgets),
+       .dapm_routes            = rt298_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt298_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt298_regmap = {
@@ -1288,7 +1287,8 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
                }
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt298,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_rt298,
                                     rt298_dai, ARRAY_SIZE(rt298_dai));
 
        return ret;
@@ -1300,7 +1300,6 @@ static int rt298_i2c_remove(struct i2c_client *i2c)
 
        if (i2c->irq)
                free_irq(i2c->irq, rt298);
-       snd_soc_unregister_codec(&i2c->dev);
 
        return 0;
 }
index 3638f3d61209eb4c72c2bdb5dcef770485978bfe..b4db935359fa246db1806edb0865fc0914660185 100644 (file)
@@ -210,7 +210,7 @@ enum {
        RT298_AIFS,
 };
 
-int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #endif /* __RT298_H__ */
 
index 2144edca97b0959430be176feeec47ad0c6f265b..18686ffb0cd5738419e5bcee1479d924b63c6487 100644 (file)
@@ -35,6 +35,8 @@
 
 #include "rt5514-spi.h"
 
+#define DRV_NAME "rt5514-spi"
+
 static struct spi_device *rt5514_spi;
 
 struct rt5514_dsp {
@@ -211,8 +213,9 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
                               struct snd_pcm_hw_params *hw_params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct rt5514_dsp *rt5514_dsp =
-                       snd_soc_platform_get_drvdata(rtd->platform);
+               snd_soc_component_get_drvdata(component);
        int ret;
        u8 buf[8];
 
@@ -235,8 +238,9 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
 static int rt5514_spi_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct rt5514_dsp *rt5514_dsp =
-                       snd_soc_platform_get_drvdata(rtd->platform);
+               snd_soc_component_get_drvdata(component);
 
        mutex_lock(&rt5514_dsp->dma_lock);
        rt5514_dsp->substream = NULL;
@@ -252,8 +256,9 @@ static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct rt5514_dsp *rt5514_dsp =
-               snd_soc_platform_get_drvdata(rtd->platform);
+               snd_soc_component_get_drvdata(component);
 
        return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
 }
@@ -267,18 +272,18 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
        .page           = snd_pcm_lib_get_vmalloc_page,
 };
 
-static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
+static int rt5514_spi_pcm_probe(struct snd_soc_component *component)
 {
        struct rt5514_dsp *rt5514_dsp;
        int ret;
 
-       rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp),
+       rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
                        GFP_KERNEL);
 
        rt5514_dsp->dev = &rt5514_spi->dev;
        mutex_init(&rt5514_dsp->dma_lock);
        INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work);
-       snd_soc_platform_set_drvdata(platform, rt5514_dsp);
+       snd_soc_component_set_drvdata(component, rt5514_dsp);
 
        if (rt5514_spi->irq) {
                ret = devm_request_threaded_irq(&rt5514_spi->dev,
@@ -296,15 +301,12 @@ static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
        return 0;
 }
 
-static const struct snd_soc_platform_driver rt5514_spi_platform = {
+static const struct snd_soc_component_driver rt5514_spi_component = {
+       .name  = DRV_NAME,
        .probe = rt5514_spi_pcm_probe,
        .ops = &rt5514_spi_pcm_ops,
 };
 
-static const struct snd_soc_component_driver rt5514_spi_dai_component = {
-       .name           = "rt5514-spi-dai",
-};
-
 /**
  * rt5514_spi_burst_read - Read data from SPI by rt5514 address.
  * @addr: Start address.
@@ -445,14 +447,8 @@ static int rt5514_spi_probe(struct spi_device *spi)
 
        rt5514_spi = spi;
 
-       ret = devm_snd_soc_register_platform(&spi->dev, &rt5514_spi_platform);
-       if (ret < 0) {
-               dev_err(&spi->dev, "Failed to register platform.\n");
-               return ret;
-       }
-
        ret = devm_snd_soc_register_component(&spi->dev,
-                                             &rt5514_spi_dai_component,
+                                             &rt5514_spi_component,
                                              &rt5514_spi_dai, 1);
        if (ret < 0) {
                dev_err(&spi->dev, "Failed to register component.\n");
@@ -474,9 +470,9 @@ static int __maybe_unused rt5514_suspend(struct device *dev)
 
 static int __maybe_unused rt5514_resume(struct device *dev)
 {
-       struct snd_soc_platform *platform = snd_soc_lookup_platform(dev);
+       struct snd_soc_component *component = snd_soc_lookup_component(dev, DRV_NAME);
        struct rt5514_dsp *rt5514_dsp =
-               snd_soc_platform_get_drvdata(platform);
+               snd_soc_component_get_drvdata(component);
        int irq = to_spi_device(dev)->irq;
        u8 buf[8];
 
index 198df016802f826dff3681d5f6496c4484d3e431..e8a66b03faabf405ec43f7170e0205fd4650eb29 100644 (file)
@@ -327,14 +327,13 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
-       struct snd_soc_codec *codec = rt5514->codec;
        const struct firmware *fw = NULL;
        u8 buf[8];
 
        if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled)
                return 0;
 
-       if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+       if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                rt5514->dsp_enabled = ucontrol->value.integer.value[0];
 
                if (rt5514->dsp_enabled) {
@@ -342,11 +341,11 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
                                !IS_ERR(rt5514->dsp_calib_clk)) {
                                if (clk_set_rate(rt5514->dsp_calib_clk,
                                        rt5514->pdata.dsp_calib_clk_rate))
-                                       dev_err(codec->dev,
+                                       dev_err(component->dev,
                                                "Can't set rate for mclk");
 
                                if (clk_prepare_enable(rt5514->dsp_calib_clk))
-                                       dev_err(codec->dev,
+                                       dev_err(component->dev,
                                                "Can't enable dsp_calib_clk");
 
                                rt5514_calibration(rt5514, true);
@@ -354,11 +353,11 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
                                msleep(20);
 #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
                                rt5514_spi_burst_read(RT5514_PLL3_CALIB_CTRL6 |
-                                       RT5514_DSP_MAPPING,
-                                       (u8 *)&buf, sizeof(buf));
+                                       RT5514_DSP_MAPPING, buf, sizeof(buf));
 #else
-                               dev_err(codec->dev, "There is no SPI driver for"
+                               dev_err(component->dev, "There is no SPI driver for"
                                        " loading the firmware\n");
+                               memset(buf, 0, sizeof(buf));
 #endif
                                rt5514->pll3_cal_value = buf[0] | buf[1] << 8 |
                                        buf[2] << 16 | buf[3] << 24;
@@ -369,26 +368,26 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
 
                        rt5514_enable_dsp_prepare(rt5514);
 
-                       request_firmware(&fw, RT5514_FIRMWARE1, codec->dev);
+                       request_firmware(&fw, RT5514_FIRMWARE1, component->dev);
                        if (fw) {
 #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
                                rt5514_spi_burst_write(0x4ff60000, fw->data,
                                        ((fw->size/8)+1)*8);
 #else
-                               dev_err(codec->dev, "There is no SPI driver for"
+                               dev_err(component->dev, "There is no SPI driver for"
                                        " loading the firmware\n");
 #endif
                                release_firmware(fw);
                                fw = NULL;
                        }
 
-                       request_firmware(&fw, RT5514_FIRMWARE2, codec->dev);
+                       request_firmware(&fw, RT5514_FIRMWARE2, component->dev);
                        if (fw) {
 #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
                                rt5514_spi_burst_write(0x4ffc0000, fw->data,
                                        ((fw->size/8)+1)*8);
 #else
-                               dev_err(codec->dev, "There is no SPI driver for"
+                               dev_err(component->dev, "There is no SPI driver for"
                                        " loading the firmware\n");
 #endif
                                release_firmware(fw);
@@ -492,7 +491,7 @@ static const struct snd_kcontrol_new rt5514_sto2_dmic_mux =
  * Choose divider parameter that gives the highest possible DMIC frequency in
  * 1MHz - 3MHz range.
  */
-static int rt5514_calc_dmic_clk(struct snd_soc_codec *codec, int rate)
+static int rt5514_calc_dmic_clk(struct snd_soc_component *component, int rate)
 {
        int div[] = {2, 3, 4, 8, 12, 16, 24, 32};
        int i;
@@ -508,20 +507,20 @@ static int rt5514_calc_dmic_clk(struct snd_soc_codec *codec, int rate)
                        return i;
        }
 
-       dev_warn(codec->dev, "Base clock rate %d is too high\n", rate);
+       dev_warn(component->dev, "Base clock rate %d is too high\n", rate);
        return -EINVAL;
 }
 
 static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        int idx;
 
-       idx = rt5514_calc_dmic_clk(codec, rt5514->sysclk);
+       idx = rt5514_calc_dmic_clk(component, rt5514->sysclk);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
                regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL1,
                        RT5514_CLK_DMIC_OUT_SEL_MASK,
@@ -536,8 +535,8 @@ static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 
        if (rt5514->sysclk_src == RT5514_SCLK_S_PLL1)
                return 1;
@@ -548,8 +547,8 @@ static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int rt5514_i2s_use_asrc(struct snd_soc_dapm_widget *source,
        struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
 
        return (rt5514->sysclk > rt5514->lrck * 384);
 }
@@ -751,21 +750,21 @@ static const struct snd_soc_dapm_route rt5514_dapm_routes[] = {
 static int rt5514_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        int pre_div, bclk_ms, frame_size;
        unsigned int val_len = 0;
 
        rt5514->lrck = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5514->sysclk, rt5514->lrck);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting\n");
+               dev_err(component->dev, "Unsupported clock setting\n");
                return -EINVAL;
        }
 
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
 
@@ -808,8 +807,8 @@ static int rt5514_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -862,8 +861,8 @@ static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5514->sysclk && clk_id == rt5514->sysclk_src)
@@ -879,7 +878,7 @@ static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
                break;
 
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
 
@@ -897,13 +896,13 @@ static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5514->pll_in = 0;
                rt5514->pll_out = 0;
@@ -930,17 +929,17 @@ static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                break;
 
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
@@ -961,8 +960,8 @@ static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0, val2 = 0;
 
        if (rx_mask || tx_mask)
@@ -1047,10 +1046,10 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        return 0;
 }
 
-static int rt5514_set_bias_level(struct snd_soc_codec *codec,
+static int rt5514_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1058,7 +1057,7 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
                if (IS_ERR(rt5514->mclk))
                        break;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
                        clk_disable_unprepare(rt5514->mclk);
                } else {
                        ret = clk_prepare_enable(rt5514->mclk);
@@ -1068,7 +1067,7 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /*
                         * If the DSP is enabled in start of recording, the DSP
                         * should be disabled, and sync back to normal recording
@@ -1092,13 +1091,13 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5514_probe(struct snd_soc_codec *codec)
+static int rt5514_probe(struct snd_soc_component *component)
 {
-       struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
-       struct platform_device *pdev = container_of(codec->dev,
+       struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
+       struct platform_device *pdev = container_of(component->dev,
                                                   struct platform_device, dev);
 
-       rt5514->mclk = devm_clk_get(codec->dev, "mclk");
+       rt5514->mclk = devm_clk_get(component->dev, "mclk");
        if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
@@ -1109,7 +1108,7 @@ static int rt5514_probe(struct snd_soc_codec *codec)
                        return -EPROBE_DEFER;
        }
 
-       rt5514->codec = codec;
+       rt5514->component = component;
        rt5514->pll3_cal_value = 0x0078b000;
 
        return 0;
@@ -1162,18 +1161,18 @@ static struct snd_soc_dai_driver rt5514_dai[] = {
        }
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
-       .probe = rt5514_probe,
-       .idle_bias_off = true,
-       .set_bias_level = rt5514_set_bias_level,
-       .component_driver = {
-               .controls               = rt5514_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5514_snd_controls),
-               .dapm_widgets           = rt5514_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5514_dapm_widgets),
-               .dapm_routes            = rt5514_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5514_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5514 = {
+       .probe                  = rt5514_probe,
+       .set_bias_level         = rt5514_set_bias_level,
+       .controls               = rt5514_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5514_snd_controls),
+       .dapm_widgets           = rt5514_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5514_dapm_widgets),
+       .dapm_routes            = rt5514_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5514_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5514_i2c_regmap = {
@@ -1313,17 +1312,11 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
        if (ret != 0)
                dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5514,
+       return devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt5514,
                        rt5514_dai, ARRAY_SIZE(rt5514_dai));
 }
 
-static int rt5514_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static const struct dev_pm_ops rt5514_i2_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume)
 };
@@ -1336,7 +1329,6 @@ static struct i2c_driver rt5514_i2c_driver = {
                .pm = &rt5514_i2_pm_ops,
        },
        .probe = rt5514_i2c_probe,
-       .remove   = rt5514_i2c_remove,
        .id_table = rt5514_i2c_id,
 };
 module_i2c_driver(rt5514_i2c_driver);
index f0f3400ce6b15174dc5037274f372c615f8fa3d5..d1ef0b3f566fcfbe4e3f151890eef004410df29e 100644 (file)
@@ -272,7 +272,7 @@ enum {
 
 struct rt5514_priv {
        struct rt5514_platform_data pdata;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regmap *i2c_regmap, *regmap;
        struct clk *mclk, *dsp_calib_clk;
        int sysclk;
index 0e5f54a9bc7efdf1db73307030310b21472c862c..3dc795f444ce9bb529e2366b091f480bfe0f9345 100644 (file)
@@ -142,7 +142,7 @@ static const struct reg_default rt5616_reg[] = {
 };
 
 struct rt5616_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct delayed_work patch_work;
        struct regmap *regmap;
        struct clk *mclk;
@@ -351,7 +351,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 {
        unsigned int val;
 
-       val = snd_soc_read(snd_soc_dapm_to_codec(source->dapm), RT5616_GLB_CLK);
+       val = snd_soc_component_read32(snd_soc_dapm_to_component(source->dapm), RT5616_GLB_CLK);
        val &= RT5616_SCLK_SRC_MASK;
        if (val == RT5616_SCLK_SRC_PLL1)
                return 1;
@@ -466,16 +466,16 @@ static const struct snd_kcontrol_new rt5616_lout_mix[] = {
 static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
+               snd_soc_component_update_bits(component, RT5616_ADC_DIG_VOL,
                                    RT5616_L_MUTE | RT5616_R_MUTE, 0);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
+               snd_soc_component_update_bits(component, RT5616_ADC_DIG_VOL,
                                    RT5616_L_MUTE | RT5616_R_MUTE,
                                    RT5616_L_MUTE | RT5616_R_MUTE);
                break;
@@ -490,51 +490,51 @@ static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
 static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
                                    struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* depop parameters */
-               snd_soc_update_bits(codec, RT5616_DEPOP_M2,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M2,
                                    RT5616_DEPOP_MASK, RT5616_DEPOP_MAN);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
                                    RT5616_HP_CB_MASK, RT5616_HP_CP_PU |
                                    RT5616_HP_SG_DIS | RT5616_HP_CB_PU);
-               snd_soc_write(codec, RT5616_PR_BASE +
+               snd_soc_component_write(component, RT5616_PR_BASE +
                              RT5616_HP_DCC_INT1, 0x9f00);
                /* headphone amp power on */
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                    RT5616_PWR_FV1 | RT5616_PWR_FV2, 0);
-               snd_soc_update_bits(codec, RT5616_PWR_VOL,
+               snd_soc_component_update_bits(component, RT5616_PWR_VOL,
                                    RT5616_PWR_HV_L | RT5616_PWR_HV_R,
                                    RT5616_PWR_HV_L | RT5616_PWR_HV_R);
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                    RT5616_PWR_HP_L | RT5616_PWR_HP_R |
                                    RT5616_PWR_HA, RT5616_PWR_HP_L |
                                    RT5616_PWR_HP_R | RT5616_PWR_HA);
                msleep(50);
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                    RT5616_PWR_FV1 | RT5616_PWR_FV2,
                                    RT5616_PWR_FV1 | RT5616_PWR_FV2);
 
-               snd_soc_update_bits(codec, RT5616_CHARGE_PUMP,
+               snd_soc_component_update_bits(component, RT5616_CHARGE_PUMP,
                                    RT5616_PM_HP_MASK, RT5616_PM_HP_HV);
-               snd_soc_update_bits(codec, RT5616_PR_BASE +
+               snd_soc_component_update_bits(component, RT5616_PR_BASE +
                                    RT5616_CHOP_DAC_ADC, 0x0200, 0x0200);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_HP_CO_MASK | RT5616_HP_SG_MASK,
                                    RT5616_HP_CO_EN | RT5616_HP_SG_EN);
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5616_PR_BASE +
+               snd_soc_component_update_bits(component, RT5616_PR_BASE +
                                    RT5616_CHOP_DAC_ADC, 0x0200, 0x0);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
                                    RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
                                    RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
                /* headphone amp power down */
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_SMT_TRIG_MASK |
                                    RT5616_HP_CD_PD_MASK | RT5616_HP_CO_MASK |
                                    RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
@@ -542,7 +542,7 @@ static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
                                    RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN |
                                    RT5616_HP_CO_DIS | RT5616_HP_CP_PD |
                                    RT5616_HP_SG_EN | RT5616_HP_CB_PD);
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                    RT5616_PWR_HP_L | RT5616_PWR_HP_R |
                                    RT5616_PWR_HA, 0);
                break;
@@ -556,61 +556,61 @@ static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
 static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* headphone unmute sequence */
-               snd_soc_update_bits(codec, RT5616_DEPOP_M3,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M3,
                                    RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
                                    RT5616_CP_FQ3_MASK,
                                    RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT |
                                    RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT |
                                    RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT);
-               snd_soc_write(codec, RT5616_PR_BASE +
+               snd_soc_component_write(component, RT5616_PR_BASE +
                              RT5616_MAMP_INT_REG2, 0xfc00);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_RSTN_MASK, RT5616_RSTN_EN);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK |
                                    RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS |
                                    RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
-               snd_soc_update_bits(codec, RT5616_HP_VOL,
+               snd_soc_component_update_bits(component, RT5616_HP_VOL,
                                    RT5616_L_MUTE | RT5616_R_MUTE, 0);
                msleep(100);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
                                    RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
                                    RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
                msleep(20);
-               snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
+               snd_soc_component_update_bits(component, RT5616_HP_CALIB_AMP_DET,
                                    RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
                /* headphone mute sequence */
-               snd_soc_update_bits(codec, RT5616_DEPOP_M3,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M3,
                                    RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
                                    RT5616_CP_FQ3_MASK,
                                    RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT |
                                    RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT |
                                    RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT);
-               snd_soc_write(codec, RT5616_PR_BASE +
+               snd_soc_component_write(component, RT5616_PR_BASE +
                              RT5616_MAMP_INT_REG2, 0xfc00);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_HP_SG_MASK, RT5616_HP_SG_EN);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_RSTP_MASK, RT5616_RSTP_EN);
-               snd_soc_update_bits(codec, RT5616_DEPOP_M1,
+               snd_soc_component_update_bits(component, RT5616_DEPOP_M1,
                                    RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK |
                                    RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS |
                                    RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
-               snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
+               snd_soc_component_update_bits(component, RT5616_HP_CALIB_AMP_DET,
                                    RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS);
                msleep(90);
-               snd_soc_update_bits(codec, RT5616_HP_VOL,
+               snd_soc_component_update_bits(component, RT5616_HP_VOL,
                                    RT5616_L_MUTE | RT5616_R_MUTE,
                                    RT5616_L_MUTE | RT5616_R_MUTE);
                msleep(30);
@@ -626,21 +626,21 @@ static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                    RT5616_PWR_LM, RT5616_PWR_LM);
-               snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
+               snd_soc_component_update_bits(component, RT5616_LOUT_CTRL1,
                                    RT5616_L_MUTE | RT5616_R_MUTE, 0);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
+               snd_soc_component_update_bits(component, RT5616_LOUT_CTRL1,
                                    RT5616_L_MUTE | RT5616_R_MUTE,
                                    RT5616_L_MUTE | RT5616_R_MUTE);
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                    RT5616_PWR_LM, 0);
                break;
 
@@ -654,16 +654,16 @@ static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
 static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
                                    RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
                                    RT5616_PWR_BST1_OP2, 0);
                break;
 
@@ -677,16 +677,16 @@ static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5616_bst2_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
                                    RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5616_PWR_ANLG2,
                                    RT5616_PWR_BST2_OP2, 0);
                break;
 
@@ -960,8 +960,8 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int pre_div, bclk_ms, frame_size;
 
@@ -970,12 +970,12 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream,
        pre_div = rl6231_get_clk_info(rt5616->sysclk, rt5616->lrck[dai->id]);
 
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting\n");
+               dev_err(component->dev, "Unsupported clock setting\n");
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
        bclk_ms = frame_size > 32 ? 1 : 0;
@@ -1004,17 +1004,17 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream,
 
        mask_clk = RT5616_I2S_PD1_MASK;
        val_clk = pre_div << RT5616_I2S_PD1_SFT;
-       snd_soc_update_bits(codec, RT5616_I2S1_SDP,
+       snd_soc_component_update_bits(component, RT5616_I2S1_SDP,
                            RT5616_I2S_DL_MASK, val_len);
-       snd_soc_update_bits(codec, RT5616_ADDA_CLK1, mask_clk, val_clk);
+       snd_soc_component_update_bits(component, RT5616_ADDA_CLK1, mask_clk, val_clk);
 
        return 0;
 }
 
 static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1055,7 +1055,7 @@ static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5616_I2S1_SDP,
+       snd_soc_component_update_bits(component, RT5616_I2S1_SDP,
                            RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK |
                            RT5616_I2S_DF_MASK, reg_val);
 
@@ -1065,8 +1065,8 @@ static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5616->sysclk && clk_id == rt5616->sysclk_src)
@@ -1080,11 +1080,11 @@ static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
                reg_val |= RT5616_SCLK_SRC_PLL1;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5616_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5616_GLB_CLK,
                            RT5616_SCLK_SRC_MASK, reg_val);
        rt5616->sysclk = freq;
        rt5616->sysclk_src = clk_id;
@@ -1097,8 +1097,8 @@ static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                              unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -1107,11 +1107,11 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5616->pll_in = 0;
                rt5616->pll_out = 0;
-               snd_soc_update_bits(codec, RT5616_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5616_GLB_CLK,
                                    RT5616_SCLK_SRC_MASK,
                                    RT5616_SCLK_SRC_MCLK);
                return 0;
@@ -1119,34 +1119,34 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 
        switch (source) {
        case RT5616_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5616_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5616_GLB_CLK,
                                    RT5616_PLL1_SRC_MASK,
                                    RT5616_PLL1_SRC_MCLK);
                break;
        case RT5616_PLL1_S_BCLK1:
        case RT5616_PLL1_S_BCLK2:
-               snd_soc_update_bits(codec, RT5616_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5616_GLB_CLK,
                                    RT5616_PLL1_SRC_MASK,
                                    RT5616_PLL1_SRC_BCLK1);
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5616_PLL_CTRL1,
+       snd_soc_component_write(component, RT5616_PLL_CTRL1,
                      pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5616_PLL_CTRL2,
+       snd_soc_component_write(component, RT5616_PLL_CTRL2,
                      (pll_code.m_bp ? 0 : pll_code.m_code) <<
                      RT5616_PLL_M_SFT |
                      pll_code.m_bp << RT5616_PLL_M_BP_SFT);
@@ -1158,10 +1158,10 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
        return 0;
 }
 
-static int rt5616_set_bias_level(struct snd_soc_codec *codec,
+static int rt5616_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1180,7 +1180,7 @@ static int rt5616_set_bias_level(struct snd_soc_codec *codec,
                if (IS_ERR(rt5616->mclk))
                        break;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
                        clk_disable_unprepare(rt5616->mclk);
                } else {
                        ret = clk_prepare_enable(rt5616->mclk);
@@ -1190,30 +1190,30 @@ static int rt5616_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                            RT5616_PWR_VREF1 | RT5616_PWR_MB |
                                            RT5616_PWR_BG | RT5616_PWR_VREF2,
                                            RT5616_PWR_VREF1 | RT5616_PWR_MB |
                                            RT5616_PWR_BG | RT5616_PWR_VREF2);
                        mdelay(10);
-                       snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5616_PWR_ANLG1,
                                            RT5616_PWR_FV1 | RT5616_PWR_FV2,
                                            RT5616_PWR_FV1 | RT5616_PWR_FV2);
-                       snd_soc_update_bits(codec, RT5616_D_MISC,
+                       snd_soc_component_update_bits(component, RT5616_D_MISC,
                                            RT5616_D_GATE_EN,
                                            RT5616_D_GATE_EN);
                }
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, RT5616_D_MISC, RT5616_D_GATE_EN, 0);
-               snd_soc_write(codec, RT5616_PWR_DIG1, 0x0000);
-               snd_soc_write(codec, RT5616_PWR_DIG2, 0x0000);
-               snd_soc_write(codec, RT5616_PWR_VOL, 0x0000);
-               snd_soc_write(codec, RT5616_PWR_MIXER, 0x0000);
-               snd_soc_write(codec, RT5616_PWR_ANLG1, 0x0000);
-               snd_soc_write(codec, RT5616_PWR_ANLG2, 0x0000);
+               snd_soc_component_update_bits(component, RT5616_D_MISC, RT5616_D_GATE_EN, 0);
+               snd_soc_component_write(component, RT5616_PWR_DIG1, 0x0000);
+               snd_soc_component_write(component, RT5616_PWR_DIG2, 0x0000);
+               snd_soc_component_write(component, RT5616_PWR_VOL, 0x0000);
+               snd_soc_component_write(component, RT5616_PWR_MIXER, 0x0000);
+               snd_soc_component_write(component, RT5616_PWR_ANLG1, 0x0000);
+               snd_soc_component_write(component, RT5616_PWR_ANLG2, 0x0000);
                break;
 
        default:
@@ -1223,24 +1223,24 @@ static int rt5616_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5616_probe(struct snd_soc_codec *codec)
+static int rt5616_probe(struct snd_soc_component *component)
 {
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 
        /* Check if MCLK provided */
-       rt5616->mclk = devm_clk_get(codec->dev, "mclk");
+       rt5616->mclk = devm_clk_get(component->dev, "mclk");
        if (PTR_ERR(rt5616->mclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
-       rt5616->codec = codec;
+       rt5616->component = component;
 
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5616_suspend(struct snd_soc_codec *codec)
+static int rt5616_suspend(struct snd_soc_component *component)
 {
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5616->regmap, true);
        regcache_mark_dirty(rt5616->regmap);
@@ -1248,9 +1248,9 @@ static int rt5616_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5616_resume(struct snd_soc_codec *codec)
+static int rt5616_resume(struct snd_soc_component *component)
 {
-       struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
+       struct rt5616_priv *rt5616 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5616->regmap, false);
        regcache_sync(rt5616->regmap);
@@ -1294,20 +1294,20 @@ static struct snd_soc_dai_driver rt5616_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5616 = {
-       .probe = rt5616_probe,
-       .suspend = rt5616_suspend,
-       .resume = rt5616_resume,
-       .set_bias_level = rt5616_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5616_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5616_snd_controls),
-               .dapm_widgets           = rt5616_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5616_dapm_widgets),
-               .dapm_routes            = rt5616_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5616_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5616 = {
+       .probe                  = rt5616_probe,
+       .suspend                = rt5616_suspend,
+       .resume                 = rt5616_resume,
+       .set_bias_level         = rt5616_set_bias_level,
+       .controls               = rt5616_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5616_snd_controls),
+       .dapm_widgets           = rt5616_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5616_dapm_widgets),
+       .dapm_routes            = rt5616_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5616_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5616_regmap = {
@@ -1387,14 +1387,13 @@ static int rt5616_i2c_probe(struct i2c_client *i2c,
        regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
                           RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V);
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5616,
+       return devm_snd_soc_register_component(&i2c->dev,
+                                     &soc_component_dev_rt5616,
                                      rt5616_dai, ARRAY_SIZE(rt5616_dai));
 }
 
 static int rt5616_i2c_remove(struct i2c_client *i2c)
 {
-       snd_soc_unregister_codec(&i2c->dev);
-
        return 0;
 }
 
index 55b04c55fb4b37b91f5e890e1daad3b8a9b4eee3..cf6dce69eb2ad0bfe22c43236f80ffc228a9be46 100644 (file)
@@ -71,30 +71,30 @@ static const struct reg_default rt5631_reg[] = {
 /**
  * rt5631_write_index - write index register of 2nd layer
  */
-static void rt5631_write_index(struct snd_soc_codec *codec,
+static void rt5631_write_index(struct snd_soc_component *component,
                unsigned int reg, unsigned int value)
 {
-       snd_soc_write(codec, RT5631_INDEX_ADD, reg);
-       snd_soc_write(codec, RT5631_INDEX_DATA, value);
+       snd_soc_component_write(component, RT5631_INDEX_ADD, reg);
+       snd_soc_component_write(component, RT5631_INDEX_DATA, value);
 }
 
 /**
  * rt5631_read_index - read index register of 2nd layer
  */
-static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
+static unsigned int rt5631_read_index(struct snd_soc_component *component,
                                unsigned int reg)
 {
        unsigned int value;
 
-       snd_soc_write(codec, RT5631_INDEX_ADD, reg);
-       value = snd_soc_read(codec, RT5631_INDEX_DATA);
+       snd_soc_component_write(component, RT5631_INDEX_ADD, reg);
+       value = snd_soc_component_read32(component, RT5631_INDEX_DATA);
 
        return value;
 }
 
-static int rt5631_reset(struct snd_soc_codec *codec)
+static int rt5631_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, RT5631_RESET, 0);
+       return snd_soc_component_write(component, RT5631_RESET, 0);
 }
 
 static bool rt5631_volatile_register(struct device *dev, unsigned int reg)
@@ -187,8 +187,8 @@ static const DECLARE_TLV_DB_RANGE(mic_bst_tlv,
 static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = rt5631->dmic_used_flag;
 
@@ -198,8 +198,8 @@ static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
 static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
        rt5631->dmic_used_flag = ucontrol->value.integer.value[0];
        return 0;
@@ -286,78 +286,78 @@ static const struct snd_kcontrol_new rt5631_snd_controls[] = {
 static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_GLOBAL_CLK_CTRL);
+       reg = snd_soc_component_read32(component, RT5631_GLOBAL_CLK_CTRL);
        return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
 }
 
 static int check_dmic_used(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
        return rt5631->dmic_used_flag;
 }
 
 static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_OUTMIXER_L_CTRL);
+       reg = snd_soc_component_read32(component, RT5631_OUTMIXER_L_CTRL);
        return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
 }
 
 static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_OUTMIXER_R_CTRL);
+       reg = snd_soc_component_read32(component, RT5631_OUTMIXER_R_CTRL);
        return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
 }
 
 static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL);
+       reg = snd_soc_component_read32(component, RT5631_SPK_MIXER_CTRL);
        return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
 }
 
 static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL);
+       reg = snd_soc_component_read32(component, RT5631_SPK_MIXER_CTRL);
        return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
 }
 
 static int check_adcl_select(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER);
+       reg = snd_soc_component_read32(component, RT5631_ADC_REC_MIXER);
        return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
 }
 
 static int check_adcr_select(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg;
 
-       reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER);
+       reg = snd_soc_component_read32(component, RT5631_ADC_REC_MIXER);
        return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
 }
 
@@ -367,36 +367,36 @@ static int check_adcr_select(struct snd_soc_dapm_widget *source,
  *
  * When power on/off headphone, the depop sequence is done by hardware.
  */
-static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
+static void onebit_depop_power_stage(struct snd_soc_component *component, int enable)
 {
        unsigned int soft_vol, hp_zc;
 
        /* enable one-bit depop function */
-       snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+       snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
                                RT5631_EN_ONE_BIT_DEPOP, 0);
 
        /* keep soft volume and zero crossing setting */
-       soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-       hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+       soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+       hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
        if (enable) {
                /* config one-bit depop parameter */
-               rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
-               rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
-               rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
+               rt5631_write_index(component, RT5631_TEST_MODE_CTRL, 0x84c0);
+               rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x309f);
+               rt5631_write_index(component, RT5631_CP_INTL_REG2, 0x6530);
                /* power on capless block */
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2,
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_2,
                                RT5631_EN_CAP_FREE_DEPOP);
        } else {
                /* power off capless block */
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_2, 0);
                msleep(100);
        }
 
        /* recover soft volume and zero crossing setting */
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 /**
@@ -405,36 +405,36 @@ static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
  *
  * When mute/unmute headphone, the depop sequence is done by hardware.
  */
-static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
+static void onebit_depop_mute_stage(struct snd_soc_component *component, int enable)
 {
        unsigned int soft_vol, hp_zc;
 
        /* enable one-bit depop function */
-       snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+       snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
                                RT5631_EN_ONE_BIT_DEPOP, 0);
 
        /* keep soft volume and zero crossing setting */
-       soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-       hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+       soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+       hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
        if (enable) {
                schedule_timeout_uninterruptible(msecs_to_jiffies(10));
                /* config one-bit depop parameter */
-               rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
-               snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+               rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x307f);
+               snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
                                RT5631_L_MUTE | RT5631_R_MUTE, 0);
                msleep(300);
        } else {
-               snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+               snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
                        RT5631_L_MUTE | RT5631_R_MUTE,
                        RT5631_L_MUTE | RT5631_R_MUTE);
                msleep(100);
        }
 
        /* recover soft volume and zero crossing setting */
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 /**
@@ -443,70 +443,70 @@ static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
  *
  * When power on/off headphone, the depop sequence is done in step by step.
  */
-static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
+static void depop_seq_power_stage(struct snd_soc_component *component, int enable)
 {
        unsigned int soft_vol, hp_zc;
 
        /* depop control by register */
-       snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+       snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
                RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
 
        /* keep soft volume and zero crossing setting */
-       soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-       hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+       soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+       hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
        if (enable) {
                /* config depop sequence parameter */
-               rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
+               rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x303e);
 
                /* power on headphone and charge pump */
-               snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+               snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                        RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
                        RT5631_PWR_HP_R_AMP,
                        RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
                        RT5631_PWR_HP_R_AMP);
 
                /* power on soft generator and depop mode2 */
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP);
                msleep(100);
 
                /* stop depop mode */
-               snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+               snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                        RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS);
        } else {
                /* config depop sequence parameter */
-               rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x303F);
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
                        RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
                msleep(75);
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP |
                        RT5631_PD_HPAMP_R_ST_UP);
 
                /* start depop mode */
-               snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+               snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                                RT5631_PWR_HP_DEPOP_DIS, 0);
 
                /* config depop sequence parameter */
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP |
                        RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
                msleep(80);
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN);
 
                /* power down headphone and charge pump */
-               snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+               snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                        RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
                        RT5631_PWR_HP_R_AMP, 0);
        }
 
        /* recover soft volume and zero crossing setting */
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 /**
@@ -515,75 +515,75 @@ static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
  *
  * When mute/unmute headphone, the depop sequence is done in step by step.
  */
-static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
+static void depop_seq_mute_stage(struct snd_soc_component *component, int enable)
 {
        unsigned int soft_vol, hp_zc;
 
        /* depop control by register */
-       snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+       snd_soc_component_update_bits(component, RT5631_DEPOP_FUN_CTRL_2,
                RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
 
        /* keep soft volume and zero crossing setting */
-       soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
-       hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+       soft_vol = snd_soc_component_read32(component, RT5631_SOFT_VOL_CTRL);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, 0);
+       hp_zc = snd_soc_component_read32(component, RT5631_INT_ST_IRQ_CTRL_2);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
        if (enable) {
                schedule_timeout_uninterruptible(msecs_to_jiffies(10));
 
                /* config depop sequence parameter */
-               rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x302f);
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
                        RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
                        RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
 
-               snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+               snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
                                RT5631_L_MUTE | RT5631_R_MUTE, 0);
                msleep(160);
        } else {
                /* config depop sequence parameter */
-               rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
-               snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+               rt5631_write_index(component, RT5631_SPK_INTL_CTRL, 0x302f);
+               snd_soc_component_write(component, RT5631_DEPOP_FUN_CTRL_1,
                        RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
                        RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
                        RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
 
-               snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+               snd_soc_component_update_bits(component, RT5631_HP_OUT_VOL,
                        RT5631_L_MUTE | RT5631_R_MUTE,
                        RT5631_L_MUTE | RT5631_R_MUTE);
                msleep(150);
        }
 
        /* recover soft volume and zero crossing setting */
-       snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
+       snd_soc_component_write(component, RT5631_SOFT_VOL_CTRL, soft_vol);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
 }
 
 static int hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMD:
                if (rt5631->codec_version) {
-                       onebit_depop_mute_stage(codec, 0);
-                       onebit_depop_power_stage(codec, 0);
+                       onebit_depop_mute_stage(component, 0);
+                       onebit_depop_power_stage(component, 0);
                } else {
-                       depop_seq_mute_stage(codec, 0);
-                       depop_seq_power_stage(codec, 0);
+                       depop_seq_mute_stage(component, 0);
+                       depop_seq_power_stage(component, 0);
                }
                break;
 
        case SND_SOC_DAPM_POST_PMU:
                if (rt5631->codec_version) {
-                       onebit_depop_power_stage(codec, 1);
-                       onebit_depop_mute_stage(codec, 1);
+                       onebit_depop_power_stage(component, 1);
+                       onebit_depop_mute_stage(component, 1);
                } else {
-                       depop_seq_power_stage(codec, 1);
-                       depop_seq_mute_stage(codec, 1);
+                       depop_seq_power_stage(component, 1);
+                       depop_seq_mute_stage(component, 1);
                }
                break;
 
@@ -597,20 +597,20 @@ static int hp_event(struct snd_soc_dapm_widget *w,
 static int set_dmic_params(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
        switch (rt5631->rx_rate) {
        case 44100:
        case 48000:
-               snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+               snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
                        RT5631_DMIC_CLK_CTRL_MASK,
                        RT5631_DMIC_CLK_CTRL_TO_32FS);
                break;
 
        case 32000:
        case 22050:
-               snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+               snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
                        RT5631_DMIC_CLK_CTRL_MASK,
                        RT5631_DMIC_CLK_CTRL_TO_64FS);
                break;
@@ -618,7 +618,7 @@ static int set_dmic_params(struct snd_soc_dapm_widget *w,
        case 16000:
        case 11025:
        case 8000:
-               snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+               snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
                        RT5631_DMIC_CLK_CTRL_MASK,
                        RT5631_DMIC_CLK_CTRL_TO_128FS);
                break;
@@ -1352,16 +1352,16 @@ static int get_coeff(int mclk, int rate, int timesofbclk)
 static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
        int timesofbclk = 32, coeff;
        unsigned int iface = 0;
 
-       dev_dbg(codec->dev, "enter %s\n", __func__);
+       dev_dbg(component->dev, "enter %s\n", __func__);
 
        rt5631->bclk_rate = snd_soc_params_to_bclk(params);
        if (rt5631->bclk_rate < 0) {
-               dev_err(codec->dev, "Fail to get BCLK rate\n");
+               dev_err(component->dev, "Fail to get BCLK rate\n");
                return rt5631->bclk_rate;
        }
        rt5631->rx_rate = params_rate(params);
@@ -1373,7 +1373,7 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
                coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
                                        timesofbclk);
        if (coeff < 0) {
-               dev_err(codec->dev, "Fail to get coeff\n");
+               dev_err(component->dev, "Fail to get coeff\n");
                return coeff;
        }
 
@@ -1393,9 +1393,9 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5631_SDP_CTRL,
+       snd_soc_component_update_bits(component, RT5631_SDP_CTRL,
                RT5631_SDP_I2S_DL_MASK, iface);
-       snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
+       snd_soc_component_write(component, RT5631_STEREO_AD_DA_CLK_CTRL,
                                        coeff_div[coeff].reg_val);
 
        return 0;
@@ -1404,11 +1404,11 @@ static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
 static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
                                                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
        unsigned int iface = 0;
 
-       dev_dbg(codec->dev, "enter %s\n", __func__);
+       dev_dbg(component->dev, "enter %s\n", __func__);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -1448,7 +1448,7 @@ static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, RT5631_SDP_CTRL, iface);
+       snd_soc_component_write(component, RT5631_SDP_CTRL, iface);
 
        return 0;
 }
@@ -1456,10 +1456,10 @@ static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq);
+       dev_dbg(component->dev, "enter %s, syclk=%d\n", __func__, freq);
 
        if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
                rt5631->sysclk = freq;
@@ -1472,16 +1472,16 @@ static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
        int i, ret = -EINVAL;
 
-       dev_dbg(codec->dev, "enter %s\n", __func__);
+       dev_dbg(component->dev, "enter %s\n", __func__);
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
-               snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL,
+               snd_soc_component_update_bits(component, RT5631_GLOBAL_CLK_CTRL,
                        RT5631_SYSCLK_SOUR_SEL_MASK,
                        RT5631_SYSCLK_SOUR_SEL_MCLK);
 
@@ -1492,13 +1492,13 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
                        if (freq_in == codec_master_pll_div[i].pll_in &&
                        freq_out == codec_master_pll_div[i].pll_out) {
-                               dev_info(codec->dev,
+                               dev_info(component->dev,
                                        "change PLL in master mode\n");
-                               snd_soc_write(codec, RT5631_PLL_CTRL,
+                               snd_soc_component_write(component, RT5631_PLL_CTRL,
                                        codec_master_pll_div[i].reg_val);
                                schedule_timeout_uninterruptible(
                                        msecs_to_jiffies(20));
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        RT5631_GLOBAL_CLK_CTRL,
                                        RT5631_SYSCLK_SOUR_SEL_MASK |
                                        RT5631_PLLCLK_SOUR_SEL_MASK,
@@ -1511,13 +1511,13 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
                        if (freq_in == codec_slave_pll_div[i].pll_in &&
                        freq_out == codec_slave_pll_div[i].pll_out) {
-                               dev_info(codec->dev,
+                               dev_info(component->dev,
                                        "change PLL in slave mode\n");
-                               snd_soc_write(codec, RT5631_PLL_CTRL,
+                               snd_soc_component_write(component, RT5631_PLL_CTRL,
                                        codec_slave_pll_div[i].reg_val);
                                schedule_timeout_uninterruptible(
                                        msecs_to_jiffies(20));
-                               snd_soc_update_bits(codec,
+                               snd_soc_component_update_bits(component,
                                        RT5631_GLOBAL_CLK_CTRL,
                                        RT5631_SYSCLK_SOUR_SEL_MASK |
                                        RT5631_PLLCLK_SOUR_SEL_MASK,
@@ -1531,26 +1531,26 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        return ret;
 }
 
-static int rt5631_set_bias_level(struct snd_soc_codec *codec,
+static int rt5631_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2,
+               snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD2,
                        RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL,
                        RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL);
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                                RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
                                RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
                        msleep(80);
-                       snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+                       snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                                RT5631_PWR_FAST_VREF_CTRL,
                                RT5631_PWR_FAST_VREF_CTRL);
                        regcache_cache_only(rt5631->regmap, false);
@@ -1559,10 +1559,10 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
-               snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
-               snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
-               snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
+               snd_soc_component_write(component, RT5631_PWR_MANAG_ADD1, 0x0000);
+               snd_soc_component_write(component, RT5631_PWR_MANAG_ADD2, 0x0000);
+               snd_soc_component_write(component, RT5631_PWR_MANAG_ADD3, 0x0000);
+               snd_soc_component_write(component, RT5631_PWR_MANAG_ADD4, 0x0000);
                break;
 
        default:
@@ -1572,48 +1572,48 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5631_probe(struct snd_soc_codec *codec)
+static int rt5631_probe(struct snd_soc_component *component)
 {
-       struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+       struct rt5631_priv *rt5631 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
-       val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
+       val = rt5631_read_index(component, RT5631_ADDA_MIXER_INTL_REG3);
        if (val & 0x0002)
                rt5631->codec_version = 1;
        else
                rt5631->codec_version = 0;
 
-       rt5631_reset(codec);
-       snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+       rt5631_reset(component);
+       snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
                RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
        msleep(80);
-       snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+       snd_soc_component_update_bits(component, RT5631_PWR_MANAG_ADD3,
                RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL);
        /* enable HP zero cross */
-       snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
+       snd_soc_component_write(component, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
        /* power off ClassD auto Recovery */
        if (rt5631->codec_version)
-               snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
+               snd_soc_component_update_bits(component, RT5631_INT_ST_IRQ_CTRL_2,
                                        0x2000, 0x2000);
        else
-               snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
+               snd_soc_component_update_bits(component, RT5631_INT_ST_IRQ_CTRL_2,
                                        0x2000, 0);
        /* DMIC */
        if (rt5631->dmic_used_flag) {
-               snd_soc_update_bits(codec, RT5631_GPIO_CTRL,
+               snd_soc_component_update_bits(component, RT5631_GPIO_CTRL,
                        RT5631_GPIO_PIN_FUN_SEL_MASK |
                        RT5631_GPIO_DMIC_FUN_SEL_MASK,
                        RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC |
                        RT5631_GPIO_DMIC_FUN_SEL_DIMC);
-               snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+               snd_soc_component_update_bits(component, RT5631_DIG_MIC_CTRL,
                        RT5631_DMIC_L_CH_LATCH_MASK |
                        RT5631_DMIC_R_CH_LATCH_MASK,
                        RT5631_DMIC_L_CH_LATCH_FALLING |
                        RT5631_DMIC_R_CH_LATCH_RISING);
        }
 
-       snd_soc_codec_init_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_init_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        return 0;
 }
@@ -1653,18 +1653,20 @@ static struct snd_soc_dai_driver rt5631_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
-       .probe = rt5631_probe,
-       .set_bias_level = rt5631_set_bias_level,
-       .suspend_bias_off = true,
-       .component_driver = {
-               .controls               = rt5631_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5631_snd_controls),
-               .dapm_widgets           = rt5631_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5631_dapm_widgets),
-               .dapm_routes            = rt5631_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5631_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5631 = {
+       .probe                  = rt5631_probe,
+       .set_bias_level         = rt5631_set_bias_level,
+       .controls               = rt5631_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5631_snd_controls),
+       .dapm_widgets           = rt5631_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5631_dapm_widgets),
+       .dapm_routes            = rt5631_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5631_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct i2c_device_id rt5631_i2c_id[] = {
@@ -1712,14 +1714,14 @@ static int rt5631_i2c_probe(struct i2c_client *i2c,
        if (IS_ERR(rt5631->regmap))
                return PTR_ERR(rt5631->regmap);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt5631,
                        rt5631_dai, ARRAY_SIZE(rt5631_dai));
        return ret;
 }
 
 static int rt5631_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index 438fe52a12dfb50472437ca1204c7a2b1748ba34..05567426f2119cb26bc06f480c245e87dbab21f8 100644 (file)
@@ -166,9 +166,9 @@ static const struct reg_default rt5640_reg[] = {
        { 0xff, 0x6231 },
 };
 
-static int rt5640_reset(struct snd_soc_codec *codec)
+static int rt5640_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, RT5640_RESET, 0);
+       return snd_soc_component_write(component, RT5640_RESET, 0);
 }
 
 static bool rt5640_volatile_register(struct device *dev, unsigned int reg)
@@ -461,17 +461,17 @@ static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        int idx, rate;
 
        rate = rt5640->sysclk / rl6231_get_pre_div(rt5640->regmap,
                RT5640_ADDA_CLK1, RT5640_I2S_PD1_SFT);
        idx = rl6231_calc_dmic_clk(rate);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
-               snd_soc_update_bits(codec, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
+               snd_soc_component_update_bits(component, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
                                        idx << RT5640_DMIC_CLK_SFT);
        return idx;
 }
@@ -479,10 +479,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int val;
 
-       val = snd_soc_read(codec, RT5640_GLB_CLK);
+       val = snd_soc_component_read32(component, RT5640_GLB_CLK);
        val &= RT5640_SCLK_SRC_MASK;
        if (val == RT5640_SCLK_SRC_PLL1)
                return 1;
@@ -493,8 +493,8 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        if (!rt5640->asrc_en)
                return 0;
@@ -930,9 +930,9 @@ static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP,
 static const struct snd_kcontrol_new rt5640_sdi_mux =
        SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
 
-static void hp_amp_power_on(struct snd_soc_codec *codec)
+static void hp_amp_power_on(struct snd_soc_component *component)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        /* depop parameters */
        regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
@@ -956,9 +956,9 @@ static void hp_amp_power_on(struct snd_soc_codec *codec)
                RT5640_PWR_FV1 | RT5640_PWR_FV2);
 }
 
-static void rt5640_pmu_depop(struct snd_soc_codec *codec)
+static void rt5640_pmu_depop(struct snd_soc_component *component)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
                RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK,
@@ -984,12 +984,12 @@ static void rt5640_pmu_depop(struct snd_soc_codec *codec)
 static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               rt5640_pmu_depop(codec);
+               rt5640_pmu_depop(component);
                rt5640->hp_mute = 0;
                break;
 
@@ -1008,22 +1008,22 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5640_lout_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               hp_amp_power_on(codec);
-               snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+               hp_amp_power_on(component);
+               snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
                        RT5640_PWR_LM, RT5640_PWR_LM);
-               snd_soc_update_bits(codec, RT5640_OUTPUT,
+               snd_soc_component_update_bits(component, RT5640_OUTPUT,
                        RT5640_L_MUTE | RT5640_R_MUTE, 0);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5640_OUTPUT,
+               snd_soc_component_update_bits(component, RT5640_OUTPUT,
                        RT5640_L_MUTE | RT5640_R_MUTE,
                        RT5640_L_MUTE | RT5640_R_MUTE);
-               snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
                        RT5640_PWR_LM, 0);
                break;
 
@@ -1037,11 +1037,11 @@ static int rt5640_lout_event(struct snd_soc_dapm_widget *w,
 static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               hp_amp_power_on(codec);
+               hp_amp_power_on(component);
                break;
        default:
                return 0;
@@ -1053,8 +1053,8 @@ static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
 static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -1671,14 +1671,14 @@ static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = {
        {"IF2 DAC R", NULL, "DAC R2 Power"},
 };
 
-static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
+static int get_sdp_info(struct snd_soc_component *component, int dai_id)
 {
        int ret = 0, val;
 
-       if (codec == NULL)
+       if (component == NULL)
                return -EINVAL;
 
-       val = snd_soc_read(codec, RT5640_I2S1_SDP);
+       val = snd_soc_component_read32(component, RT5640_I2S1_SDP);
        val = (val & RT5640_I2S_IF_MASK) >> RT5640_I2S_IF_SFT;
        switch (dai_id) {
        case RT5640_AIF1:
@@ -1722,21 +1722,21 @@ static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
 static int rt5640_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int dai_sel, pre_div, bclk_ms, frame_size;
 
        rt5640->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+               dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
                        rt5640->lrck[dai->id], dai->id);
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return frame_size;
        }
        if (frame_size > 32)
@@ -1766,26 +1766,26 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       dai_sel = get_sdp_info(codec, dai->id);
+       dai_sel = get_sdp_info(component, dai->id);
        if (dai_sel < 0) {
-               dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
+               dev_err(component->dev, "Failed to get sdp info: %d\n", dai_sel);
                return -EINVAL;
        }
        if (dai_sel & RT5640_U_IF1) {
                mask_clk = RT5640_I2S_BCLK_MS1_MASK | RT5640_I2S_PD1_MASK;
                val_clk = bclk_ms << RT5640_I2S_BCLK_MS1_SFT |
                        pre_div << RT5640_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5640_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5640_I2S1_SDP,
                        RT5640_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5640_ADDA_CLK1, mask_clk, val_clk);
        }
        if (dai_sel & RT5640_U_IF2) {
                mask_clk = RT5640_I2S_BCLK_MS2_MASK | RT5640_I2S_PD2_MASK;
                val_clk = bclk_ms << RT5640_I2S_BCLK_MS2_SFT |
                        pre_div << RT5640_I2S_PD2_SFT;
-               snd_soc_update_bits(codec, RT5640_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5640_I2S2_SDP,
                        RT5640_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5640_ADDA_CLK1, mask_clk, val_clk);
        }
 
        return 0;
@@ -1793,8 +1793,8 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
        int dai_sel;
 
@@ -1836,18 +1836,18 @@ static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       dai_sel = get_sdp_info(codec, dai->id);
+       dai_sel = get_sdp_info(component, dai->id);
        if (dai_sel < 0) {
-               dev_err(codec->dev, "Failed to get sdp info: %d\n", dai_sel);
+               dev_err(component->dev, "Failed to get sdp info: %d\n", dai_sel);
                return -EINVAL;
        }
        if (dai_sel & RT5640_U_IF1) {
-               snd_soc_update_bits(codec, RT5640_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5640_I2S1_SDP,
                        RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
                        RT5640_I2S_DF_MASK, reg_val);
        }
        if (dai_sel & RT5640_U_IF2) {
-               snd_soc_update_bits(codec, RT5640_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5640_I2S2_SDP,
                        RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
                        RT5640_I2S_DF_MASK, reg_val);
        }
@@ -1858,8 +1858,8 @@ static int rt5640_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src)
@@ -1876,10 +1876,10 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
                reg_val |= RT5640_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5640_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5640_GLB_CLK,
                RT5640_SCLK_SRC_MASK, reg_val);
        rt5640->sysclk = freq;
        rt5640->sysclk_src = clk_id;
@@ -1891,8 +1891,8 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -1901,46 +1901,46 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5640->pll_in = 0;
                rt5640->pll_out = 0;
-               snd_soc_update_bits(codec, RT5640_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5640_GLB_CLK,
                        RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5640_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5640_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5640_GLB_CLK,
                        RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK);
                break;
        case RT5640_PLL1_S_BCLK1:
-               snd_soc_update_bits(codec, RT5640_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5640_GLB_CLK,
                        RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1);
                break;
        case RT5640_PLL1_S_BCLK2:
-               snd_soc_update_bits(codec, RT5640_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5640_GLB_CLK,
                        RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2);
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5640_PLL_CTRL1,
+       snd_soc_component_write(component, RT5640_PLL_CTRL1,
                pll_code.n_code << RT5640_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5640_PLL_CTRL2,
+       snd_soc_component_write(component, RT5640_PLL_CTRL2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5640_PLL_M_SFT |
                pll_code.m_bp << RT5640_PLL_M_BP_SFT);
 
@@ -1951,10 +1951,10 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
        return 0;
 }
 
-static int rt5640_set_bias_level(struct snd_soc_codec *codec,
+static int rt5640_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1972,7 +1972,7 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
                if (IS_ERR(rt5640->mclk))
                        break;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
                        clk_disable_unprepare(rt5640->mclk);
                } else {
                        ret = clk_prepare_enable(rt5640->mclk);
@@ -1982,33 +1982,33 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+               if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
                                RT5640_PWR_VREF1 | RT5640_PWR_MB |
                                RT5640_PWR_BG | RT5640_PWR_VREF2,
                                RT5640_PWR_VREF1 | RT5640_PWR_MB |
                                RT5640_PWR_BG | RT5640_PWR_VREF2);
                        usleep_range(10000, 15000);
-                       snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5640_PWR_ANLG1,
                                RT5640_PWR_FV1 | RT5640_PWR_FV2,
                                RT5640_PWR_FV1 | RT5640_PWR_FV2);
-                       snd_soc_update_bits(codec, RT5640_DUMMY1,
+                       snd_soc_component_update_bits(component, RT5640_DUMMY1,
                                                0x0301, 0x0301);
-                       snd_soc_update_bits(codec, RT5640_MICBIAS,
+                       snd_soc_component_update_bits(component, RT5640_MICBIAS,
                                                0x0030, 0x0030);
                }
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, RT5640_DEPOP_M1, 0x0004);
-               snd_soc_write(codec, RT5640_DEPOP_M2, 0x1100);
-               snd_soc_update_bits(codec, RT5640_DUMMY1, 0x1, 0);
-               snd_soc_write(codec, RT5640_PWR_DIG1, 0x0000);
-               snd_soc_write(codec, RT5640_PWR_DIG2, 0x0000);
-               snd_soc_write(codec, RT5640_PWR_VOL, 0x0000);
-               snd_soc_write(codec, RT5640_PWR_MIXER, 0x0000);
-               snd_soc_write(codec, RT5640_PWR_ANLG1, 0x0000);
-               snd_soc_write(codec, RT5640_PWR_ANLG2, 0x0000);
+               snd_soc_component_write(component, RT5640_DEPOP_M1, 0x0004);
+               snd_soc_component_write(component, RT5640_DEPOP_M2, 0x1100);
+               snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x1, 0);
+               snd_soc_component_write(component, RT5640_PWR_DIG1, 0x0000);
+               snd_soc_component_write(component, RT5640_PWR_DIG2, 0x0000);
+               snd_soc_component_write(component, RT5640_PWR_VOL, 0x0000);
+               snd_soc_component_write(component, RT5640_PWR_MIXER, 0x0000);
+               snd_soc_component_write(component, RT5640_PWR_ANLG1, 0x0000);
+               snd_soc_component_write(component, RT5640_PWR_ANLG2, 0x0000);
                break;
 
        default:
@@ -2018,10 +2018,10 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-int rt5640_dmic_enable(struct snd_soc_codec *codec,
+int rt5640_dmic_enable(struct snd_soc_component *component,
                       bool dmic1_data_pin, bool dmic2_data_pin)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
                RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL);
@@ -2044,10 +2044,10 @@ int rt5640_dmic_enable(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(rt5640_dmic_enable);
 
-int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
        unsigned int asrc2_mask = 0;
        unsigned int asrc2_value = 0;
 
@@ -2099,43 +2099,43 @@ int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
                        | (clk_src << RT5640_MAD_R_M_SFT);
        }
 
-       snd_soc_update_bits(codec, RT5640_ASRC_2,
+       snd_soc_component_update_bits(component, RT5640_ASRC_2,
                asrc2_mask, asrc2_value);
 
-       if (snd_soc_read(codec, RT5640_ASRC_2)) {
+       if (snd_soc_component_read32(component, RT5640_ASRC_2)) {
                rt5640->asrc_en = true;
-               snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x3);
+               snd_soc_component_update_bits(component, RT5640_JD_CTRL, 0x3, 0x3);
        } else {
                rt5640->asrc_en = false;
-               snd_soc_update_bits(codec, RT5640_JD_CTRL, 0x3, 0x0);
+               snd_soc_component_update_bits(component, RT5640_JD_CTRL, 0x3, 0x0);
        }
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
 
-static int rt5640_probe(struct snd_soc_codec *codec)
+static int rt5640_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        /* Check if MCLK provided */
-       rt5640->mclk = devm_clk_get(codec->dev, "mclk");
+       rt5640->mclk = devm_clk_get(component->dev, "mclk");
        if (PTR_ERR(rt5640->mclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
-       rt5640->codec = codec;
+       rt5640->component = component;
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
-       snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
-       snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
-       snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
+       snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x0301, 0x0301);
+       snd_soc_component_update_bits(component, RT5640_MICBIAS, 0x0030, 0x0030);
+       snd_soc_component_update_bits(component, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
 
-       switch (snd_soc_read(codec, RT5640_RESET) & RT5640_ID_MASK) {
+       switch (snd_soc_component_read32(component, RT5640_RESET) & RT5640_ID_MASK) {
        case RT5640_ID_5640:
        case RT5640_ID_5642:
-               snd_soc_add_codec_controls(codec,
+               snd_soc_add_component_controls(component,
                        rt5640_specific_snd_controls,
                        ARRAY_SIZE(rt5640_specific_snd_controls));
                snd_soc_dapm_new_controls(dapm,
@@ -2154,32 +2154,30 @@ static int rt5640_probe(struct snd_soc_codec *codec)
                        ARRAY_SIZE(rt5639_specific_dapm_routes));
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "The driver is for RT5639 RT5640 or RT5642 only\n");
                return -ENODEV;
        }
 
        if (rt5640->pdata.dmic_en)
-               rt5640_dmic_enable(codec, rt5640->pdata.dmic1_data_pin,
+               rt5640_dmic_enable(component, rt5640->pdata.dmic1_data_pin,
                                          rt5640->pdata.dmic2_data_pin);
 
        return 0;
 }
 
-static int rt5640_remove(struct snd_soc_codec *codec)
+static void rt5640_remove(struct snd_soc_component *component)
 {
-       rt5640_reset(codec);
-
-       return 0;
+       rt5640_reset(component);
 }
 
 #ifdef CONFIG_PM
-static int rt5640_suspend(struct snd_soc_codec *codec)
+static int rt5640_suspend(struct snd_soc_component *component)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
-       rt5640_reset(codec);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
+       rt5640_reset(component);
        regcache_cache_only(rt5640->regmap, true);
        regcache_mark_dirty(rt5640->regmap);
        if (gpio_is_valid(rt5640->pdata.ldo1_en))
@@ -2188,9 +2186,9 @@ static int rt5640_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5640_resume(struct snd_soc_codec *codec)
+static int rt5640_resume(struct snd_soc_component *component)
 {
-       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
                gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 1);
@@ -2259,21 +2257,22 @@ static struct snd_soc_dai_driver rt5640_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5640 = {
-       .probe = rt5640_probe,
-       .remove = rt5640_remove,
-       .suspend = rt5640_suspend,
-       .resume = rt5640_resume,
-       .set_bias_level = rt5640_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5640_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5640_snd_controls),
-               .dapm_widgets           = rt5640_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5640_dapm_widgets),
-               .dapm_routes            = rt5640_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5640_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5640 = {
+       .probe                  = rt5640_probe,
+       .remove                 = rt5640_remove,
+       .suspend                = rt5640_suspend,
+       .resume                 = rt5640_resume,
+       .set_bias_level         = rt5640_set_bias_level,
+       .controls               = rt5640_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5640_snd_controls),
+       .dapm_widgets           = rt5640_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5640_dapm_widgets),
+       .dapm_routes            = rt5640_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5640_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+
 };
 
 static const struct regmap_config rt5640_regmap = {
@@ -2427,17 +2426,11 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 
        rt5640->hp_mute = 1;
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
+       return devm_snd_soc_register_component(&i2c->dev,
+                                     &soc_component_dev_rt5640,
                                      rt5640_dai, ARRAY_SIZE(rt5640_dai));
 }
 
-static int rt5640_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static struct i2c_driver rt5640_i2c_driver = {
        .driver = {
                .name = "rt5640",
@@ -2445,7 +2438,6 @@ static struct i2c_driver rt5640_i2c_driver = {
                .of_match_table = of_match_ptr(rt5640_of_match),
        },
        .probe = rt5640_i2c_probe,
-       .remove   = rt5640_i2c_remove,
        .id_table = rt5640_i2c_id,
 };
 module_i2c_driver(rt5640_i2c_driver);
index b8a811732a52ebb408a2787740dd449b7be9b3c6..c473e8ae2edab2daca7eae34f282c5c3c0a7c6cd 100644 (file)
@@ -2102,7 +2102,7 @@ enum {
 };
 
 struct rt5640_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5640_platform_data pdata;
        struct regmap *regmap;
        struct clk *mclk;
@@ -2121,9 +2121,9 @@ struct rt5640_priv {
        bool asrc_en;
 };
 
-int rt5640_dmic_enable(struct snd_soc_codec *codec,
+int rt5640_dmic_enable(struct snd_soc_component *component,
                       bool dmic1_data_pin, bool dmic2_data_pin);
-int rt5640_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src);
 
 #endif
index 8f140c8b93acd3e4ba14fb1f1a9dc6a19b2916f7..bc8d829ce45bec68b338d45d6374823e38776d38 100644 (file)
@@ -407,7 +407,7 @@ static const char *const rt5645_supply_names[] = {
 };
 
 struct rt5645_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5645_platform_data pdata;
        struct regmap *regmap;
        struct i2c_client *i2c;
@@ -437,9 +437,9 @@ struct rt5645_priv {
        int v_id;
 };
 
-static int rt5645_reset(struct snd_soc_codec *codec)
+static int rt5645_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, RT5645_RESET, 0);
+       return snd_soc_component_write(component, RT5645_RESET, 0);
 }
 
 static bool rt5645_volatile_register(struct device *dev, unsigned int reg)
@@ -846,17 +846,17 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        int idx, rate;
 
        rate = rt5645->sysclk / rl6231_get_pre_div(rt5645->regmap,
                RT5645_ADDA_CLK1, RT5645_I2S_PD1_SFT);
        idx = rl6231_calc_dmic_clk(rate);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
-               snd_soc_update_bits(codec, RT5645_DMIC_CTRL1,
+               snd_soc_component_update_bits(component, RT5645_DMIC_CTRL1,
                        RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT);
        return idx;
 }
@@ -864,10 +864,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int val;
 
-       val = snd_soc_read(codec, RT5645_GLB_CLK);
+       val = snd_soc_component_read32(component, RT5645_GLB_CLK);
        val &= RT5645_SCLK_SRC_MASK;
        if (val == RT5645_SCLK_SRC_PLL1)
                return 1;
@@ -878,7 +878,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg, shift, val;
 
        switch (source->shift) {
@@ -910,7 +910,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
                return 0;
        }
 
-       val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+       val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
        switch (val) {
        case 1:
        case 2:
@@ -923,9 +923,9 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 
 }
 
-static int rt5645_enable_hweq(struct snd_soc_codec *codec)
+static int rt5645_enable_hweq(struct snd_soc_component *component)
 {
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < RT5645_HWEQ_NUM; i++) {
@@ -941,7 +941,7 @@ static int rt5645_enable_hweq(struct snd_soc_codec *codec)
 
 /**
  * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -953,7 +953,7 @@ static int rt5645_enable_hweq(struct snd_soc_codec *codec)
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5645_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src)
 {
        unsigned int asrc2_mask = 0;
@@ -1009,11 +1009,11 @@ int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
        }
 
        if (asrc2_mask)
-               snd_soc_update_bits(codec, RT5645_ASRC_2,
+               snd_soc_component_update_bits(component, RT5645_ASRC_2,
                        asrc2_mask, asrc2_value);
 
        if (asrc3_mask)
-               snd_soc_update_bits(codec, RT5645_ASRC_3,
+               snd_soc_component_update_bits(component, RT5645_ASRC_3,
                        asrc3_mask, asrc3_value);
 
        return 0;
@@ -1678,56 +1678,56 @@ static const struct snd_kcontrol_new pdm1_r_vol_control =
        SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_PDM_OUT_CTRL,
                RT5645_M_PDM1_R, 1, 1);
 
-static void hp_amp_power(struct snd_soc_codec *codec, int on)
+static void hp_amp_power(struct snd_soc_component *component, int on)
 {
        static int hp_amp_power_count;
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        if (on) {
                if (hp_amp_power_count <= 0) {
                        if (rt5645->codec_type == CODEC_TYPE_RT5650) {
-                               snd_soc_write(codec, RT5645_DEPOP_M2, 0x3100);
-                               snd_soc_write(codec, RT5645_CHARGE_PUMP,
+                               snd_soc_component_write(component, RT5645_DEPOP_M2, 0x3100);
+                               snd_soc_component_write(component, RT5645_CHARGE_PUMP,
                                        0x0e06);
-                               snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d);
+                               snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d);
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        RT5645_HP_DCC_INT1, 0x9f01);
                                msleep(20);
-                               snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                               snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                        RT5645_HP_CO_MASK, RT5645_HP_CO_EN);
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        0x3e, 0x7400);
-                               snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
+                               snd_soc_component_write(component, RT5645_DEPOP_M3, 0x0737);
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        RT5645_MAMP_INT_REG2, 0xfc00);
-                               snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+                               snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
                                msleep(90);
                                rt5645->hp_on = true;
                        } else {
                                /* depop parameters */
-                               snd_soc_update_bits(codec, RT5645_DEPOP_M2,
+                               snd_soc_component_update_bits(component, RT5645_DEPOP_M2,
                                        RT5645_DEPOP_MASK, RT5645_DEPOP_MAN);
-                               snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d);
+                               snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d);
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        RT5645_HP_DCC_INT1, 0x9f01);
                                mdelay(150);
                                /* headphone amp power on */
-                               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+                               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                        RT5645_PWR_FV1 | RT5645_PWR_FV2, 0);
-                               snd_soc_update_bits(codec, RT5645_PWR_VOL,
+                               snd_soc_component_update_bits(component, RT5645_PWR_VOL,
                                        RT5645_PWR_HV_L | RT5645_PWR_HV_R,
                                        RT5645_PWR_HV_L | RT5645_PWR_HV_R);
-                               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+                               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                        RT5645_PWR_HP_L | RT5645_PWR_HP_R |
                                        RT5645_PWR_HA,
                                        RT5645_PWR_HP_L | RT5645_PWR_HP_R |
                                        RT5645_PWR_HA);
                                mdelay(5);
-                               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+                               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                        RT5645_PWR_FV1 | RT5645_PWR_FV2,
                                        RT5645_PWR_FV1 | RT5645_PWR_FV2);
 
-                               snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                               snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                        RT5645_HP_CO_MASK | RT5645_HP_SG_MASK,
                                        RT5645_HP_CO_EN | RT5645_HP_SG_EN);
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
@@ -1743,15 +1743,15 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
                        if (rt5645->codec_type == CODEC_TYPE_RT5650) {
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        0x3e, 0x7400);
-                               snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
+                               snd_soc_component_write(component, RT5645_DEPOP_M3, 0x0737);
                                regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                        RT5645_MAMP_INT_REG2, 0xfc00);
-                               snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+                               snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
                                msleep(100);
-                               snd_soc_write(codec, RT5645_DEPOP_M1, 0x0001);
+                               snd_soc_component_write(component, RT5645_DEPOP_M1, 0x0001);
 
                        } else {
-                               snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                               snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                        RT5645_HP_SG_MASK |
                                        RT5645_HP_L_SMT_MASK |
                                        RT5645_HP_R_SMT_MASK,
@@ -1759,11 +1759,11 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
                                        RT5645_HP_L_SMT_DIS |
                                        RT5645_HP_R_SMT_DIS);
                                /* headphone amp power down */
-                               snd_soc_write(codec, RT5645_DEPOP_M1, 0x0000);
-                               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+                               snd_soc_component_write(component, RT5645_DEPOP_M1, 0x0000);
+                               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                        RT5645_PWR_HP_L | RT5645_PWR_HP_R |
                                        RT5645_PWR_HA, 0);
-                               snd_soc_update_bits(codec, RT5645_DEPOP_M2,
+                               snd_soc_component_update_bits(component, RT5645_DEPOP_M2,
                                        RT5645_DEPOP_MASK, 0);
                        }
                }
@@ -1773,15 +1773,15 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
 static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               hp_amp_power(codec, 1);
+               hp_amp_power(component, 1);
                /* headphone unmute sequence */
                if (rt5645->codec_type == CODEC_TYPE_RT5645) {
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M3,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M3,
                                RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
                                RT5645_CP_FQ3_MASK,
                                (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
@@ -1789,16 +1789,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
                                (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
                        regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                RT5645_MAMP_INT_REG2, 0xfc00);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_SMT_TRIG_MASK, RT5645_SMT_TRIG_EN);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_RSTN_MASK, RT5645_RSTN_EN);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_RSTN_MASK | RT5645_HP_L_SMT_MASK |
                                RT5645_HP_R_SMT_MASK, RT5645_RSTN_DIS |
                                RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN);
                        msleep(40);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK |
                                RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS |
                                RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS);
@@ -1808,7 +1808,7 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_PRE_PMD:
                /* headphone mute sequence */
                if (rt5645->codec_type == CODEC_TYPE_RT5645) {
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M3,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M3,
                                RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
                                RT5645_CP_FQ3_MASK,
                                (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
@@ -1816,17 +1816,17 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
                                (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
                        regmap_write(rt5645->regmap, RT5645_PR_BASE +
                                RT5645_MAMP_INT_REG2, 0xfc00);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_HP_SG_MASK, RT5645_HP_SG_EN);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_RSTP_MASK, RT5645_RSTP_EN);
-                       snd_soc_update_bits(codec, RT5645_DEPOP_M1,
+                       snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
                                RT5645_RSTP_MASK | RT5645_HP_L_SMT_MASK |
                                RT5645_HP_R_SMT_MASK, RT5645_RSTP_DIS |
                                RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN);
                        msleep(30);
                }
-               hp_amp_power(codec, 0);
+               hp_amp_power(component, 0);
                break;
 
        default:
@@ -1839,25 +1839,25 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               rt5645_enable_hweq(codec);
-               snd_soc_update_bits(codec, RT5645_PWR_DIG1,
+               rt5645_enable_hweq(component);
+               snd_soc_component_update_bits(component, RT5645_PWR_DIG1,
                        RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
                        RT5645_PWR_CLS_D_L,
                        RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
                        RT5645_PWR_CLS_D_L);
-               snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+               snd_soc_component_update_bits(component, RT5645_GEN_CTRL3,
                        RT5645_DET_CLK_MASK, RT5645_DET_CLK_MODE1);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5645_GEN_CTRL3,
+               snd_soc_component_update_bits(component, RT5645_GEN_CTRL3,
                        RT5645_DET_CLK_MASK, RT5645_DET_CLK_DIS);
-               snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
-               snd_soc_update_bits(codec, RT5645_PWR_DIG1,
+               snd_soc_component_write(component, RT5645_EQ_CTRL2, 0);
+               snd_soc_component_update_bits(component, RT5645_PWR_DIG1,
                        RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
                        RT5645_PWR_CLS_D_L, 0);
                break;
@@ -1872,24 +1872,24 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
 static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               hp_amp_power(codec, 1);
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+               hp_amp_power(component, 1);
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                        RT5645_PWR_LM, RT5645_PWR_LM);
-               snd_soc_update_bits(codec, RT5645_LOUT1,
+               snd_soc_component_update_bits(component, RT5645_LOUT1,
                        RT5645_L_MUTE | RT5645_R_MUTE, 0);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5645_LOUT1,
+               snd_soc_component_update_bits(component, RT5645_LOUT1,
                        RT5645_L_MUTE | RT5645_R_MUTE,
                        RT5645_L_MUTE | RT5645_R_MUTE);
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                        RT5645_PWR_LM, 0);
-               hp_amp_power(codec, 0);
+               hp_amp_power(component, 0);
                break;
 
        default:
@@ -1902,16 +1902,16 @@ static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
 static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG2,
                        RT5645_PWR_BST2_P, RT5645_PWR_BST2_P);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG2,
                        RT5645_PWR_BST2_P, 0);
                break;
 
@@ -1925,8 +1925,8 @@ static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
 static int rt5650_hp_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -1946,17 +1946,17 @@ static int rt5650_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+               snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
                        RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
                        RT5645_MICBIAS1_POW_CTRL_SEL_M);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+               snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
                        RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
                        RT5645_MICBIAS1_POW_CTRL_SEL_A);
                break;
@@ -1971,17 +1971,17 @@ static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w,
 static int rt5645_set_micbias2_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *k, int  event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+               snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
                        RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
                        RT5645_MICBIAS2_POW_CTRL_SEL_M);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, RT5645_GEN_CTRL2,
+               snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
                        RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
                        RT5645_MICBIAS2_POW_CTRL_SEL_A);
                break;
@@ -2768,20 +2768,20 @@ static const struct snd_soc_dapm_route rt5645_old_dapm_routes[] = {
 static int rt5645_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk, dl_sft;
        int pre_div, bclk_ms, frame_size;
 
        rt5645->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5645->sysclk, rt5645->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting\n");
+               dev_err(component->dev, "Unsupported clock setting\n");
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
 
@@ -2822,20 +2822,20 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
        case RT5645_AIF1:
                mask_clk = RT5645_I2S_PD1_MASK;
                val_clk = pre_div << RT5645_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5645_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5645_I2S1_SDP,
                        (0x3 << dl_sft), (val_len << dl_sft));
-               snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5645_ADDA_CLK1, mask_clk, val_clk);
                break;
        case  RT5645_AIF2:
                mask_clk = RT5645_I2S_BCLK_MS2_MASK | RT5645_I2S_PD2_MASK;
                val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT |
                        pre_div << RT5645_I2S_PD2_SFT;
-               snd_soc_update_bits(codec, RT5645_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5645_I2S2_SDP,
                        (0x3 << dl_sft), (val_len << dl_sft));
-               snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5645_ADDA_CLK1, mask_clk, val_clk);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
@@ -2844,8 +2844,8 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0, pol_sft;
 
        switch (rt5645->codec_type) {
@@ -2896,17 +2896,17 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
        switch (dai->id) {
        case RT5645_AIF1:
-               snd_soc_update_bits(codec, RT5645_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5645_I2S1_SDP,
                        RT5645_I2S_MS_MASK | (1 << pol_sft) |
                        RT5645_I2S_DF_MASK, reg_val);
                break;
        case RT5645_AIF2:
-               snd_soc_update_bits(codec, RT5645_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5645_I2S2_SDP,
                        RT5645_I2S_MS_MASK | (1 << pol_sft) |
                        RT5645_I2S_DF_MASK, reg_val);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
        return 0;
@@ -2915,8 +2915,8 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5645->sysclk && clk_id == rt5645->sysclk_src)
@@ -2933,10 +2933,10 @@ static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
                reg_val |= RT5645_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5645_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5645_GLB_CLK,
                RT5645_SCLK_SRC_MASK, reg_val);
        rt5645->sysclk = freq;
        rt5645->sysclk_src = clk_id;
@@ -2949,8 +2949,8 @@ static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -2959,54 +2959,54 @@ static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5645->pll_in = 0;
                rt5645->pll_out = 0;
-               snd_soc_update_bits(codec, RT5645_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5645_GLB_CLK,
                        RT5645_SCLK_SRC_MASK, RT5645_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5645_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5645_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5645_GLB_CLK,
                        RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_MCLK);
                break;
        case RT5645_PLL1_S_BCLK1:
        case RT5645_PLL1_S_BCLK2:
                switch (dai->id) {
                case RT5645_AIF1:
-                       snd_soc_update_bits(codec, RT5645_GLB_CLK,
+                       snd_soc_component_update_bits(component, RT5645_GLB_CLK,
                                RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK1);
                        break;
                case  RT5645_AIF2:
-                       snd_soc_update_bits(codec, RT5645_GLB_CLK,
+                       snd_soc_component_update_bits(component, RT5645_GLB_CLK,
                                RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK2);
                        break;
                default:
-                       dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+                       dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                        return -EINVAL;
                }
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5645_PLL_CTRL1,
+       snd_soc_component_write(component, RT5645_PLL_CTRL1,
                pll_code.n_code << RT5645_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5645_PLL_CTRL2,
+       snd_soc_component_write(component, RT5645_PLL_CTRL2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5645_PLL_M_SFT |
                pll_code.m_bp << RT5645_PLL_M_BP_SFT);
 
@@ -3020,8 +3020,8 @@ static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        unsigned int i_slot_sft, o_slot_sft, i_width_sht, o_width_sht, en_sft;
        unsigned int mask, val = 0;
 
@@ -3044,7 +3044,7 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        if (rx_mask || tx_mask) {
                val |= (1 << en_sft);
                if (rt5645->codec_type == CODEC_TYPE_RT5645)
-                       snd_soc_update_bits(codec, RT5645_BASS_BACK,
+                       snd_soc_component_update_bits(component, RT5645_BASS_BACK,
                                RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB);
        }
 
@@ -3078,45 +3078,45 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                break;
        }
 
-       snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, mask, val);
+       snd_soc_component_update_bits(component, RT5645_TDM_CTRL_1, mask, val);
 
        return 0;
 }
 
-static int rt5645_set_bias_level(struct snd_soc_codec *codec,
+static int rt5645_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
-               if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+               if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                RT5645_PWR_VREF1 | RT5645_PWR_MB |
                                RT5645_PWR_BG | RT5645_PWR_VREF2,
                                RT5645_PWR_VREF1 | RT5645_PWR_MB |
                                RT5645_PWR_BG | RT5645_PWR_VREF2);
                        mdelay(10);
-                       snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                RT5645_PWR_FV1 | RT5645_PWR_FV2,
                                RT5645_PWR_FV1 | RT5645_PWR_FV2);
-                       snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
+                       snd_soc_component_update_bits(component, RT5645_GEN_CTRL1,
                                RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
                }
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                        RT5645_PWR_VREF1 | RT5645_PWR_MB |
                        RT5645_PWR_BG | RT5645_PWR_VREF2,
                        RT5645_PWR_VREF1 | RT5645_PWR_MB |
                        RT5645_PWR_BG | RT5645_PWR_VREF2);
                mdelay(10);
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                        RT5645_PWR_FV1 | RT5645_PWR_FV2,
                        RT5645_PWR_FV1 | RT5645_PWR_FV2);
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
                        msleep(40);
                        if (rt5645->en_button_func)
                                queue_delayed_work(system_power_efficient_wq,
@@ -3126,11 +3126,11 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100);
+               snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1100);
                if (!rt5645->en_button_func)
-                       snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
+                       snd_soc_component_update_bits(component, RT5645_GEN_CTRL1,
                                        RT5645_DIG_GATE_CTRL, 0);
-               snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
                                RT5645_PWR_VREF1 | RT5645_PWR_MB |
                                RT5645_PWR_BG | RT5645_PWR_VREF2 |
                                RT5645_PWR_FV1 | RT5645_PWR_FV2, 0x0);
@@ -3143,27 +3143,27 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5645_enable_push_button_irq(struct snd_soc_component *component,
        bool enable)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (enable) {
                snd_soc_dapm_force_enable_pin(dapm, "ADC L power");
                snd_soc_dapm_force_enable_pin(dapm, "ADC R power");
                snd_soc_dapm_sync(dapm);
 
-               snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
+               snd_soc_component_update_bits(component,
                                        RT5645_INT_IRQ_ST, 0x8, 0x8);
-               snd_soc_update_bits(codec,
+               snd_soc_component_update_bits(component,
                                        RT5650_4BTN_IL_CMD2, 0x8000, 0x8000);
-               snd_soc_read(codec, RT5650_4BTN_IL_CMD1);
+               snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1);
                pr_debug("%s read %x = %x\n", __func__, RT5650_4BTN_IL_CMD1,
-                       snd_soc_read(codec, RT5650_4BTN_IL_CMD1));
+                       snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1));
        } else {
-               snd_soc_update_bits(codec, RT5650_4BTN_IL_CMD2, 0x8000, 0x0);
-               snd_soc_update_bits(codec, RT5645_INT_IRQ_ST, 0x8, 0x0);
+               snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD2, 0x8000, 0x0);
+               snd_soc_component_update_bits(component, RT5645_INT_IRQ_ST, 0x8, 0x0);
 
                snd_soc_dapm_disable_pin(dapm, "ADC L power");
                snd_soc_dapm_disable_pin(dapm, "ADC R power");
@@ -3171,10 +3171,10 @@ static void rt5645_enable_push_button_irq(struct snd_soc_codec *codec,
        }
 }
 
-static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5645_jack_detect(struct snd_soc_component *component, int jack_insert)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (jack_insert) {
@@ -3208,12 +3208,12 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                msleep(600);
                regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val);
                val &= 0x7;
-               dev_dbg(codec->dev, "val = %d\n", val);
+               dev_dbg(component->dev, "val = %d\n", val);
 
                if (val == 1 || val == 2) {
                        rt5645->jack_type = SND_JACK_HEADSET;
                        if (rt5645->en_button_func) {
-                               rt5645_enable_push_button_irq(codec, true);
+                               rt5645_enable_push_button_irq(component, true);
                        }
                } else {
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
@@ -3235,7 +3235,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                        RT5645_CBJ_BST1_EN, 0);
 
                if (rt5645->en_button_func)
-                       rt5645_enable_push_button_irq(codec, false);
+                       rt5645_enable_push_button_irq(component, false);
 
                if (rt5645->pdata.jd_mode == 0)
                        snd_soc_dapm_disable_pin(dapm, "LDO2");
@@ -3249,25 +3249,25 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
        return rt5645->jack_type;
 }
 
-static int rt5645_button_detect(struct snd_soc_codec *codec)
+static int rt5645_button_detect(struct snd_soc_component *component)
 {
        int btn_type, val;
 
-       val = snd_soc_read(codec, RT5650_4BTN_IL_CMD1);
+       val = snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1);
        pr_debug("val=0x%x\n", val);
        btn_type = val & 0xfff0;
-       snd_soc_write(codec, RT5650_4BTN_IL_CMD1, val);
+       snd_soc_component_write(component, RT5650_4BTN_IL_CMD1, val);
 
        return btn_type;
 }
 
 static irqreturn_t rt5645_irq(int irq, void *data);
 
-int rt5645_set_jack_detect(struct snd_soc_codec *codec,
+int rt5645_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
        struct snd_soc_jack *btn_jack)
 {
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        rt5645->hp_jack = hp_jack;
        rt5645->mic_jack = mic_jack;
@@ -3291,16 +3291,16 @@ static void rt5645_jack_detect_work(struct work_struct *work)
                container_of(work, struct rt5645_priv, jack_detect_work.work);
        int val, btn_type, gpio_state = 0, report = 0;
 
-       if (!rt5645->codec)
+       if (!rt5645->component)
                return;
 
        switch (rt5645->pdata.jd_mode) {
        case 0: /* Not using rt5645 JD */
                if (rt5645->gpiod_hp_det) {
                        gpio_state = gpiod_get_value(rt5645->gpiod_hp_det);
-                       dev_dbg(rt5645->codec->dev, "gpio_state = %d\n",
+                       dev_dbg(rt5645->component->dev, "gpio_state = %d\n",
                                gpio_state);
-                       report = rt5645_jack_detect(rt5645->codec, gpio_state);
+                       report = rt5645_jack_detect(rt5645->component, gpio_state);
                }
                snd_soc_jack_report(rt5645->hp_jack,
                                    report, SND_JACK_HEADPHONE);
@@ -3308,20 +3308,20 @@ static void rt5645_jack_detect_work(struct work_struct *work)
                                    report, SND_JACK_MICROPHONE);
                return;
        default: /* read rt5645 jd1_1 status */
-               val = snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x1000;
+               val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000;
                break;
 
        }
 
        if (!val && (rt5645->jack_type == 0)) { /* jack in */
-               report = rt5645_jack_detect(rt5645->codec, 1);
+               report = rt5645_jack_detect(rt5645->component, 1);
        } else if (!val && rt5645->jack_type != 0) {
                /* for push button and jack out */
                btn_type = 0;
-               if (snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x4) {
+               if (snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) {
                        /* button pressed */
                        report = SND_JACK_HEADSET;
-                       btn_type = rt5645_button_detect(rt5645->codec);
+                       btn_type = rt5645_button_detect(rt5645->component);
                        /* rt5650 can report three kinds of button behavior,
                           one click, double click and hold. However,
                           currently we will report button pressed/released
@@ -3351,7 +3351,7 @@ static void rt5645_jack_detect_work(struct work_struct *work)
                        case 0x0000: /* unpressed */
                                break;
                        default:
-                               dev_err(rt5645->codec->dev,
+                               dev_err(rt5645->component->dev,
                                        "Unexpected button code 0x%04x\n",
                                        btn_type);
                                break;
@@ -3366,9 +3366,9 @@ static void rt5645_jack_detect_work(struct work_struct *work)
        } else {
                /* jack out */
                report = 0;
-               snd_soc_update_bits(rt5645->codec,
+               snd_soc_component_update_bits(rt5645->component,
                                    RT5645_INT_IRQ_ST, 0x1, 0x0);
-               rt5645_jack_detect(rt5645->codec, 0);
+               rt5645_jack_detect(rt5645->component, 0);
        }
 
        snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE);
@@ -3406,12 +3406,12 @@ static void rt5645_btn_check_callback(struct timer_list *t)
                   &rt5645->jack_detect_work, msecs_to_jiffies(5));
 }
 
-static int rt5645_probe(struct snd_soc_codec *codec)
+static int rt5645_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
-       rt5645->codec = codec;
+       rt5645->component = component;
 
        switch (rt5645->codec_type) {
        case CODEC_TYPE_RT5645:
@@ -3437,7 +3437,7 @@ static int rt5645_probe(struct snd_soc_codec *codec)
                break;
        }
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
        /* for JD function */
        if (rt5645->pdata.jd_mode) {
@@ -3447,24 +3447,23 @@ static int rt5645_probe(struct snd_soc_codec *codec)
        }
 
        if (rt5645->pdata.long_name)
-               codec->component.card->long_name = rt5645->pdata.long_name;
+               component->card->long_name = rt5645->pdata.long_name;
 
-       rt5645->eq_param = devm_kzalloc(codec->dev,
+       rt5645->eq_param = devm_kzalloc(component->dev,
                RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL);
 
        return 0;
 }
 
-static int rt5645_remove(struct snd_soc_codec *codec)
+static void rt5645_remove(struct snd_soc_component *component)
 {
-       rt5645_reset(codec);
-       return 0;
+       rt5645_reset(component);
 }
 
 #ifdef CONFIG_PM
-static int rt5645_suspend(struct snd_soc_codec *codec)
+static int rt5645_suspend(struct snd_soc_component *component)
 {
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5645->regmap, true);
        regcache_mark_dirty(rt5645->regmap);
@@ -3472,9 +3471,9 @@ static int rt5645_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5645_resume(struct snd_soc_codec *codec)
+static int rt5645_resume(struct snd_soc_component *component)
 {
-       struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
+       struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5645->regmap, false);
        regcache_sync(rt5645->regmap);
@@ -3539,21 +3538,21 @@ static struct snd_soc_dai_driver rt5645_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5645 = {
-       .probe = rt5645_probe,
-       .remove = rt5645_remove,
-       .suspend = rt5645_suspend,
-       .resume = rt5645_resume,
-       .set_bias_level = rt5645_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5645_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5645_snd_controls),
-               .dapm_widgets           = rt5645_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5645_dapm_widgets),
-               .dapm_routes            = rt5645_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5645_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5645 = {
+       .probe                  = rt5645_probe,
+       .remove                 = rt5645_remove,
+       .suspend                = rt5645_suspend,
+       .resume                 = rt5645_resume,
+       .set_bias_level         = rt5645_set_bias_level,
+       .controls               = rt5645_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5645_snd_controls),
+       .dapm_widgets           = rt5645_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5645_dapm_widgets),
+       .dapm_routes            = rt5645_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5645_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5645_regmap = {
@@ -4028,7 +4027,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
                }
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645,
+       ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5645,
                                     rt5645_dai, ARRAY_SIZE(rt5645_dai));
        if (ret)
                goto err_irq;
@@ -4054,7 +4053,6 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
        cancel_delayed_work_sync(&rt5645->rcclock_work);
        del_timer_sync(&rt5645->btn_check_timer);
 
-       snd_soc_unregister_codec(&i2c->dev);
        regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
 
        return 0;
index 940325b28c299daa7d3b2b4dafda5e059a85b679..cc24557683680afe0acd7a8a3c892e53d1523940 100644 (file)
@@ -2200,10 +2200,10 @@ enum {
        RT5645_AD_MONO_R_FILTER = (0x1 << 5),
 };
 
-int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5645_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src);
 
-int rt5645_set_jack_detect(struct snd_soc_codec *codec,
+int rt5645_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
        struct snd_soc_jack *btn_jack);
 #endif /* __RT5645_H__ */
index 831b297978a485ff58fe4eea38373c6392cab7ae..6b5669f3e85d740d3c088ac17f87074af352afd0 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/acpi.h>
-#include <linux/dmi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include "rl6231.h"
 #include "rt5651.h"
 
-#define RT5651_JD_MAP(quirk)   ((quirk) & GENMASK(7, 0))
-#define RT5651_IN2_DIFF                BIT(16)
-#define RT5651_DMIC_EN         BIT(17)
-
 #define RT5651_DEVICE_ID_VALUE 0x6281
 
 #define RT5651_PR_RANGE_BASE (0xff + 1)
@@ -43,8 +38,6 @@
 
 #define RT5651_PR_BASE (RT5651_PR_RANGE_BASE + (0 * RT5651_PR_SPACING))
 
-static unsigned long rt5651_quirk;
-
 static const struct regmap_range_cfg rt5651_ranges[] = {
        { .name = "PR", .range_min = RT5651_PR_BASE,
          .range_max = RT5651_PR_BASE + 0xb4,
@@ -384,36 +377,22 @@ static const struct snd_kcontrol_new rt5651_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
        int idx, rate;
 
        rate = rt5651->sysclk / rl6231_get_pre_div(rt5651->regmap,
                RT5651_ADDA_CLK1, RT5651_I2S_PD1_SFT);
        idx = rl6231_calc_dmic_clk(rate);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
-               snd_soc_update_bits(codec, RT5651_DMIC, RT5651_DMIC_CLK_MASK,
+               snd_soc_component_update_bits(component, RT5651_DMIC, RT5651_DMIC_CLK_MASK,
                                        idx << RT5651_DMIC_CLK_SFT);
 
        return idx;
 }
 
-static int is_sysclk_from_pll(struct snd_soc_dapm_widget *source,
-                        struct snd_soc_dapm_widget *sink)
-{
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       unsigned int val;
-
-       val = snd_soc_read(codec, RT5651_GLB_CLK);
-       val &= RT5651_SCLK_SRC_MASK;
-       if (val == RT5651_SCLK_SRC_PLL1)
-               return 1;
-       else
-               return 0;
-}
-
 /* Digital Mixer */
 static const struct snd_kcontrol_new rt5651_sto1_adc_l_mix[] = {
        SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO1_ADC_MIXER,
@@ -703,8 +682,8 @@ static const struct snd_kcontrol_new rt5651_pdm_r_mux =
 static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -741,8 +720,8 @@ static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w,
 static int rt5651_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -786,8 +765,8 @@ static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
 
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -806,16 +785,16 @@ static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w,
 static int rt5651_bst1_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
                        RT5651_PWR_BST1_OP2, RT5651_PWR_BST1_OP2);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
                        RT5651_PWR_BST1_OP2, 0);
                break;
 
@@ -829,16 +808,16 @@ static int rt5651_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5651_bst2_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
                        RT5651_PWR_BST2_OP2, RT5651_PWR_BST2_OP2);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
                        RT5651_PWR_BST2_OP2, 0);
                break;
 
@@ -852,16 +831,16 @@ static int rt5651_bst2_event(struct snd_soc_dapm_widget *w,
 static int rt5651_bst3_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
                        RT5651_PWR_BST3_OP2, RT5651_PWR_BST3_OP2);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5651_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
                        RT5651_PWR_BST3_OP2, 0);
                break;
 
@@ -885,12 +864,6 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY_S("ADC ASRC", 1, RT5651_PLL_MODE_2,
                              11, 0, NULL, 0),
 
-       SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2,
-                       RT5651_PWR_PLL_BIT, 0, NULL, 0),
-       /* Input Side */
-       SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2,
-               RT5651_PWM_JD_M_BIT, 0, NULL, 0),
-
        /* micbias */
        SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
                        RT5651_PWR_LDO_BIT, 0, NULL, 0),
@@ -1169,7 +1142,6 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
        {"Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux"},
        {"Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux"},
        {"Stereo1 ADC MIXL", NULL, "Stereo1 Filter"},
-       {"Stereo1 Filter", NULL, "PLL1", is_sysclk_from_pll},
        {"Stereo1 Filter", NULL, "ADC ASRC"},
 
        {"Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux"},
@@ -1179,7 +1151,6 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
        {"Stereo2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux"},
        {"Stereo2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux"},
        {"Stereo2 ADC MIXL", NULL, "Stereo2 Filter"},
-       {"Stereo2 Filter", NULL, "PLL1", is_sysclk_from_pll},
        {"Stereo2 Filter", NULL, "ADC ASRC"},
 
        {"Stereo2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux"},
@@ -1246,10 +1217,8 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
        {"PDM R Mux", "DD MIX", "DAC MIXR"},
 
        {"DAC L1", NULL, "Stereo DAC MIXL"},
-       {"DAC L1", NULL, "PLL1", is_sysclk_from_pll},
        {"DAC L1", NULL, "DAC L1 Power"},
        {"DAC R1", NULL, "Stereo DAC MIXR"},
-       {"DAC R1", NULL, "PLL1", is_sysclk_from_pll},
        {"DAC R1", NULL, "DAC R1 Power"},
 
        {"DD MIXL", "DAC L1 Switch", "DAC MIXL"},
@@ -1313,8 +1282,8 @@ static const struct snd_soc_dapm_route rt5651_dapm_routes[] = {
 static int rt5651_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int pre_div, bclk_ms, frame_size;
 
@@ -1322,12 +1291,12 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream,
        pre_div = rl6231_get_clk_info(rt5651->sysclk, rt5651->lrck[dai->id]);
 
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting\n");
+               dev_err(component->dev, "Unsupported clock setting\n");
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
        bclk_ms = frame_size > 32 ? 1 : 0;
@@ -1358,19 +1327,19 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream,
        case RT5651_AIF1:
                mask_clk = RT5651_I2S_PD1_MASK;
                val_clk = pre_div << RT5651_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5651_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5651_I2S1_SDP,
                        RT5651_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT5651_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5651_ADDA_CLK1, mask_clk, val_clk);
                break;
        case RT5651_AIF2:
                mask_clk = RT5651_I2S_BCLK_MS2_MASK | RT5651_I2S_PD2_MASK;
                val_clk = pre_div << RT5651_I2S_PD2_SFT;
-               snd_soc_update_bits(codec, RT5651_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5651_I2S2_SDP,
                        RT5651_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT5651_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5651_ADDA_CLK1, mask_clk, val_clk);
                break;
        default:
-               dev_err(codec->dev, "Wrong dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Wrong dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
@@ -1379,8 +1348,8 @@ static int rt5651_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1423,17 +1392,17 @@ static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (dai->id) {
        case RT5651_AIF1:
-               snd_soc_update_bits(codec, RT5651_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5651_I2S1_SDP,
                        RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK |
                        RT5651_I2S_DF_MASK, reg_val);
                break;
        case RT5651_AIF2:
-               snd_soc_update_bits(codec, RT5651_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5651_I2S2_SDP,
                        RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK |
                        RT5651_I2S_DF_MASK, reg_val);
                break;
        default:
-               dev_err(codec->dev, "Wrong dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Wrong dai->id: %d\n", dai->id);
                return -EINVAL;
        }
        return 0;
@@ -1442,9 +1411,10 @@ static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
+       unsigned int pll_bit = 0;
 
        if (freq == rt5651->sysclk && clk_id == rt5651->sysclk_src)
                return 0;
@@ -1455,15 +1425,18 @@ static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai,
                break;
        case RT5651_SCLK_S_PLL1:
                reg_val |= RT5651_SCLK_SRC_PLL1;
+               pll_bit |= RT5651_PWR_PLL;
                break;
        case RT5651_SCLK_S_RCCLK:
                reg_val |= RT5651_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5651_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
+               RT5651_PWR_PLL, pll_bit);
+       snd_soc_component_update_bits(component, RT5651_GLB_CLK,
                RT5651_SCLK_SRC_MASK, reg_val);
        rt5651->sysclk = freq;
        rt5651->sysclk_src = clk_id;
@@ -1476,8 +1449,8 @@ static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -1486,46 +1459,46 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5651->pll_in = 0;
                rt5651->pll_out = 0;
-               snd_soc_update_bits(codec, RT5651_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5651_GLB_CLK,
                        RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5651_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5651_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5651_GLB_CLK,
                        RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_MCLK);
                break;
        case RT5651_PLL1_S_BCLK1:
-               snd_soc_update_bits(codec, RT5651_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5651_GLB_CLK,
                                RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK1);
                break;
        case RT5651_PLL1_S_BCLK2:
-                       snd_soc_update_bits(codec, RT5651_GLB_CLK,
+                       snd_soc_component_update_bits(component, RT5651_GLB_CLK,
                                RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK2);
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5651_PLL_CTRL1,
+       snd_soc_component_write(component, RT5651_PLL_CTRL1,
                pll_code.n_code << RT5651_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5651_PLL_CTRL2,
+       snd_soc_component_write(component, RT5651_PLL_CTRL2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5651_PLL_M_SFT |
                pll_code.m_bp << RT5651_PLL_M_BP_SFT);
 
@@ -1536,46 +1509,44 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
        return 0;
 }
 
-static int rt5651_set_bias_level(struct snd_soc_codec *codec,
+static int rt5651_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
-               if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
+               if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+                       if (snd_soc_component_read32(component, RT5651_PLL_MODE_1) & 0x9200)
+                               snd_soc_component_update_bits(component, RT5651_D_MISC,
+                                                   0xc00, 0xc00);
+               }
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               if (SND_SOC_BIAS_OFF == snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
                                RT5651_PWR_VREF1 | RT5651_PWR_MB |
                                RT5651_PWR_BG | RT5651_PWR_VREF2,
                                RT5651_PWR_VREF1 | RT5651_PWR_MB |
                                RT5651_PWR_BG | RT5651_PWR_VREF2);
                        usleep_range(10000, 15000);
-                       snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
                                RT5651_PWR_FV1 | RT5651_PWR_FV2,
                                RT5651_PWR_FV1 | RT5651_PWR_FV2);
-                       snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
-                               RT5651_PWR_LDO_DVO_MASK,
-                               RT5651_PWR_LDO_DVO_1_2V);
-                       snd_soc_update_bits(codec, RT5651_D_MISC, 0x1, 0x1);
-                       if (snd_soc_read(codec, RT5651_PLL_MODE_1) & 0x9200)
-                               snd_soc_update_bits(codec, RT5651_D_MISC,
-                                                   0xc00, 0xc00);
+                       snd_soc_component_update_bits(component, RT5651_D_MISC, 0x1, 0x1);
                }
                break;
 
-       case SND_SOC_BIAS_STANDBY:
-               snd_soc_write(codec, RT5651_D_MISC, 0x0010);
-               snd_soc_write(codec, RT5651_PWR_DIG1, 0x0000);
-               snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000);
-               snd_soc_write(codec, RT5651_PWR_VOL, 0x0000);
-               snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000);
-               if (rt5651->pdata.jd_src) {
-                       snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204);
-                       snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002);
-               } else {
-                       snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
-                       snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
-               }
+       case SND_SOC_BIAS_OFF:
+               snd_soc_component_write(component, RT5651_D_MISC, 0x0010);
+               snd_soc_component_write(component, RT5651_PWR_DIG1, 0x0000);
+               snd_soc_component_write(component, RT5651_PWR_DIG2, 0x0000);
+               snd_soc_component_write(component, RT5651_PWR_VOL, 0x0000);
+               snd_soc_component_write(component, RT5651_PWR_MIXER, 0x0000);
+               /* Do not touch the LDO voltage select bits on bias-off */
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
+                       ~RT5651_PWR_LDO_DVO_MASK, 0);
+               /* Leave PLL1 and jack-detect power as is, all others off */
+               snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
+                                   ~(RT5651_PWR_PLL | RT5651_PWR_JD_M), 0);
                break;
 
        default:
@@ -1585,53 +1556,326 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5651_probe(struct snd_soc_codec *codec)
+static void rt5651_enable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+       snd_soc_dapm_mutex_lock(dapm);
+       snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO");
+       snd_soc_dapm_force_enable_pin_unlocked(dapm, "micbias1");
+       /* OVCD is unreliable when used with RCCLK as sysclk-source */
+       snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock");
+       snd_soc_dapm_sync_unlocked(dapm);
+       snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static void rt5651_disable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+       snd_soc_dapm_mutex_lock(dapm);
+       snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock");
+       snd_soc_dapm_disable_pin_unlocked(dapm, "micbias1");
+       snd_soc_dapm_disable_pin_unlocked(dapm, "LDO");
+       snd_soc_dapm_sync_unlocked(dapm);
+       snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static void rt5651_clear_micbias1_ovcd(struct snd_soc_component *component)
+{
+       snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
+               RT5651_MB1_OC_CLR, 0);
+}
+
+static bool rt5651_micbias1_ovcd(struct snd_soc_component *component)
+{
+       int val;
+
+       val = snd_soc_component_read32(component, RT5651_IRQ_CTRL2);
+       dev_dbg(component->dev, "irq ctrl2 %#04x\n", val);
+
+       return (val & RT5651_MB1_OC_CLR);
+}
+
+static bool rt5651_jack_inserted(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+       int val;
+
+       val = snd_soc_component_read32(component, RT5651_INT_IRQ_ST);
+       dev_dbg(component->dev, "irq status %#04x\n", val);
+
+       switch (rt5651->jd_src) {
+       case RT5651_JD1_1:
+               val &= 0x1000;
+               break;
+       case RT5651_JD1_2:
+               val &= 0x2000;
+               break;
+       case RT5651_JD2:
+               val &= 0x4000;
+               break;
+       default:
+               break;
+       }
+
+       return val == 0;
+}
+
+/* Jack detect timings */
+#define JACK_SETTLE_TIME       100 /* milli seconds */
+#define JACK_DETECT_COUNT      5
+#define JACK_DETECT_MAXCOUNT   20  /* Aprox. 2 seconds worth of tries */
+
+static int rt5651_detect_headset(struct snd_soc_component *component)
+{
+       int i, headset_count = 0, headphone_count = 0;
+
+       /*
+        * We get the insertion event before the jack is fully inserted at which
+        * point the second ring on a TRRS connector may short the 2nd ring and
+        * sleeve contacts, also the overcurrent detection is not entirely
+        * reliable. So we try several times with a wait in between until we
+        * detect the same type JACK_DETECT_COUNT times in a row.
+        */
+       for (i = 0; i < JACK_DETECT_MAXCOUNT; i++) {
+               /* Clear any previous over-current status flag */
+               rt5651_clear_micbias1_ovcd(component);
+
+               msleep(JACK_SETTLE_TIME);
+
+               /* Check the jack is still connected before checking ovcd */
+               if (!rt5651_jack_inserted(component))
+                       return 0;
+
+               if (rt5651_micbias1_ovcd(component)) {
+                       /*
+                        * Over current detected, there is a short between the
+                        * 2nd ring contact and the ground, so a TRS connector
+                        * without a mic contact and thus plain headphones.
+                        */
+                       dev_dbg(component->dev, "mic-gnd shorted\n");
+                       headset_count = 0;
+                       headphone_count++;
+                       if (headphone_count == JACK_DETECT_COUNT)
+                               return SND_JACK_HEADPHONE;
+               } else {
+                       dev_dbg(component->dev, "mic-gnd open\n");
+                       headphone_count = 0;
+                       headset_count++;
+                       if (headset_count == JACK_DETECT_COUNT)
+                               return SND_JACK_HEADSET;
+               }
+       }
+
+       dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n");
+       return SND_JACK_HEADPHONE;
+}
+
+static void rt5651_jack_detect_work(struct work_struct *work)
 {
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-
-       rt5651->codec = codec;
-
-       snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
-               RT5651_PWR_VREF1 | RT5651_PWR_MB |
-               RT5651_PWR_BG | RT5651_PWR_VREF2,
-               RT5651_PWR_VREF1 | RT5651_PWR_MB |
-               RT5651_PWR_BG | RT5651_PWR_VREF2);
-       usleep_range(10000, 15000);
-       snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
-               RT5651_PWR_FV1 | RT5651_PWR_FV2,
-               RT5651_PWR_FV1 | RT5651_PWR_FV2);
-
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
-
-       if (rt5651->pdata.jd_src) {
-               snd_soc_dapm_force_enable_pin(dapm, "JD Power");
-               snd_soc_dapm_force_enable_pin(dapm, "LDO");
-               snd_soc_dapm_sync(dapm);
-
-               regmap_update_bits(rt5651->regmap, RT5651_MICBIAS,
-                                  0x38, 0x38);
+       struct rt5651_priv *rt5651 =
+               container_of(work, struct rt5651_priv, jack_detect_work);
+       int report = 0;
+
+       if (rt5651_jack_inserted(rt5651->component)) {
+               rt5651_enable_micbias1_for_ovcd(rt5651->component);
+               report = rt5651_detect_headset(rt5651->component);
+               rt5651_disable_micbias1_for_ovcd(rt5651->component);
+       }
+
+       snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
+}
+
+static irqreturn_t rt5651_irq(int irq, void *data)
+{
+       struct rt5651_priv *rt5651 = data;
+
+       queue_work(system_power_efficient_wq, &rt5651->jack_detect_work);
+
+       return IRQ_HANDLED;
+}
+
+static int rt5651_set_jack(struct snd_soc_component *component,
+                          struct snd_soc_jack *hp_jack, void *data)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+       int ret;
+
+       if (!rt5651->irq)
+               return -EINVAL;
+
+       /* IRQ output on GPIO1 */
+       snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1,
+               RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
+
+       /* Select jack detect source */
+       switch (rt5651->jd_src) {
+       case RT5651_JD1_1:
+               snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
+                       RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_1);
+               snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
+                       RT5651_JD1_1_IRQ_EN, RT5651_JD1_1_IRQ_EN);
+               break;
+       case RT5651_JD1_2:
+               snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
+                       RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_2);
+               snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
+                       RT5651_JD1_2_IRQ_EN, RT5651_JD1_2_IRQ_EN);
+               break;
+       case RT5651_JD2:
+               snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
+                       RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD2);
+               snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
+                       RT5651_JD2_IRQ_EN, RT5651_JD2_IRQ_EN);
+               break;
+       case RT5651_JD_NULL:
+               return 0;
+       default:
+               dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
+               return -EINVAL;
        }
 
+       /* Enable jack detect power */
+       snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
+               RT5651_PWR_JD_M, RT5651_PWR_JD_M);
+
+       /* Set OVCD threshold current and scale-factor */
+       snd_soc_component_write(component, RT5651_PR_BASE + RT5651_BIAS_CUR4,
+                               0xa800 | rt5651->ovcd_sf);
+
+       snd_soc_component_update_bits(component, RT5651_MICBIAS,
+                                     RT5651_MIC1_OVCD_MASK |
+                                     RT5651_MIC1_OVTH_MASK |
+                                     RT5651_PWR_CLK12M_MASK |
+                                     RT5651_PWR_MB_MASK,
+                                     RT5651_MIC1_OVCD_EN |
+                                     rt5651->ovcd_th |
+                                     RT5651_PWR_MB_PU |
+                                     RT5651_PWR_CLK12M_PU);
+
+       /*
+        * The over-current-detect is only reliable in detecting the absence
+        * of over-current, when the mic-contact in the jack is short-circuited,
+        * the hardware periodically retries if it can apply the bias-current
+        * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
+        * 10% of the time, as we poll the ovcd status bit we might hit that
+        * 10%, so we enable sticky mode and when checking OVCD we clear the
+        * status, msleep() a bit and then check to get a reliable reading.
+        */
+       snd_soc_component_update_bits(component, RT5651_IRQ_CTRL2,
+               RT5651_MB1_OC_STKY_MASK, RT5651_MB1_OC_STKY_EN);
+
+       rt5651->hp_jack = hp_jack;
+
+       ret = devm_request_threaded_irq(component->dev, rt5651->irq, NULL,
+                                       rt5651_irq,
+                                       IRQF_TRIGGER_RISING |
+                                       IRQF_TRIGGER_FALLING |
+                                       IRQF_ONESHOT, "rt5651", rt5651);
+       if (ret) {
+               dev_err(component->dev, "Failed to reguest IRQ: %d\n", ret);
+               return ret;
+       }
+
+       /* sync initial jack state */
+       queue_work(system_power_efficient_wq, &rt5651->jack_detect_work);
+
+       return 0;
+}
+
+/*
+ * Note on some platforms the platform code may need to add device-properties,
+ * rather then relying only on properties set by the firmware. Therefor the
+ * property parsing MUST be done from the component driver's probe function,
+ * rather then from the i2c driver's probe function, so that the platform-code
+ * can attach extra properties before calling snd_soc_register_card().
+ */
+static void rt5651_apply_properties(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+       u32 val;
+
+       if (device_property_read_bool(component->dev, "realtek,in2-differential"))
+               snd_soc_component_update_bits(component, RT5651_IN1_IN2,
+                               RT5651_IN_DF2, RT5651_IN_DF2);
+
+       if (device_property_read_bool(component->dev, "realtek,dmic-en"))
+               snd_soc_component_update_bits(component, RT5651_GPIO_CTRL1,
+                               RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL);
+
+       if (device_property_read_u32(component->dev,
+                                    "realtek,jack-detect-source", &val) == 0)
+               rt5651->jd_src = val;
+
+       /*
+        * Testing on various boards has shown that good defaults for the OVCD
+        * threshold and scale-factor are 2000µA and 0.75. For an effective
+        * limit of 1500µA, this seems to be more reliable then 1500µA and 1.0.
+        */
+       rt5651->ovcd_th = RT5651_MIC1_OVTH_2000UA;
+       rt5651->ovcd_sf = RT5651_MIC_OVCD_SF_0P75;
+
+       if (device_property_read_u32(component->dev,
+                       "realtek,over-current-threshold-microamp", &val) == 0) {
+               switch (val) {
+               case 600:
+                       rt5651->ovcd_th = RT5651_MIC1_OVTH_600UA;
+                       break;
+               case 1500:
+                       rt5651->ovcd_th = RT5651_MIC1_OVTH_1500UA;
+                       break;
+               case 2000:
+                       rt5651->ovcd_th = RT5651_MIC1_OVTH_2000UA;
+                       break;
+               default:
+                       dev_warn(component->dev, "Warning: Invalid over-current-threshold-microamp value: %d, defaulting to 2000uA\n",
+                                val);
+               }
+       }
+
+       if (device_property_read_u32(component->dev,
+                       "realtek,over-current-scale-factor", &val) == 0) {
+               if (val <= RT5651_OVCD_SF_1P5)
+                       rt5651->ovcd_sf = val << RT5651_MIC_OVCD_SF_SFT;
+               else
+                       dev_warn(component->dev, "Warning: Invalid over-current-scale-factor value: %d, defaulting to 0.75\n",
+                                val);
+       }
+}
+
+static int rt5651_probe(struct snd_soc_component *component)
+{
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+
+       rt5651->component = component;
+
+       snd_soc_component_update_bits(component, RT5651_PWR_ANLG1,
+               RT5651_PWR_LDO_DVO_MASK, RT5651_PWR_LDO_DVO_1_2V);
+
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
+
+       rt5651_apply_properties(component);
+
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5651_suspend(struct snd_soc_codec *codec)
+static int rt5651_suspend(struct snd_soc_component *component)
 {
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5651->regmap, true);
        regcache_mark_dirty(rt5651->regmap);
        return 0;
 }
 
-static int rt5651_resume(struct snd_soc_codec *codec)
+static int rt5651_resume(struct snd_soc_component *component)
 {
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+       struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5651->regmap, false);
-       snd_soc_cache_sync(codec);
+       snd_soc_component_cache_sync(component);
 
        return 0;
 }
@@ -1692,20 +1936,21 @@ static struct snd_soc_dai_driver rt5651_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5651 = {
-       .probe = rt5651_probe,
-       .suspend = rt5651_suspend,
-       .resume = rt5651_resume,
-       .set_bias_level = rt5651_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5651_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5651_snd_controls),
-               .dapm_widgets           = rt5651_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5651_dapm_widgets),
-               .dapm_routes            = rt5651_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5651_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5651 = {
+       .probe                  = rt5651_probe,
+       .suspend                = rt5651_suspend,
+       .resume                 = rt5651_resume,
+       .set_bias_level         = rt5651_set_bias_level,
+       .set_jack               = rt5651_set_jack,
+       .controls               = rt5651_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5651_snd_controls),
+       .dapm_widgets           = rt5651_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5651_dapm_widgets),
+       .dapm_routes            = rt5651_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5651_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5651_regmap = {
@@ -1722,6 +1967,7 @@ static const struct regmap_config rt5651_regmap = {
        .num_reg_defaults = ARRAY_SIZE(rt5651_reg),
        .ranges = rt5651_ranges,
        .num_ranges = ARRAY_SIZE(rt5651_ranges),
+       .use_single_rw = true,
 };
 
 #if defined(CONFIG_OF)
@@ -1746,135 +1992,13 @@ static const struct i2c_device_id rt5651_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id);
 
-static int rt5651_quirk_cb(const struct dmi_system_id *id)
-{
-       rt5651_quirk = (unsigned long) id->driver_data;
-       return 1;
-}
-
-static const struct dmi_system_id rt5651_quirk_table[] = {
-       {
-               .callback = rt5651_quirk_cb,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
-               },
-               .driver_data = (unsigned long *) RT5651_JD1_1,
-       },
-       {}
-};
-
-static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
-{
-       if (of_property_read_bool(np, "realtek,in2-differential"))
-               rt5651_quirk |= RT5651_IN2_DIFF;
-       if (of_property_read_bool(np, "realtek,dmic-en"))
-               rt5651_quirk |= RT5651_DMIC_EN;
-
-       return 0;
-}
-
-static void rt5651_set_pdata(struct rt5651_priv *rt5651)
-{
-       if (rt5651_quirk & RT5651_IN2_DIFF)
-               rt5651->pdata.in2_diff = true;
-       if (rt5651_quirk & RT5651_DMIC_EN)
-               rt5651->pdata.dmic_en = true;
-       if (RT5651_JD_MAP(rt5651_quirk))
-               rt5651->pdata.jd_src = RT5651_JD_MAP(rt5651_quirk);
-}
-
-static irqreturn_t rt5651_irq(int irq, void *data)
-{
-       struct rt5651_priv *rt5651 = data;
-
-       queue_delayed_work(system_power_efficient_wq,
-                          &rt5651->jack_detect_work, msecs_to_jiffies(250));
-
-       return IRQ_HANDLED;
-}
-
-static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert)
-{
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       int jack_type;
-
-       if (jack_insert) {
-               snd_soc_dapm_force_enable_pin(dapm, "LDO");
-               snd_soc_dapm_sync(dapm);
-
-               snd_soc_update_bits(codec, RT5651_MICBIAS,
-                                   RT5651_MIC1_OVCD_MASK |
-                                   RT5651_MIC1_OVTH_MASK |
-                                   RT5651_PWR_CLK12M_MASK |
-                                   RT5651_PWR_MB_MASK,
-                                   RT5651_MIC1_OVCD_EN |
-                                   RT5651_MIC1_OVTH_600UA |
-                                   RT5651_PWR_MB_PU |
-                                   RT5651_PWR_CLK12M_PU);
-               msleep(100);
-               if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR)
-                       jack_type = SND_JACK_HEADPHONE;
-               else
-                       jack_type = SND_JACK_HEADSET;
-               snd_soc_update_bits(codec, RT5651_IRQ_CTRL2,
-                                   RT5651_MB1_OC_CLR, 0);
-       } else { /* jack out */
-               jack_type = 0;
-
-               snd_soc_update_bits(codec, RT5651_MICBIAS,
-                                   RT5651_MIC1_OVCD_MASK,
-                                   RT5651_MIC1_OVCD_DIS);
-       }
-
-       return jack_type;
-}
-
-static void rt5651_jack_detect_work(struct work_struct *work)
-{
-       struct rt5651_priv *rt5651 =
-               container_of(work, struct rt5651_priv, jack_detect_work.work);
-
-       int report, val = 0;
-
-       if (!rt5651->codec)
-               return;
-
-       switch (rt5651->pdata.jd_src) {
-       case RT5651_JD1_1:
-               val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000;
-               break;
-       case RT5651_JD1_2:
-               val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000;
-               break;
-       case RT5651_JD2:
-               val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000;
-               break;
-       default:
-               break;
-       }
-
-       report = rt5651_jack_detect(rt5651->codec, !val);
-
-       snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
-}
-
-int rt5651_set_jack_detect(struct snd_soc_codec *codec,
-                          struct snd_soc_jack *hp_jack)
-{
-       struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-
-       rt5651->hp_jack = hp_jack;
-       rt5651_irq(0, rt5651);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(rt5651_set_jack_detect);
-
+/*
+ * Note this function MUST not look at device-properties, see the comment
+ * above rt5651_apply_properties().
+ */
 static int rt5651_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
-       struct rt5651_platform_data *pdata = dev_get_platdata(&i2c->dev);
        struct rt5651_priv *rt5651;
        int ret;
 
@@ -1885,15 +2009,6 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, rt5651);
 
-       if (pdata)
-               rt5651->pdata = *pdata;
-       else if (i2c->dev.of_node)
-               rt5651_parse_dt(rt5651, i2c->dev.of_node);
-       else
-               dmi_check_system(rt5651_quirk_table);
-
-       rt5651_set_pdata(rt5651);
-
        rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap);
        if (IS_ERR(rt5651->regmap)) {
                ret = PTR_ERR(rt5651->regmap);
@@ -1916,70 +2031,13 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
        if (ret != 0)
                dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
 
-       if (rt5651->pdata.in2_diff)
-               regmap_update_bits(rt5651->regmap, RT5651_IN1_IN2,
-                                       RT5651_IN_DF2, RT5651_IN_DF2);
-
-       if (rt5651->pdata.dmic_en)
-               regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
-                               RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL);
-
+       rt5651->irq = i2c->irq;
        rt5651->hp_mute = 1;
 
-       if (rt5651->pdata.jd_src) {
-
-               /* IRQ output on GPIO1 */
-               regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
-                                  RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
-
-               switch (rt5651->pdata.jd_src) {
-               case RT5651_JD1_1:
-                       regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
-                                          RT5651_JD_TRG_SEL_MASK,
-                                          RT5651_JD_TRG_SEL_JD1_1);
-                       regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
-                                          RT5651_JD1_1_IRQ_EN,
-                                          RT5651_JD1_1_IRQ_EN);
-                       break;
-               case RT5651_JD1_2:
-                       regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
-                                          RT5651_JD_TRG_SEL_MASK,
-                                          RT5651_JD_TRG_SEL_JD1_2);
-                       regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
-                                          RT5651_JD1_2_IRQ_EN,
-                                          RT5651_JD1_2_IRQ_EN);
-                       break;
-               case RT5651_JD2:
-                       regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
-                                          RT5651_JD_TRG_SEL_MASK,
-                                          RT5651_JD_TRG_SEL_JD2);
-                       regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
-                                          RT5651_JD2_IRQ_EN,
-                                          RT5651_JD2_IRQ_EN);
-                       break;
-               case RT5651_JD_NULL:
-                       break;
-               default:
-                       dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
-                       break;
-               }
-       }
-
-       INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
-
-       if (i2c->irq) {
-               ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
-                                               rt5651_irq,
-                                               IRQF_TRIGGER_RISING |
-                                               IRQF_TRIGGER_FALLING |
-                                               IRQF_ONESHOT, "rt5651", rt5651);
-               if (ret) {
-                       dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
-                       return ret;
-               }
-       }
+       INIT_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                               &soc_component_dev_rt5651,
                                rt5651_dai, ARRAY_SIZE(rt5651_dai));
 
        return ret;
@@ -1989,8 +2047,7 @@ static int rt5651_i2c_remove(struct i2c_client *i2c)
 {
        struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
 
-       cancel_delayed_work_sync(&rt5651->jack_detect_work);
-       snd_soc_unregister_codec(&i2c->dev);
+       cancel_work_sync(&rt5651->jack_detect_work);
 
        return 0;
 }
index 4f8b202121d7a7ee07b1796fe8565a95b209759f..3a0968c53fde8ef5c5040d56c4621d4842af768e 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef __RT5651_H__
 #define __RT5651_H__
 
-#include <sound/rt5651.h>
+#include <dt-bindings/sound/rt5651.h>
 
 /* Info */
 #define RT5651_RESET                           0x00
 /* Index of Codec Private Register definition */
 #define RT5651_BIAS_CUR1                       0x12
 #define RT5651_BIAS_CUR3                       0x14
+#define RT5651_BIAS_CUR4                       0x15
 #define RT5651_CLSD_INT_REG1                   0x1c
 #define RT5651_CHPUMP_INT_REG1                 0x24
 #define RT5651_MAMP_INT_REG2                   0x37
 #define RT5651_D_GATE_EN_SFT                   0
 
 /* Codec Private Register definition */
+
+/* MIC Over current threshold scale factor (0x15) */
+#define RT5651_MIC_OVCD_SF_MASK                        (0x3 << 8)
+#define RT5651_MIC_OVCD_SF_SFT                 8
+#define RT5651_MIC_OVCD_SF_0P5                 (0x0 << 8)
+#define RT5651_MIC_OVCD_SF_0P75                        (0x1 << 8)
+#define RT5651_MIC_OVCD_SF_1P0                 (0x2 << 8)
+#define RT5651_MIC_OVCD_SF_1P5                 (0x3 << 8)
+
 /* 3D Speaker Control (0x63) */
 #define RT5651_3D_SPK_MASK                     (0x1 << 15)
 #define RT5651_3D_SPK_SFT                      15
@@ -2059,12 +2069,15 @@ struct rt5651_pll_code {
 };
 
 struct rt5651_priv {
-       struct snd_soc_codec *codec;
-       struct rt5651_platform_data pdata;
+       struct snd_soc_component *component;
        struct regmap *regmap;
        struct snd_soc_jack *hp_jack;
-       struct delayed_work jack_detect_work;
+       struct work_struct jack_detect_work;
+       unsigned int jd_src;
+       unsigned int ovcd_th;
+       unsigned int ovcd_sf;
 
+       int irq;
        int sysclk;
        int sysclk_src;
        int lrck[RT5651_AIFS];
@@ -2079,6 +2092,4 @@ struct rt5651_priv {
        bool hp_mute;
 };
 
-int rt5651_set_jack_detect(struct snd_soc_codec *codec,
-                          struct snd_soc_jack *hp_jack);
 #endif /* __RT5651_H__ */
index 07e7757417bc4e8ae159fae364f396f478f91a81..1c1a521c73cb4cb0f07954715548b7d574b9635f 100644 (file)
@@ -1238,26 +1238,26 @@ static SOC_VALUE_ENUM_SINGLE_DECL(
 static int rt5659_hp_vol_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int ret = snd_soc_put_volsw(kcontrol, ucontrol);
 
-       if (snd_soc_read(codec, RT5659_STO_NG2_CTRL_1) & RT5659_NG2_EN) {
-               snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
+       if (snd_soc_component_read32(component, RT5659_STO_NG2_CTRL_1) & RT5659_NG2_EN) {
+               snd_soc_component_update_bits(component, RT5659_STO_NG2_CTRL_1,
                        RT5659_NG2_EN_MASK, RT5659_NG2_DIS);
-               snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
+               snd_soc_component_update_bits(component, RT5659_STO_NG2_CTRL_1,
                        RT5659_NG2_EN_MASK, RT5659_NG2_EN);
        }
 
        return ret;
 }
 
-static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5659_enable_push_button_irq(struct snd_soc_component *component,
        bool enable)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (enable) {
-               snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, 0x000b);
+               snd_soc_component_write(component, RT5659_4BTN_IL_CMD_1, 0x000b);
 
                /* MICBIAS1 and Mic Det Power for button detect*/
                snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
@@ -1265,19 +1265,19 @@ static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
                        "Mic Det Power");
                snd_soc_dapm_sync(dapm);
 
-               snd_soc_update_bits(codec, RT5659_PWR_ANLG_2,
+               snd_soc_component_update_bits(component, RT5659_PWR_ANLG_2,
                        RT5659_PWR_MB1, RT5659_PWR_MB1);
-               snd_soc_update_bits(codec, RT5659_PWR_VOL,
+               snd_soc_component_update_bits(component, RT5659_PWR_VOL,
                        RT5659_PWR_MIC_DET, RT5659_PWR_MIC_DET);
 
-               snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
+               snd_soc_component_update_bits(component, RT5659_IRQ_CTRL_2,
                                RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
-               snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
+               snd_soc_component_update_bits(component, RT5659_4BTN_IL_CMD_2,
                                RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
        } else {
-               snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
+               snd_soc_component_update_bits(component, RT5659_4BTN_IL_CMD_2,
                                RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_DIS);
-               snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
+               snd_soc_component_update_bits(component, RT5659_IRQ_CTRL_2,
                                RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_DIS);
                /* MICBIAS1 and Mic Det Power for button detect*/
                snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
@@ -1288,7 +1288,7 @@ static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
 
 /**
  * rt5659_headset_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
@@ -1296,37 +1296,37 @@ static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
  * Returns detect status.
  */
 
-static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5659_headset_detect(struct snd_soc_component *component, int jack_insert)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
        int reg_63;
 
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
        if (jack_insert) {
                snd_soc_dapm_force_enable_pin(dapm,
                        "Mic Det Power");
                snd_soc_dapm_sync(dapm);
-               reg_63 = snd_soc_read(codec, RT5659_PWR_ANLG_1);
+               reg_63 = snd_soc_component_read32(component, RT5659_PWR_ANLG_1);
 
-               snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
+               snd_soc_component_update_bits(component, RT5659_PWR_ANLG_1,
                        RT5659_PWR_VREF2 | RT5659_PWR_MB,
                        RT5659_PWR_VREF2 | RT5659_PWR_MB);
                msleep(20);
-               snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
+               snd_soc_component_update_bits(component, RT5659_PWR_ANLG_1,
                        RT5659_PWR_FV2, RT5659_PWR_FV2);
 
-               snd_soc_write(codec, RT5659_EJD_CTRL_2, 0x4160);
-               snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
+               snd_soc_component_write(component, RT5659_EJD_CTRL_2, 0x4160);
+               snd_soc_component_update_bits(component, RT5659_EJD_CTRL_1,
                        0x20, 0x0);
                msleep(20);
-               snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
+               snd_soc_component_update_bits(component, RT5659_EJD_CTRL_1,
                        0x20, 0x20);
 
                while (i < 5) {
                        msleep(sleep_time[i]);
-                       val = snd_soc_read(codec, RT5659_EJD_CTRL_2) & 0x0003;
+                       val = snd_soc_component_read32(component, RT5659_EJD_CTRL_2) & 0x0003;
                        i++;
                        if (val == 0x1 || val == 0x2 || val == 0x3)
                                break;
@@ -1335,10 +1335,10 @@ static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
                switch (val) {
                case 1:
                        rt5659->jack_type = SND_JACK_HEADSET;
-                       rt5659_enable_push_button_irq(codec, true);
+                       rt5659_enable_push_button_irq(component, true);
                        break;
                default:
-                       snd_soc_write(codec, RT5659_PWR_ANLG_1, reg_63);
+                       snd_soc_component_write(component, RT5659_PWR_ANLG_1, reg_63);
                        rt5659->jack_type = SND_JACK_HEADPHONE;
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                        snd_soc_dapm_sync(dapm);
@@ -1348,21 +1348,21 @@ static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
                snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                snd_soc_dapm_sync(dapm);
                if (rt5659->jack_type == SND_JACK_HEADSET)
-                       rt5659_enable_push_button_irq(codec, false);
+                       rt5659_enable_push_button_irq(component, false);
                rt5659->jack_type = 0;
        }
 
-       dev_dbg(codec->dev, "jack_type = %d\n", rt5659->jack_type);
+       dev_dbg(component->dev, "jack_type = %d\n", rt5659->jack_type);
        return rt5659->jack_type;
 }
 
-static int rt5659_button_detect(struct snd_soc_codec *codec)
+static int rt5659_button_detect(struct snd_soc_component *component)
 {
        int btn_type, val;
 
-       val = snd_soc_read(codec, RT5659_4BTN_IL_CMD_1);
+       val = snd_soc_component_read32(component, RT5659_4BTN_IL_CMD_1);
        btn_type = val & 0xfff0;
-       snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, val);
+       snd_soc_component_write(component, RT5659_4BTN_IL_CMD_1, val);
 
        return btn_type;
 }
@@ -1377,10 +1377,10 @@ static irqreturn_t rt5659_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-int rt5659_set_jack_detect(struct snd_soc_codec *codec,
+int rt5659_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hs_jack)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
        rt5659->hs_jack = hs_jack;
 
@@ -1396,19 +1396,19 @@ static void rt5659_jack_detect_work(struct work_struct *work)
                container_of(work, struct rt5659_priv, jack_detect_work.work);
        int val, btn_type, report = 0;
 
-       if (!rt5659->codec)
+       if (!rt5659->component)
                return;
 
-       val = snd_soc_read(rt5659->codec, RT5659_INT_ST_1) & 0x0080;
+       val = snd_soc_component_read32(rt5659->component, RT5659_INT_ST_1) & 0x0080;
        if (!val) {
                /* jack in */
                if (rt5659->jack_type == 0) {
                        /* jack was out, report jack type */
-                       report = rt5659_headset_detect(rt5659->codec, 1);
+                       report = rt5659_headset_detect(rt5659->component, 1);
                } else {
                        /* jack is already in, report button event */
                        report = SND_JACK_HEADSET;
-                       btn_type = rt5659_button_detect(rt5659->codec);
+                       btn_type = rt5659_button_detect(rt5659->component);
                        /**
                         * rt5659 can report three kinds of button behavior,
                         * one click, double click and hold. However,
@@ -1441,7 +1441,7 @@ static void rt5659_jack_detect_work(struct work_struct *work)
                                break;
                        default:
                                btn_type = 0;
-                               dev_err(rt5659->codec->dev,
+                               dev_err(rt5659->component->dev,
                                        "Unexpected button code 0x%04x\n",
                                        btn_type);
                                break;
@@ -1453,7 +1453,7 @@ static void rt5659_jack_detect_work(struct work_struct *work)
                }
        } else {
                /* jack out */
-               report = rt5659_headset_detect(rt5659->codec, 0);
+               report = rt5659_headset_detect(rt5659->component, 0);
        }
 
        snd_soc_jack_report(rt5659->hs_jack, report, SND_JACK_HEADSET |
@@ -1461,6 +1461,61 @@ static void rt5659_jack_detect_work(struct work_struct *work)
                            SND_JACK_BTN_2 | SND_JACK_BTN_3);
 }
 
+static void rt5659_jack_detect_intel_hd_header(struct work_struct *work)
+{
+       struct rt5659_priv *rt5659 =
+               container_of(work, struct rt5659_priv, jack_detect_work.work);
+       unsigned int value;
+       bool hp_flag, mic_flag;
+
+       if (!rt5659->hs_jack)
+               return;
+
+       /* headphone jack */
+       regmap_read(rt5659->regmap, RT5659_GPIO_STA, &value);
+       hp_flag = (!(value & 0x8)) ? true : false;
+
+       if (hp_flag != rt5659->hda_hp_plugged) {
+               rt5659->hda_hp_plugged = hp_flag;
+
+               if (hp_flag) {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                               0x10, 0x0);
+                       rt5659->jack_type |= SND_JACK_HEADPHONE;
+               } else {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                               0x10, 0x10);
+                       rt5659->jack_type = rt5659->jack_type &
+                               (~SND_JACK_HEADPHONE);
+               }
+
+               snd_soc_jack_report(rt5659->hs_jack, rt5659->jack_type,
+                       SND_JACK_HEADPHONE);
+       }
+
+       /* mic jack */
+       regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+       regmap_write(rt5659->regmap, RT5659_4BTN_IL_CMD_1, value);
+       mic_flag = (value & 0x2000) ? true : false;
+
+       if (mic_flag != rt5659->hda_mic_plugged) {
+               rt5659->hda_mic_plugged = mic_flag;
+               if (mic_flag) {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                               0x2, 0x2);
+                       rt5659->jack_type |= SND_JACK_MICROPHONE;
+               } else {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                               0x2, 0x0);
+                       rt5659->jack_type = rt5659->jack_type
+                               & (~SND_JACK_MICROPHONE);
+               }
+
+               snd_soc_jack_report(rt5659->hs_jack, rt5659->jack_type,
+                       SND_JACK_MICROPHONE);
+       }
+}
+
 static const struct snd_kcontrol_new rt5659_snd_controls[] = {
        /* Speaker Output Volume */
        SOC_DOUBLE_TLV("Speaker Playback Volume", RT5659_SPO_VOL,
@@ -1550,8 +1605,8 @@ static const struct snd_kcontrol_new rt5659_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
        int pd, idx = -EINVAL;
 
        pd = rl6231_get_pre_div(rt5659->regmap,
@@ -1559,29 +1614,55 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        idx = rl6231_calc_dmic_clk(rt5659->sysclk / pd);
 
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else {
-               snd_soc_update_bits(codec, RT5659_DMIC_CTRL_1,
+               snd_soc_component_update_bits(component, RT5659_DMIC_CTRL_1,
                        RT5659_DMIC_CLK_MASK, idx << RT5659_DMIC_CLK_SFT);
        }
        return idx;
 }
 
-static int set_adc_clk(struct snd_soc_dapm_widget *w,
+static int set_adc1_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5659_CHOP_ADC,
-                       RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK,
-                       RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK);
+               snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+                       RT5659_CKXEN_ADC1_MASK | RT5659_CKGEN_ADC1_MASK,
+                       RT5659_CKXEN_ADC1_MASK | RT5659_CKGEN_ADC1_MASK);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5659_CHOP_ADC,
-                       RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK, 0);
+               snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+                       RT5659_CKXEN_ADC1_MASK | RT5659_CKGEN_ADC1_MASK, 0);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+
+}
+
+static int set_adc2_clk(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_component *component =
+               snd_soc_dapm_to_component(w->dapm);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+                       RT5659_CKXEN_ADC2_MASK | RT5659_CKGEN_ADC2_MASK,
+                       RT5659_CKXEN_ADC2_MASK | RT5659_CKGEN_ADC2_MASK);
+               break;
+
+       case SND_SOC_DAPM_PRE_PMD:
+               snd_soc_component_update_bits(component, RT5659_CHOP_ADC,
+                       RT5659_CKXEN_ADC2_MASK | RT5659_CKGEN_ADC2_MASK, 0);
                break;
 
        default:
@@ -1595,15 +1676,15 @@ static int set_adc_clk(struct snd_soc_dapm_widget *w,
 static int rt5659_charge_pump_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                /* Depop */
-               snd_soc_write(codec, RT5659_DEPOP_1, 0x0009);
+               snd_soc_component_write(component, RT5659_DEPOP_1, 0x0009);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
+               snd_soc_component_write(component, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
                break;
        default:
                return 0;
@@ -1616,9 +1697,9 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
                         struct snd_soc_dapm_widget *sink)
 {
        unsigned int val;
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-       val = snd_soc_read(codec, RT5659_GLB_CLK);
+       val = snd_soc_component_read32(component, RT5659_GLB_CLK);
        val &= RT5659_SCLK_SRC_MASK;
        if (val == RT5659_SCLK_SRC_PLL1)
                return 1;
@@ -1630,7 +1711,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
                         struct snd_soc_dapm_widget *sink)
 {
        unsigned int reg, shift, val;
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (w->shift) {
        case RT5659_ADC_MONO_R_ASRC_SFT:
@@ -1661,13 +1742,13 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
                return 0;
        }
 
-       val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+       val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
        switch (val) {
        case 1:
        case 2:
        case 3:
                /* I2S_Pre_Div1 should be 1 in asrc mode */
-               snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
                        RT5659_I2S_PD1_MASK, RT5659_I2S_PD1_2);
                return 1;
        default:
@@ -2303,24 +2384,24 @@ static const struct snd_kcontrol_new pdm_r_switch =
 static int rt5659_spk_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
+               snd_soc_component_update_bits(component, RT5659_CLASSD_CTRL_1,
                        RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_EN);
-               snd_soc_update_bits(codec, RT5659_CLASSD_2,
+               snd_soc_component_update_bits(component, RT5659_CLASSD_2,
                        RT5659_M_RI_DIG, RT5659_M_RI_DIG);
-               snd_soc_write(codec, RT5659_CLASSD_1, 0x0803);
-               snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
+               snd_soc_component_write(component, RT5659_CLASSD_1, 0x0803);
+               snd_soc_component_write(component, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_write(codec, RT5659_CLASSD_1, 0x0011);
-               snd_soc_update_bits(codec, RT5659_CLASSD_2,
+               snd_soc_component_write(component, RT5659_CLASSD_1, 0x0011);
+               snd_soc_component_update_bits(component, RT5659_CLASSD_2,
                        RT5659_M_RI_DIG, 0x0);
-               snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
-               snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
+               snd_soc_component_write(component, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
+               snd_soc_component_update_bits(component, RT5659_CLASSD_CTRL_1,
                        RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_DIS);
                break;
 
@@ -2335,15 +2416,15 @@ static int rt5659_spk_event(struct snd_soc_dapm_widget *w,
 static int rt5659_mono_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
+               snd_soc_component_write(component, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
+               snd_soc_component_write(component, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
                break;
 
        default:
@@ -2357,16 +2438,16 @@ static int rt5659_mono_event(struct snd_soc_dapm_widget *w,
 static int rt5659_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0e1e);
-               snd_soc_update_bits(codec, RT5659_DEPOP_1, 0x0010, 0x0010);
+               snd_soc_component_write(component, RT5659_HP_CHARGE_PUMP_1, 0x0e1e);
+               snd_soc_component_update_bits(component, RT5659_DEPOP_1, 0x0010, 0x0010);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_write(codec, RT5659_DEPOP_1, 0x0000);
+               snd_soc_component_write(component, RT5659_DEPOP_1, 0x0000);
                break;
 
        default:
@@ -2500,13 +2581,13 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
                RT5659_PWR_ADC_L1_BIT, 0, NULL, 0),
        SND_SOC_DAPM_SUPPLY("ADC1 R Power", RT5659_PWR_DIG_1,
                RT5659_PWR_ADC_R1_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_SUPPLY("ADC2 L Power", RT5659_PWR_DIG_2,
+       SND_SOC_DAPM_SUPPLY("ADC2 L Power", RT5659_PWR_DIG_1,
                RT5659_PWR_ADC_L2_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_SUPPLY("ADC2 R Power", RT5659_PWR_DIG_2,
+       SND_SOC_DAPM_SUPPLY("ADC2 R Power", RT5659_PWR_DIG_1,
                RT5659_PWR_ADC_R2_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_SUPPLY("ADC1 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
+       SND_SOC_DAPM_SUPPLY("ADC1 clock", SND_SOC_NOPM, 0, 0, set_adc1_clk,
                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-       SND_SOC_DAPM_SUPPLY("ADC2 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
+       SND_SOC_DAPM_SUPPLY("ADC2 clock", SND_SOC_NOPM, 0, 0, set_adc2_clk,
                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
        /* ADC Mux */
@@ -2818,11 +2899,6 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
        { "I2S2", NULL, "I2S2 ASRC" },
        { "I2S3", NULL, "I2S3 ASRC" },
 
-       { "IN1P", NULL, "LDO2" },
-       { "IN2P", NULL, "LDO2" },
-       { "IN3P", NULL, "LDO2" },
-       { "IN4P", NULL, "LDO2" },
-
        { "DMIC1", NULL, "DMIC L1" },
        { "DMIC1", NULL, "DMIC R1" },
        { "DMIC2", NULL, "DMIC L2" },
@@ -3237,21 +3313,21 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
 static int rt5659_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int pre_div, frame_size;
 
        rt5659->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5659->sysclk, rt5659->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+               dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
                        rt5659->lrck[dai->id], dai->id);
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
 
@@ -3278,39 +3354,39 @@ static int rt5659_hw_params(struct snd_pcm_substream *substream,
        case RT5659_AIF1:
                mask_clk = RT5659_I2S_PD1_MASK;
                val_clk = pre_div << RT5659_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5659_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5659_I2S1_SDP,
                        RT5659_I2S_DL_MASK, val_len);
                break;
        case RT5659_AIF2:
                mask_clk = RT5659_I2S_PD2_MASK;
                val_clk = pre_div << RT5659_I2S_PD2_SFT;
-               snd_soc_update_bits(codec, RT5659_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5659_I2S2_SDP,
                        RT5659_I2S_DL_MASK, val_len);
                break;
        case RT5659_AIF3:
                mask_clk = RT5659_I2S_PD3_MASK;
                val_clk = pre_div << RT5659_I2S_PD3_SFT;
-               snd_soc_update_bits(codec, RT5659_I2S3_SDP,
+               snd_soc_component_update_bits(component, RT5659_I2S3_SDP,
                        RT5659_I2S_DL_MASK, val_len);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5659_ADDA_CLK_1, mask_clk, val_clk);
+       snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1, mask_clk, val_clk);
 
        switch (rt5659->lrck[dai->id]) {
        case 192000:
-               snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
                        RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_32);
                break;
        case 96000:
-               snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
                        RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_64);
                break;
        default:
-               snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
                        RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_128);
                break;
        }
@@ -3320,8 +3396,8 @@ static int rt5659_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -3364,31 +3440,31 @@ static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (dai->id) {
        case RT5659_AIF1:
-               snd_soc_update_bits(codec, RT5659_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5659_I2S1_SDP,
                        RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
                        RT5659_I2S_DF_MASK, reg_val);
                break;
        case RT5659_AIF2:
-               snd_soc_update_bits(codec, RT5659_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5659_I2S2_SDP,
                        RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
                        RT5659_I2S_DF_MASK, reg_val);
                break;
        case RT5659_AIF3:
-               snd_soc_update_bits(codec, RT5659_I2S3_SDP,
+               snd_soc_component_update_bits(component, RT5659_I2S3_SDP,
                        RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
                        RT5659_I2S_DF_MASK, reg_val);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
        return 0;
 }
 
-static int rt5659_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int rt5659_set_component_sysclk(struct snd_soc_component *component, int clk_id,
                                   int source, unsigned int freq, int dir)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5659->sysclk && clk_id == rt5659->sysclk_src)
@@ -3405,25 +3481,25 @@ static int rt5659_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
                reg_val |= RT5659_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5659_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5659_GLB_CLK,
                RT5659_SCLK_SRC_MASK, reg_val);
        rt5659->sysclk = freq;
        rt5659->sysclk_src = clk_id;
 
-       dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n",
+       dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
                freq, clk_id);
 
        return 0;
 }
 
-static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
+static int rt5659_set_component_pll(struct snd_soc_component *component, int pll_id,
                                int source, unsigned int freq_in,
                                unsigned int freq_out)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -3432,50 +3508,50 @@ static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5659->pll_in = 0;
                rt5659->pll_out = 0;
-               snd_soc_update_bits(codec, RT5659_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5659_GLB_CLK,
                        RT5659_SCLK_SRC_MASK, RT5659_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5659_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5659_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5659_GLB_CLK,
                        RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_MCLK);
                break;
        case RT5659_PLL1_S_BCLK1:
-               snd_soc_update_bits(codec, RT5659_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5659_GLB_CLK,
                                RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK1);
                break;
        case RT5659_PLL1_S_BCLK2:
-               snd_soc_update_bits(codec, RT5659_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5659_GLB_CLK,
                                RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK2);
                break;
        case RT5659_PLL1_S_BCLK3:
-               snd_soc_update_bits(codec, RT5659_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5659_GLB_CLK,
                                RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK3);
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5659_PLL_CTRL_1,
+       snd_soc_component_write(component, RT5659_PLL_CTRL_1,
                pll_code.n_code << RT5659_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5659_PLL_CTRL_2,
+       snd_soc_component_write(component, RT5659_PLL_CTRL_2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5659_PLL_M_SFT |
                pll_code.m_bp << RT5659_PLL_M_BP_SFT);
 
@@ -3489,7 +3565,7 @@ static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
 static int rt5659_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val = 0;
 
        if (rx_mask || tx_mask)
@@ -3533,29 +3609,29 @@ static int rt5659_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5659_TDM_CTRL_1, 0x8ff0, val);
+       snd_soc_component_update_bits(component, RT5659_TDM_CTRL_1, 0x8ff0, val);
 
        return 0;
 }
 
 static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 
        rt5659->bclk[dai->id] = ratio;
 
        if (ratio == 64) {
                switch (dai->id) {
                case RT5659_AIF2:
-                       snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+                       snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
                                RT5659_I2S_BCLK_MS2_MASK,
                                RT5659_I2S_BCLK_MS2_64);
                        break;
                case RT5659_AIF3:
-                       snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
+                       snd_soc_component_update_bits(component, RT5659_ADDA_CLK_1,
                                RT5659_I2S_BCLK_MS3_MASK,
                                RT5659_I2S_BCLK_MS3_64);
                        break;
@@ -3565,11 +3641,11 @@ static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
        return 0;
 }
 
-static int rt5659_set_bias_level(struct snd_soc_codec *codec,
+static int rt5659_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -3591,7 +3667,7 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
                if (dapm->bias_level == SND_SOC_BIAS_OFF) {
                        ret = clk_prepare_enable(rt5659->mclk);
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "failed to enable MCLK: %d\n", ret);
                                return ret;
                        }
@@ -3617,37 +3693,35 @@ static int rt5659_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5659_probe(struct snd_soc_codec *codec)
+static int rt5659_probe(struct snd_soc_component *component)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
-       rt5659->codec = codec;
+       rt5659->component = component;
 
        return 0;
 }
 
-static int rt5659_remove(struct snd_soc_codec *codec)
+static void rt5659_remove(struct snd_soc_component *component)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
        regmap_write(rt5659->regmap, RT5659_RESET, 0);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5659_suspend(struct snd_soc_codec *codec)
+static int rt5659_suspend(struct snd_soc_component *component)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5659->regmap, true);
        regcache_mark_dirty(rt5659->regmap);
        return 0;
 }
 
-static int rt5659_resume(struct snd_soc_codec *codec)
+static int rt5659_resume(struct snd_soc_component *component)
 {
-       struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
+       struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5659->regmap, false);
        regcache_sync(rt5659->regmap);
@@ -3730,23 +3804,23 @@ static struct snd_soc_dai_driver rt5659_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
-       .probe = rt5659_probe,
-       .remove = rt5659_remove,
-       .suspend = rt5659_suspend,
-       .resume = rt5659_resume,
-       .set_bias_level = rt5659_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5659_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5659_snd_controls),
-               .dapm_widgets           = rt5659_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5659_dapm_widgets),
-               .dapm_routes            = rt5659_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5659_dapm_routes),
-       },
-       .set_sysclk = rt5659_set_codec_sysclk,
-       .set_pll = rt5659_set_codec_pll,
+static const struct snd_soc_component_driver soc_component_dev_rt5659 = {
+       .probe                  = rt5659_probe,
+       .remove                 = rt5659_remove,
+       .suspend                = rt5659_suspend,
+       .resume                 = rt5659_resume,
+       .set_bias_level         = rt5659_set_bias_level,
+       .controls               = rt5659_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5659_snd_controls),
+       .dapm_widgets           = rt5659_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5659_dapm_widgets),
+       .dapm_routes            = rt5659_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5659_dapm_routes),
+       .set_sysclk             = rt5659_set_component_sysclk,
+       .set_pll                = rt5659_set_component_pll,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 
@@ -3849,7 +3923,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
                        break;
 
                if (count > 30) {
-                       dev_err(rt5659->codec->dev,
+                       dev_err(rt5659->component->dev,
                                "HP Calibration 1 Failure\n");
                        return;
                }
@@ -3874,7 +3948,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
                        break;
 
                if (count > 85) {
-                       dev_err(rt5659->codec->dev,
+                       dev_err(rt5659->component->dev,
                                "HP Calibration 2 Failure\n");
                        return;
                }
@@ -3922,7 +3996,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
                        break;
 
                if (count > 10) {
-                       dev_err(rt5659->codec->dev,
+                       dev_err(rt5659->component->dev,
                                "SPK Calibration Failure\n");
                        return;
                }
@@ -3955,7 +4029,7 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
                        break;
 
                if (count > 35) {
-                       dev_err(rt5659->codec->dev,
+                       dev_err(rt5659->component->dev,
                                "Mono Calibration Failure\n");
                        return;
                }
@@ -3990,6 +4064,54 @@ static void rt5659_calibrate(struct rt5659_priv *rt5659)
        regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
 }
 
+static void rt5659_intel_hd_header_probe_setup(struct rt5659_priv *rt5659)
+{
+       int value;
+
+       regmap_read(rt5659->regmap, RT5659_GPIO_STA, &value);
+       if (!(value & 0x8)) {
+               rt5659->hda_hp_plugged = true;
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                       0x10, 0x0);
+       } else {
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                       0x10, 0x10);
+       }
+
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
+               RT5659_PWR_VREF2 | RT5659_PWR_MB,
+               RT5659_PWR_VREF2 | RT5659_PWR_MB);
+       msleep(20);
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
+               RT5659_PWR_FV2, RT5659_PWR_FV2);
+
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_3, RT5659_PWR_LDO2,
+               RT5659_PWR_LDO2);
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_2, RT5659_PWR_MB1,
+               RT5659_PWR_MB1);
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_VOL, RT5659_PWR_MIC_DET,
+               RT5659_PWR_MIC_DET);
+       msleep(20);
+
+       regmap_update_bits(rt5659->regmap, RT5659_4BTN_IL_CMD_2,
+               RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
+       regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+       regmap_write(rt5659->regmap, RT5659_4BTN_IL_CMD_1, value);
+       regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+
+       if (value & 0x2000) {
+               rt5659->hda_mic_plugged = true;
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                       0x2, 0x2);
+       } else {
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                       0x2, 0x0);
+       }
+
+       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+               RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
+}
+
 static int rt5659_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
@@ -4174,16 +4296,23 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
                                RT5659_PWR_MB, RT5659_PWR_MB);
                regmap_write(rt5659->regmap, RT5659_PWR_ANLG_2, 0x0001);
                regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_2, 0x0040);
+               INIT_DELAYED_WORK(&rt5659->jack_detect_work,
+                       rt5659_jack_detect_work);
                break;
-       case RT5659_JD_NULL:
+       case RT5659_JD_HDA_HEADER:
+               regmap_write(rt5659->regmap, RT5659_GPIO_CTRL_3, 0x8000);
+               regmap_write(rt5659->regmap, RT5659_RC_CLK_CTRL, 0x0900);
+               regmap_write(rt5659->regmap, RT5659_EJD_CTRL_1,  0x70c0);
+               regmap_write(rt5659->regmap, RT5659_JD_CTRL_1,   0x2000);
+               regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_1,  0x0040);
+               INIT_DELAYED_WORK(&rt5659->jack_detect_work,
+                       rt5659_jack_detect_intel_hd_header);
+               rt5659_intel_hd_header_probe_setup(rt5659);
                break;
        default:
-               dev_warn(&i2c->dev, "Currently, support JD3 only\n");
                break;
        }
 
-       INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work);
-
        if (i2c->irq) {
                ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
                        rt5659_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -4196,17 +4325,11 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
                                   RT5659_GP1_PIN_MASK, RT5659_GP1_PIN_IRQ);
        }
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
+       return devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt5659,
                        rt5659_dai, ARRAY_SIZE(rt5659_dai));
 }
 
-static int rt5659_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static void rt5659_i2c_shutdown(struct i2c_client *client)
 {
        struct rt5659_priv *rt5659 = i2c_get_clientdata(client);
@@ -4239,7 +4362,6 @@ static struct i2c_driver rt5659_i2c_driver = {
                .acpi_match_table = ACPI_PTR(rt5659_acpi_match),
        },
        .probe = rt5659_i2c_probe,
-       .remove = rt5659_i2c_remove,
        .shutdown = rt5659_i2c_shutdown,
        .id_table = rt5659_i2c_id,
 };
index 8f1aeef084891eacb2c9aa85ef9040a9c714a06d..8b576d7687449bcf44a744810750c1c06a459653 100644 (file)
 #define RT5659_PWR_ADC_R1                      (0x1 << 3)
 #define RT5659_PWR_ADC_R1_BIT                  3
 #define RT5659_PWR_ADC_L2                      (0x1 << 2)
-#define RT5659_PWR_ADC_L2_BIT                  4
+#define RT5659_PWR_ADC_L2_BIT                  2
 #define RT5659_PWR_ADC_R2                      (0x1 << 1)
 #define RT5659_PWR_ADC_R2_BIT                  1
 #define RT5659_PWR_CLS_D                       (0x1)
 #define RT5659_CKGEN_DAC2_SFT                  4
 
 /* Chopper and Clock control for ADC (0x013b)*/
-#define RT5659_CKXEN_ADCC_MASK                 (0x1 << 13)
-#define RT5659_CKXEN_ADCC_SFT                  13
-#define RT5659_CKGEN_ADCC_MASK                 (0x1 << 12)
-#define RT5659_CKGEN_ADCC_SFT                  12
+#define RT5659_CKXEN_ADC1_MASK                 (0x1 << 13)
+#define RT5659_CKXEN_ADC1_SFT                  13
+#define RT5659_CKGEN_ADC1_MASK                 (0x1 << 12)
+#define RT5659_CKGEN_ADC1_SFT                  12
+#define RT5659_CKXEN_ADC2_MASK                 (0x1 << 5)
+#define RT5659_CKXEN_ADC2_SFT                  5
+#define RT5659_CKGEN_ADC2_MASK                 (0x1 << 4)
+#define RT5659_CKGEN_ADC2_SFT                  4
 
 /* Test Mode Control 1 (0x0145) */
 #define RT5659_AD2DA_LB_MASK                   (0x1 << 9)
@@ -1789,7 +1793,7 @@ struct rt5659_pll_code {
 };
 
 struct rt5659_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5659_platform_data pdata;
        struct regmap *regmap;
        struct gpio_desc *gpiod_ldo1_en;
@@ -1810,10 +1814,11 @@ struct rt5659_priv {
        int pll_out;
 
        int jack_type;
-
+       bool hda_hp_plugged;
+       bool hda_mic_plugged;
 };
 
-int rt5659_set_jack_detect(struct snd_soc_codec *codec,
+int rt5659_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hs_jack);
 
 #endif /* __RT5659_H__ */
index d22ef00e0d964e09c9930f58d62c5f5c247e1a25..20a755137e637c2dbafc7d1268a937fca90d28a4 100644 (file)
@@ -354,17 +354,17 @@ static const struct snd_kcontrol_new rt5660_snd_controls[] = {
 static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
        int idx, rate;
 
        rate = rt5660->sysclk / rl6231_get_pre_div(rt5660->regmap,
                RT5660_ADDA_CLK1, RT5660_I2S_PD1_SFT);
        idx = rl6231_calc_dmic_clk(rate);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
-               snd_soc_update_bits(codec, RT5660_DMIC_CTRL1,
+               snd_soc_component_update_bits(component, RT5660_DMIC_CTRL1,
                        RT5660_DMIC_CLK_MASK, idx << RT5660_DMIC_CLK_SFT);
 
        return idx;
@@ -373,10 +373,10 @@ static int rt5660_set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int rt5660_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int val;
 
-       val = snd_soc_read(codec, RT5660_GLB_CLK);
+       val = snd_soc_component_read32(component, RT5660_GLB_CLK);
        val &= RT5660_SCLK_SRC_MASK;
        if (val == RT5660_SCLK_SRC_PLL1)
                return 1;
@@ -541,17 +541,17 @@ static const struct snd_kcontrol_new rt5660_if1_adc_swap_mux =
 static int rt5660_lout_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL,
+               snd_soc_component_update_bits(component, RT5660_LOUT_AMP_CTRL,
                        RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK,
                        RT5660_LOUT_CO_EN | RT5660_LOUT_CB_PU);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5660_LOUT_AMP_CTRL,
+               snd_soc_component_update_bits(component, RT5660_LOUT_AMP_CTRL,
                        RT5660_LOUT_CO_MASK | RT5660_LOUT_CB_MASK,
                        RT5660_LOUT_CO_DIS | RT5660_LOUT_CB_PD);
                break;
@@ -838,22 +838,22 @@ static const struct snd_soc_dapm_route rt5660_dapm_routes[] = {
 static int rt5660_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int pre_div, bclk_ms, frame_size;
 
        rt5660->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5660->sysclk, rt5660->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+               dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
                        rt5660->lrck[dai->id], dai->id);
                return -EINVAL;
        }
 
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return frame_size;
        }
 
@@ -890,13 +890,13 @@ static int rt5660_hw_params(struct snd_pcm_substream *substream,
                mask_clk = RT5660_I2S_BCLK_MS1_MASK | RT5660_I2S_PD1_MASK;
                val_clk = bclk_ms << RT5660_I2S_BCLK_MS1_SFT |
                        pre_div << RT5660_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK,
+               snd_soc_component_update_bits(component, RT5660_I2S1_SDP, RT5660_I2S_DL_MASK,
                        val_len);
-               snd_soc_update_bits(codec, RT5660_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5660_ADDA_CLK1, mask_clk, val_clk);
                break;
 
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
@@ -905,8 +905,8 @@ static int rt5660_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -957,13 +957,13 @@ static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (dai->id) {
        case RT5660_AIF1:
-               snd_soc_update_bits(codec, RT5660_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5660_I2S1_SDP,
                        RT5660_I2S_MS_MASK | RT5660_I2S_BP_MASK |
                        RT5660_I2S_DF_MASK, reg_val);
                break;
 
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
@@ -973,8 +973,8 @@ static int rt5660_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5660->sysclk && clk_id == rt5660->sysclk_src)
@@ -994,11 +994,11 @@ static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
                break;
 
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK,
+       snd_soc_component_update_bits(component, RT5660_GLB_CLK, RT5660_SCLK_SRC_MASK,
                reg_val);
 
        rt5660->sysclk = freq;
@@ -1012,8 +1012,8 @@ static int rt5660_set_dai_sysclk(struct snd_soc_dai *dai,
 static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -1022,44 +1022,44 @@ static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5660->pll_in = 0;
                rt5660->pll_out = 0;
-               snd_soc_update_bits(codec, RT5660_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5660_GLB_CLK,
                        RT5660_SCLK_SRC_MASK, RT5660_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5660_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5660_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5660_GLB_CLK,
                        RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_MCLK);
                break;
 
        case RT5660_PLL1_S_BCLK:
-               snd_soc_update_bits(codec, RT5660_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5660_GLB_CLK,
                        RT5660_PLL1_SRC_MASK, RT5660_PLL1_SRC_BCLK1);
                break;
 
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5660_PLL_CTRL1,
+       snd_soc_component_write(component, RT5660_PLL_CTRL1,
                pll_code.n_code << RT5660_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5660_PLL_CTRL2,
+       snd_soc_component_write(component, RT5660_PLL_CTRL2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5660_PLL_M_SFT |
                pll_code.m_bp << RT5660_PLL_M_BP_SFT);
 
@@ -1070,10 +1070,10 @@ static int rt5660_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
        return 0;
 }
 
-static int rt5660_set_bias_level(struct snd_soc_codec *codec,
+static int rt5660_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -1081,13 +1081,13 @@ static int rt5660_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, RT5660_GEN_CTRL1,
+               snd_soc_component_update_bits(component, RT5660_GEN_CTRL1,
                        RT5660_DIG_GATE_CTRL, RT5660_DIG_GATE_CTRL);
 
                if (IS_ERR(rt5660->mclk))
                        break;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) {
                        clk_disable_unprepare(rt5660->mclk);
                } else {
                        ret = clk_prepare_enable(rt5660->mclk);
@@ -1097,21 +1097,21 @@ static int rt5660_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_update_bits(codec, RT5660_PWR_ANLG1,
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_update_bits(component, RT5660_PWR_ANLG1,
                                RT5660_PWR_VREF1 | RT5660_PWR_MB |
                                RT5660_PWR_BG | RT5660_PWR_VREF2,
                                RT5660_PWR_VREF1 | RT5660_PWR_MB |
                                RT5660_PWR_BG | RT5660_PWR_VREF2);
                        usleep_range(10000, 15000);
-                       snd_soc_update_bits(codec, RT5660_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5660_PWR_ANLG1,
                                RT5660_PWR_FV1 | RT5660_PWR_FV2,
                                RT5660_PWR_FV1 | RT5660_PWR_FV2);
                }
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, RT5660_GEN_CTRL1,
+               snd_soc_component_update_bits(component, RT5660_GEN_CTRL1,
                        RT5660_DIG_GATE_CTRL, 0);
                break;
 
@@ -1122,24 +1122,24 @@ static int rt5660_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5660_probe(struct snd_soc_codec *codec)
+static int rt5660_probe(struct snd_soc_component *component)
 {
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 
-       rt5660->codec = codec;
+       rt5660->component = component;
 
        return 0;
 }
 
-static int rt5660_remove(struct snd_soc_codec *codec)
+static void rt5660_remove(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, RT5660_RESET, 0);
+       snd_soc_component_write(component, RT5660_RESET, 0);
 }
 
 #ifdef CONFIG_PM
-static int rt5660_suspend(struct snd_soc_codec *codec)
+static int rt5660_suspend(struct snd_soc_component *component)
 {
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5660->regmap, true);
        regcache_mark_dirty(rt5660->regmap);
@@ -1147,9 +1147,9 @@ static int rt5660_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5660_resume(struct snd_soc_codec *codec)
+static int rt5660_resume(struct snd_soc_component *component)
 {
-       struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
+       struct rt5660_priv *rt5660 = snd_soc_component_get_drvdata(component);
 
        if (rt5660->pdata.poweroff_codec_in_suspend)
                msleep(350);
@@ -1197,21 +1197,21 @@ static struct snd_soc_dai_driver rt5660_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5660 = {
-       .probe = rt5660_probe,
-       .remove = rt5660_remove,
-       .suspend = rt5660_suspend,
-       .resume = rt5660_resume,
-       .set_bias_level = rt5660_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5660_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5660_snd_controls),
-               .dapm_widgets           = rt5660_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5660_dapm_widgets),
-               .dapm_routes            = rt5660_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5660_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5660 = {
+       .probe                  = rt5660_probe,
+       .remove                 = rt5660_remove,
+       .suspend                = rt5660_suspend,
+       .resume                 = rt5660_resume,
+       .set_bias_level         = rt5660_set_bias_level,
+       .controls               = rt5660_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5660_snd_controls),
+       .dapm_widgets           = rt5660_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5660_dapm_widgets),
+       .dapm_routes            = rt5660_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5660_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5660_regmap = {
@@ -1329,17 +1329,11 @@ static int rt5660_i2c_probe(struct i2c_client *i2c,
                                RT5660_SEL_DMIC_DATA_IN1P);
        }
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5660,
+       return devm_snd_soc_register_component(&i2c->dev,
+                                     &soc_component_dev_rt5660,
                                      rt5660_dai, ARRAY_SIZE(rt5660_dai));
 }
 
-static int rt5660_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static struct i2c_driver rt5660_i2c_driver = {
        .driver = {
                .name = "rt5660",
@@ -1347,7 +1341,6 @@ static struct i2c_driver rt5660_i2c_driver = {
                .of_match_table = of_match_ptr(rt5660_of_match),
        },
        .probe = rt5660_i2c_probe,
-       .remove   = rt5660_i2c_remove,
        .id_table = rt5660_i2c_id,
 };
 module_i2c_driver(rt5660_i2c_driver);
index bba18fb66b6f7685dc883c4671c416e2bed7d0f1..c65de0a20a49c261d1df8c698949249914e7498c 100644 (file)
@@ -831,7 +831,7 @@ enum {
 };
 
 struct rt5660_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5660_platform_data pdata;
        struct regmap *regmap;
        struct clk *mclk;
index d329bf719d80f01e5dc67865e4258f0cca50d6d5..20c0aeea6ca3489acd0bc29daf418298c5c546f8 100644 (file)
@@ -49,7 +49,7 @@ struct impedance_mapping_table {
 };
 
 struct rt5663_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5663_platform_data pdata;
        struct regmap *regmap;
        struct delayed_work jack_detect_work, jd_unplug_work;
@@ -1384,57 +1384,57 @@ static const char * const rt5663_if1_adc_data_select[] = {
 static SOC_ENUM_SINGLE_DECL(rt5663_if1_adc_enum, RT5663_TDM_2,
        RT5663_DATA_SWAP_ADCDAT1_SHIFT, rt5663_if1_adc_data_select);
 
-static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5663_enable_push_button_irq(struct snd_soc_component *component,
        bool enable)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        if (enable) {
-               snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
                        RT5663_EN_4BTN_INL_MASK, RT5663_EN_4BTN_INL_EN);
                /* reset in-line command */
-               snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
                        RT5663_RESET_4BTN_INL_MASK,
                        RT5663_RESET_4BTN_INL_RESET);
-               snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
                        RT5663_RESET_4BTN_INL_MASK,
                        RT5663_RESET_4BTN_INL_NOR);
                switch (rt5663->codec_ver) {
                case CODEC_VER_1:
-                       snd_soc_update_bits(codec, RT5663_IRQ_3,
+                       snd_soc_component_update_bits(component, RT5663_IRQ_3,
                                RT5663_V2_EN_IRQ_INLINE_MASK,
                                RT5663_V2_EN_IRQ_INLINE_NOR);
                        break;
                case CODEC_VER_0:
-                       snd_soc_update_bits(codec, RT5663_IRQ_2,
+                       snd_soc_component_update_bits(component, RT5663_IRQ_2,
                                RT5663_EN_IRQ_INLINE_MASK,
                                RT5663_EN_IRQ_INLINE_NOR);
                        break;
                default:
-                       dev_err(codec->dev, "Unknown CODEC Version\n");
+                       dev_err(component->dev, "Unknown CODEC Version\n");
                }
        } else {
                switch (rt5663->codec_ver) {
                case CODEC_VER_1:
-                       snd_soc_update_bits(codec, RT5663_IRQ_3,
+                       snd_soc_component_update_bits(component, RT5663_IRQ_3,
                                RT5663_V2_EN_IRQ_INLINE_MASK,
                                RT5663_V2_EN_IRQ_INLINE_BYP);
                        break;
                case CODEC_VER_0:
-                       snd_soc_update_bits(codec, RT5663_IRQ_2,
+                       snd_soc_component_update_bits(component, RT5663_IRQ_2,
                                RT5663_EN_IRQ_INLINE_MASK,
                                RT5663_EN_IRQ_INLINE_BYP);
                        break;
                default:
-                       dev_err(codec->dev, "Unknown CODEC Version\n");
+                       dev_err(component->dev, "Unknown CODEC Version\n");
                }
-               snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
                        RT5663_EN_4BTN_INL_MASK, RT5663_EN_4BTN_INL_DIS);
                /* reset in-line command */
-               snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
                        RT5663_RESET_4BTN_INL_MASK,
                        RT5663_RESET_4BTN_INL_RESET);
-               snd_soc_update_bits(codec, RT5663_IL_CMD_6,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_6,
                        RT5663_RESET_4BTN_INL_MASK,
                        RT5663_RESET_4BTN_INL_NOR);
        }
@@ -1442,7 +1442,7 @@ static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
 
 /**
  * rt5663_v2_jack_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
@@ -1450,41 +1450,41 @@ static void rt5663_enable_push_button_irq(struct snd_soc_codec *codec,
  * Returns detect status.
  */
 
-static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5663_v2_jack_detect(struct snd_soc_component *component, int jack_insert)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
 
-       dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
+       dev_dbg(component->dev, "%s jack_insert:%d\n", __func__, jack_insert);
        if (jack_insert) {
-               snd_soc_write(codec, RT5663_CBJ_TYPE_2, 0x8040);
-               snd_soc_write(codec, RT5663_CBJ_TYPE_3, 0x1484);
+               snd_soc_component_write(component, RT5663_CBJ_TYPE_2, 0x8040);
+               snd_soc_component_write(component, RT5663_CBJ_TYPE_3, 0x1484);
 
                snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
                snd_soc_dapm_force_enable_pin(dapm, "MICBIAS2");
                snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
                snd_soc_dapm_force_enable_pin(dapm, "CBJ Power");
                snd_soc_dapm_sync(dapm);
-               snd_soc_update_bits(codec, RT5663_RC_CLK,
+               snd_soc_component_update_bits(component, RT5663_RC_CLK,
                        RT5663_DIG_1M_CLK_MASK, RT5663_DIG_1M_CLK_EN);
-               snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x8);
+               snd_soc_component_update_bits(component, RT5663_RECMIX, 0x8, 0x8);
 
                while (i < 5) {
                        msleep(sleep_time[i]);
-                       val = snd_soc_read(codec, RT5663_CBJ_TYPE_2) & 0x0003;
+                       val = snd_soc_component_read32(component, RT5663_CBJ_TYPE_2) & 0x0003;
                        if (val == 0x1 || val == 0x2 || val == 0x3)
                                break;
-                       dev_dbg(codec->dev, "%s: MX-0011 val=%x sleep %d\n",
+                       dev_dbg(component->dev, "%s: MX-0011 val=%x sleep %d\n",
                                __func__, val, sleep_time[i]);
                        i++;
                }
-               dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
+               dev_dbg(component->dev, "%s val = %d\n", __func__, val);
                switch (val) {
                case 1:
                case 2:
                        rt5663->jack_type = SND_JACK_HEADSET;
-                       rt5663_enable_push_button_irq(codec, true);
+                       rt5663_enable_push_button_irq(component, true);
                        break;
                default:
                        snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
@@ -1496,10 +1496,10 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                        break;
                }
        } else {
-               snd_soc_update_bits(codec, RT5663_RECMIX, 0x8, 0x0);
+               snd_soc_component_update_bits(component, RT5663_RECMIX, 0x8, 0x0);
 
                if (rt5663->jack_type == SND_JACK_HEADSET) {
-                       rt5663_enable_push_button_irq(codec, false);
+                       rt5663_enable_push_button_irq(component, false);
                        snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
                        snd_soc_dapm_disable_pin(dapm, "MICBIAS2");
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
@@ -1509,60 +1509,60 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                rt5663->jack_type = 0;
        }
 
-       dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type);
+       dev_dbg(component->dev, "jack_type = %d\n", rt5663->jack_type);
        return rt5663->jack_type;
 }
 
 /**
  * rt5663_jack_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
  *
  * Returns detect status.
  */
-static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5663_jack_detect(struct snd_soc_component *component, int jack_insert)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        int val, i = 0;
 
-       dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
+       dev_dbg(component->dev, "%s jack_insert:%d\n", __func__, jack_insert);
 
        if (jack_insert) {
-               snd_soc_update_bits(codec, RT5663_DIG_MISC,
+               snd_soc_component_update_bits(component, RT5663_DIG_MISC,
                        RT5663_DIG_GATE_CTRL_MASK, RT5663_DIG_GATE_CTRL_EN);
-               snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+               snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
                        RT5663_SI_HP_MASK | RT5663_OSW_HP_L_MASK |
                        RT5663_OSW_HP_R_MASK, RT5663_SI_HP_EN |
                        RT5663_OSW_HP_L_DIS | RT5663_OSW_HP_R_DIS);
-               snd_soc_update_bits(codec, RT5663_DUMMY_1,
+               snd_soc_component_update_bits(component, RT5663_DUMMY_1,
                        RT5663_EMB_CLK_MASK | RT5663_HPA_CPL_BIAS_MASK |
                        RT5663_HPA_CPR_BIAS_MASK, RT5663_EMB_CLK_EN |
                        RT5663_HPA_CPL_BIAS_1 | RT5663_HPA_CPR_BIAS_1);
-               snd_soc_update_bits(codec, RT5663_CBJ_1,
+               snd_soc_component_update_bits(component, RT5663_CBJ_1,
                        RT5663_INBUF_CBJ_BST1_MASK | RT5663_CBJ_SENSE_BST1_MASK,
                        RT5663_INBUF_CBJ_BST1_ON | RT5663_CBJ_SENSE_BST1_L);
-               snd_soc_update_bits(codec, RT5663_IL_CMD_2,
+               snd_soc_component_update_bits(component, RT5663_IL_CMD_2,
                        RT5663_PWR_MIC_DET_MASK, RT5663_PWR_MIC_DET_ON);
                /* BST1 power on for JD */
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
                        RT5663_PWR_BST1_MASK, RT5663_PWR_BST1_ON);
-               snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
+               snd_soc_component_update_bits(component, RT5663_EM_JACK_TYPE_1,
                        RT5663_CBJ_DET_MASK | RT5663_EXT_JD_MASK |
                        RT5663_POL_EXT_JD_MASK, RT5663_CBJ_DET_EN |
                        RT5663_EXT_JD_EN | RT5663_POL_EXT_JD_EN);
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                        RT5663_PWR_MB_MASK | RT5663_LDO1_DVO_MASK |
                        RT5663_AMP_HP_MASK, RT5663_PWR_MB |
                        RT5663_LDO1_DVO_0_9V | RT5663_AMP_HP_3X);
-               snd_soc_update_bits(codec, RT5663_AUTO_1MRC_CLK,
+               snd_soc_component_update_bits(component, RT5663_AUTO_1MRC_CLK,
                        RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN);
-               snd_soc_update_bits(codec, RT5663_IRQ_1,
+               snd_soc_component_update_bits(component, RT5663_IRQ_1,
                        RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN);
-               snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
+               snd_soc_component_update_bits(component, RT5663_EM_JACK_TYPE_1,
                        RT5663_EM_JD_MASK, RT5663_EM_JD_RST);
-               snd_soc_update_bits(codec, RT5663_EM_JACK_TYPE_1,
+               snd_soc_component_update_bits(component, RT5663_EM_JACK_TYPE_1,
                        RT5663_EM_JD_MASK, RT5663_EM_JD_NOR);
 
                while (true) {
@@ -1577,10 +1577,10 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                        i++;
                }
 
-               val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003;
-               dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
+               val = snd_soc_component_read32(component, RT5663_EM_JACK_TYPE_2) & 0x0003;
+               dev_dbg(component->dev, "%s val = %d\n", __func__, val);
 
-               snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+               snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
                        RT5663_OSW_HP_L_MASK | RT5663_OSW_HP_R_MASK,
                        RT5663_OSW_HP_L_EN | RT5663_OSW_HP_R_EN);
 
@@ -1588,7 +1588,7 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                case 1:
                case 2:
                        rt5663->jack_type = SND_JACK_HEADSET;
-                       rt5663_enable_push_button_irq(codec, true);
+                       rt5663_enable_push_button_irq(component, true);
 
                        if (rt5663->pdata.impedance_sensing_num)
                                break;
@@ -1636,17 +1636,17 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                }
        } else {
                if (rt5663->jack_type == SND_JACK_HEADSET)
-                       rt5663_enable_push_button_irq(codec, false);
+                       rt5663_enable_push_button_irq(component, false);
                rt5663->jack_type = 0;
        }
 
-       dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type);
+       dev_dbg(component->dev, "jack_type = %d\n", rt5663->jack_type);
        return rt5663->jack_type;
 }
 
-static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
+static int rt5663_impedance_sensing(struct snd_soc_component *component)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        unsigned int value, i, reg84, reg26, reg2fa, reg91, reg10, reg80;
 
        for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) {
@@ -1655,59 +1655,59 @@ static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
        }
 
        if (rt5663->jack_type == SND_JACK_HEADSET) {
-               snd_soc_write(codec, RT5663_MIC_DECRO_2,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_2,
                        rt5663->imp_table[i].dc_offset_l_manual_mic >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_3,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_3,
                        rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff);
-               snd_soc_write(codec, RT5663_MIC_DECRO_5,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_5,
                        rt5663->imp_table[i].dc_offset_r_manual_mic >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_6,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_6,
                        rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff);
        } else {
-               snd_soc_write(codec, RT5663_MIC_DECRO_2,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_2,
                        rt5663->imp_table[i].dc_offset_l_manual >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_3,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_3,
                        rt5663->imp_table[i].dc_offset_l_manual & 0xffff);
-               snd_soc_write(codec, RT5663_MIC_DECRO_5,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_5,
                        rt5663->imp_table[i].dc_offset_r_manual >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_6,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_6,
                        rt5663->imp_table[i].dc_offset_r_manual & 0xffff);
        }
 
-       reg84 = snd_soc_read(codec, RT5663_ASRC_2);
-       reg26 = snd_soc_read(codec, RT5663_STO1_ADC_MIXER);
-       reg2fa = snd_soc_read(codec, RT5663_DUMMY_1);
-       reg91 = snd_soc_read(codec, RT5663_HP_CHARGE_PUMP_1);
-       reg10 = snd_soc_read(codec, RT5663_RECMIX);
-       reg80 = snd_soc_read(codec, RT5663_GLB_CLK);
-
-       snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000, 0);
-       snd_soc_write(codec, RT5663_ASRC_2, 0);
-       snd_soc_write(codec, RT5663_STO1_ADC_MIXER, 0x4040);
-       snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+       reg84 = snd_soc_component_read32(component, RT5663_ASRC_2);
+       reg26 = snd_soc_component_read32(component, RT5663_STO1_ADC_MIXER);
+       reg2fa = snd_soc_component_read32(component, RT5663_DUMMY_1);
+       reg91 = snd_soc_component_read32(component, RT5663_HP_CHARGE_PUMP_1);
+       reg10 = snd_soc_component_read32(component, RT5663_RECMIX);
+       reg80 = snd_soc_component_read32(component, RT5663_GLB_CLK);
+
+       snd_soc_component_update_bits(component, RT5663_STO_DRE_1, 0x8000, 0);
+       snd_soc_component_write(component, RT5663_ASRC_2, 0);
+       snd_soc_component_write(component, RT5663_STO1_ADC_MIXER, 0x4040);
+       snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
                RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
                RT5663_PWR_VREF1 | RT5663_PWR_VREF2);
        usleep_range(10000, 10005);
-       snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+       snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
                RT5663_PWR_FV1 | RT5663_PWR_FV2);
-       snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
+       snd_soc_component_update_bits(component, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
                RT5663_SCLK_SRC_RCCLK);
-       snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
+       snd_soc_component_update_bits(component, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
                RT5663_DIG_25M_CLK_EN);
-       snd_soc_update_bits(codec, RT5663_ADDA_CLK_1, RT5663_I2S_PD1_MASK, 0);
-       snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00);
-       snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc);
-       snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, 0x1232);
-       snd_soc_write(codec, RT5663_HP_LOGIC_2, 0x0005);
-       snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
-       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0030);
-       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0x0003);
-       snd_soc_update_bits(codec, RT5663_PWR_DIG_2,
+       snd_soc_component_update_bits(component, RT5663_ADDA_CLK_1, RT5663_I2S_PD1_MASK, 0);
+       snd_soc_component_write(component, RT5663_PRE_DIV_GATING_1, 0xff00);
+       snd_soc_component_write(component, RT5663_PRE_DIV_GATING_2, 0xfffc);
+       snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_1, 0x1232);
+       snd_soc_component_write(component, RT5663_HP_LOGIC_2, 0x0005);
+       snd_soc_component_write(component, RT5663_DEPOP_2, 0x3003);
+       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030, 0x0030);
+       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003, 0x0003);
+       snd_soc_component_update_bits(component, RT5663_PWR_DIG_2,
                RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F,
                RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F);
-       snd_soc_update_bits(codec, RT5663_PWR_DIG_1,
+       snd_soc_component_update_bits(component, RT5663_PWR_DIG_1,
                RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
                RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 |
                RT5663_PWR_ADC_R1,
@@ -1715,71 +1715,71 @@ static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
                RT5663_PWR_LDO_DACREF_ON | RT5663_PWR_ADC_L1 |
                RT5663_PWR_ADC_R1);
        msleep(40);
-       snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+       snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
                RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2,
                RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2);
        msleep(30);
-       snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
-       snd_soc_write(codec, RT5663_STO_DAC_MIXER, 0);
-       snd_soc_write(codec, RT5663_BYPASS_STO_DAC, 0x000c);
-       snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
-       snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224);
-       snd_soc_write(codec, RT5663_HP_OUT_EN, 0x8088);
-       snd_soc_write(codec, RT5663_CHOP_ADC, 0x3000);
-       snd_soc_write(codec, RT5663_ADDA_RST, 0xc000);
-       snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0x3320);
-       snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c9);
-       snd_soc_write(codec, RT5663_DUMMY_1, 0x004c);
-       snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7733);
-       snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
-       snd_soc_write(codec, RT5663_STO_DRE_9, 0x0007);
-       snd_soc_write(codec, RT5663_STO_DRE_10, 0x0007);
-       snd_soc_write(codec, RT5663_DUMMY_2, 0x02a4);
-       snd_soc_write(codec, RT5663_RECMIX, 0x0005);
-       snd_soc_write(codec, RT5663_HP_IMP_SEN_1, 0x4334);
-       snd_soc_update_bits(codec, RT5663_IRQ_3, 0x0004, 0x0004);
-       snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x2200);
-       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x3000);
-       snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x6200);
+       snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_2, 0x1371);
+       snd_soc_component_write(component, RT5663_STO_DAC_MIXER, 0);
+       snd_soc_component_write(component, RT5663_BYPASS_STO_DAC, 0x000c);
+       snd_soc_component_write(component, RT5663_HP_BIAS, 0xafaa);
+       snd_soc_component_write(component, RT5663_CHARGE_PUMP_1, 0x2224);
+       snd_soc_component_write(component, RT5663_HP_OUT_EN, 0x8088);
+       snd_soc_component_write(component, RT5663_CHOP_ADC, 0x3000);
+       snd_soc_component_write(component, RT5663_ADDA_RST, 0xc000);
+       snd_soc_component_write(component, RT5663_STO1_HPF_ADJ1, 0x3320);
+       snd_soc_component_write(component, RT5663_HP_CALIB_2, 0x00c9);
+       snd_soc_component_write(component, RT5663_DUMMY_1, 0x004c);
+       snd_soc_component_write(component, RT5663_ANA_BIAS_CUR_1, 0x7733);
+       snd_soc_component_write(component, RT5663_CHARGE_PUMP_2, 0x7777);
+       snd_soc_component_write(component, RT5663_STO_DRE_9, 0x0007);
+       snd_soc_component_write(component, RT5663_STO_DRE_10, 0x0007);
+       snd_soc_component_write(component, RT5663_DUMMY_2, 0x02a4);
+       snd_soc_component_write(component, RT5663_RECMIX, 0x0005);
+       snd_soc_component_write(component, RT5663_HP_IMP_SEN_1, 0x4334);
+       snd_soc_component_update_bits(component, RT5663_IRQ_3, 0x0004, 0x0004);
+       snd_soc_component_write(component, RT5663_HP_LOGIC_1, 0x2200);
+       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0x3000);
+       snd_soc_component_write(component, RT5663_HP_LOGIC_1, 0x6200);
 
        for (i = 0; i < 100; i++) {
                msleep(20);
-               if (snd_soc_read(codec, RT5663_INT_ST_1) & 0x2)
+               if (snd_soc_component_read32(component, RT5663_INT_ST_1) & 0x2)
                        break;
        }
 
-       value = snd_soc_read(codec, RT5663_HP_IMP_SEN_4);
+       value = snd_soc_component_read32(component, RT5663_HP_IMP_SEN_4);
 
-       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0);
-       snd_soc_write(codec, RT5663_INT_ST_1, 0);
-       snd_soc_write(codec, RT5663_HP_LOGIC_1, 0);
-       snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
+       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0);
+       snd_soc_component_write(component, RT5663_INT_ST_1, 0);
+       snd_soc_component_write(component, RT5663_HP_LOGIC_1, 0);
+       snd_soc_component_update_bits(component, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
                RT5663_DIG_25M_CLK_DIS);
-       snd_soc_write(codec, RT5663_GLB_CLK, reg80);
-       snd_soc_write(codec, RT5663_RECMIX, reg10);
-       snd_soc_write(codec, RT5663_DUMMY_2, 0x00a4);
-       snd_soc_write(codec, RT5663_DUMMY_1, reg2fa);
-       snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c8);
-       snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0xb320);
-       snd_soc_write(codec, RT5663_ADDA_RST, 0xe400);
-       snd_soc_write(codec, RT5663_CHOP_ADC, 0x2000);
-       snd_soc_write(codec, RT5663_HP_OUT_EN, 0x0008);
-       snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+       snd_soc_component_write(component, RT5663_GLB_CLK, reg80);
+       snd_soc_component_write(component, RT5663_RECMIX, reg10);
+       snd_soc_component_write(component, RT5663_DUMMY_2, 0x00a4);
+       snd_soc_component_write(component, RT5663_DUMMY_1, reg2fa);
+       snd_soc_component_write(component, RT5663_HP_CALIB_2, 0x00c8);
+       snd_soc_component_write(component, RT5663_STO1_HPF_ADJ1, 0xb320);
+       snd_soc_component_write(component, RT5663_ADDA_RST, 0xe400);
+       snd_soc_component_write(component, RT5663_CHOP_ADC, 0x2000);
+       snd_soc_component_write(component, RT5663_HP_OUT_EN, 0x0008);
+       snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
                RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2, 0);
-       snd_soc_update_bits(codec, RT5663_PWR_DIG_1,
+       snd_soc_component_update_bits(component, RT5663_PWR_DIG_1,
                RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
                RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 |
                RT5663_PWR_ADC_R1, 0);
-       snd_soc_update_bits(codec, RT5663_PWR_DIG_2,
+       snd_soc_component_update_bits(component, RT5663_PWR_DIG_2,
                RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F, 0);
-       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
-       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
-       snd_soc_write(codec, RT5663_HP_LOGIC_2, 0);
-       snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, reg91);
-       snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003, 0);
+       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030, 0);
+       snd_soc_component_write(component, RT5663_HP_LOGIC_2, 0);
+       snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_1, reg91);
+       snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK, 0);
-       snd_soc_write(codec, RT5663_STO1_ADC_MIXER, reg26);
-       snd_soc_write(codec, RT5663_ASRC_2, reg84);
+       snd_soc_component_write(component, RT5663_STO1_ADC_MIXER, reg26);
+       snd_soc_component_write(component, RT5663_ASRC_2, reg84);
 
        for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) {
                if (value >= rt5663->imp_table[i].imp_min &&
@@ -1787,42 +1787,42 @@ static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
                        break;
        }
 
-       snd_soc_update_bits(codec, RT5663_STO_DRE_9, RT5663_DRE_GAIN_HP_MASK,
+       snd_soc_component_update_bits(component, RT5663_STO_DRE_9, RT5663_DRE_GAIN_HP_MASK,
                rt5663->imp_table[i].vol);
-       snd_soc_update_bits(codec, RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_MASK,
+       snd_soc_component_update_bits(component, RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_MASK,
                rt5663->imp_table[i].vol);
 
        if (rt5663->jack_type == SND_JACK_HEADSET) {
-               snd_soc_write(codec, RT5663_MIC_DECRO_2,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_2,
                        rt5663->imp_table[i].dc_offset_l_manual_mic >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_3,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_3,
                        rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff);
-               snd_soc_write(codec, RT5663_MIC_DECRO_5,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_5,
                        rt5663->imp_table[i].dc_offset_r_manual_mic >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_6,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_6,
                        rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff);
        } else {
-               snd_soc_write(codec, RT5663_MIC_DECRO_2,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_2,
                        rt5663->imp_table[i].dc_offset_l_manual >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_3,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_3,
                        rt5663->imp_table[i].dc_offset_l_manual & 0xffff);
-               snd_soc_write(codec, RT5663_MIC_DECRO_5,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_5,
                        rt5663->imp_table[i].dc_offset_r_manual >> 16);
-               snd_soc_write(codec, RT5663_MIC_DECRO_6,
+               snd_soc_component_write(component, RT5663_MIC_DECRO_6,
                        rt5663->imp_table[i].dc_offset_r_manual & 0xffff);
        }
 
        return 0;
 }
 
-static int rt5663_button_detect(struct snd_soc_codec *codec)
+static int rt5663_button_detect(struct snd_soc_component *component)
 {
        int btn_type, val;
 
-       val = snd_soc_read(codec, RT5663_IL_CMD_5);
-       dev_dbg(codec->dev, "%s: val=0x%x\n", __func__, val);
+       val = snd_soc_component_read32(component, RT5663_IL_CMD_5);
+       dev_dbg(component->dev, "%s: val=0x%x\n", __func__, val);
        btn_type = val & 0xfff0;
-       snd_soc_write(codec, RT5663_IL_CMD_5, val);
+       snd_soc_component_write(component, RT5663_IL_CMD_5, val);
 
        return btn_type;
 }
@@ -1840,10 +1840,10 @@ static irqreturn_t rt5663_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-int rt5663_set_jack_detect(struct snd_soc_codec *codec,
+int rt5663_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hs_jack)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        rt5663->hs_jack = hs_jack;
 
@@ -1853,12 +1853,12 @@ int rt5663_set_jack_detect(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(rt5663_set_jack_detect);
 
-static bool rt5663_check_jd_status(struct snd_soc_codec *codec)
+static bool rt5663_check_jd_status(struct snd_soc_component *component)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
-       int val = snd_soc_read(codec, RT5663_INT_ST_1);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
+       int val = snd_soc_component_read32(component, RT5663_INT_ST_1);
 
-       dev_dbg(codec->dev, "%s val=%x\n", __func__, val);
+       dev_dbg(component->dev, "%s val=%x\n", __func__, val);
 
        /* JD1 */
        switch (rt5663->codec_ver) {
@@ -1867,7 +1867,7 @@ static bool rt5663_check_jd_status(struct snd_soc_codec *codec)
        case CODEC_VER_0:
                return !(val & 0x1000);
        default:
-               dev_err(codec->dev, "Unknown CODEC Version\n");
+               dev_err(component->dev, "Unknown CODEC Version\n");
        }
 
        return false;
@@ -1877,28 +1877,28 @@ static void rt5663_jack_detect_work(struct work_struct *work)
 {
        struct rt5663_priv *rt5663 =
                container_of(work, struct rt5663_priv, jack_detect_work.work);
-       struct snd_soc_codec *codec = rt5663->codec;
+       struct snd_soc_component *component = rt5663->component;
        int btn_type, report = 0;
 
-       if (!codec)
+       if (!component)
                return;
 
-       if (rt5663_check_jd_status(codec)) {
+       if (rt5663_check_jd_status(component)) {
                /* jack in */
                if (rt5663->jack_type == 0) {
                        /* jack was out, report jack type */
                        switch (rt5663->codec_ver) {
                        case CODEC_VER_1:
                                report = rt5663_v2_jack_detect(
-                                               rt5663->codec, 1);
+                                               rt5663->component, 1);
                                break;
                        case CODEC_VER_0:
-                               report = rt5663_jack_detect(rt5663->codec, 1);
+                               report = rt5663_jack_detect(rt5663->component, 1);
                                if (rt5663->pdata.impedance_sensing_num)
-                                       rt5663_impedance_sensing(rt5663->codec);
+                                       rt5663_impedance_sensing(rt5663->component);
                                break;
                        default:
-                               dev_err(codec->dev, "Unknown CODEC Version\n");
+                               dev_err(component->dev, "Unknown CODEC Version\n");
                        }
 
                        /* Delay the jack insert report to avoid pop noise */
@@ -1906,7 +1906,7 @@ static void rt5663_jack_detect_work(struct work_struct *work)
                } else {
                        /* jack is already in, report button event */
                        report = SND_JACK_HEADSET;
-                       btn_type = rt5663_button_detect(rt5663->codec);
+                       btn_type = rt5663_button_detect(rt5663->component);
                        /**
                         * rt5663 can report three kinds of button behavior,
                         * one click, double click and hold. However,
@@ -1939,7 +1939,7 @@ static void rt5663_jack_detect_work(struct work_struct *work)
                                break;
                        default:
                                btn_type = 0;
-                               dev_err(rt5663->codec->dev,
+                               dev_err(rt5663->component->dev,
                                        "Unexpected button code 0x%04x\n",
                                        btn_type);
                                break;
@@ -1959,16 +1959,16 @@ static void rt5663_jack_detect_work(struct work_struct *work)
                /* jack out */
                switch (rt5663->codec_ver) {
                case CODEC_VER_1:
-                       report = rt5663_v2_jack_detect(rt5663->codec, 0);
+                       report = rt5663_v2_jack_detect(rt5663->component, 0);
                        break;
                case CODEC_VER_0:
-                       report = rt5663_jack_detect(rt5663->codec, 0);
+                       report = rt5663_jack_detect(rt5663->component, 0);
                        break;
                default:
-                       dev_err(codec->dev, "Unknown CODEC Version\n");
+                       dev_err(component->dev, "Unknown CODEC Version\n");
                }
        }
-       dev_dbg(codec->dev, "%s jack report: 0x%04x\n", __func__, report);
+       dev_dbg(component->dev, "%s jack report: 0x%04x\n", __func__, report);
        snd_soc_jack_report(rt5663->hs_jack, report, SND_JACK_HEADSET |
                            SND_JACK_BTN_0 | SND_JACK_BTN_1 |
                            SND_JACK_BTN_2 | SND_JACK_BTN_3);
@@ -1978,22 +1978,22 @@ static void rt5663_jd_unplug_work(struct work_struct *work)
 {
        struct rt5663_priv *rt5663 =
                container_of(work, struct rt5663_priv, jd_unplug_work.work);
-       struct snd_soc_codec *codec = rt5663->codec;
+       struct snd_soc_component *component = rt5663->component;
 
-       if (!codec)
+       if (!component)
                return;
 
-       if (!rt5663_check_jd_status(codec)) {
+       if (!rt5663_check_jd_status(component)) {
                /* jack out */
                switch (rt5663->codec_ver) {
                case CODEC_VER_1:
-                       rt5663_v2_jack_detect(rt5663->codec, 0);
+                       rt5663_v2_jack_detect(rt5663->component, 0);
                        break;
                case CODEC_VER_0:
-                       rt5663_jack_detect(rt5663->codec, 0);
+                       rt5663_jack_detect(rt5663->component, 0);
                        break;
                default:
-                       dev_err(codec->dev, "Unknown CODEC Version\n");
+                       dev_err(component->dev, "Unknown CODEC Version\n");
                }
 
                snd_soc_jack_report(rt5663->hs_jack, 0, SND_JACK_HEADSET |
@@ -2047,9 +2047,9 @@ static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
        struct snd_soc_dapm_widget *sink)
 {
        unsigned int val;
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-       val = snd_soc_read(codec, RT5663_GLB_CLK);
+       val = snd_soc_component_read32(component, RT5663_GLB_CLK);
        val &= RT5663_SCLK_SRC_MASK;
        if (val == RT5663_SCLK_SRC_PLL1)
                return 1;
@@ -2061,8 +2061,8 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
        struct snd_soc_dapm_widget *sink)
 {
        unsigned int reg, shift, val;
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        if (rt5663->codec_ver == CODEC_VER_1) {
                switch (w->shift) {
@@ -2092,7 +2092,7 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
                }
        }
 
-       val = (snd_soc_read(codec, reg) >> shift) & 0x7;
+       val = (snd_soc_component_read32(component, reg) >> shift) & 0x7;
 
        if (val)
                return 1;
@@ -2103,23 +2103,23 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w,
 static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
        struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        int da_asrc_en, ad_asrc_en;
 
-       da_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) &
+       da_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) &
                RT5663_DA_STO1_TRACK_MASK) ? 1 : 0;
        switch (rt5663->codec_ver) {
        case CODEC_VER_1:
-               ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_3) &
+               ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_3) &
                        RT5663_V2_AD_STO1_TRACK_MASK) ? 1 : 0;
                break;
        case CODEC_VER_0:
-               ad_asrc_en = (snd_soc_read(codec, RT5663_ASRC_2) &
+               ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) &
                        RT5663_AD_STO1_TRACK_MASK) ? 1 : 0;
                break;
        default:
-               dev_err(codec->dev, "Unknown CODEC Version\n");
+               dev_err(component->dev, "Unknown CODEC Version\n");
                return 1;
        }
 
@@ -2127,14 +2127,14 @@ static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
                if (rt5663->sysclk > rt5663->lrck * 384)
                        return 1;
 
-       dev_err(codec->dev, "sysclk < 384 x fs, disable i2s asrc\n");
+       dev_err(component->dev, "sysclk < 384 x fs, disable i2s asrc\n");
 
        return 0;
 }
 
 /**
  * rt5663_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -2146,10 +2146,10 @@ static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5663_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        unsigned int asrc2_mask = 0;
        unsigned int asrc2_value = 0;
        unsigned int asrc3_mask = 0;
@@ -2180,16 +2180,16 @@ int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
                        asrc2_value |= clk_src << RT5663_AD_STO1_TRACK_SHIFT;
                        break;
                default:
-                       dev_err(codec->dev, "Unknown CODEC Version\n");
+                       dev_err(component->dev, "Unknown CODEC Version\n");
                }
        }
 
        if (asrc2_mask)
-               snd_soc_update_bits(codec, RT5663_ASRC_2, asrc2_mask,
+               snd_soc_component_update_bits(component, RT5663_ASRC_2, asrc2_mask,
                        asrc2_value);
 
        if (asrc3_mask)
-               snd_soc_update_bits(codec, RT5663_ASRC_3, asrc3_mask,
+               snd_soc_component_update_bits(component, RT5663_ASRC_3, asrc3_mask,
                        asrc3_value);
 
        return 0;
@@ -2295,42 +2295,42 @@ static const struct snd_kcontrol_new rt5663_alg_dacr_mux =
 static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                if (rt5663->codec_ver == CODEC_VER_1) {
-                       snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+                       snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
                                RT5663_SEL_PM_HP_SHIFT, RT5663_SEL_PM_HP_HIGH);
-                       snd_soc_update_bits(codec, RT5663_HP_LOGIC_2,
+                       snd_soc_component_update_bits(component, RT5663_HP_LOGIC_2,
                                RT5663_HP_SIG_SRC1_MASK,
                                RT5663_HP_SIG_SRC1_SILENCE);
                } else {
-                       snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
-                       snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+                       snd_soc_component_write(component, RT5663_DEPOP_2, 0x3003);
+                       snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
                                RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS);
-                       snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
-                       snd_soc_write(codec, RT5663_HP_BIAS, 0xabba);
-                       snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224);
-                       snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766);
-                       snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
-                       snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
-                       snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000,
+                       snd_soc_component_write(component, RT5663_HP_CHARGE_PUMP_2, 0x1371);
+                       snd_soc_component_write(component, RT5663_HP_BIAS, 0xabba);
+                       snd_soc_component_write(component, RT5663_CHARGE_PUMP_1, 0x2224);
+                       snd_soc_component_write(component, RT5663_ANA_BIAS_CUR_1, 0x7766);
+                       snd_soc_component_write(component, RT5663_HP_BIAS, 0xafaa);
+                       snd_soc_component_write(component, RT5663_CHARGE_PUMP_2, 0x7777);
+                       snd_soc_component_update_bits(component, RT5663_STO_DRE_1, 0x8000,
                                0x8000);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000,
+                       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000,
                                0x3000);
                }
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
                if (rt5663->codec_ver == CODEC_VER_1) {
-                       snd_soc_update_bits(codec, RT5663_HP_LOGIC_2,
+                       snd_soc_component_update_bits(component, RT5663_HP_LOGIC_2,
                                RT5663_HP_SIG_SRC1_MASK,
                                RT5663_HP_SIG_SRC1_REG);
                } else {
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0);
-                       snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+                       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0x0);
+                       snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
                                RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN);
                }
                break;
@@ -2345,23 +2345,23 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                if (rt5663->codec_ver == CODEC_VER_0) {
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
+                       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030,
                                0x0030);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003,
+                       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003,
                                0x0003);
                }
                break;
 
        case SND_SOC_DAPM_POST_PMD:
                if (rt5663->codec_ver == CODEC_VER_0) {
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
+                       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0003, 0);
+                       snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x0030, 0);
                }
                break;
 
@@ -2375,17 +2375,17 @@ static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w,
 static int rt5663_bst2_power(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
                        RT5663_PWR_BST2_MASK | RT5663_PWR_BST2_OP_MASK,
                        RT5663_PWR_BST2 | RT5663_PWR_BST2_OP);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_2,
                        RT5663_PWR_BST2_MASK | RT5663_PWR_BST2_OP_MASK, 0);
                break;
 
@@ -2399,17 +2399,17 @@ static int rt5663_bst2_power(struct snd_soc_dapm_widget *w,
 static int rt5663_pre_div_power(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00);
-               snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc);
+               snd_soc_component_write(component, RT5663_PRE_DIV_GATING_1, 0xff00);
+               snd_soc_component_write(component, RT5663_PRE_DIV_GATING_2, 0xfffc);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0x0000);
-               snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0x0000);
+               snd_soc_component_write(component, RT5663_PRE_DIV_GATING_1, 0x0000);
+               snd_soc_component_write(component, RT5663_PRE_DIV_GATING_2, 0x0000);
                break;
 
        default:
@@ -2731,8 +2731,8 @@ static const struct snd_soc_dapm_route rt5663_specific_dapm_routes[] = {
 static int rt5663_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0;
        int pre_div;
 
@@ -2743,7 +2743,7 @@ static int rt5663_hw_params(struct snd_pcm_substream *substream,
 
        pre_div = rl6231_get_clk_info(rt5663->sysclk, rt5663->lrck);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+               dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
                        rt5663->lrck, dai->id);
                return -EINVAL;
        }
@@ -2767,10 +2767,10 @@ static int rt5663_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5663_I2S1_SDP,
+       snd_soc_component_update_bits(component, RT5663_I2S1_SDP,
                RT5663_I2S_DL_MASK, val_len);
 
-       snd_soc_update_bits(codec, RT5663_ADDA_CLK_1,
+       snd_soc_component_update_bits(component, RT5663_ADDA_CLK_1,
                RT5663_I2S_PD1_MASK, pre_div << RT5663_I2S_PD1_SHIFT);
 
        return 0;
@@ -2778,7 +2778,7 @@ static int rt5663_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -2817,7 +2817,7 @@ static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5663_I2S1_SDP, RT5663_I2S_MS_MASK |
+       snd_soc_component_update_bits(component, RT5663_I2S1_SDP, RT5663_I2S_MS_MASK |
                RT5663_I2S_BP_MASK | RT5663_I2S_DF_MASK, reg_val);
 
        return 0;
@@ -2826,8 +2826,8 @@ static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
        unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5663->sysclk && clk_id == rt5663->sysclk_src)
@@ -2844,15 +2844,15 @@ static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                reg_val |= RT5663_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
+       snd_soc_component_update_bits(component, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
                reg_val);
        rt5663->sysclk = freq;
        rt5663->sysclk_src = clk_id;
 
-       dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n",
+       dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
                freq, clk_id);
 
        return 0;
@@ -2861,8 +2861,8 @@ static int rt5663_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
        int mask, shift, val;
@@ -2872,11 +2872,11 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5663->pll_in = 0;
                rt5663->pll_out = 0;
-               snd_soc_update_bits(codec, RT5663_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5663_GLB_CLK,
                        RT5663_SCLK_SRC_MASK, RT5663_SCLK_SRC_MCLK);
                return 0;
        }
@@ -2891,7 +2891,7 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                shift = RT5663_PLL1_SRC_SHIFT;
                break;
        default:
-               dev_err(codec->dev, "Unknown CODEC Version\n");
+               dev_err(component->dev, "Unknown CODEC Version\n");
                return -EINVAL;
        }
 
@@ -2903,24 +2903,24 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                val = 0x1;
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5663_GLB_CLK, mask, (val << shift));
+       snd_soc_component_update_bits(component, RT5663_GLB_CLK, mask, (val << shift));
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n", pll_code.m_bp,
                (pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code,
                pll_code.k_code);
 
-       snd_soc_write(codec, RT5663_PLL_1,
+       snd_soc_component_write(component, RT5663_PLL_1,
                pll_code.n_code << RT5663_PLL_N_SHIFT | pll_code.k_code);
-       snd_soc_write(codec, RT5663_PLL_2,
+       snd_soc_component_write(component, RT5663_PLL_2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5663_PLL_M_SHIFT |
                pll_code.m_bp << RT5663_PLL_M_BP_SHIFT);
 
@@ -2934,8 +2934,8 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0, reg;
 
        if (rx_mask || tx_mask)
@@ -2987,11 +2987,11 @@ static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                reg = RT5663_TDM_1;
                break;
        default:
-               dev_err(codec->dev, "Unknown CODEC Version\n");
+               dev_err(component->dev, "Unknown CODEC Version\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, reg, RT5663_TDM_MODE_MASK |
+       snd_soc_component_update_bits(component, reg, RT5663_TDM_MODE_MASK |
                RT5663_TDM_IN_CH_MASK | RT5663_TDM_OUT_CH_MASK |
                RT5663_TDM_IN_LEN_MASK | RT5663_TDM_OUT_LEN_MASK, val);
 
@@ -3000,11 +3000,11 @@ static int rt5663_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 
 static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
        unsigned int reg;
 
-       dev_dbg(codec->dev, "%s ratio = %d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio = %d\n", __func__, ratio);
 
        if (rt5663->codec_ver == CODEC_VER_1)
                reg = RT5663_TDM_9;
@@ -3013,51 +3013,51 @@ static int rt5663_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 
        switch (ratio) {
        case 32:
-               snd_soc_update_bits(codec, reg,
+               snd_soc_component_update_bits(component, reg,
                        RT5663_TDM_LENGTN_MASK,
                        RT5663_TDM_LENGTN_16);
                break;
        case 40:
-               snd_soc_update_bits(codec, reg,
+               snd_soc_component_update_bits(component, reg,
                        RT5663_TDM_LENGTN_MASK,
                        RT5663_TDM_LENGTN_20);
                break;
        case 48:
-               snd_soc_update_bits(codec, reg,
+               snd_soc_component_update_bits(component, reg,
                        RT5663_TDM_LENGTN_MASK,
                        RT5663_TDM_LENGTN_24);
                break;
        case 64:
-               snd_soc_update_bits(codec, reg,
+               snd_soc_component_update_bits(component, reg,
                        RT5663_TDM_LENGTN_MASK,
                        RT5663_TDM_LENGTN_32);
                break;
        default:
-               dev_err(codec->dev, "Invalid ratio!\n");
+               dev_err(component->dev, "Invalid ratio!\n");
                return -EINVAL;
        }
 
        return 0;
 }
 
-static int rt5663_set_bias_level(struct snd_soc_codec *codec,
+static int rt5663_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                        RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
                        RT5663_PWR_FV1 | RT5663_PWR_FV2);
                break;
 
        case SND_SOC_BIAS_PREPARE:
                if (rt5663->codec_ver == CODEC_VER_1) {
-                       snd_soc_update_bits(codec, RT5663_DIG_MISC,
+                       snd_soc_component_update_bits(component, RT5663_DIG_MISC,
                                RT5663_DIG_GATE_CTRL_MASK,
                                RT5663_DIG_GATE_CTRL_EN);
-                       snd_soc_update_bits(codec, RT5663_SIG_CLK_DET,
+                       snd_soc_component_update_bits(component, RT5663_SIG_CLK_DET,
                                RT5663_EN_ANA_CLK_DET_MASK |
                                RT5663_PWR_CLK_DET_MASK,
                                RT5663_EN_ANA_CLK_DET_AUTO |
@@ -3067,17 +3067,17 @@ static int rt5663_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_STANDBY:
                if (rt5663->codec_ver == CODEC_VER_1)
-                       snd_soc_update_bits(codec, RT5663_DIG_MISC,
+                       snd_soc_component_update_bits(component, RT5663_DIG_MISC,
                                RT5663_DIG_GATE_CTRL_MASK,
                                RT5663_DIG_GATE_CTRL_DIS);
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                        RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
                        RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK |
                        RT5663_PWR_MB_MASK, RT5663_PWR_VREF1 |
                        RT5663_PWR_VREF2 | RT5663_PWR_MB);
                usleep_range(10000, 10005);
                if (rt5663->codec_ver == CODEC_VER_1) {
-                       snd_soc_update_bits(codec, RT5663_SIG_CLK_DET,
+                       snd_soc_component_update_bits(component, RT5663_SIG_CLK_DET,
                                RT5663_EN_ANA_CLK_DET_MASK |
                                RT5663_PWR_CLK_DET_MASK,
                                RT5663_EN_ANA_CLK_DET_DIS |
@@ -3086,7 +3086,7 @@ static int rt5663_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+               snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
                        RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
                        RT5663_PWR_FV1 | RT5663_PWR_FV2, 0x0);
                break;
@@ -3098,12 +3098,12 @@ static int rt5663_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5663_probe(struct snd_soc_codec *codec)
+static int rt5663_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
-       rt5663->codec = codec;
+       rt5663->component = component;
 
        switch (rt5663->codec_ver) {
        case CODEC_VER_1:
@@ -3113,7 +3113,7 @@ static int rt5663_probe(struct snd_soc_codec *codec)
                snd_soc_dapm_add_routes(dapm,
                        rt5663_v2_specific_dapm_routes,
                        ARRAY_SIZE(rt5663_v2_specific_dapm_routes));
-               snd_soc_add_codec_controls(codec, rt5663_v2_specific_controls,
+               snd_soc_add_component_controls(component, rt5663_v2_specific_controls,
                        ARRAY_SIZE(rt5663_v2_specific_controls));
                break;
        case CODEC_VER_0:
@@ -3123,11 +3123,11 @@ static int rt5663_probe(struct snd_soc_codec *codec)
                snd_soc_dapm_add_routes(dapm,
                        rt5663_specific_dapm_routes,
                        ARRAY_SIZE(rt5663_specific_dapm_routes));
-               snd_soc_add_codec_controls(codec, rt5663_specific_controls,
+               snd_soc_add_component_controls(component, rt5663_specific_controls,
                        ARRAY_SIZE(rt5663_specific_controls));
 
                if (!rt5663->imp_table)
-                       snd_soc_add_codec_controls(codec, rt5663_hpvol_controls,
+                       snd_soc_add_component_controls(component, rt5663_hpvol_controls,
                                ARRAY_SIZE(rt5663_hpvol_controls));
                break;
        }
@@ -3135,19 +3135,17 @@ static int rt5663_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5663_remove(struct snd_soc_codec *codec)
+static void rt5663_remove(struct snd_soc_component *component)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        regmap_write(rt5663->regmap, RT5663_RESET, 0);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5663_suspend(struct snd_soc_codec *codec)
+static int rt5663_suspend(struct snd_soc_component *component)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5663->regmap, true);
        regcache_mark_dirty(rt5663->regmap);
@@ -3155,9 +3153,9 @@ static int rt5663_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5663_resume(struct snd_soc_codec *codec)
+static int rt5663_resume(struct snd_soc_component *component)
 {
-       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+       struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5663->regmap, false);
        regcache_sync(rt5663->regmap);
@@ -3206,21 +3204,22 @@ static struct snd_soc_dai_driver rt5663_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5663 = {
-       .probe = rt5663_probe,
-       .remove = rt5663_remove,
-       .suspend = rt5663_suspend,
-       .resume = rt5663_resume,
-       .set_bias_level = rt5663_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls = rt5663_snd_controls,
-               .num_controls = ARRAY_SIZE(rt5663_snd_controls),
-               .dapm_widgets = rt5663_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets),
-               .dapm_routes = rt5663_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes),
-       }
+static const struct snd_soc_component_driver soc_component_dev_rt5663 = {
+       .probe                  = rt5663_probe,
+       .remove                 = rt5663_remove,
+       .suspend                = rt5663_suspend,
+       .resume                 = rt5663_resume,
+       .set_bias_level         = rt5663_set_bias_level,
+       .controls               = rt5663_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5663_snd_controls),
+       .dapm_widgets           = rt5663_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5663_dapm_widgets),
+       .dapm_routes            = rt5663_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5663_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+
 };
 
 static const struct regmap_config rt5663_v2_regmap = {
@@ -3610,7 +3609,8 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
                                __func__, ret);
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5663,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt5663,
                        rt5663_dai, ARRAY_SIZE(rt5663_dai));
 
        if (ret) {
@@ -3628,8 +3628,6 @@ static int rt5663_i2c_remove(struct i2c_client *i2c)
        if (i2c->irq)
                free_irq(i2c->irq, rt5663);
 
-       snd_soc_unregister_codec(&i2c->dev);
-
        return 0;
 }
 
index 03adc8004ba98d73da3f132d23285fdae77bf72d..865203cc2034a383a6cc62b4a6308bd63ecfa2ee 100644 (file)
@@ -1125,9 +1125,9 @@ enum {
        RT5663_AD_STEREO_FILTER = 0x2,
 };
 
-int rt5663_set_jack_detect(struct snd_soc_codec *codec,
+int rt5663_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hs_jack);
-int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5663_sel_asrc_clk_src(struct snd_soc_component *component,
        unsigned int filter_mask, unsigned int clk_src);
 
 #endif /* __RT5663_H__ */
index f05d362c4e23b859ccc823502751a91d9417c023..6ba99f5ed3f42e54e52af662b6fbe647f25b6f0a 100644 (file)
@@ -44,7 +44,7 @@ static const char *rt5665_supply_names[RT5665_NUM_SUPPLIES] = {
 };
 
 struct rt5665_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5665_platform_data pdata;
        struct regmap *regmap;
        struct gpio_desc *gpiod_ldo1_en;
@@ -1000,13 +1000,13 @@ static const struct snd_kcontrol_new rt5665_if3_adc_swap_mux =
 static int rt5665_hp_vol_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int ret = snd_soc_put_volsw(kcontrol, ucontrol);
 
-       if (snd_soc_read(codec, RT5665_STO_NG2_CTRL_1) & RT5665_NG2_EN) {
-               snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+       if (snd_soc_component_read32(component, RT5665_STO_NG2_CTRL_1) & RT5665_NG2_EN) {
+               snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
-               snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_EN);
        }
 
@@ -1016,13 +1016,13 @@ static int rt5665_hp_vol_put(struct snd_kcontrol *kcontrol,
 static int rt5665_mono_vol_put(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int ret = snd_soc_put_volsw(kcontrol, ucontrol);
 
-       if (snd_soc_read(codec, RT5665_MONO_NG2_CTRL_1) & RT5665_NG2_EN) {
-               snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+       if (snd_soc_component_read32(component, RT5665_MONO_NG2_CTRL_1) & RT5665_NG2_EN) {
+               snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
-               snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_EN);
        }
 
@@ -1031,7 +1031,7 @@ static int rt5665_mono_vol_put(struct snd_kcontrol *kcontrol,
 
 /**
  * rt5665_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -1043,7 +1043,7 @@ static int rt5665_mono_vol_put(struct snd_kcontrol *kcontrol,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5665_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src)
 {
        unsigned int asrc2_mask = 0;
@@ -1114,63 +1114,63 @@ int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
        }
 
        if (asrc2_mask)
-               snd_soc_update_bits(codec, RT5665_ASRC_2,
+               snd_soc_component_update_bits(component, RT5665_ASRC_2,
                        asrc2_mask, asrc2_value);
 
        if (asrc3_mask)
-               snd_soc_update_bits(codec, RT5665_ASRC_3,
+               snd_soc_component_update_bits(component, RT5665_ASRC_3,
                        asrc3_mask, asrc3_value);
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt5665_sel_asrc_clk_src);
 
-static int rt5665_button_detect(struct snd_soc_codec *codec)
+static int rt5665_button_detect(struct snd_soc_component *component)
 {
        int btn_type, val;
 
-       val = snd_soc_read(codec, RT5665_4BTN_IL_CMD_1);
+       val = snd_soc_component_read32(component, RT5665_4BTN_IL_CMD_1);
        btn_type = val & 0xfff0;
-       snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, val);
+       snd_soc_component_write(component, RT5665_4BTN_IL_CMD_1, val);
 
        return btn_type;
 }
 
-static void rt5665_enable_push_button_irq(struct snd_soc_codec *codec,
+static void rt5665_enable_push_button_irq(struct snd_soc_component *component,
        bool enable)
 {
        if (enable) {
-               snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x0003);
-               snd_soc_update_bits(codec, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
-               snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048);
-               snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
+               snd_soc_component_write(component, RT5665_4BTN_IL_CMD_1, 0x0003);
+               snd_soc_component_update_bits(component, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
+               snd_soc_component_write(component, RT5665_IL_CMD_1, 0x0048);
+               snd_soc_component_update_bits(component, RT5665_4BTN_IL_CMD_2,
                                RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK,
                                RT5665_4BTN_IL_EN | RT5665_4BTN_IL_NOR);
-               snd_soc_update_bits(codec, RT5665_IRQ_CTRL_3,
+               snd_soc_component_update_bits(component, RT5665_IRQ_CTRL_3,
                                RT5665_IL_IRQ_MASK, RT5665_IL_IRQ_EN);
        } else {
-               snd_soc_update_bits(codec, RT5665_IRQ_CTRL_3,
+               snd_soc_component_update_bits(component, RT5665_IRQ_CTRL_3,
                                RT5665_IL_IRQ_MASK, RT5665_IL_IRQ_DIS);
-               snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
+               snd_soc_component_update_bits(component, RT5665_4BTN_IL_CMD_2,
                                RT5665_4BTN_IL_MASK, RT5665_4BTN_IL_DIS);
-               snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
+               snd_soc_component_update_bits(component, RT5665_4BTN_IL_CMD_2,
                                RT5665_4BTN_IL_RST_MASK, RT5665_4BTN_IL_RST);
        }
 }
 
 /**
  * rt5665_headset_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
  *
  * Returns detect status.
  */
-static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5665_headset_detect(struct snd_soc_component *component, int jack_insert)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        unsigned int sar_hs_type, val;
 
        if (jack_insert) {
@@ -1201,7 +1201,7 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 
                usleep_range(10000, 15000);
 
-               rt5665->sar_adc_value = snd_soc_read(rt5665->codec,
+               rt5665->sar_adc_value = snd_soc_component_read32(rt5665->component,
                        RT5665_SAR_IL_CMD_4) & 0x7ff;
 
                sar_hs_type = rt5665->pdata.sar_hs_type ?
@@ -1209,7 +1209,7 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 
                if (rt5665->sar_adc_value > sar_hs_type) {
                        rt5665->jack_type = SND_JACK_HEADSET;
-                       rt5665_enable_push_button_irq(codec, true);
+                       rt5665_enable_push_button_irq(component, true);
                        } else {
                        rt5665->jack_type = SND_JACK_HEADPHONE;
                        regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1,
@@ -1225,11 +1225,11 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
                snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
                snd_soc_dapm_sync(dapm);
                if (rt5665->jack_type == SND_JACK_HEADSET)
-                       rt5665_enable_push_button_irq(codec, false);
+                       rt5665_enable_push_button_irq(component, false);
                rt5665->jack_type = 0;
        }
 
-       dev_dbg(codec->dev, "jack_type = %d\n", rt5665->jack_type);
+       dev_dbg(component->dev, "jack_type = %d\n", rt5665->jack_type);
        return rt5665->jack_type;
 }
 
@@ -1248,9 +1248,9 @@ static void rt5665_jd_check_handler(struct work_struct *work)
        struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
                jd_check_work.work);
 
-       if (snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010) {
+       if (snd_soc_component_read32(rt5665->component, RT5665_AJD1_CTRL) & 0x0010) {
                /* jack out */
-               rt5665->jack_type = rt5665_headset_detect(rt5665->codec, 0);
+               rt5665->jack_type = rt5665_headset_detect(rt5665->component, 0);
 
                snd_soc_jack_report(rt5665->hs_jack, rt5665->jack_type,
                                SND_JACK_HEADSET |
@@ -1261,10 +1261,10 @@ static void rt5665_jd_check_handler(struct work_struct *work)
        }
 }
 
-static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
+static int rt5665_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *hs_jack, void *data)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
        switch (rt5665->pdata.jd_src) {
        case RT5665_JD1:
@@ -1281,7 +1281,7 @@ static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
                break;
 
        default:
-               dev_warn(codec->dev, "Wrong JD source\n");
+               dev_warn(component->dev, "Wrong JD source\n");
                break;
        }
 
@@ -1296,12 +1296,12 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
                container_of(work, struct rt5665_priv, jack_detect_work.work);
        int val, btn_type;
 
-       while (!rt5665->codec) {
+       while (!rt5665->component) {
                pr_debug("%s codec = null\n", __func__);
                usleep_range(10000, 15000);
        }
 
-       while (!rt5665->codec->component.card->instantiated) {
+       while (!rt5665->component->card->instantiated) {
                pr_debug("%s\n", __func__);
                usleep_range(10000, 15000);
        }
@@ -1313,17 +1313,17 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
 
        mutex_lock(&rt5665->calibrate_mutex);
 
-       val = snd_soc_read(rt5665->codec, RT5665_AJD1_CTRL) & 0x0010;
+       val = snd_soc_component_read32(rt5665->component, RT5665_AJD1_CTRL) & 0x0010;
        if (!val) {
                /* jack in */
                if (rt5665->jack_type == 0) {
                        /* jack was out, report jack type */
                        rt5665->jack_type =
-                               rt5665_headset_detect(rt5665->codec, 1);
+                               rt5665_headset_detect(rt5665->component, 1);
                } else {
                        /* jack is already in, report button event */
                        rt5665->jack_type = SND_JACK_HEADSET;
-                       btn_type = rt5665_button_detect(rt5665->codec);
+                       btn_type = rt5665_button_detect(rt5665->component);
                        /**
                         * rt5665 can report three kinds of button behavior,
                         * one click, double click and hold. However,
@@ -1356,7 +1356,7 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
                                break;
                        default:
                                btn_type = 0;
-                               dev_err(rt5665->codec->dev,
+                               dev_err(rt5665->component->dev,
                                        "Unexpected button code 0x%04x\n",
                                        btn_type);
                                break;
@@ -1364,7 +1364,7 @@ static void rt5665_jack_detect_handler(struct work_struct *work)
                }
        } else {
                /* jack out */
-               rt5665->jack_type = rt5665_headset_detect(rt5665->codec, 0);
+               rt5665->jack_type = rt5665_headset_detect(rt5665->component, 0);
        }
 
        snd_soc_jack_report(rt5665->hs_jack, rt5665->jack_type,
@@ -1479,8 +1479,8 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
        int pd, idx = -EINVAL;
 
        pd = rl6231_get_pre_div(rt5665->regmap,
@@ -1488,9 +1488,9 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        idx = rl6231_calc_dmic_clk(rt5665->sysclk / pd);
 
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else {
-               snd_soc_update_bits(codec, RT5665_DMIC_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_DMIC_CTRL_1,
                        RT5665_DMIC_CLK_MASK, idx << RT5665_DMIC_CLK_SFT);
        }
        return idx;
@@ -1499,16 +1499,16 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int rt5665_charge_pump_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, RT5665_HP_CHARGE_PUMP_1,
+               snd_soc_component_update_bits(component, RT5665_HP_CHARGE_PUMP_1,
                        RT5665_PM_HP_MASK | RT5665_OSW_L_MASK,
                        RT5665_PM_HP_HV | RT5665_OSW_L_EN);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, RT5665_HP_CHARGE_PUMP_1,
+               snd_soc_component_update_bits(component, RT5665_HP_CHARGE_PUMP_1,
                        RT5665_PM_HP_MASK | RT5665_OSW_L_MASK,
                        RT5665_PM_HP_LV | RT5665_OSW_L_DIS);
                break;
@@ -1523,9 +1523,9 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
                         struct snd_soc_dapm_widget *sink)
 {
        unsigned int val;
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-       val = snd_soc_read(codec, RT5665_GLB_CLK);
+       val = snd_soc_component_read32(component, RT5665_GLB_CLK);
        val &= RT5665_SCLK_SRC_MASK;
        if (val == RT5665_SCLK_SRC_PLL1)
                return 1;
@@ -1537,7 +1537,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
                         struct snd_soc_dapm_widget *sink)
 {
        unsigned int reg, shift, val;
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (w->shift) {
        case RT5665_ADC_MONO_R_ASRC_SFT:
@@ -1576,13 +1576,13 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w,
                return 0;
        }
 
-       val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+       val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
        switch (val) {
        case RT5665_CLK_SEL_I2S1_ASRC:
        case RT5665_CLK_SEL_I2S2_ASRC:
        case RT5665_CLK_SEL_I2S3_ASRC:
                /* I2S_Pre_Div1 should be 1 in asrc mode */
-               snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
                        RT5665_I2S_PD1_MASK, RT5665_I2S_PD1_2);
                return 1;
        default:
@@ -2474,24 +2474,24 @@ static const struct snd_kcontrol_new pdm_r_switch =
 static int rt5665_mono_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_EN);
-               snd_soc_update_bits(codec, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
+               snd_soc_component_update_bits(component, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
                        0x0);
-               snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x10, 0x10);
-               snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x20, 0x20);
+               snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x10, 0x10);
+               snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x20, 0x20);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x20, 0);
-               snd_soc_update_bits(codec, RT5665_MONO_OUT, 0x10, 0);
-               snd_soc_update_bits(codec, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
+               snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x20, 0);
+               snd_soc_component_update_bits(component, RT5665_MONO_OUT, 0x10, 0);
+               snd_soc_component_update_bits(component, RT5665_MONO_AMP_CALIB_CTRL_1, 0x40,
                        0x40);
-               snd_soc_update_bits(codec, RT5665_MONO_NG2_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_MONO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
                break;
 
@@ -2506,18 +2506,18 @@ static int rt5665_mono_event(struct snd_soc_dapm_widget *w,
 static int rt5665_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_EN);
-               snd_soc_write(codec, RT5665_HP_LOGIC_CTRL_2, 0x0003);
+               snd_soc_component_write(component, RT5665_HP_LOGIC_CTRL_2, 0x0003);
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_write(codec, RT5665_HP_LOGIC_CTRL_2, 0x0002);
-               snd_soc_update_bits(codec, RT5665_STO_NG2_CTRL_1,
+               snd_soc_component_write(component, RT5665_HP_LOGIC_CTRL_2, 0x0002);
+               snd_soc_component_update_bits(component, RT5665_STO_NG2_CTRL_1,
                        RT5665_NG2_EN_MASK, RT5665_NG2_DIS);
                break;
 
@@ -2532,16 +2532,16 @@ static int rt5665_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5665_lout_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5665_DEPOP_1,
+               snd_soc_component_update_bits(component, RT5665_DEPOP_1,
                        RT5665_PUMP_EN, RT5665_PUMP_EN);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5665_DEPOP_1,
+               snd_soc_component_update_bits(component, RT5665_DEPOP_1,
                        RT5665_PUMP_EN, 0);
                break;
 
@@ -2572,23 +2572,23 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,
 static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                switch (w->shift) {
                case RT5665_PWR_VREF1_BIT:
-                       snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+                       snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
                                RT5665_PWR_FV1, 0);
                        break;
 
                case RT5665_PWR_VREF2_BIT:
-                       snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+                       snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
                                RT5665_PWR_FV2, 0);
                        break;
 
                case RT5665_PWR_VREF3_BIT:
-                       snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+                       snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
                                RT5665_PWR_FV3, 0);
                        break;
 
@@ -2601,17 +2601,17 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
                usleep_range(15000, 20000);
                switch (w->shift) {
                case RT5665_PWR_VREF1_BIT:
-                       snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+                       snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
                                RT5665_PWR_FV1, RT5665_PWR_FV1);
                        break;
 
                case RT5665_PWR_VREF2_BIT:
-                       snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+                       snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
                                RT5665_PWR_FV2, RT5665_PWR_FV2);
                        break;
 
                case RT5665_PWR_VREF3_BIT:
-                       snd_soc_update_bits(codec, RT5665_PWR_ANLG_1,
+                       snd_soc_component_update_bits(component, RT5665_PWR_ANLG_1,
                                RT5665_PWR_FV3, RT5665_PWR_FV3);
                        break;
 
@@ -2630,7 +2630,7 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
 static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int val1, val2, mask1 = 0, mask2 = 0;
 
        switch (w->shift) {
@@ -2660,18 +2660,18 @@ static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w,
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                if (mask1)
-                       snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1,
+                       snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_1,
                                            mask1, val1);
                if (mask2)
-                       snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
+                       snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_2,
                                            mask2, val2);
                break;
        case SND_SOC_DAPM_POST_PMD:
                if (mask1)
-                       snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1,
+                       snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_1,
                                            mask1, 0);
                if (mask2)
-                       snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
+                       snd_soc_component_update_bits(component, RT5665_GPIO_CTRL_2,
                                            mask2, 0);
                break;
        default:
@@ -4052,7 +4052,7 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
 static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val = 0;
 
        if (rx_mask || tx_mask)
@@ -4096,7 +4096,7 @@ static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
+       snd_soc_component_update_bits(component, RT5665_TDM_CTRL_1,
                RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
                RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
                RT5665_TDM_OUT_LEN_MASK, val);
@@ -4108,24 +4108,24 @@ static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int rt5665_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, reg_clk, mask_clk, val_bits = 0x0100;
        int pre_div, frame_size;
 
        rt5665->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_warn(codec->dev, "Force using PLL");
-               snd_soc_codec_set_pll(codec, 0, RT5665_PLL1_S_MCLK,
+               dev_warn(component->dev, "Force using PLL");
+               snd_soc_component_set_pll(component, 0, RT5665_PLL1_S_MCLK,
                        rt5665->sysclk, rt5665->lrck[dai->id] * 512);
-               snd_soc_codec_set_sysclk(codec, RT5665_SCLK_S_PLL1, 0,
+               snd_soc_component_set_sysclk(component, RT5665_SCLK_S_PLL1, 0,
                        rt5665->lrck[dai->id] * 512, 0);
                pre_div = 1;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
 
@@ -4160,7 +4160,7 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
                reg_clk = RT5665_ADDA_CLK_1;
                mask_clk = RT5665_I2S_PD1_MASK;
                val_clk = pre_div << RT5665_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5665_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5665_I2S1_SDP,
                        RT5665_I2S_DL_MASK, val_len);
                break;
        case RT5665_AIF2_1:
@@ -4168,48 +4168,48 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
                reg_clk = RT5665_ADDA_CLK_2;
                mask_clk = RT5665_I2S_PD2_MASK;
                val_clk = pre_div << RT5665_I2S_PD2_SFT;
-               snd_soc_update_bits(codec, RT5665_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5665_I2S2_SDP,
                        RT5665_I2S_DL_MASK, val_len);
                break;
        case RT5665_AIF3:
                reg_clk = RT5665_ADDA_CLK_2;
                mask_clk = RT5665_I2S_PD3_MASK;
                val_clk = pre_div << RT5665_I2S_PD3_SFT;
-               snd_soc_update_bits(codec, RT5665_I2S3_SDP,
+               snd_soc_component_update_bits(component, RT5665_I2S3_SDP,
                        RT5665_I2S_DL_MASK, val_len);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, reg_clk, mask_clk, val_clk);
-       snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
+       snd_soc_component_update_bits(component, reg_clk, mask_clk, val_clk);
+       snd_soc_component_update_bits(component, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
 
        switch (rt5665->lrck[dai->id]) {
        case 192000:
-               snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
                        RT5665_DAC_OSR_MASK | RT5665_ADC_OSR_MASK,
                        RT5665_DAC_OSR_32 | RT5665_ADC_OSR_32);
                break;
        case 96000:
-               snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
                        RT5665_DAC_OSR_MASK | RT5665_ADC_OSR_MASK,
                        RT5665_DAC_OSR_64 | RT5665_ADC_OSR_64);
                break;
        default:
-               snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+               snd_soc_component_update_bits(component, RT5665_ADDA_CLK_1,
                        RT5665_DAC_OSR_MASK | RT5665_ADC_OSR_MASK,
                        RT5665_DAC_OSR_128 | RT5665_ADC_OSR_128);
                break;
        }
 
        if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) {
-               snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
                        RT5665_I2S2_M_PD_MASK, pre_div << RT5665_I2S2_M_PD_SFT);
        }
        if (rt5665->master[RT5665_AIF3]) {
-               snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
                        RT5665_I2S3_M_PD_MASK, pre_div << RT5665_I2S3_M_PD_SFT);
        }
 
@@ -4218,8 +4218,8 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -4263,32 +4263,32 @@ static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        switch (dai->id) {
        case RT5665_AIF1_1:
        case RT5665_AIF1_2:
-               snd_soc_update_bits(codec, RT5665_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5665_I2S1_SDP,
                        RT5665_I2S_MS_MASK | RT5665_I2S_BP_MASK |
                        RT5665_I2S_DF_MASK, reg_val);
                break;
        case RT5665_AIF2_1:
        case RT5665_AIF2_2:
-               snd_soc_update_bits(codec, RT5665_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5665_I2S2_SDP,
                        RT5665_I2S_MS_MASK | RT5665_I2S_BP_MASK |
                        RT5665_I2S_DF_MASK, reg_val);
                break;
        case RT5665_AIF3:
-               snd_soc_update_bits(codec, RT5665_I2S3_SDP,
+               snd_soc_component_update_bits(component, RT5665_I2S3_SDP,
                        RT5665_I2S_MS_MASK | RT5665_I2S_BP_MASK |
                        RT5665_I2S_DF_MASK, reg_val);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
        return 0;
 }
 
-static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int rt5665_set_component_sysclk(struct snd_soc_component *component, int clk_id,
                                   int source, unsigned int freq, int dir)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0, src = 0;
 
        if (freq == rt5665->sysclk && clk_id == rt5665->sysclk_src)
@@ -4308,34 +4308,34 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
                src = RT5665_CLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5665_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5665_GLB_CLK,
                RT5665_SCLK_SRC_MASK, reg_val);
 
        if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) {
-               snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
                        RT5665_I2S2_SRC_MASK, src << RT5665_I2S2_SRC_SFT);
        }
        if (rt5665->master[RT5665_AIF3]) {
-               snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1,
+               snd_soc_component_update_bits(component, RT5665_I2S_M_CLK_CTRL_1,
                        RT5665_I2S3_SRC_MASK, src << RT5665_I2S3_SRC_SFT);
        }
 
        rt5665->sysclk = freq;
        rt5665->sysclk_src = clk_id;
 
-       dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
+       dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
 
        return 0;
 }
 
-static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
+static int rt5665_set_component_pll(struct snd_soc_component *component, int pll_id,
                                int source, unsigned int freq_in,
                                unsigned int freq_out)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -4344,50 +4344,50 @@ static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5665->pll_in = 0;
                rt5665->pll_out = 0;
-               snd_soc_update_bits(codec, RT5665_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5665_GLB_CLK,
                        RT5665_SCLK_SRC_MASK, RT5665_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5665_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5665_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5665_GLB_CLK,
                        RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK);
                break;
        case RT5665_PLL1_S_BCLK1:
-               snd_soc_update_bits(codec, RT5665_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5665_GLB_CLK,
                                RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK1);
                break;
        case RT5665_PLL1_S_BCLK2:
-               snd_soc_update_bits(codec, RT5665_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5665_GLB_CLK,
                                RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK2);
                break;
        case RT5665_PLL1_S_BCLK3:
-               snd_soc_update_bits(codec, RT5665_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5665_GLB_CLK,
                                RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3);
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL Source %d\n", source);
+               dev_err(component->dev, "Unknown PLL Source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5665_PLL_CTRL_1,
+       snd_soc_component_write(component, RT5665_PLL_CTRL_1,
                pll_code.n_code << RT5665_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5665_PLL_CTRL_2,
+       snd_soc_component_write(component, RT5665_PLL_CTRL_2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5665_PLL_M_SFT |
                pll_code.m_bp << RT5665_PLL_M_BP_SFT);
 
@@ -4400,10 +4400,10 @@ static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
 
 static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
 
        rt5665->bclk[dai->id] = ratio;
 
@@ -4411,12 +4411,12 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
                switch (dai->id) {
                case RT5665_AIF2_1:
                case RT5665_AIF2_2:
-                       snd_soc_update_bits(codec, RT5665_ADDA_CLK_2,
+                       snd_soc_component_update_bits(component, RT5665_ADDA_CLK_2,
                                RT5665_I2S_BCLK_MS2_MASK,
                                RT5665_I2S_BCLK_MS2_64);
                        break;
                case RT5665_AIF3:
-                       snd_soc_update_bits(codec, RT5665_ADDA_CLK_2,
+                       snd_soc_component_update_bits(component, RT5665_ADDA_CLK_2,
                                RT5665_I2S_BCLK_MS3_MASK,
                                RT5665_I2S_BCLK_MS3_64);
                        break;
@@ -4426,10 +4426,10 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
        return 0;
 }
 
-static int rt5665_set_bias_level(struct snd_soc_codec *codec,
+static int rt5665_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
@@ -4459,39 +4459,37 @@ static int rt5665_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5665_probe(struct snd_soc_codec *codec)
+static int rt5665_probe(struct snd_soc_component *component)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
-       rt5665->codec = codec;
+       rt5665->component = component;
 
        schedule_delayed_work(&rt5665->calibrate_work, msecs_to_jiffies(100));
 
        return 0;
 }
 
-static int rt5665_remove(struct snd_soc_codec *codec)
+static void rt5665_remove(struct snd_soc_component *component)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
        regmap_write(rt5665->regmap, RT5665_RESET, 0);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5665_suspend(struct snd_soc_codec *codec)
+static int rt5665_suspend(struct snd_soc_component *component)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5665->regmap, true);
        regcache_mark_dirty(rt5665->regmap);
        return 0;
 }
 
-static int rt5665_resume(struct snd_soc_codec *codec)
+static int rt5665_resume(struct snd_soc_component *component)
 {
-       struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
+       struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5665->regmap, false);
        regcache_sync(rt5665->regmap);
@@ -4605,24 +4603,24 @@ static struct snd_soc_dai_driver rt5665_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5665 = {
-       .probe = rt5665_probe,
-       .remove = rt5665_remove,
-       .suspend = rt5665_suspend,
-       .resume = rt5665_resume,
-       .set_bias_level = rt5665_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls = rt5665_snd_controls,
-               .num_controls = ARRAY_SIZE(rt5665_snd_controls),
-               .dapm_widgets = rt5665_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets),
-               .dapm_routes = rt5665_dapm_routes,
-               .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes),
-       },
-       .set_sysclk = rt5665_set_codec_sysclk,
-       .set_pll = rt5665_set_codec_pll,
-       .set_jack = rt5665_set_jack_detect,
+static const struct snd_soc_component_driver soc_component_dev_rt5665 = {
+       .probe                  = rt5665_probe,
+       .remove                 = rt5665_remove,
+       .suspend                = rt5665_suspend,
+       .resume                 = rt5665_resume,
+       .set_bias_level         = rt5665_set_bias_level,
+       .controls               = rt5665_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5665_snd_controls),
+       .dapm_widgets           = rt5665_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5665_dapm_widgets),
+       .dapm_routes            = rt5665_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5665_dapm_routes),
+       .set_sysclk             = rt5665_set_component_sysclk,
+       .set_pll                = rt5665_set_component_pll,
+       .set_jack               = rt5665_set_jack_detect,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 
@@ -4753,7 +4751,7 @@ static void rt5665_calibrate_handler(struct work_struct *work)
        struct rt5665_priv *rt5665 = container_of(work, struct rt5665_priv,
                calibrate_work.work);
 
-       while (!rt5665->codec->component.card->instantiated) {
+       while (!rt5665->component->card->instantiated) {
                pr_debug("%s\n", __func__);
                usleep_range(10000, 15000);
        }
@@ -4828,9 +4826,6 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
        case 0x0:
                rt5665->id = CODEC_5666;
                break;
-       case 0x6:
-               rt5665->id = CODEC_5668;
-               break;
        case 0x3:
        default:
                rt5665->id = CODEC_5665;
@@ -4941,17 +4936,11 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
 
        }
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5665,
+       return devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt5665,
                        rt5665_dai, ARRAY_SIZE(rt5665_dai));
 }
 
-static int rt5665_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static void rt5665_i2c_shutdown(struct i2c_client *client)
 {
        struct rt5665_priv *rt5665 = i2c_get_clientdata(client);
@@ -4963,7 +4952,6 @@ static void rt5665_i2c_shutdown(struct i2c_client *client)
 static const struct of_device_id rt5665_of_match[] = {
        {.compatible = "realtek,rt5665"},
        {.compatible = "realtek,rt5666"},
-       {.compatible = "realtek,rt5668"},
        {},
 };
 MODULE_DEVICE_TABLE(of, rt5665_of_match);
@@ -4973,7 +4961,6 @@ MODULE_DEVICE_TABLE(of, rt5665_of_match);
 static const struct acpi_device_id rt5665_acpi_match[] = {
        {"10EC5665", 0,},
        {"10EC5666", 0,},
-       {"10EC5668", 0,},
        {},
 };
 MODULE_DEVICE_TABLE(acpi, rt5665_acpi_match);
@@ -4986,7 +4973,6 @@ static struct i2c_driver rt5665_i2c_driver = {
                .acpi_match_table = ACPI_PTR(rt5665_acpi_match),
        },
        .probe = rt5665_i2c_probe,
-       .remove = rt5665_i2c_remove,
        .shutdown = rt5665_i2c_shutdown,
        .id_table = rt5665_i2c_id,
 };
index 5ddebd6a4a1b5508fd158a0f1ac88ecf29b3fed8..b0a98ca39c5b044b2e8d762603aa9fd3ea9af6fa 100644 (file)
@@ -1978,7 +1978,6 @@ enum {
 enum {
        CODEC_5665,
        CODEC_5666,
-       CODEC_5668,
 };
 
 /* filter mask */
@@ -2003,7 +2002,7 @@ enum {
        RT5665_CLK_SEL_SYS4,
 };
 
-int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5665_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src);
 
 #endif /* __RT5665_H__ */
index c5094b4399e2e335556e78eaf0513b76aba51800..dc7df337d5f83dfee936a1380d68173f44b64692 100644 (file)
@@ -423,7 +423,7 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
 
 /**
  * rt5670_headset_detect - Detect headset.
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @jack_insert: Jack insert or not.
  *
  * Detect whether is headset or not when jack inserted.
@@ -431,46 +431,46 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
  * Returns detect status.
  */
 
-static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
+static int rt5670_headset_detect(struct snd_soc_component *component, int jack_insert)
 {
        int val;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        if (jack_insert) {
                snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
                snd_soc_dapm_sync(dapm);
-               snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
-               snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+               snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x0);
+               snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
                        RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
                        RT5670_CBJ_MN_JD);
-               snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
-               snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
+               snd_soc_component_write(component, RT5670_GPIO_CTRL2, 0x0004);
+               snd_soc_component_update_bits(component, RT5670_GPIO_CTRL1,
                        RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
-               snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
+               snd_soc_component_update_bits(component, RT5670_CJ_CTRL1,
                        RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
-               snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
-               snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+               snd_soc_component_write(component, RT5670_JD_CTRL3, 0x00f0);
+               snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
                        RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
-               snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
+               snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
                        RT5670_CBJ_MN_JD, 0);
                msleep(300);
-               val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
+               val = snd_soc_component_read32(component, RT5670_CJ_CTRL3) & 0x7;
                if (val == 0x1 || val == 0x2) {
                        rt5670->jack_type = SND_JACK_HEADSET;
                        /* for push button */
-                       snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
-                       snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
-                       snd_soc_read(codec, RT5670_IL_CMD);
+                       snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8);
+                       snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40);
+                       snd_soc_component_read32(component, RT5670_IL_CMD);
                } else {
-                       snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+                       snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
                        rt5670->jack_type = SND_JACK_HEADPHONE;
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                        snd_soc_dapm_sync(dapm);
                }
        } else {
-               snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
-               snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
+               snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x0);
+               snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
                rt5670->jack_type = 0;
                snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                snd_soc_dapm_sync(dapm);
@@ -479,35 +479,35 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
        return rt5670->jack_type;
 }
 
-void rt5670_jack_suspend(struct snd_soc_codec *codec)
+void rt5670_jack_suspend(struct snd_soc_component *component)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        rt5670->jack_type_saved = rt5670->jack_type;
-       rt5670_headset_detect(codec, 0);
+       rt5670_headset_detect(component, 0);
 }
 EXPORT_SYMBOL_GPL(rt5670_jack_suspend);
 
-void rt5670_jack_resume(struct snd_soc_codec *codec)
+void rt5670_jack_resume(struct snd_soc_component *component)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        if (rt5670->jack_type_saved)
-               rt5670_headset_detect(codec, 1);
+               rt5670_headset_detect(component, 1);
 }
 EXPORT_SYMBOL_GPL(rt5670_jack_resume);
 
-static int rt5670_button_detect(struct snd_soc_codec *codec)
+static int rt5670_button_detect(struct snd_soc_component *component)
 {
        int btn_type, val;
 
-       val = snd_soc_read(codec, RT5670_IL_CMD);
+       val = snd_soc_component_read32(component, RT5670_IL_CMD);
        btn_type = val & 0xff80;
-       snd_soc_write(codec, RT5670_IL_CMD, val);
+       snd_soc_component_write(component, RT5670_IL_CMD, val);
        if (btn_type != 0) {
                msleep(20);
-               val = snd_soc_read(codec, RT5670_IL_CMD);
-               snd_soc_write(codec, RT5670_IL_CMD, val);
+               val = snd_soc_component_read32(component, RT5670_IL_CMD);
+               snd_soc_component_write(component, RT5670_IL_CMD, val);
        }
 
        return btn_type;
@@ -521,25 +521,25 @@ static int rt5670_irq_detection(void *data)
        int val, btn_type, report = jack->status;
 
        if (rt5670->pdata.jd_mode == 1) /* 2 port */
-               val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0070;
+               val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070;
        else
-               val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0020;
+               val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020;
 
        switch (val) {
        /* jack in */
        case 0x30: /* 2 port */
        case 0x0: /* 1 port or 2 port */
                if (rt5670->jack_type == 0) {
-                       report = rt5670_headset_detect(rt5670->codec, 1);
+                       report = rt5670_headset_detect(rt5670->component, 1);
                        /* for push button and jack out */
                        gpio->debounce_time = 25;
                        break;
                }
                btn_type = 0;
-               if (snd_soc_read(rt5670->codec, RT5670_INT_IRQ_ST) & 0x4) {
+               if (snd_soc_component_read32(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) {
                        /* button pressed */
                        report = SND_JACK_HEADSET;
-                       btn_type = rt5670_button_detect(rt5670->codec);
+                       btn_type = rt5670_button_detect(rt5670->component);
                        switch (btn_type) {
                        case 0x2000: /* up */
                                report |= SND_JACK_BTN_1;
@@ -551,7 +551,7 @@ static int rt5670_irq_detection(void *data)
                                report |= SND_JACK_BTN_2;
                                break;
                        default:
-                               dev_err(rt5670->codec->dev,
+                               dev_err(rt5670->component->dev,
                                        "Unexpected button code 0x%04x\n",
                                        btn_type);
                                break;
@@ -566,8 +566,8 @@ static int rt5670_irq_detection(void *data)
        case 0x10: /* 2 port */
        case 0x20: /* 1 port */
                report = 0;
-               snd_soc_update_bits(rt5670->codec, RT5670_INT_IRQ_ST, 0x1, 0x0);
-               rt5670_headset_detect(rt5670->codec, 0);
+               snd_soc_component_update_bits(rt5670->component, RT5670_INT_IRQ_ST, 0x1, 0x0);
+               rt5670_headset_detect(rt5670->component, 0);
                gpio->debounce_time = 150; /* for jack in */
                break;
        default:
@@ -577,14 +577,14 @@ static int rt5670_irq_detection(void *data)
        return report;
 }
 
-int rt5670_set_jack_detect(struct snd_soc_codec *codec,
+int rt5670_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
        int ret;
 
        rt5670->jack = jack;
-       rt5670->hp_gpio.gpiod_dev = codec->dev;
+       rt5670->hp_gpio.gpiod_dev = component->dev;
        rt5670->hp_gpio.name = "headset";
        rt5670->hp_gpio.report = SND_JACK_HEADSET |
                SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
@@ -596,7 +596,7 @@ int rt5670_set_jack_detect(struct snd_soc_codec *codec,
        ret = snd_soc_jack_add_gpios(rt5670->jack, 1,
                        &rt5670->hp_gpio);
        if (ret) {
-               dev_err(codec->dev, "Adding jack GPIO failed\n");
+               dev_err(component->dev, "Adding jack GPIO failed\n");
                return ret;
        }
 
@@ -699,17 +699,17 @@ static const struct snd_kcontrol_new rt5670_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
        int idx, rate;
 
        rate = rt5670->sysclk / rl6231_get_pre_div(rt5670->regmap,
                RT5670_ADDA_CLK1, RT5670_I2S_PD1_SFT);
        idx = rl6231_calc_dmic_clk(rate);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
-               snd_soc_update_bits(codec, RT5670_DMIC_CTRL1,
+               snd_soc_component_update_bits(component, RT5670_DMIC_CTRL1,
                        RT5670_DMIC_CLK_MASK, idx << RT5670_DMIC_CLK_SFT);
        return idx;
 }
@@ -717,8 +717,8 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1)
                return 1;
@@ -729,7 +729,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
        unsigned int reg, shift, val;
 
        switch (source->shift) {
@@ -765,7 +765,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
                return 0;
        }
 
-       val = (snd_soc_read(codec, reg) >> shift) & 0xf;
+       val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
        switch (val) {
        case 1:
        case 2:
@@ -781,8 +781,8 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 static int can_use_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        if (rt5670->sysclk > rt5670->lrck[RT5670_AIF1] * 384)
                return 1;
@@ -793,7 +793,7 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
 
 /**
  * rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -805,7 +805,7 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5670_sel_asrc_clk_src(struct snd_soc_component *component,
                            unsigned int filter_mask, unsigned int clk_src)
 {
        unsigned int asrc2_mask = 0, asrc2_value = 0;
@@ -863,11 +863,11 @@ int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
        }
 
        if (asrc2_mask)
-               snd_soc_update_bits(codec, RT5670_ASRC_2,
+               snd_soc_component_update_bits(component, RT5670_ASRC_2,
                                    asrc2_mask, asrc2_value);
 
        if (asrc3_mask)
-               snd_soc_update_bits(codec, RT5670_ASRC_3,
+               snd_soc_component_update_bits(component, RT5670_ASRC_3,
                                    asrc3_mask, asrc3_value);
        return 0;
 }
@@ -1421,8 +1421,8 @@ static const struct snd_kcontrol_new rt5670_vad_adc_mux =
 static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
                           struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -1457,8 +1457,8 @@ static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
 static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -1507,16 +1507,16 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
 static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
                                    RT5670_PWR_BST1_P, RT5670_PWR_BST1_P);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
                                    RT5670_PWR_BST1_P, 0);
                break;
 
@@ -1530,16 +1530,16 @@ static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
                                    RT5670_PWR_BST2_P, RT5670_PWR_BST2_P);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
+               snd_soc_component_update_bits(component, RT5670_PWR_ANLG2,
                                    RT5670_PWR_BST2_P, 0);
                break;
 
@@ -2322,21 +2322,21 @@ static const struct snd_soc_dapm_route rt5672_specific_dapm_routes[] = {
 static int rt5670_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int pre_div, bclk_ms, frame_size;
 
        rt5670->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5670->sysclk, rt5670->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
+               dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
                        rt5670->lrck[dai->id], dai->id);
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
        bclk_ms = frame_size > 32;
@@ -2368,20 +2368,20 @@ static int rt5670_hw_params(struct snd_pcm_substream *substream,
                mask_clk = RT5670_I2S_BCLK_MS1_MASK | RT5670_I2S_PD1_MASK;
                val_clk = bclk_ms << RT5670_I2S_BCLK_MS1_SFT |
                        pre_div << RT5670_I2S_PD1_SFT;
-               snd_soc_update_bits(codec, RT5670_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5670_I2S1_SDP,
                        RT5670_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5670_ADDA_CLK1, mask_clk, val_clk);
                break;
        case RT5670_AIF2:
                mask_clk = RT5670_I2S_BCLK_MS2_MASK | RT5670_I2S_PD2_MASK;
                val_clk = bclk_ms << RT5670_I2S_BCLK_MS2_SFT |
                        pre_div << RT5670_I2S_PD2_SFT;
-               snd_soc_update_bits(codec, RT5670_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5670_I2S2_SDP,
                        RT5670_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT5670_ADDA_CLK1, mask_clk, val_clk);
+               snd_soc_component_update_bits(component, RT5670_ADDA_CLK1, mask_clk, val_clk);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
 
@@ -2390,8 +2390,8 @@ static int rt5670_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -2434,26 +2434,26 @@ static int rt5670_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
        switch (dai->id) {
        case RT5670_AIF1:
-               snd_soc_update_bits(codec, RT5670_I2S1_SDP,
+               snd_soc_component_update_bits(component, RT5670_I2S1_SDP,
                        RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
                        RT5670_I2S_DF_MASK, reg_val);
                break;
        case RT5670_AIF2:
-               snd_soc_update_bits(codec, RT5670_I2S2_SDP,
+               snd_soc_component_update_bits(component, RT5670_I2S2_SDP,
                        RT5670_I2S_MS_MASK | RT5670_I2S_BP_MASK |
                        RT5670_I2S_DF_MASK, reg_val);
                break;
        default:
-               dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+               dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                return -EINVAL;
        }
        return 0;
 }
 
-static int rt5670_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int rt5670_set_codec_sysclk(struct snd_soc_component *component, int clk_id,
                                   int source, unsigned int freq, int dir)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (clk_id) {
@@ -2467,16 +2467,16 @@ static int rt5670_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
                reg_val |= RT5670_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
-       snd_soc_update_bits(codec, RT5670_GLB_CLK,
+       snd_soc_component_update_bits(component, RT5670_GLB_CLK,
                RT5670_SCLK_SRC_MASK, reg_val);
        rt5670->sysclk = freq;
        if (clk_id != RT5670_SCLK_S_RCCLK)
                rt5670->sysclk_src = clk_id;
 
-       dev_dbg(codec->dev, "Sysclk : %dHz clock id : %d\n", freq, clk_id);
+       dev_dbg(component->dev, "Sysclk : %dHz clock id : %d\n", freq, clk_id);
 
        return 0;
 }
@@ -2484,8 +2484,8 @@ static int rt5670_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
 static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -2494,18 +2494,18 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5670->pll_in = 0;
                rt5670->pll_out = 0;
-               snd_soc_update_bits(codec, RT5670_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5670_GLB_CLK,
                        RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_MCLK);
                return 0;
        }
 
        switch (source) {
        case RT5670_PLL1_S_MCLK:
-               snd_soc_update_bits(codec, RT5670_GLB_CLK,
+               snd_soc_component_update_bits(component, RT5670_GLB_CLK,
                        RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_MCLK);
                break;
        case RT5670_PLL1_S_BCLK1:
@@ -2514,36 +2514,36 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
        case RT5670_PLL1_S_BCLK4:
                switch (dai->id) {
                case RT5670_AIF1:
-                       snd_soc_update_bits(codec, RT5670_GLB_CLK,
+                       snd_soc_component_update_bits(component, RT5670_GLB_CLK,
                                RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK1);
                        break;
                case RT5670_AIF2:
-                       snd_soc_update_bits(codec, RT5670_GLB_CLK,
+                       snd_soc_component_update_bits(component, RT5670_GLB_CLK,
                                RT5670_PLL1_SRC_MASK, RT5670_PLL1_SRC_BCLK2);
                        break;
                default:
-                       dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
+                       dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
                        return -EINVAL;
                }
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
-       snd_soc_write(codec, RT5670_PLL_CTRL1,
+       snd_soc_component_write(component, RT5670_PLL_CTRL1,
                pll_code.n_code << RT5670_PLL_N_SFT | pll_code.k_code);
-       snd_soc_write(codec, RT5670_PLL_CTRL2,
+       snd_soc_component_write(component, RT5670_PLL_CTRL2,
                (pll_code.m_bp ? 0 : pll_code.m_code) << RT5670_PLL_M_SFT |
                pll_code.m_bp << RT5670_PLL_M_BP_SFT);
 
@@ -2557,7 +2557,7 @@ static int rt5670_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val = 0;
 
        if (rx_mask || tx_mask)
@@ -2595,75 +2595,75 @@ static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, RT5670_TDM_CTRL_1, 0x7c00, val);
+       snd_soc_component_update_bits(component, RT5670_TDM_CTRL_1, 0x7c00, val);
 
        return 0;
 }
 
 static int rt5670_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+       dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
        if (dai->id != RT5670_AIF1)
                return 0;
 
        if ((ratio % 50) == 0)
-               snd_soc_update_bits(codec, RT5670_GEN_CTRL3,
+               snd_soc_component_update_bits(component, RT5670_GEN_CTRL3,
                        RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_50FS);
        else
-               snd_soc_update_bits(codec, RT5670_GEN_CTRL3,
+               snd_soc_component_update_bits(component, RT5670_GEN_CTRL3,
                        RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_NOR);
 
        return 0;
 }
 
-static int rt5670_set_bias_level(struct snd_soc_codec *codec,
+static int rt5670_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
-               if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
-                       snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+               if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
+                       snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_PWR_VREF1 | RT5670_PWR_MB |
                                RT5670_PWR_BG | RT5670_PWR_VREF2,
                                RT5670_PWR_VREF1 | RT5670_PWR_MB |
                                RT5670_PWR_BG | RT5670_PWR_VREF2);
                        mdelay(10);
-                       snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_PWR_FV1 | RT5670_PWR_FV2,
                                RT5670_PWR_FV1 | RT5670_PWR_FV2);
-                       snd_soc_update_bits(codec, RT5670_CHARGE_PUMP,
+                       snd_soc_component_update_bits(component, RT5670_CHARGE_PUMP,
                                RT5670_OSW_L_MASK | RT5670_OSW_R_MASK,
                                RT5670_OSW_L_DIS | RT5670_OSW_R_DIS);
-                       snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x1);
-                       snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5670_DIG_MISC, 0x1, 0x1);
+                       snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_LDO_SEL_MASK, 0x5);
                }
                break;
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_PWR_VREF1 | RT5670_PWR_VREF2 |
                                RT5670_PWR_FV1 | RT5670_PWR_FV2, 0);
-               snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+               snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_LDO_SEL_MASK, 0x3);
                break;
        case SND_SOC_BIAS_OFF:
                if (rt5670->pdata.jd_mode)
-                       snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_PWR_VREF1 | RT5670_PWR_MB |
                                RT5670_PWR_BG | RT5670_PWR_VREF2 |
                                RT5670_PWR_FV1 | RT5670_PWR_FV2,
                                RT5670_PWR_MB | RT5670_PWR_BG);
                else
-                       snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
+                       snd_soc_component_update_bits(component, RT5670_PWR_ANLG1,
                                RT5670_PWR_VREF1 | RT5670_PWR_MB |
                                RT5670_PWR_BG | RT5670_PWR_VREF2 |
                                RT5670_PWR_FV1 | RT5670_PWR_FV2, 0);
 
-               snd_soc_update_bits(codec, RT5670_DIG_MISC, 0x1, 0x0);
+               snd_soc_component_update_bits(component, RT5670_DIG_MISC, 0x1, 0x0);
                break;
 
        default:
@@ -2673,12 +2673,12 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int rt5670_probe(struct snd_soc_codec *codec)
+static int rt5670_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
-       switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) {
+       switch (snd_soc_component_read32(component, RT5670_RESET) & RT5670_ID_MASK) {
        case RT5670_ID_5670:
        case RT5670_ID_5671:
                snd_soc_dapm_new_controls(dapm,
@@ -2697,37 +2697,36 @@ static int rt5670_probe(struct snd_soc_codec *codec)
                        ARRAY_SIZE(rt5672_specific_dapm_routes));
                break;
        default:
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "The driver is for RT5670 RT5671 or RT5672 only\n");
                return -ENODEV;
        }
-       rt5670->codec = codec;
+       rt5670->component = component;
 
        return 0;
 }
 
-static int rt5670_remove(struct snd_soc_codec *codec)
+static void rt5670_remove(struct snd_soc_component *component)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        regmap_write(rt5670->regmap, RT5670_RESET, 0);
        snd_soc_jack_free_gpios(rt5670->jack, 1, &rt5670->hp_gpio);
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5670_suspend(struct snd_soc_codec *codec)
+static int rt5670_suspend(struct snd_soc_component *component)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5670->regmap, true);
        regcache_mark_dirty(rt5670->regmap);
        return 0;
 }
 
-static int rt5670_resume(struct snd_soc_codec *codec)
+static int rt5670_resume(struct snd_soc_component *component)
 {
-       struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+       struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(rt5670->regmap, false);
        regcache_sync(rt5670->regmap);
@@ -2794,22 +2793,22 @@ static struct snd_soc_dai_driver rt5670_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5670 = {
-       .probe = rt5670_probe,
-       .remove = rt5670_remove,
-       .suspend = rt5670_suspend,
-       .resume = rt5670_resume,
-       .set_bias_level = rt5670_set_bias_level,
-       .idle_bias_off = true,
-       .set_sysclk = rt5670_set_codec_sysclk,
-       .component_driver = {
-               .controls               = rt5670_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5670_snd_controls),
-               .dapm_widgets           = rt5670_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5670_dapm_widgets),
-               .dapm_routes            = rt5670_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5670_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5670 = {
+       .probe                  = rt5670_probe,
+       .remove                 = rt5670_remove,
+       .suspend                = rt5670_suspend,
+       .resume                 = rt5670_resume,
+       .set_bias_level         = rt5670_set_bias_level,
+       .set_sysclk             = rt5670_set_codec_sysclk,
+       .controls               = rt5670_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5670_snd_controls),
+       .dapm_widgets           = rt5670_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5670_dapm_widgets),
+       .dapm_routes            = rt5670_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5670_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5670_regmap = {
@@ -3171,7 +3170,8 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
        pm_runtime_enable(&i2c->dev);
        pm_request_idle(&i2c->dev);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_rt5670,
                        rt5670_dai, ARRAY_SIZE(rt5670_dai));
        if (ret < 0)
                goto err;
@@ -3188,7 +3188,6 @@ err:
 static int rt5670_i2c_remove(struct i2c_client *i2c)
 {
        pm_runtime_disable(&i2c->dev);
-       snd_soc_unregister_codec(&i2c->dev);
 
        return 0;
 }
index 265df80d504e0f1528a651cb2e3bcb6f9370fdd6..97e8eebe63fa5ed0eb97802c5a25dd6682c6eea7 100644 (file)
@@ -1986,11 +1986,11 @@ enum {
        RT5670_DOWN_RATE_FILTER = (0x1 << 7),
 };
 
-int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5670_sel_asrc_clk_src(struct snd_soc_component *component,
                            unsigned int filter_mask, unsigned int clk_src);
 
 struct rt5670_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5670_platform_data pdata;
        struct regmap *regmap;
        struct snd_soc_jack *jack;
@@ -2012,8 +2012,8 @@ struct rt5670_priv {
        int jack_type_saved;
 };
 
-void rt5670_jack_suspend(struct snd_soc_codec *codec);
-void rt5670_jack_resume(struct snd_soc_codec *codec);
-int rt5670_set_jack_detect(struct snd_soc_codec *codec,
+void rt5670_jack_suspend(struct snd_soc_component *component);
+void rt5670_jack_resume(struct snd_soc_component *component);
+int rt5670_set_jack_detect(struct snd_soc_component *component,
        struct snd_soc_jack *jack);
 #endif /* __RT5670_H__ */
index 0791fec398fb63a67c88d206b28536b6e5571079..bc1a23dd7c2de0902cfecb12a5cf1d5b3eebfa9d 100644 (file)
@@ -554,7 +554,7 @@ static bool rt5677_readable_register(struct device *dev, unsigned int reg)
 static int rt5677_dsp_mode_i2c_write_addr(struct rt5677_priv *rt5677,
                unsigned int addr, unsigned int value, unsigned int opcode)
 {
-       struct snd_soc_codec *codec = rt5677->codec;
+       struct snd_soc_component *component = rt5677->component;
        int ret;
 
        mutex_lock(&rt5677->dsp_cmd_lock);
@@ -562,35 +562,35 @@ static int rt5677_dsp_mode_i2c_write_addr(struct rt5677_priv *rt5677,
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_MSB,
                addr >> 16);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret);
+               dev_err(component->dev, "Failed to set addr msb value: %d\n", ret);
                goto err;
        }
 
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_LSB,
                addr & 0xffff);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret);
+               dev_err(component->dev, "Failed to set addr lsb value: %d\n", ret);
                goto err;
        }
 
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_MSB,
                value >> 16);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set data msb value: %d\n", ret);
+               dev_err(component->dev, "Failed to set data msb value: %d\n", ret);
                goto err;
        }
 
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_DATA_LSB,
                value & 0xffff);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set data lsb value: %d\n", ret);
+               dev_err(component->dev, "Failed to set data lsb value: %d\n", ret);
                goto err;
        }
 
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_OP_CODE,
                opcode);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set op code value: %d\n", ret);
+               dev_err(component->dev, "Failed to set op code value: %d\n", ret);
                goto err;
        }
 
@@ -612,7 +612,7 @@ err:
 static int rt5677_dsp_mode_i2c_read_addr(
        struct rt5677_priv *rt5677, unsigned int addr, unsigned int *value)
 {
-       struct snd_soc_codec *codec = rt5677->codec;
+       struct snd_soc_component *component = rt5677->component;
        int ret;
        unsigned int msb, lsb;
 
@@ -621,21 +621,21 @@ static int rt5677_dsp_mode_i2c_read_addr(
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_MSB,
                addr >> 16);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret);
+               dev_err(component->dev, "Failed to set addr msb value: %d\n", ret);
                goto err;
        }
 
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_ADDR_LSB,
                addr & 0xffff);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret);
+               dev_err(component->dev, "Failed to set addr lsb value: %d\n", ret);
                goto err;
        }
 
        ret = regmap_write(rt5677->regmap_physical, RT5677_DSP_I2C_OP_CODE,
                0x0002);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set op code value: %d\n", ret);
+               dev_err(component->dev, "Failed to set op code value: %d\n", ret);
                goto err;
        }
 
@@ -685,9 +685,9 @@ static int rt5677_dsp_mode_i2c_read(
        return ret;
 }
 
-static void rt5677_set_dsp_mode(struct snd_soc_codec *codec, bool on)
+static void rt5677_set_dsp_mode(struct snd_soc_component *component, bool on)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        if (on) {
                regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2);
@@ -698,9 +698,9 @@ static void rt5677_set_dsp_mode(struct snd_soc_codec *codec, bool on)
        }
 }
 
-static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
+static int rt5677_set_dsp_vad(struct snd_soc_component *component, bool on)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        static bool activity;
        int ret;
 
@@ -740,17 +740,17 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
                }
                regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff);
                regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07fd);
-               rt5677_set_dsp_mode(codec, true);
+               rt5677_set_dsp_mode(component, true);
 
                ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1,
-                       codec->dev);
+                       component->dev);
                if (ret == 0) {
                        rt5677_spi_write_firmware(0x50000000, rt5677->fw1);
                        release_firmware(rt5677->fw1);
                }
 
                ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2,
-                       codec->dev);
+                       component->dev);
                if (ret == 0) {
                        rt5677_spi_write_firmware(0x60000000, rt5677->fw2);
                        release_firmware(rt5677->fw2);
@@ -767,7 +767,7 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
                regcache_cache_bypass(rt5677->regmap, true);
 
                regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x1, 0x1);
-               rt5677_set_dsp_mode(codec, false);
+               rt5677_set_dsp_mode(component, false);
                regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x0001);
 
                regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
@@ -812,12 +812,11 @@ static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
-       struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
        rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
 
-       if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-               rt5677_set_dsp_vad(codec, rt5677->dsp_vad_en);
+       if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+               rt5677_set_dsp_vad(component, rt5677->dsp_vad_en);
 
        return 0;
 }
@@ -911,15 +910,15 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
 static int set_dmic_clk(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        int idx, rate;
 
        rate = rt5677->sysclk / rl6231_get_pre_div(rt5677->regmap,
                RT5677_CLK_TREE_CTRL1, RT5677_I2S_PD1_SFT);
        idx = rl6231_calc_dmic_clk(rate);
        if (idx < 0)
-               dev_err(codec->dev, "Failed to set DMIC clock\n");
+               dev_err(component->dev, "Failed to set DMIC clock\n");
        else
                regmap_update_bits(rt5677->regmap, RT5677_DMIC_CTRL1,
                        RT5677_DMIC_CLK_MASK, idx << RT5677_DMIC_CLK_SFT);
@@ -929,8 +928,8 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        regmap_read(rt5677->regmap, RT5677_GLB_CLK1, &val);
@@ -944,8 +943,8 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int reg, shift, val;
 
        if (source->reg == RT5677_ASRC_1) {
@@ -1027,8 +1026,8 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
 static int can_use_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        if (rt5677->sysclk > rt5677->lrck[RT5677_AIF1] * 384)
                return 1;
@@ -1038,7 +1037,7 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
 
 /**
  * rt5677_sel_asrc_clk_src - select ASRC clock source for a set of filters
- * @codec: SoC audio codec device.
+ * @component: SoC audio component device.
  * @filter_mask: mask of filters.
  * @clk_src: clock source
  *
@@ -1050,10 +1049,10 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
  * set of filters specified by the mask. And the codec driver will turn on ASRC
  * for these filters if ASRC is selected as their clock source.
  */
-int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int asrc3_mask = 0, asrc3_value = 0;
        unsigned int asrc4_mask = 0, asrc4_value = 0;
        unsigned int asrc5_mask = 0, asrc5_value = 0;
@@ -1232,8 +1231,8 @@ EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
 static int rt5677_dmic_use_asrc(struct snd_soc_dapm_widget *source,
                         struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int asrc_setting;
 
        switch (source->shift) {
@@ -2393,8 +2392,8 @@ static const struct snd_kcontrol_new rt5677_if2_dac7_tdm_sel_mux =
 static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -2417,8 +2416,8 @@ static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
 static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -2441,8 +2440,8 @@ static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
 static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -2463,8 +2462,8 @@ static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
 static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
@@ -2485,8 +2484,8 @@ static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
 static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -2512,8 +2511,8 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
 static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int value;
 
        switch (event) {
@@ -2535,8 +2534,8 @@ static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
 static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int value;
 
        switch (event) {
@@ -2558,12 +2557,12 @@ static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
 static int rt5677_vref_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_ON &&
+               if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON &&
                        !rt5677->is_vref_slow) {
                        mdelay(20);
                        regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
@@ -4098,21 +4097,21 @@ static const struct snd_soc_dapm_route rt5677_dmic2_clk_2[] = {
 static int rt5677_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int val_len = 0, val_clk, mask_clk;
        int pre_div, bclk_ms, frame_size;
 
        rt5677->lrck[dai->id] = params_rate(params);
        pre_div = rl6231_get_clk_info(rt5677->sysclk, rt5677->lrck[dai->id]);
        if (pre_div < 0) {
-               dev_err(codec->dev, "Unsupported clock setting: sysclk=%dHz lrck=%dHz\n",
+               dev_err(component->dev, "Unsupported clock setting: sysclk=%dHz lrck=%dHz\n",
                        rt5677->sysclk, rt5677->lrck[dai->id]);
                return -EINVAL;
        }
        frame_size = snd_soc_params_to_frame_size(params);
        if (frame_size < 0) {
-               dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
+               dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
                return -EINVAL;
        }
        bclk_ms = frame_size > 32;
@@ -4183,8 +4182,8 @@ static int rt5677_hw_params(struct snd_pcm_substream *substream,
 
 static int rt5677_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -4257,8 +4256,8 @@ static int rt5677_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int rt5677_set_dai_sysclk(struct snd_soc_dai *dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int reg_val = 0;
 
        if (freq == rt5677->sysclk && clk_id == rt5677->sysclk_src)
@@ -4275,7 +4274,7 @@ static int rt5677_set_dai_sysclk(struct snd_soc_dai *dai,
                reg_val |= RT5677_SCLK_SRC_RCCLK;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
                return -EINVAL;
        }
        regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK1,
@@ -4310,8 +4309,8 @@ static int rt5677_pll_calc(const unsigned int freq_in,
 static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                        unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        struct rl6231_pll_code pll_code;
        int ret;
 
@@ -4320,7 +4319,7 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                return 0;
 
        if (!freq_in || !freq_out) {
-               dev_dbg(codec->dev, "PLL disabled\n");
+               dev_dbg(component->dev, "PLL disabled\n");
 
                rt5677->pll_in = 0;
                rt5677->pll_out = 0;
@@ -4360,17 +4359,17 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
                }
                break;
        default:
-               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               dev_err(component->dev, "Unknown PLL source %d\n", source);
                return -EINVAL;
        }
 
        ret = rt5677_pll_calc(freq_in, freq_out, &pll_code);
        if (ret < 0) {
-               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
                return ret;
        }
 
-       dev_dbg(codec->dev, "m_bypass=%d m=%d n=%d k=%d\n",
+       dev_dbg(component->dev, "m_bypass=%d m=%d n=%d k=%d\n",
                pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
                pll_code.n_code, pll_code.k_code);
 
@@ -4390,8 +4389,8 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
 static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0, slot_width_25 = 0;
 
        if (rx_mask || tx_mask)
@@ -4449,18 +4448,18 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        return 0;
 }
 
-static int rt5677_set_bias_level(struct snd_soc_codec *codec,
+static int rt5677_set_bias_level(struct snd_soc_component *component,
                        enum snd_soc_bias_level level)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
 
        case SND_SOC_BIAS_PREPARE:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
-                       rt5677_set_dsp_vad(codec, false);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
+                       rt5677_set_dsp_vad(component, false);
 
                        regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
                                RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK,
@@ -4495,7 +4494,7 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
                        RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000);
 
                if (rt5677->dsp_vad_en)
-                       rt5677_set_dsp_vad(codec, true);
+                       rt5677_set_dsp_vad(component, true);
                break;
 
        default:
@@ -4696,13 +4695,13 @@ static void rt5677_free_gpio(struct i2c_client *i2c)
 }
 #endif
 
-static int rt5677_probe(struct snd_soc_codec *codec)
+static int rt5677_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
        int i;
 
-       rt5677->codec = codec;
+       rt5677->component = component;
 
        if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
                snd_soc_dapm_add_routes(dapm,
@@ -4714,7 +4713,7 @@ static int rt5677_probe(struct snd_soc_codec *codec)
                        ARRAY_SIZE(rt5677_dmic2_clk_1));
        }
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
        regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
        regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
@@ -4753,21 +4752,19 @@ static int rt5677_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5677_remove(struct snd_soc_codec *codec)
+static void rt5677_remove(struct snd_soc_component *component)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
        gpiod_set_value_cansleep(rt5677->pow_ldo2, 0);
        gpiod_set_value_cansleep(rt5677->reset_pin, 1);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM
-static int rt5677_suspend(struct snd_soc_codec *codec)
+static int rt5677_suspend(struct snd_soc_component *component)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        if (!rt5677->dsp_vad_en) {
                regcache_cache_only(rt5677->regmap, true);
@@ -4780,9 +4777,9 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int rt5677_resume(struct snd_soc_codec *codec)
+static int rt5677_resume(struct snd_soc_component *component)
 {
-       struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+       struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
        if (!rt5677->dsp_vad_en) {
                rt5677->pll_src = 0;
@@ -4959,21 +4956,21 @@ static struct snd_soc_dai_driver rt5677_dai[] = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_rt5677 = {
-       .probe = rt5677_probe,
-       .remove = rt5677_remove,
-       .suspend = rt5677_suspend,
-       .resume = rt5677_resume,
-       .set_bias_level = rt5677_set_bias_level,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = rt5677_snd_controls,
-               .num_controls           = ARRAY_SIZE(rt5677_snd_controls),
-               .dapm_widgets           = rt5677_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(rt5677_dapm_widgets),
-               .dapm_routes            = rt5677_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(rt5677_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_rt5677 = {
+       .probe                  = rt5677_probe,
+       .remove                 = rt5677_remove,
+       .suspend                = rt5677_suspend,
+       .resume                 = rt5677_resume,
+       .set_bias_level         = rt5677_set_bias_level,
+       .controls               = rt5677_snd_controls,
+       .num_controls           = ARRAY_SIZE(rt5677_snd_controls),
+       .dapm_widgets           = rt5677_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(rt5677_dapm_widgets),
+       .dapm_routes            = rt5677_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(rt5677_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config rt5677_regmap_physical = {
@@ -5262,13 +5259,13 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
        rt5677_init_gpio(i2c);
        rt5677_init_irq(i2c);
 
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677,
+       return devm_snd_soc_register_component(&i2c->dev,
+                                     &soc_component_dev_rt5677,
                                      rt5677_dai, ARRAY_SIZE(rt5677_dai));
 }
 
 static int rt5677_i2c_remove(struct i2c_client *i2c)
 {
-       snd_soc_unregister_codec(&i2c->dev);
        rt5677_free_irq(i2c);
        rt5677_free_gpio(i2c);
 
index 97239973edc4df2eb26afb845160776474af1579..183d92b030459f3323112b137b86fee74dffe741 100644 (file)
@@ -1790,7 +1790,7 @@ struct rt5677_platform_data {
 };
 
 struct rt5677_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct rt5677_platform_data pdata;
        struct regmap *regmap, *regmap_physical;
        const struct firmware *fw1, *fw2;
@@ -1816,7 +1816,7 @@ struct rt5677_priv {
        bool is_vref_slow;
 };
 
-int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
+int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,
                unsigned int filter_mask, unsigned int clk_src);
 
 #endif /* __RT5677_H__ */
index e1ab5537d27a80f702a2f8934b79c21ddf514d87..7c1d65830c050f488f1e7e4d64ae8dc047334a61 100644 (file)
@@ -147,19 +147,19 @@ struct sgtl5000_priv {
 static int mic_bias_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* change mic bias resistor */
-               snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
                        SGTL5000_BIAS_R_MASK,
                        sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
                                SGTL5000_BIAS_R_MASK, 0);
                break;
        }
@@ -174,12 +174,12 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
 static int power_vag_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP;
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
                msleep(400);
                break;
@@ -190,9 +190,9 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
                 * operational to prevent inadvertently starving the
                 * other one of them.
                 */
-               if ((snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER) &
+               if ((snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) &
                                mask) != mask) {
-                       snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+                       snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
                                SGTL5000_VAG_POWERUP, 0);
                        msleep(400);
                }
@@ -216,17 +216,54 @@ static SOC_ENUM_SINGLE_DECL(adc_enum,
 static const struct snd_kcontrol_new adc_mux =
 SOC_DAPM_ENUM("Capture Mux", adc_enum);
 
+/* input sources for headphone */
+static const char *hp_mux_text[] = {
+       "DAC", "LINE_IN"
+};
+
+static SOC_ENUM_SINGLE_DECL(hp_enum,
+                           SGTL5000_CHIP_ANA_CTRL, 6,
+                           hp_mux_text);
+
+static const struct snd_kcontrol_new hp_mux =
+SOC_DAPM_ENUM("Headphone Mux", hp_enum);
+
 /* input sources for DAC */
 static const char *dac_mux_text[] = {
-       "DAC", "LINE_IN"
+       "ADC", "I2S", "Rsvrd", "DAP"
 };
 
 static SOC_ENUM_SINGLE_DECL(dac_enum,
-                           SGTL5000_CHIP_ANA_CTRL, 6,
+                           SGTL5000_CHIP_SSS_CTRL, SGTL5000_DAC_SEL_SHIFT,
                            dac_mux_text);
 
 static const struct snd_kcontrol_new dac_mux =
-SOC_DAPM_ENUM("Headphone Mux", dac_enum);
+SOC_DAPM_ENUM("Digital Input Mux", dac_enum);
+
+/* input sources for DAP */
+static const char *dap_mux_text[] = {
+       "ADC", "I2S"
+};
+
+static SOC_ENUM_SINGLE_DECL(dap_enum,
+                           SGTL5000_CHIP_SSS_CTRL, SGTL5000_DAP_SEL_SHIFT,
+                           dap_mux_text);
+
+static const struct snd_kcontrol_new dap_mux =
+SOC_DAPM_ENUM("DAP Mux", dap_enum);
+
+/* input sources for DAP mix */
+static const char *dapmix_mux_text[] = {
+       "ADC", "I2S"
+};
+
+static SOC_ENUM_SINGLE_DECL(dapmix_enum,
+                           SGTL5000_CHIP_SSS_CTRL, SGTL5000_DAP_MIX_SEL_SHIFT,
+                           dapmix_mux_text);
+
+static const struct snd_kcontrol_new dapmix_mux =
+SOC_DAPM_ENUM("DAP MIX Mux", dapmix_enum);
+
 
 static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
        SND_SOC_DAPM_INPUT("LINE_IN"),
@@ -243,7 +280,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
        SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
 
        SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
-       SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
+       SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &hp_mux),
+       SND_SOC_DAPM_MUX("Digital Input Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
+       SND_SOC_DAPM_MUX("DAP Mux", SGTL5000_DAP_CTRL, 0, 0, &dap_mux),
+       SND_SOC_DAPM_MUX("DAP MIX Mux", SGTL5000_DAP_CTRL, 4, 0, &dapmix_mux),
+       SND_SOC_DAPM_MIXER("DAP", SGTL5000_CHIP_DIG_POWER, 4, 0, NULL, 0),
+
 
        /* aif for i2s input */
        SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
@@ -270,7 +312,19 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
        {"ADC", NULL, "Capture Mux"},           /* adc_mux --> adc */
        {"AIFOUT", NULL, "ADC"},                /* adc --> i2s_out */
 
-       {"DAC", NULL, "AIFIN"},                 /* i2s-->dac,skip audio mux */
+       {"DAP Mux", "ADC", "ADC"},              /* adc --> DAP mux */
+       {"DAP Mux", NULL, "AIFIN"},             /* i2s --> DAP mux */
+       {"DAP", NULL, "DAP Mux"},               /* DAP mux --> dap */
+
+       {"DAP MIX Mux", "ADC", "ADC"},          /* adc --> DAP MIX mux */
+       {"DAP MIX Mux", NULL, "AIFIN"},         /* i2s --> DAP MIX mux */
+       {"DAP", NULL, "DAP MIX Mux"},           /* DAP MIX mux --> dap */
+
+       {"Digital Input Mux", "ADC", "ADC"},    /* adc --> audio mux */
+       {"Digital Input Mux", NULL, "AIFIN"},   /* i2s --> audio mux */
+       {"Digital Input Mux", NULL, "DAP"},     /* dap --> audio mux */
+       {"DAC", NULL, "Digital Input Mux"},     /* audio mux --> dac */
+
        {"Headphone Mux", "DAC", "DAC"},        /* dac --> hp_mux */
        {"LO", NULL, "DAC"},                    /* dac --> line_out */
 
@@ -318,12 +372,12 @@ static int dac_info_volsw(struct snd_kcontrol *kcontrol,
 static int dac_get_volsw(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int reg;
        int l;
        int r;
 
-       reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
+       reg = snd_soc_component_read32(component, SGTL5000_CHIP_DAC_VOL);
 
        /* get left channel volume */
        l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
@@ -371,7 +425,7 @@ static int dac_get_volsw(struct snd_kcontrol *kcontrol,
 static int dac_put_volsw(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int reg;
        int l;
        int r;
@@ -391,7 +445,7 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
        reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
                r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
 
-       snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
+       snd_soc_component_write(component, SGTL5000_CHIP_DAC_VOL, reg);
 
        return 0;
 }
@@ -409,9 +463,9 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
 static int avc_get_threshold(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int db, i;
-       u16 reg = snd_soc_read(codec, SGTL5000_DAP_AVC_THRESHOLD);
+       u16 reg = snd_soc_component_read32(component, SGTL5000_DAP_AVC_THRESHOLD);
 
        /* register value 0 => -96dB */
        if (!reg) {
@@ -442,7 +496,7 @@ static int avc_get_threshold(struct snd_kcontrol *kcontrol,
 static int avc_put_threshold(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        int db;
        u16 reg;
 
@@ -450,7 +504,7 @@ static int avc_put_threshold(struct snd_kcontrol *kcontrol,
        if (db < 0 || db > 96)
                return -EINVAL;
        reg = avc_thr_db2reg[db];
-       snd_soc_write(codec, SGTL5000_DAP_AVC_THRESHOLD, reg);
+       snd_soc_component_write(component, SGTL5000_DAP_AVC_THRESHOLD, reg);
 
        return 0;
 }
@@ -463,6 +517,12 @@ static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
        1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0)
 );
 
+/* tlv for DAP channels, 0% - 100% - 200% */
+static const DECLARE_TLV_DB_SCALE(dap_volume, 0, 1, 0);
+
+/* tlv for bass bands, -11.75db to 12.0db, step .25db */
+static const DECLARE_TLV_DB_SCALE(bass_band, -1175, 25, 0);
+
 /* tlv for hp volume, -51.5db to 12.0db, step .5db */
 static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
 
@@ -514,6 +574,11 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
                        lineout_volume),
        SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1),
 
+       SOC_SINGLE_TLV("DAP Main channel", SGTL5000_DAP_MAIN_CHAN,
+       0, 0xffff, 0, dap_volume),
+
+       SOC_SINGLE_TLV("DAP Mix channel", SGTL5000_DAP_MIX_CHAN,
+       0, 0xffff, 0, dap_volume),
        /* Automatic Volume Control (DAP AVC) */
        SOC_SINGLE("AVC Switch", SGTL5000_DAP_AVC_CTRL, 0, 1, 0),
        SOC_SINGLE("AVC Hard Limiter Switch", SGTL5000_DAP_AVC_CTRL, 5, 1, 0),
@@ -523,16 +588,36 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
        SOC_SINGLE_EXT_TLV("AVC Threshold Volume", SGTL5000_DAP_AVC_THRESHOLD,
                        0, 96, 0, avc_get_threshold, avc_put_threshold,
                        avc_threshold),
+
+       SOC_SINGLE_TLV("BASS 0", SGTL5000_DAP_EQ_BASS_BAND0,
+       0, 0x5F, 0, bass_band),
+
+       SOC_SINGLE_TLV("BASS 1", SGTL5000_DAP_EQ_BASS_BAND1,
+       0, 0x5F, 0, bass_band),
+
+       SOC_SINGLE_TLV("BASS 2", SGTL5000_DAP_EQ_BASS_BAND2,
+       0, 0x5F, 0, bass_band),
+
+       SOC_SINGLE_TLV("BASS 3", SGTL5000_DAP_EQ_BASS_BAND3,
+       0, 0x5F, 0, bass_band),
+
+       SOC_SINGLE_TLV("BASS 4", SGTL5000_DAP_EQ_BASS_BAND4,
+       0, 0x5F, 0, bass_band),
 };
 
 /* mute the codec used by alsa core */
 static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 adcdac_ctrl = SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT;
+       struct snd_soc_component *component = codec_dai->component;
+       u16 i2s_pwr = SGTL5000_I2S_IN_POWERUP;
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
-                       adcdac_ctrl, mute ? adcdac_ctrl : 0);
+       /*
+        * During 'digital mute' do not mute DAC
+        * because LINE_IN would be muted aswell. We want to mute
+        * only I2S block - this can be done by powering it off
+        */
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_DIG_POWER,
+                       i2s_pwr, mute ? 0 : i2s_pwr);
 
        return 0;
 }
@@ -540,8 +625,8 @@ static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 /* set codec format */
 static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
        u16 i2sctl = 0;
 
        sgtl5000->master = 0;
@@ -599,7 +684,7 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
+       snd_soc_component_write(component, SGTL5000_CHIP_I2S_CTRL, i2sctl);
 
        return 0;
 }
@@ -608,8 +693,8 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                   int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case SGTL5000_SYSCLK:
@@ -635,9 +720,9 @@ static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  * and above.
  * 3. usage of sys_mclk is preferred over pll to save power.
  */
-static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
+static int sgtl5000_set_clock(struct snd_soc_component *component, int frame_rate)
 {
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
        int clk_ctl = 0;
        int sys_fs;     /* sample freq */
 
@@ -690,7 +775,7 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
                clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
                break;
        default:
-               dev_err(codec->dev, "frame rate %d not supported\n",
+               dev_err(component->dev, "frame rate %d not supported\n",
                        frame_rate);
                return -EINVAL;
        }
@@ -719,9 +804,9 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
                        clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
                                SGTL5000_MCLK_FREQ_SHIFT;
                } else {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "PLL not supported in slave mode\n");
-                       dev_err(codec->dev, "%d ratio is not supported. "
+                       dev_err(component->dev, "%d ratio is not supported. "
                                "SYS_MCLK needs to be 256, 384 or 512 * fs\n",
                                sgtl5000->sysclk / frame_rate);
                        return -EINVAL;
@@ -754,31 +839,31 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
                pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
                    frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
 
-               snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
+               snd_soc_component_write(component, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
                if (div2)
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                SGTL5000_CHIP_CLK_TOP_CTRL,
                                SGTL5000_INPUT_FREQ_DIV2,
                                SGTL5000_INPUT_FREQ_DIV2);
                else
-                       snd_soc_update_bits(codec,
+                       snd_soc_component_update_bits(component,
                                SGTL5000_CHIP_CLK_TOP_CTRL,
                                SGTL5000_INPUT_FREQ_DIV2,
                                0);
 
                /* power up pll */
-               snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
                        SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
 
                /* if using pll, clk_ctrl must be set after pll power up */
-               snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
+               snd_soc_component_write(component, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
        } else {
                /* otherwise, clk_ctrl must be set before pll power down */
-               snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
+               snd_soc_component_write(component, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
 
                /* power down pll */
-               snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
                        0);
        }
@@ -794,8 +879,8 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_pcm_hw_params *params,
                                  struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
        int channels = params_channels(params);
        int i2s_ctl = 0;
        int stereo;
@@ -803,7 +888,7 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
 
        /* sysclk should already set */
        if (!sgtl5000->sysclk) {
-               dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
+               dev_err(component->dev, "%s: set sysclk first!\n", __func__);
                return -EFAULT;
        }
 
@@ -813,11 +898,11 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
                stereo = SGTL5000_ADC_STEREO;
 
        /* set mono to save power */
-       snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER, stereo,
                        channels == 1 ? 0 : stereo);
 
        /* set codec clock base on lrclk */
-       ret = sgtl5000_set_clock(codec, params_rate(params));
+       ret = sgtl5000_set_clock(component, params_rate(params));
        if (ret)
                return ret;
 
@@ -851,7 +936,7 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_I2S_CTRL,
                            SGTL5000_I2S_DLEN_MASK | SGTL5000_I2S_SCLKFREQ_MASK,
                            i2s_ctl);
 
@@ -868,19 +953,30 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
  * stop:
  * on --> prepare --> standby
  */
-static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
+static int sgtl5000_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
+       struct sgtl5000_priv *sgtl = snd_soc_component_get_drvdata(component);
+       int ret;
+
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+               regcache_cache_only(sgtl->regmap, false);
+               ret = regcache_sync(sgtl->regmap);
+               if (ret) {
+                       regcache_cache_only(sgtl->regmap, true);
+                       return ret;
+               }
+
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
                                    SGTL5000_REFTOP_POWERUP,
                                    SGTL5000_REFTOP_POWERUP);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
+               regcache_cache_only(sgtl->regmap, true);
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
                                    SGTL5000_REFTOP_POWERUP, 0);
                break;
        }
@@ -1020,7 +1116,7 @@ static const u8 vol_quot_table[] = {
  * 1. vddd provided by external or not
  * 2. vdda and vddio voltage value. > 3.1v or not
  */
-static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
+static int sgtl5000_set_power_regs(struct snd_soc_component *component)
 {
        int vddd;
        int vdda;
@@ -1032,7 +1128,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
        int vol_quot;
        int lo_vol;
        size_t i;
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
        vdda  = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
        vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
@@ -1045,14 +1141,14 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
        vddd  = vddd / 1000;
 
        if (vdda <= 0 || vddio <= 0 || vddd < 0) {
-               dev_err(codec->dev, "regulator voltage not set correctly\n");
+               dev_err(component->dev, "regulator voltage not set correctly\n");
 
                return -EINVAL;
        }
 
        /* according to datasheet, maximum voltage of supplies */
        if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "exceed max voltage vdda %dmV vddio %dmV vddd %dmV\n",
                        vdda, vddio, vddd);
 
@@ -1060,15 +1156,15 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
        }
 
        /* reset value */
-       ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
+       ana_pwr = snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER);
        ana_pwr |= SGTL5000_DAC_STEREO |
                        SGTL5000_ADC_STEREO |
                        SGTL5000_REFTOP_POWERUP;
-       lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
+       lreg_ctrl = snd_soc_component_read32(component, SGTL5000_CHIP_LINREG_CTRL);
 
        if (vddio < 3100 && vdda < 3100) {
                /* enable internal oscillator used for charge pump */
-               snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
+               snd_soc_component_update_bits(component, SGTL5000_CHIP_CLK_TOP_CTRL,
                                        SGTL5000_INT_OSC_EN,
                                        SGTL5000_INT_OSC_EN);
                /* Enable VDDC charge pump */
@@ -1081,9 +1177,9 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
                            SGTL5000_VDDC_MAN_ASSN_SHIFT;
        }
 
-       snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
+       snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
 
-       snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
+       snd_soc_component_write(component, SGTL5000_CHIP_ANA_POWER, ana_pwr);
 
        /*
         * set ADC/DAC VAG to vdda / 2,
@@ -1098,7 +1194,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
        else
                vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL,
                        SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
 
        /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
@@ -1112,7 +1208,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
                lo_vag = (lo_vag - SGTL5000_LINE_OUT_GND_BASE) /
                    SGTL5000_LINE_OUT_GND_STP;
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_LINE_OUT_CTRL,
                        SGTL5000_LINE_OUT_CURRENT_MASK |
                        SGTL5000_LINE_OUT_GND_MASK,
                        lo_vag << SGTL5000_LINE_OUT_GND_SHIFT |
@@ -1135,7 +1231,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
                        break;
        }
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_VOL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_LINE_OUT_VOL,
                SGTL5000_LINE_OUT_VOL_RIGHT_MASK |
                SGTL5000_LINE_OUT_VOL_LEFT_MASK,
                lo_vol << SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT |
@@ -1183,59 +1279,57 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
        return ret;
 }
 
-static int sgtl5000_probe(struct snd_soc_codec *codec)
+static int sgtl5000_probe(struct snd_soc_component *component)
 {
        int ret;
        u16 reg;
-       struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
 
        /* power up sgtl5000 */
-       ret = sgtl5000_set_power_regs(codec);
+       ret = sgtl5000_set_power_regs(component);
        if (ret)
                goto err;
 
        /* enable small pop, introduce 400ms delay in turning off */
-       snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL,
                                SGTL5000_SMALL_POP, 1);
 
        /* disable short cut detector */
-       snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
+       snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0);
 
-       /*
-        * set i2s as default input of sound switch
-        * TODO: add sound switch to control and dapm widge.
-        */
-       snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
-                       SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
-       snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
+       snd_soc_component_write(component, SGTL5000_CHIP_DIG_POWER,
                        SGTL5000_ADC_EN | SGTL5000_DAC_EN);
 
        /* enable dac volume ramp by default */
-       snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
+       snd_soc_component_write(component, SGTL5000_CHIP_ADCDAC_CTRL,
                        SGTL5000_DAC_VOL_RAMP_EN |
                        SGTL5000_DAC_MUTE_RIGHT |
                        SGTL5000_DAC_MUTE_LEFT);
 
        reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
-       snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);
+       snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg);
 
-       snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
+       snd_soc_component_write(component, SGTL5000_CHIP_ANA_CTRL,
                        SGTL5000_HP_ZCD_EN |
                        SGTL5000_ADC_ZCD_EN);
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
                        SGTL5000_BIAS_R_MASK,
                        sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
 
-       snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
                        SGTL5000_BIAS_VOLT_MASK,
                        sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);
        /*
-        * disable DAP
+        * enable DAP Graphic EQ
         * TODO:
-        * Enable DAP in kcontrol and dapm.
+        * Add control for changing between PEQ/Tone Control/GEQ
         */
-       snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
+       snd_soc_component_write(component, SGTL5000_DAP_AUDIO_EQ, SGTL5000_DAP_SEL_GEQ);
+
+       /* Unmute DAC after start */
+       snd_soc_component_update_bits(component, SGTL5000_CHIP_ADCDAC_CTRL,
+               SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT, 0);
 
        return 0;
 
@@ -1243,24 +1337,20 @@ err:
        return ret;
 }
 
-static int sgtl5000_remove(struct snd_soc_codec *codec)
-{
-       return 0;
-}
-
-static const struct snd_soc_codec_driver sgtl5000_driver = {
-       .probe = sgtl5000_probe,
-       .remove = sgtl5000_remove,
-       .set_bias_level = sgtl5000_set_bias_level,
-       .suspend_bias_off = true,
-       .component_driver = {
-               .controls               = sgtl5000_snd_controls,
-               .num_controls           = ARRAY_SIZE(sgtl5000_snd_controls),
-               .dapm_widgets           = sgtl5000_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(sgtl5000_dapm_widgets),
-               .dapm_routes            = sgtl5000_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(sgtl5000_dapm_routes),
-       },
+static const struct snd_soc_component_driver sgtl5000_driver = {
+       .probe                  = sgtl5000_probe,
+       .set_bias_level         = sgtl5000_set_bias_level,
+       .controls               = sgtl5000_snd_controls,
+       .num_controls           = ARRAY_SIZE(sgtl5000_snd_controls),
+       .dapm_widgets           = sgtl5000_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sgtl5000_dapm_widgets),
+       .dapm_routes            = sgtl5000_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(sgtl5000_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config sgtl5000_regmap = {
@@ -1459,7 +1549,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
        /* Ensure sgtl5000 will start with sane register values */
        sgtl5000_fill_defaults(client);
 
-       ret = snd_soc_register_codec(&client->dev,
+       ret = devm_snd_soc_register_component(&client->dev,
                        &sgtl5000_driver, &sgtl5000_dai, 1);
        if (ret)
                goto disable_clk;
@@ -1480,7 +1570,6 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
 {
        struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
        clk_disable_unprepare(sgtl5000->mclk);
        regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies);
        regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies);
index 22f3442af9826ce5868619bf993123bafdb0c82f..28cf637155bba4a6df87707591eb34a1218a0e7e 100644 (file)
 #define SGTL5000_SYSCLK                                0x00
 #define SGTL5000_LRCLK                         0x01
 
+/*
+ * SGTL5000_DAP_AUDIO_EQ
+ */
+#define SGTL5000_DAP_SEL_PEQ                   1
+#define SGTL5000_DAP_SEL_TONE_CTRL             2
+#define SGTL5000_DAP_SEL_GEQ                   3
+
 #endif
index 7b91ee267b4eb24347e90c72894fb1daee3b6467..b779c2855c014951578c67aa76eb1dd537b9c91f 100644 (file)
@@ -140,14 +140,14 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
        si476x_core_lock(core);
 
-       err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
+       err = snd_soc_component_update_bits(codec_dai->component, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
                                  SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
                                  format);
 
        si476x_core_unlock(core);
 
        if (err < 0) {
-               dev_err(codec_dai->codec->dev, "Failed to set output format\n");
+               dev_err(codec_dai->component->dev, "Failed to set output format\n");
                return err;
        }
 
@@ -163,7 +163,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
 
        rate = params_rate(params);
        if (rate < 32000 || rate > 48000) {
-               dev_err(dai->codec->dev, "Rate: %d is not supported\n", rate);
+               dev_err(dai->component->dev, "Rate: %d is not supported\n", rate);
                return -EINVAL;
        }
 
@@ -186,19 +186,19 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
 
        si476x_core_lock(core);
 
-       err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
+       err = snd_soc_component_write(dai->component, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
                            rate);
        if (err < 0) {
-               dev_err(dai->codec->dev, "Failed to set sample rate\n");
+               dev_err(dai->component->dev, "Failed to set sample rate\n");
                goto out;
        }
 
-       err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
+       err = snd_soc_component_update_bits(dai->component, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
                                  SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK,
                                  (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) |
                                  (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
        if (err < 0) {
-               dev_err(dai->codec->dev, "Failed to set output width\n");
+               dev_err(dai->component->dev, "Failed to set output width\n");
                goto out;
        }
 
@@ -239,28 +239,25 @@ static int si476x_probe(struct snd_soc_component *component)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_si476x = {
-       .component_driver = {
-               .probe                  = si476x_probe,
-               .dapm_widgets           = si476x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(si476x_dapm_widgets),
-               .dapm_routes            = si476x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(si476x_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_si476x = {
+       .probe                  = si476x_probe,
+       .dapm_widgets           = si476x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(si476x_dapm_widgets),
+       .dapm_routes            = si476x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(si476x_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int si476x_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si476x,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &soc_component_dev_si476x,
                                      &si476x_dai, 1);
 }
 
-static int si476x_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 MODULE_ALIAS("platform:si476x-codec");
 
 static struct platform_driver si476x_platform_driver = {
@@ -268,7 +265,6 @@ static struct platform_driver si476x_platform_driver = {
                .name   = "si476x-codec",
        },
        .probe          = si476x_platform_probe,
-       .remove         = si476x_platform_remove,
 };
 module_platform_driver(si476x_platform_driver);
 
index 7ae8c181d1a4284aebe5e6095a897df3a6c73854..e424499a8450643f657780ec618d39de0b538892 100644 (file)
@@ -120,8 +120,8 @@ static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
 {
 #define ATLAS6_CODEC_ENABLE_BITS (1 << 29)
 #define ATLAS6_CODEC_RESET_BITS (1 << 28)
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                enable_and_reset_codec(sirf_audio_codec->regmap,
@@ -143,8 +143,8 @@ static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w,
 {
 #define PRIMA2_CODEC_ENABLE_BITS (1 << 27)
 #define PRIMA2_CODEC_RESET_BITS (1 << 26)
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                enable_and_reset_codec(sirf_audio_codec->regmap,
@@ -333,8 +333,8 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
                int cmd,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct sirf_audio_codec *sirf_audio_codec = snd_soc_component_get_drvdata(component);
        int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
        /*
@@ -346,7 +346,7 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
                if (playback) {
-                       snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
+                       snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0,
                                IC_HSLEN | IC_HSREN, 0);
                        sirf_audio_codec_tx_disable(sirf_audio_codec);
                } else
@@ -357,7 +357,7 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                if (playback) {
                        sirf_audio_codec_tx_enable(sirf_audio_codec);
-                       snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
+                       snd_soc_component_update_bits(component, AUDIO_IC_CODEC_CTRL0,
                                IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
                } else
                        sirf_audio_codec_rx_enable(sirf_audio_codec,
@@ -393,29 +393,29 @@ static struct snd_soc_dai_driver sirf_audio_codec_dai = {
        .ops = &sirf_audio_codec_dai_ops,
 };
 
-static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
+static int sirf_audio_codec_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
-       pm_runtime_enable(codec->dev);
+       pm_runtime_enable(component->dev);
 
-       if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) {
+       if (of_device_is_compatible(component->dev->of_node, "sirf,prima2-audio-codec")) {
                snd_soc_dapm_new_controls(dapm,
                        prima2_output_driver_dapm_widgets,
                        ARRAY_SIZE(prima2_output_driver_dapm_widgets));
                snd_soc_dapm_new_controls(dapm,
                        &prima2_codec_clock_dapm_widget, 1);
-               return snd_soc_add_codec_controls(codec,
+               return snd_soc_add_component_controls(component,
                        volume_controls_prima2,
                        ARRAY_SIZE(volume_controls_prima2));
        }
-       if (of_device_is_compatible(codec->dev->of_node, "sirf,atlas6-audio-codec")) {
+       if (of_device_is_compatible(component->dev->of_node, "sirf,atlas6-audio-codec")) {
                snd_soc_dapm_new_controls(dapm,
                        atlas6_output_driver_dapm_widgets,
                        ARRAY_SIZE(atlas6_output_driver_dapm_widgets));
                snd_soc_dapm_new_controls(dapm,
                        &atlas6_codec_clock_dapm_widget, 1);
-               return snd_soc_add_codec_controls(codec,
+               return snd_soc_add_component_controls(component,
                        volume_controls_atlas6,
                        ARRAY_SIZE(volume_controls_atlas6));
        }
@@ -423,22 +423,21 @@ static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
        return -EINVAL;
 }
 
-static int sirf_audio_codec_remove(struct snd_soc_codec *codec)
+static void sirf_audio_codec_remove(struct snd_soc_component *component)
 {
-       pm_runtime_disable(codec->dev);
-       return 0;
+       pm_runtime_disable(component->dev);
 }
 
-static const struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = {
-       .probe = sirf_audio_codec_probe,
-       .remove = sirf_audio_codec_remove,
-       .component_driver = {
-               .dapm_widgets = sirf_audio_codec_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets),
-               .dapm_routes = sirf_audio_codec_map,
-               .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map),
-       },
-       .idle_bias_off = true,
+static const struct snd_soc_component_driver soc_codec_device_sirf_audio_codec = {
+       .probe                  = sirf_audio_codec_probe,
+       .remove                 = sirf_audio_codec_remove,
+       .dapm_widgets           = sirf_audio_codec_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sirf_audio_codec_dapm_widgets),
+       .dapm_routes            = sirf_audio_codec_map,
+       .num_dapm_routes        = ARRAY_SIZE(sirf_audio_codec_map),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id sirf_audio_codec_of_match[] = {
@@ -495,7 +494,7 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret = snd_soc_register_codec(&(pdev->dev),
+       ret = devm_snd_soc_register_component(&(pdev->dev),
                        &soc_codec_device_sirf_audio_codec,
                        &sirf_audio_codec_dai, 1);
        if (ret) {
@@ -525,7 +524,6 @@ static int sirf_audio_codec_driver_remove(struct platform_device *pdev)
        struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev);
 
        clk_disable_unprepare(sirf_audio_codec->clk);
-       snd_soc_unregister_codec(&(pdev->dev));
 
        return 0;
 }
index c8fd6367f6c00976e73108dfebcb41ad6cbafba7..ac69d495d1219cbc36e682b1fe0b36246a876b49 100644 (file)
@@ -38,13 +38,15 @@ static const struct snd_soc_dapm_route dir_routes[] = {
                        SNDRV_PCM_FMTBIT_S32_LE | \
                        SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
 
-static struct snd_soc_codec_driver soc_codec_spdif_dir = {
-       .component_driver = {
-               .dapm_widgets           = dir_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(dir_widgets),
-               .dapm_routes            = dir_routes,
-               .num_dapm_routes        = ARRAY_SIZE(dir_routes),
-       },
+static struct snd_soc_component_driver soc_codec_spdif_dir = {
+       .dapm_widgets           = dir_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(dir_widgets),
+       .dapm_routes            = dir_routes,
+       .num_dapm_routes        = ARRAY_SIZE(dir_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct snd_soc_dai_driver dir_stub_dai = {
@@ -60,16 +62,11 @@ static struct snd_soc_dai_driver dir_stub_dai = {
 
 static int spdif_dir_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dir,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_codec_spdif_dir,
                        &dir_stub_dai, 1);
 }
 
-static int spdif_dir_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id spdif_dir_dt_ids[] = {
        { .compatible = "linux,spdif-dir", },
@@ -80,7 +77,6 @@ MODULE_DEVICE_TABLE(of, spdif_dir_dt_ids);
 
 static struct platform_driver spdif_dir_driver = {
        .probe          = spdif_dir_probe,
-       .remove         = spdif_dir_remove,
        .driver         = {
                .name   = "spdif-dir",
                .of_match_table = of_match_ptr(spdif_dir_dt_ids),
index 037aa1d4555921e70b403a3d27706464d72b7633..b4f7fc4acb39fe98f87b0e7e06f15e5a46579c60 100644 (file)
@@ -38,13 +38,15 @@ static const struct snd_soc_dapm_route dit_routes[] = {
        { "spdif-out", NULL, "Playback" },
 };
 
-static struct snd_soc_codec_driver soc_codec_spdif_dit = {
-       .component_driver = {
-               .dapm_widgets           = dit_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(dit_widgets),
-               .dapm_routes            = dit_routes,
-               .num_dapm_routes        = ARRAY_SIZE(dit_routes),
-       },
+static struct snd_soc_component_driver soc_codec_spdif_dit = {
+       .dapm_widgets           = dit_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(dit_widgets),
+       .dapm_routes            = dit_routes,
+       .num_dapm_routes        = ARRAY_SIZE(dit_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct snd_soc_dai_driver dit_stub_dai = {
@@ -60,16 +62,11 @@ static struct snd_soc_dai_driver dit_stub_dai = {
 
 static int spdif_dit_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_codec_spdif_dit,
                        &dit_stub_dai, 1);
 }
 
-static int spdif_dit_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id spdif_dit_dt_ids[] = {
        { .compatible = "linux,spdif-dit", },
@@ -80,7 +77,6 @@ MODULE_DEVICE_TABLE(of, spdif_dit_dt_ids);
 
 static struct platform_driver spdif_dit_driver = {
        .probe          = spdif_dit_probe,
-       .remove         = spdif_dit_remove,
        .driver         = {
                .name   = DRV_NAME,
                .of_match_table = of_match_ptr(spdif_dit_dt_ids),
index 15486fd16269d1719d8d080d1e939c0208b309ae..4a1d42a3303051f93f5c28242de7030bfa0c0b7a 100644 (file)
@@ -336,8 +336,8 @@ static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
 static int ssm2518_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
        unsigned int rate = params_rate(params);
        unsigned int ctrl1, ctrl1_mask;
        int mcs;
@@ -391,7 +391,7 @@ static int ssm2518_hw_params(struct snd_pcm_substream *substream,
 
 static int ssm2518_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
        unsigned int val;
 
        if (mute)
@@ -405,7 +405,7 @@ static int ssm2518_mute(struct snd_soc_dai *dai, int mute)
 
 static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
        unsigned int ctrl1 = 0, ctrl2 = 0;
        bool invert_fclk;
        int ret;
@@ -498,10 +498,10 @@ static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
        return ret;
 }
 
-static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
+static int ssm2518_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (level) {
@@ -510,7 +510,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        ret = ssm2518_set_power(ssm2518, true);
                break;
        case SND_SOC_BIAS_OFF:
@@ -524,7 +524,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
 static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        unsigned int rx_mask, int slots, int width)
 {
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
        unsigned int ctrl1, ctrl2;
        int left_slot, right_slot;
        int ret;
@@ -609,7 +609,7 @@ static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int ssm2518_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
 
        if (ssm2518->constraints)
                snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -641,10 +641,10 @@ static struct snd_soc_dai_driver ssm2518_dai = {
        .ops = &ssm2518_dai_ops,
 };
 
-static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int ssm2518_set_sysclk(struct snd_soc_component *component, int clk_id,
        int source, unsigned int freq, int dir)
 {
-       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+       struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
        unsigned int val;
 
        if (clk_id != SSM2518_SYSCLK)
@@ -710,19 +710,18 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                        SSM2518_POWER1_NO_BCLK, val);
 }
 
-static const struct snd_soc_codec_driver ssm2518_codec_driver = {
-       .set_bias_level = ssm2518_set_bias_level,
-       .set_sysclk = ssm2518_set_sysclk,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = ssm2518_snd_controls,
-               .num_controls           = ARRAY_SIZE(ssm2518_snd_controls),
-               .dapm_widgets           = ssm2518_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ssm2518_dapm_widgets),
-               .dapm_routes            = ssm2518_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ssm2518_routes),
-       },
+static const struct snd_soc_component_driver ssm2518_component_driver = {
+       .set_bias_level         = ssm2518_set_bias_level,
+       .set_sysclk             = ssm2518_set_sysclk,
+       .controls               = ssm2518_snd_controls,
+       .num_controls           = ARRAY_SIZE(ssm2518_snd_controls),
+       .dapm_widgets           = ssm2518_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ssm2518_dapm_widgets),
+       .dapm_routes            = ssm2518_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ssm2518_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ssm2518_regmap_config = {
@@ -792,16 +791,11 @@ static int ssm2518_i2c_probe(struct i2c_client *i2c,
        if (ret)
                return ret;
 
-       return snd_soc_register_codec(&i2c->dev, &ssm2518_codec_driver,
+       return devm_snd_soc_register_component(&i2c->dev,
+                       &ssm2518_component_driver,
                        &ssm2518_dai, 1);
 }
 
-static int ssm2518_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id ssm2518_dt_ids[] = {
        { .compatible = "adi,ssm2518", },
@@ -822,7 +816,6 @@ static struct i2c_driver ssm2518_driver = {
                .of_match_table = of_match_ptr(ssm2518_dt_ids),
        },
        .probe = ssm2518_i2c_probe,
-       .remove = ssm2518_i2c_remove,
        .id_table = ssm2518_i2c_ids,
 };
 module_i2c_driver(ssm2518_driver);
index 173ba85ff59e45c65bffb6e34655a1f4c29751ba..f1c2b1a3ada36c1bc2c7cf07d6e12660707625e4 100644 (file)
@@ -27,12 +27,6 @@ static int ssm2602_i2c_probe(struct i2c_client *client,
                devm_regmap_init_i2c(client, &ssm2602_regmap_config));
 }
 
-static int ssm2602_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id ssm2602_i2c_id[] = {
        { "ssm2602", SSM2602 },
        { "ssm2603", SSM2602 },
@@ -55,7 +49,6 @@ static struct i2c_driver ssm2602_i2c_driver = {
                .of_match_table = ssm2602_of_match,
        },
        .probe = ssm2602_i2c_probe,
-       .remove = ssm2602_i2c_remove,
        .id_table = ssm2602_i2c_id,
 };
 module_i2c_driver(ssm2602_i2c_driver);
index 842f373045c607299972923861cfff1bf7287af7..8848628571a1d18e73fc8ce648696fd0a0389747 100644 (file)
@@ -20,12 +20,6 @@ static int ssm2602_spi_probe(struct spi_device *spi)
                devm_regmap_init_spi(spi, &ssm2602_regmap_config));
 }
 
-static int ssm2602_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static const struct of_device_id ssm2602_of_match[] = {
        { .compatible = "adi,ssm2602", },
        { }
@@ -38,7 +32,6 @@ static struct spi_driver ssm2602_spi_driver = {
                .of_match_table = ssm2602_of_match,
        },
        .probe          = ssm2602_spi_probe,
-       .remove         = ssm2602_spi_remove,
 };
 module_spi_driver(ssm2602_spi_driver);
 
index 9b341c23f62bdf26f2f007efb76c8709104dc48a..501a4e73b185ba9c1143a4de11da56626e7f3790 100644 (file)
@@ -54,10 +54,17 @@ struct ssm2602_priv {
  * using 2 wire for device control, so we cache them instead.
  * There is no point in caching the reset register
  */
-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
-       0x0097, 0x0097, 0x0079, 0x0079,
-       0x000a, 0x0008, 0x009f, 0x000a,
-       0x0000, 0x0000
+static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = {
+       { .reg = 0x00, .def = 0x0097 },
+       { .reg = 0x01, .def = 0x0097 },
+       { .reg = 0x02, .def = 0x0079 },
+       { .reg = 0x03, .def = 0x0079 },
+       { .reg = 0x04, .def = 0x000a },
+       { .reg = 0x05, .def = 0x0008 },
+       { .reg = 0x06, .def = 0x009f },
+       { .reg = 0x07, .def = 0x000a },
+       { .reg = 0x08, .def = 0x0000 },
+       { .reg = 0x09, .def = 0x0000 }
 };
 
 
@@ -273,8 +280,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
        int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
        unsigned int iface;
 
@@ -308,8 +315,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
 static int ssm2602_startup(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
        if (ssm2602->sysclk_constraints) {
                snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -322,7 +329,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
 
 static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(dai->component);
 
        if (mute)
                regmap_update_bits(ssm2602->regmap, SSM2602_APDIGI,
@@ -337,8 +344,8 @@ static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
 static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
        if (dir == SND_SOC_CLOCK_IN) {
                if (clk_id != SSM2602_SYSCLK)
@@ -389,7 +396,7 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec_dai->codec);
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(codec_dai->component);
        unsigned int iface = 0;
 
        /* set master/slave audio interface */
@@ -445,10 +452,10 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
+static int ssm2602_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -511,19 +518,19 @@ static struct snd_soc_dai_driver ssm2602_dai = {
        .symmetric_samplebits = 1,
 };
 
-static int ssm2602_resume(struct snd_soc_codec *codec)
+static int ssm2602_resume(struct snd_soc_component *component)
 {
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
 
        regcache_sync(ssm2602->regmap);
 
        return 0;
 }
 
-static int ssm2602_codec_probe(struct snd_soc_codec *codec)
+static int ssm2602_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
        int ret;
 
        regmap_update_bits(ssm2602->regmap, SSM2602_LOUT1V,
@@ -531,7 +538,7 @@ static int ssm2602_codec_probe(struct snd_soc_codec *codec)
        regmap_update_bits(ssm2602->regmap, SSM2602_ROUT1V,
                            ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
 
-       ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
+       ret = snd_soc_add_component_controls(component, ssm2602_snd_controls,
                        ARRAY_SIZE(ssm2602_snd_controls));
        if (ret)
                return ret;
@@ -545,9 +552,9 @@ static int ssm2602_codec_probe(struct snd_soc_codec *codec)
                        ARRAY_SIZE(ssm2602_routes));
 }
 
-static int ssm2604_codec_probe(struct snd_soc_codec *codec)
+static int ssm2604_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int ret;
 
        ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
@@ -559,14 +566,14 @@ static int ssm2604_codec_probe(struct snd_soc_codec *codec)
                        ARRAY_SIZE(ssm2604_routes));
 }
 
-static int ssm260x_codec_probe(struct snd_soc_codec *codec)
+static int ssm260x_component_probe(struct snd_soc_component *component)
 {
-       struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+       struct ssm2602_priv *ssm2602 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+               dev_err(component->dev, "Failed to issue reset: %d\n", ret);
                return ret;
        }
 
@@ -581,30 +588,31 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec)
 
        switch (ssm2602->type) {
        case SSM2602:
-               ret = ssm2602_codec_probe(codec);
+               ret = ssm2602_component_probe(component);
                break;
        case SSM2604:
-               ret = ssm2604_codec_probe(codec);
+               ret = ssm2604_component_probe(component);
                break;
        }
 
        return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
-       .probe =        ssm260x_codec_probe,
-       .resume =       ssm2602_resume,
-       .set_bias_level = ssm2602_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = ssm260x_snd_controls,
-               .num_controls           = ARRAY_SIZE(ssm260x_snd_controls),
-               .dapm_widgets           = ssm260x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ssm260x_dapm_widgets),
-               .dapm_routes            = ssm260x_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ssm260x_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_ssm2602 = {
+       .probe                  = ssm260x_component_probe,
+       .resume                 = ssm2602_resume,
+       .set_bias_level         = ssm2602_set_bias_level,
+       .controls               = ssm260x_snd_controls,
+       .num_controls           = ARRAY_SIZE(ssm260x_snd_controls),
+       .dapm_widgets           = ssm260x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ssm260x_dapm_widgets),
+       .dapm_routes            = ssm260x_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ssm260x_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static bool ssm2602_register_volatile(struct device *dev, unsigned int reg)
@@ -620,8 +628,8 @@ const struct regmap_config ssm2602_regmap_config = {
        .volatile_reg = ssm2602_register_volatile,
 
        .cache_type = REGCACHE_RBTREE,
-       .reg_defaults_raw = ssm2602_reg,
-       .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg),
+       .reg_defaults = ssm2602_reg,
+       .num_reg_defaults = ARRAY_SIZE(ssm2602_reg),
 };
 EXPORT_SYMBOL_GPL(ssm2602_regmap_config);
 
@@ -641,7 +649,7 @@ int ssm2602_probe(struct device *dev, enum ssm2602_type type,
        ssm2602->type = type;
        ssm2602->regmap = regmap;
 
-       return snd_soc_register_codec(dev, &soc_codec_dev_ssm2602,
+       return devm_snd_soc_register_component(dev, &soc_component_dev_ssm2602,
                &ssm2602_dai, 1);
 }
 EXPORT_SYMBOL_GPL(ssm2602_probe);
index 4afeddef77285386959bf106b66c5ac6b91e0c41..90119ea00498e8f3f5da4237b7989bbd81a8eb4c 100644 (file)
@@ -199,8 +199,8 @@ static const struct snd_soc_dapm_route ssm4567_routes[] = {
 static int ssm4567_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(component);
        unsigned int rate = params_rate(params);
        unsigned int dacfs;
 
@@ -223,7 +223,7 @@ static int ssm4567_hw_params(struct snd_pcm_substream *substream,
 
 static int ssm4567_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(dai->codec);
+       struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(dai->component);
        unsigned int val;
 
        val = mute ? SSM4567_DAC_MUTE : 0;
@@ -366,10 +366,10 @@ static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable)
        return ret;
 }
 
-static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
+static int ssm4567_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec);
+       struct ssm4567 *ssm4567 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (level) {
@@ -378,7 +378,7 @@ static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        ret = ssm4567_set_power(ssm4567, true);
                break;
        case SND_SOC_BIAS_OFF:
@@ -417,18 +417,17 @@ static struct snd_soc_dai_driver ssm4567_dai = {
        .ops = &ssm4567_dai_ops,
 };
 
-static const struct snd_soc_codec_driver ssm4567_codec_driver = {
-       .set_bias_level = ssm4567_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = ssm4567_snd_controls,
-               .num_controls           = ARRAY_SIZE(ssm4567_snd_controls),
-               .dapm_widgets           = ssm4567_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(ssm4567_dapm_widgets),
-               .dapm_routes            = ssm4567_routes,
-               .num_dapm_routes        = ARRAY_SIZE(ssm4567_routes),
-       },
+static const struct snd_soc_component_driver ssm4567_component_driver = {
+       .set_bias_level         = ssm4567_set_bias_level,
+       .controls               = ssm4567_snd_controls,
+       .num_controls           = ARRAY_SIZE(ssm4567_snd_controls),
+       .dapm_widgets           = ssm4567_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ssm4567_dapm_widgets),
+       .dapm_routes            = ssm4567_routes,
+       .num_dapm_routes        = ARRAY_SIZE(ssm4567_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config ssm4567_regmap_config = {
@@ -469,16 +468,10 @@ static int ssm4567_i2c_probe(struct i2c_client *i2c,
        if (ret)
                return ret;
 
-       return snd_soc_register_codec(&i2c->dev, &ssm4567_codec_driver,
+       return devm_snd_soc_register_component(&i2c->dev, &ssm4567_component_driver,
                        &ssm4567_dai, 1);
 }
 
-static int ssm4567_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id ssm4567_i2c_ids[] = {
        { "ssm4567", 0 },
        { }
@@ -510,7 +503,6 @@ static struct i2c_driver ssm4567_driver = {
                .acpi_match_table = ACPI_PTR(ssm4567_acpi_match),
        },
        .probe = ssm4567_i2c_probe,
-       .remove = ssm4567_i2c_remove,
        .id_table = ssm4567_i2c_ids,
 };
 module_i2c_driver(ssm4567_driver);
index 5b888476d9ff110b26cc6d42f1a7c808f05027ea..d5035f2f2b2ba727329570003d7d13a3c42d93d4 100644 (file)
@@ -143,7 +143,7 @@ static const char *sta32x_supply_names[] = {
 struct sta32x_priv {
        struct regmap *regmap;
        struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct sta32x_platform_data *pdata;
 
        unsigned int mclk;
@@ -270,8 +270,8 @@ static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,
 static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
        unsigned int cfud, val;
@@ -312,8 +312,8 @@ exit_unlock:
 static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
        unsigned int cfud;
@@ -347,9 +347,9 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
+static int sta32x_sync_coef_shadow(struct snd_soc_component *component)
 {
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        unsigned int cfud;
        int i;
 
@@ -375,16 +375,16 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int sta32x_cache_sync(struct snd_soc_codec *codec)
+static int sta32x_cache_sync(struct snd_soc_component *component)
 {
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        unsigned int mute;
        int rc;
 
        /* mute during register sync */
        regmap_read(sta32x->regmap, STA32X_MMUTE, &mute);
        regmap_write(sta32x->regmap, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
-       sta32x_sync_coef_shadow(codec);
+       sta32x_sync_coef_shadow(component);
        rc = regcache_sync(sta32x->regmap);
        regmap_write(sta32x->regmap, STA32X_MMUTE, mute);
        return rc;
@@ -395,17 +395,17 @@ static void sta32x_watchdog(struct work_struct *work)
 {
        struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv,
                                                  watchdog_work.work);
-       struct snd_soc_codec *codec = sta32x->codec;
+       struct snd_soc_component *component = sta32x->component;
        unsigned int confa, confa_cached;
 
        /* check if sta32x has reset itself */
-       confa_cached = snd_soc_read(codec, STA32X_CONFA);
+       confa_cached = snd_soc_component_read32(component, STA32X_CONFA);
        regcache_cache_bypass(sta32x->regmap, true);
-       confa = snd_soc_read(codec, STA32X_CONFA);
+       confa = snd_soc_component_read32(component, STA32X_CONFA);
        regcache_cache_bypass(sta32x->regmap, false);
        if (confa != confa_cached) {
                regcache_mark_dirty(sta32x->regmap);
-               sta32x_cache_sync(codec);
+               sta32x_cache_sync(component);
        }
 
        if (!sta32x->shutdown)
@@ -582,10 +582,10 @@ static int mcs_ratio_table[3][7] = {
 static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "mclk=%u\n", freq);
+       dev_dbg(component->dev, "mclk=%u\n", freq);
        sta32x->mclk = freq;
 
        return 0;
@@ -602,8 +602,8 @@ static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        u8 confb = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -651,22 +651,22 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        int i, mcs = -EINVAL, ir = -EINVAL;
        unsigned int confa, confb;
        unsigned int rate, ratio;
        int ret;
 
        if (!sta32x->mclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "sta32x->mclk is unset. Unable to determine ratio\n");
                return -EIO;
        }
 
        rate = params_rate(params);
        ratio = sta32x->mclk / rate;
-       dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio);
+       dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio);
 
        for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
                if (interpolation_ratios[i].fs == rate) {
@@ -676,7 +676,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (ir < 0) {
-               dev_err(codec->dev, "Unsupported samplerate: %u\n", rate);
+               dev_err(component->dev, "Unsupported samplerate: %u\n", rate);
                return -EINVAL;
        }
 
@@ -688,7 +688,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (mcs < 0) {
-               dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio);
+               dev_err(component->dev, "Unresolvable ratio: %u\n", ratio);
                return -EINVAL;
        }
 
@@ -698,10 +698,10 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 24:
-               dev_dbg(codec->dev, "24bit\n");
+               dev_dbg(component->dev, "24bit\n");
                /* fall through */
        case 32:
-               dev_dbg(codec->dev, "24bit or 32bit\n");
+               dev_dbg(component->dev, "24bit or 32bit\n");
                switch (sta32x->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x0;
@@ -716,7 +716,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
                break;
        case 20:
-               dev_dbg(codec->dev, "20bit\n");
+               dev_dbg(component->dev, "20bit\n");
                switch (sta32x->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x4;
@@ -731,7 +731,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
                break;
        case 18:
-               dev_dbg(codec->dev, "18bit\n");
+               dev_dbg(component->dev, "18bit\n");
                switch (sta32x->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x8;
@@ -746,7 +746,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
 
                break;
        case 16:
-               dev_dbg(codec->dev, "16bit\n");
+               dev_dbg(component->dev, "16bit\n");
                switch (sta32x->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x0;
@@ -793,20 +793,20 @@ static int sta32x_startup_sequence(struct sta32x_priv *sta32x)
 
 /**
  * sta32x_set_bias_level - DAPM callback
- * @codec: the codec device
+ * @component: the component device
  * @level: DAPM power level
  *
- * This is called by ALSA to put the codec into low power mode
- * or to wake it up.  If the codec is powered off completely
+ * This is called by ALSA to put the component into low power mode
+ * or to wake it up.  If the component is powered off completely
  * all registers must be restored after power on.
  */
-static int sta32x_set_bias_level(struct snd_soc_codec *codec,
+static int sta32x_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        int ret;
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "level = %d\n", level);
+       dev_dbg(component->dev, "level = %d\n", level);
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
@@ -819,17 +819,17 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
                                                    sta32x->supplies);
                        if (ret != 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to enable supplies: %d\n", ret);
                                return ret;
                        }
 
                        sta32x_startup_sequence(sta32x);
-                       sta32x_cache_sync(codec);
+                       sta32x_cache_sync(component);
                        sta32x_watchdog_start(sta32x);
                }
 
@@ -874,21 +874,21 @@ static struct snd_soc_dai_driver sta32x_dai = {
        .ops = &sta32x_dai_ops,
 };
 
-static int sta32x_probe(struct snd_soc_codec *codec)
+static int sta32x_probe(struct snd_soc_component *component)
 {
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
        struct sta32x_platform_data *pdata = sta32x->pdata;
        int i, ret = 0, thermal = 0;
        ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
                                    sta32x->supplies);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
                return ret;
        }
 
        ret = sta32x_startup_sequence(sta32x);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to startup device\n");
+               dev_err(component->dev, "Failed to startup device\n");
                return ret;
        }
 
@@ -968,36 +968,36 @@ static int sta32x_probe(struct snd_soc_codec *codec)
        if (sta32x->pdata->needs_esd_watchdog)
                INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 
        return 0;
 }
 
-static int sta32x_remove(struct snd_soc_codec *codec)
+static void sta32x_remove(struct snd_soc_component *component)
 {
-       struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
+       struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component);
 
        sta32x_watchdog_stop(sta32x);
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver sta32x_codec = {
-       .probe =                sta32x_probe,
-       .remove =               sta32x_remove,
-       .set_bias_level =       sta32x_set_bias_level,
-       .suspend_bias_off =     true,
-       .component_driver = {
-               .controls =             sta32x_snd_controls,
-               .num_controls =         ARRAY_SIZE(sta32x_snd_controls),
-               .dapm_widgets =         sta32x_dapm_widgets,
-               .num_dapm_widgets =     ARRAY_SIZE(sta32x_dapm_widgets),
-               .dapm_routes =          sta32x_dapm_routes,
-               .num_dapm_routes =      ARRAY_SIZE(sta32x_dapm_routes),
-       },
+static const struct snd_soc_component_driver sta32x_component = {
+       .probe                  = sta32x_probe,
+       .remove                 = sta32x_remove,
+       .set_bias_level         = sta32x_set_bias_level,
+       .controls               = sta32x_snd_controls,
+       .num_controls           = ARRAY_SIZE(sta32x_snd_controls),
+       .dapm_widgets           = sta32x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sta32x_dapm_widgets),
+       .dapm_routes            = sta32x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(sta32x_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config sta32x_regmap = {
@@ -1121,19 +1121,14 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, sta32x);
 
-       ret = snd_soc_register_codec(dev, &sta32x_codec, &sta32x_dai, 1);
+       ret = devm_snd_soc_register_component(dev, &sta32x_component,
+                                             &sta32x_dai, 1);
        if (ret < 0)
-               dev_err(dev, "Failed to register codec (%d)\n", ret);
+               dev_err(dev, "Failed to register component (%d)\n", ret);
 
        return ret;
 }
 
-static int sta32x_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id sta32x_i2c_id[] = {
        { "sta326", 0 },
        { "sta328", 0 },
@@ -1148,7 +1143,6 @@ static struct i2c_driver sta32x_i2c_driver = {
                .of_match_table = of_match_ptr(st32x_dt_ids),
        },
        .probe =    sta32x_i2c_probe,
-       .remove =   sta32x_i2c_remove,
        .id_table = sta32x_i2c_id,
 };
 
index 9644c20f44e32dca38209693a088ed0585aa011c..0b870319b1061ac12df323ec4c099c46598d1277 100644 (file)
@@ -309,8 +309,8 @@ static int sta350_coefficient_info(struct snd_kcontrol *kcontrol,
 static int sta350_coefficient_get(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
        unsigned int cfud, val;
@@ -351,8 +351,8 @@ exit_unlock:
 static int sta350_coefficient_put(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
        unsigned int cfud;
@@ -386,9 +386,9 @@ static int sta350_coefficient_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static int sta350_sync_coef_shadow(struct snd_soc_codec *codec)
+static int sta350_sync_coef_shadow(struct snd_soc_component *component)
 {
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        unsigned int cfud;
        int i;
 
@@ -414,16 +414,16 @@ static int sta350_sync_coef_shadow(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int sta350_cache_sync(struct snd_soc_codec *codec)
+static int sta350_cache_sync(struct snd_soc_component *component)
 {
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        unsigned int mute;
        int rc;
 
        /* mute during register sync */
        regmap_read(sta350->regmap, STA350_CFUD, &mute);
        regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE);
-       sta350_sync_coef_shadow(codec);
+       sta350_sync_coef_shadow(component);
        rc = regcache_sync(sta350->regmap);
        regmap_write(sta350->regmap, STA350_MMUTE, mute);
        return rc;
@@ -613,10 +613,10 @@ static int mcs_ratio_table[3][6] = {
 static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "mclk=%u\n", freq);
+       dev_dbg(component->dev, "mclk=%u\n", freq);
        sta350->mclk = freq;
 
        return 0;
@@ -633,8 +633,8 @@ static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai,
                              unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        unsigned int confb = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -682,22 +682,22 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        int i, mcs = -EINVAL, ir = -EINVAL;
        unsigned int confa, confb;
        unsigned int rate, ratio;
        int ret;
 
        if (!sta350->mclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "sta350->mclk is unset. Unable to determine ratio\n");
                return -EIO;
        }
 
        rate = params_rate(params);
        ratio = sta350->mclk / rate;
-       dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio);
+       dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio);
 
        for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
                if (interpolation_ratios[i].fs == rate) {
@@ -707,7 +707,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (ir < 0) {
-               dev_err(codec->dev, "Unsupported samplerate: %u\n", rate);
+               dev_err(component->dev, "Unsupported samplerate: %u\n", rate);
                return -EINVAL;
        }
 
@@ -719,7 +719,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (mcs < 0) {
-               dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio);
+               dev_err(component->dev, "Unresolvable ratio: %u\n", ratio);
                return -EINVAL;
        }
 
@@ -729,10 +729,10 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_width(params)) {
        case 24:
-               dev_dbg(codec->dev, "24bit\n");
+               dev_dbg(component->dev, "24bit\n");
                /* fall through */
        case 32:
-               dev_dbg(codec->dev, "24bit or 32bit\n");
+               dev_dbg(component->dev, "24bit or 32bit\n");
                switch (sta350->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x0;
@@ -747,7 +747,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
                break;
        case 20:
-               dev_dbg(codec->dev, "20bit\n");
+               dev_dbg(component->dev, "20bit\n");
                switch (sta350->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x4;
@@ -762,7 +762,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
                break;
        case 18:
-               dev_dbg(codec->dev, "18bit\n");
+               dev_dbg(component->dev, "18bit\n");
                switch (sta350->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x8;
@@ -777,7 +777,7 @@ static int sta350_hw_params(struct snd_pcm_substream *substream,
 
                break;
        case 16:
-               dev_dbg(codec->dev, "16bit\n");
+               dev_dbg(component->dev, "16bit\n");
                switch (sta350->format) {
                case SND_SOC_DAIFMT_I2S:
                        confb |= 0x0;
@@ -827,20 +827,20 @@ static int sta350_startup_sequence(struct sta350_priv *sta350)
 
 /**
  * sta350_set_bias_level - DAPM callback
- * @codec: the codec device
+ * @component: the component device
  * @level: DAPM power level
  *
- * This is called by ALSA to put the codec into low power mode
- * or to wake it up.  If the codec is powered off completely
+ * This is called by ALSA to put the component into low power mode
+ * or to wake it up.  If the component is powered off completely
  * all registers must be restored after power on.
  */
-static int sta350_set_bias_level(struct snd_soc_codec *codec,
+static int sta350_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       dev_dbg(codec->dev, "level = %d\n", level);
+       dev_dbg(component->dev, "level = %d\n", level);
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
@@ -853,18 +853,18 @@ static int sta350_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(
                                ARRAY_SIZE(sta350->supplies),
                                sta350->supplies);
                        if (ret < 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to enable supplies: %d\n",
                                        ret);
                                return ret;
                        }
                        sta350_startup_sequence(sta350);
-                       sta350_cache_sync(codec);
+                       sta350_cache_sync(component);
                }
 
                /* Power down */
@@ -911,22 +911,22 @@ static struct snd_soc_dai_driver sta350_dai = {
        .ops = &sta350_dai_ops,
 };
 
-static int sta350_probe(struct snd_soc_codec *codec)
+static int sta350_probe(struct snd_soc_component *component)
 {
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
        struct sta350_platform_data *pdata = sta350->pdata;
        int i, ret = 0, thermal = 0;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies),
                                    sta350->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
                return ret;
        }
 
        ret = sta350_startup_sequence(sta350);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to startup device\n");
+               dev_err(component->dev, "Failed to startup device\n");
                return ret;
        }
 
@@ -1036,35 +1036,35 @@ static int sta350_probe(struct snd_soc_codec *codec)
        sta350->coef_shadow[60] = 0x400000;
        sta350->coef_shadow[61] = 0x400000;
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
 
        return 0;
 }
 
-static int sta350_remove(struct snd_soc_codec *codec)
+static void sta350_remove(struct snd_soc_component *component)
 {
-       struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec);
+       struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component);
 
        regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver sta350_codec = {
-       .probe =                sta350_probe,
-       .remove =               sta350_remove,
-       .set_bias_level =       sta350_set_bias_level,
-       .suspend_bias_off =     true,
-       .component_driver = {
-               .controls =             sta350_snd_controls,
-               .num_controls =         ARRAY_SIZE(sta350_snd_controls),
-               .dapm_widgets =         sta350_dapm_widgets,
-               .num_dapm_widgets =     ARRAY_SIZE(sta350_dapm_widgets),
-               .dapm_routes =          sta350_dapm_routes,
-               .num_dapm_routes =      ARRAY_SIZE(sta350_dapm_routes),
-       },
+static const struct snd_soc_component_driver sta350_component = {
+       .probe                  = sta350_probe,
+       .remove                 = sta350_remove,
+       .set_bias_level         = sta350_set_bias_level,
+       .controls               = sta350_snd_controls,
+       .num_controls           = ARRAY_SIZE(sta350_snd_controls),
+       .dapm_widgets           = sta350_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sta350_dapm_widgets),
+       .dapm_routes            = sta350_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(sta350_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config sta350_regmap = {
@@ -1244,16 +1244,15 @@ static int sta350_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, sta350);
 
-       ret = snd_soc_register_codec(dev, &sta350_codec, &sta350_dai, 1);
+       ret = devm_snd_soc_register_component(dev, &sta350_component, &sta350_dai, 1);
        if (ret < 0)
-               dev_err(dev, "Failed to register codec (%d)\n", ret);
+               dev_err(dev, "Failed to register component (%d)\n", ret);
 
        return ret;
 }
 
 static int sta350_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index 660734359bf3c174577e9363a34cf066e4bd0f3b..2881a0f7bb399a9aaf6e02bf16da7e6b9ce8db61 100644 (file)
@@ -151,28 +151,28 @@ static const struct snd_kcontrol_new sta529_snd_controls[] = {
        SOC_ENUM("PWM Select", pwm_src),
 };
 
-static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
+static int sta529_set_bias_level(struct snd_soc_component *component, enum
                snd_soc_bias_level level)
 {
-       struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
+       struct sta529 *sta529 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
-               snd_soc_update_bits(codec, STA529_FFXCFG0, POWER_CNTLMSAK,
+               snd_soc_component_update_bits(component, STA529_FFXCFG0, POWER_CNTLMSAK,
                                POWER_UP);
-               snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
+               snd_soc_component_update_bits(component, STA529_MISC,   FFX_CLK_MSK,
                                FFX_CLK_ENB);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        regcache_sync(sta529->regmap);
-               snd_soc_update_bits(codec, STA529_FFXCFG0,
+               snd_soc_component_update_bits(component, STA529_FFXCFG0,
                                        POWER_CNTLMSAK, POWER_STDBY);
                /* Making FFX output to zero */
-               snd_soc_update_bits(codec, STA529_FFXCFG0, FFX_MASK,
+               snd_soc_component_update_bits(component, STA529_FFXCFG0, FFX_MASK,
                                FFX_OFF);
-               snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
+               snd_soc_component_update_bits(component, STA529_MISC, FFX_CLK_MSK,
                                FFX_CLK_DIS);
                break;
        case SND_SOC_BIAS_OFF:
@@ -187,7 +187,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int pdata, play_freq_val, record_freq_val;
        int bclk_to_fs_ratio;
 
@@ -205,7 +205,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
                bclk_to_fs_ratio = 2;
                break;
        default:
-               dev_err(codec->dev, "Unsupported format\n");
+               dev_err(component->dev, "Unsupported format\n");
                return -EINVAL;
        }
 
@@ -228,23 +228,23 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
                record_freq_val = 0;
                break;
        default:
-               dev_err(codec->dev, "Unsupported rate\n");
+               dev_err(component->dev, "Unsupported rate\n");
                return -EINVAL;
        }
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               snd_soc_update_bits(codec, STA529_S2PCFG1, PDATA_LEN_MSK,
+               snd_soc_component_update_bits(component, STA529_S2PCFG1, PDATA_LEN_MSK,
                                pdata << 6);
-               snd_soc_update_bits(codec, STA529_S2PCFG1, BCLK_TO_FS_MSK,
+               snd_soc_component_update_bits(component, STA529_S2PCFG1, BCLK_TO_FS_MSK,
                                bclk_to_fs_ratio << 4);
-               snd_soc_update_bits(codec, STA529_MISC, PLAY_FREQ_RANGE_MSK,
+               snd_soc_component_update_bits(component, STA529_MISC, PLAY_FREQ_RANGE_MSK,
                                play_freq_val << 4);
        } else {
-               snd_soc_update_bits(codec, STA529_P2SCFG1, PDATA_LEN_MSK,
+               snd_soc_component_update_bits(component, STA529_P2SCFG1, PDATA_LEN_MSK,
                                pdata << 6);
-               snd_soc_update_bits(codec, STA529_P2SCFG1, BCLK_TO_FS_MSK,
+               snd_soc_component_update_bits(component, STA529_P2SCFG1, BCLK_TO_FS_MSK,
                                bclk_to_fs_ratio << 4);
-               snd_soc_update_bits(codec, STA529_MISC, CAP_FREQ_RANGE_MSK,
+               snd_soc_component_update_bits(component, STA529_MISC, CAP_FREQ_RANGE_MSK,
                                record_freq_val << 2);
        }
 
@@ -258,14 +258,14 @@ static int sta529_mute(struct snd_soc_dai *dai, int mute)
        if (mute)
                val |= CODEC_MUTE_VAL;
 
-       snd_soc_update_bits(dai->codec, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
+       snd_soc_component_update_bits(dai->component, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
 
        return 0;
 }
 
 static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 mode = 0;
 
        /* interface format */
@@ -283,7 +283,7 @@ static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
+       snd_soc_component_update_bits(component, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
 
        return 0;
 }
@@ -313,14 +313,15 @@ static struct snd_soc_dai_driver sta529_dai = {
        .ops    = &sta529_dai_ops,
 };
 
-static const struct snd_soc_codec_driver sta529_codec_driver = {
-       .set_bias_level = sta529_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = sta529_snd_controls,
-               .num_controls           = ARRAY_SIZE(sta529_snd_controls),
-       },
+static const struct snd_soc_component_driver sta529_component_driver = {
+       .set_bias_level         = sta529_set_bias_level,
+       .controls               = sta529_snd_controls,
+       .num_controls           = ARRAY_SIZE(sta529_snd_controls),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config sta529_regmap = {
@@ -354,21 +355,14 @@ static int sta529_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, sta529);
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &sta529_codec_driver, &sta529_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &sta529_component_driver, &sta529_dai, 1);
        if (ret != 0)
                dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
 
        return ret;
 }
 
-static int sta529_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id sta529_i2c_id[] = {
        { "sta529", 0 },
        { }
@@ -387,7 +381,6 @@ static struct i2c_driver sta529_i2c_driver = {
                .of_match_table = sta529_of_match,
        },
        .probe          = sta529_i2c_probe,
-       .remove         = sta529_i2c_remove,
        .id_table       = sta529_i2c_id,
 };
 
index c66363a2cac7150e7240b1fd1c52bf547cf219e6..f62101a629e00160c008a86948d88b3bb844fc46 100644 (file)
@@ -168,58 +168,58 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
 static int ac97_analog_prepare(struct snd_pcm_substream *substream,
                               struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct snd_pcm_runtime *runtime = substream->runtime;
        unsigned short reg;
 
        /* enable variable rate audio, disable SPDIF output */
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x5, 0x1);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x5, 0x1);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                reg = AC97_PCM_FRONT_DAC_RATE;
        else
                reg = AC97_PCM_LR_ADC_RATE;
 
-       return snd_soc_write(codec, reg, runtime->rate);
+       return snd_soc_component_write(component, reg, runtime->rate);
 }
 
 static int ac97_digital_prepare(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct snd_pcm_runtime *runtime = substream->runtime;
        unsigned short reg;
 
-       snd_soc_write(codec, AC97_SPDIF, 0x2002);
+       snd_soc_component_write(component, AC97_SPDIF, 0x2002);
 
        /* Enable VRA and SPDIF out */
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x5, 0x5);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x5, 0x5);
 
        reg = AC97_PCM_FRONT_DAC_RATE;
 
-       return snd_soc_write(codec, reg, runtime->rate);
+       return snd_soc_component_write(component, reg, runtime->rate);
 }
 
-static int stac9766_set_bias_level(struct snd_soc_codec *codec,
+static int stac9766_set_bias_level(struct snd_soc_component *component,
                                   enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON: /* full On */
        case SND_SOC_BIAS_PREPARE: /* partial On */
        case SND_SOC_BIAS_STANDBY: /* Off, with power */
-               snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
+               snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
                break;
        case SND_SOC_BIAS_OFF: /* Off, without power */
                /* disable everything including AC link */
-               snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+               snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
                break;
        }
        return 0;
 }
 
-static int stac9766_codec_resume(struct snd_soc_codec *codec)
+static int stac9766_component_resume(struct snd_soc_component *component)
 {
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
        return snd_ac97_reset(ac97, true, STAC9766_VENDOR_ID,
                STAC9766_VENDOR_ID_MASK);
@@ -272,13 +272,13 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
 }
 };
 
-static int stac9766_codec_probe(struct snd_soc_codec *codec)
+static int stac9766_component_probe(struct snd_soc_component *component)
 {
        struct snd_ac97 *ac97;
        struct regmap *regmap;
        int ret;
 
-       ac97 = snd_soc_new_ac97_codec(codec, STAC9766_VENDOR_ID,
+       ac97 = snd_soc_new_ac97_component(component, STAC9766_VENDOR_ID,
                        STAC9766_VENDOR_ID_MASK);
        if (IS_ERR(ac97))
                return PTR_ERR(ac97);
@@ -289,46 +289,42 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
                goto err_free_ac97;
        }
 
-       snd_soc_codec_init_regmap(codec, regmap);
-       snd_soc_codec_set_drvdata(codec, ac97);
+       snd_soc_component_init_regmap(component, regmap);
+       snd_soc_component_set_drvdata(component, ac97);
 
        return 0;
 err_free_ac97:
-       snd_soc_free_ac97_codec(ac97);
+       snd_soc_free_ac97_component(ac97);
        return ret;
 }
 
-static int stac9766_codec_remove(struct snd_soc_codec *codec)
+static void stac9766_component_remove(struct snd_soc_component *component)
 {
-       struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+       struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component);
 
-       snd_soc_codec_exit_regmap(codec);
-       snd_soc_free_ac97_codec(ac97);
-       return 0;
+       snd_soc_component_exit_regmap(component);
+       snd_soc_free_ac97_component(ac97);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
-       .component_driver = {
-               .controls               = stac9766_snd_ac97_controls,
-               .num_controls           = ARRAY_SIZE(stac9766_snd_ac97_controls),
-       },
-       .set_bias_level = stac9766_set_bias_level,
-       .suspend_bias_off = true,
-       .probe = stac9766_codec_probe,
-       .remove = stac9766_codec_remove,
-       .resume = stac9766_codec_resume,
+static const struct snd_soc_component_driver soc_component_dev_stac9766 = {
+       .controls               = stac9766_snd_ac97_controls,
+       .num_controls           = ARRAY_SIZE(stac9766_snd_ac97_controls),
+       .set_bias_level         = stac9766_set_bias_level,
+       .probe                  = stac9766_component_probe,
+       .remove                 = stac9766_component_remove,
+       .resume                 = stac9766_component_resume,
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+
 };
 
 static int stac9766_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
-}
-
-static int stac9766_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
 }
 
 static struct platform_driver stac9766_codec_driver = {
@@ -337,7 +333,6 @@ static struct platform_driver stac9766_codec_driver = {
        },
 
        .probe = stac9766_probe,
-       .remove = stac9766_remove,
 };
 
 module_platform_driver(stac9766_codec_driver);
index 62c618765224b81eacc83cfddfd8eb0831e3b980..7316c80b81798cab6b95b8a7fb6558076087d351 100644 (file)
@@ -106,7 +106,7 @@ static int sti_sas_write_reg(void *context, unsigned int reg,
        return status;
 }
 
-static int  sti_sas_init_sas_registers(struct snd_soc_codec *codec,
+static int  sti_sas_init_sas_registers(struct snd_soc_component *component,
                                       struct sti_sas_data *data)
 {
        int ret;
@@ -116,35 +116,35 @@ static int  sti_sas_init_sas_registers(struct snd_soc_codec *codec,
         */
 
        /* Initialise bi-phase formatter to disabled */
-       ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+       ret = snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
                                  SPDIF_BIPHASE_ENABLE_MASK, 0);
 
        if (!ret)
                /* Initialise bi-phase formatter idle value to 0 */
-               ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+               ret = snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
                                          SPDIF_BIPHASE_IDLE_MASK, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to update SPDIF registers\n");
+               dev_err(component->dev, "Failed to update SPDIF registers\n");
                return ret;
        }
 
        /* Init DAC configuration */
        /* init configuration */
-       ret =  snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+       ret =  snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
                                   STIH407_DAC_STANDBY_MASK,
                                   STIH407_DAC_STANDBY_MASK);
 
        if (!ret)
-               ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+               ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
                                          STIH407_DAC_STANDBY_ANA_MASK,
                                          STIH407_DAC_STANDBY_ANA_MASK);
        if (!ret)
-               ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+               ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
                                          STIH407_DAC_SOFTMUTE_MASK,
                                          STIH407_DAC_SOFTMUTE_MASK);
 
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to update DAC registers\n");
+               dev_err(component->dev, "Failed to update DAC registers\n");
                return ret;
        }
 
@@ -158,7 +158,7 @@ static int sti_sas_dac_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
        /* Sanity check only */
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupporter master mask 0x%x\n",
                        __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
                return -EINVAL;
@@ -183,14 +183,14 @@ static const struct snd_soc_dapm_route stih407_sas_route[] = {
 
 static int stih407_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute) {
-               return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+               return snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
                                            STIH407_DAC_SOFTMUTE_MASK,
                                            STIH407_DAC_SOFTMUTE_MASK);
        } else {
-               return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
+               return snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
                                            STIH407_DAC_SOFTMUTE_MASK,
                                            0);
        }
@@ -203,7 +203,7 @@ static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
                                 unsigned int fmt)
 {
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-               dev_err(dai->codec->dev,
+               dev_err(dai->component->dev,
                        "%s: ERROR: Unsupporter master mask 0x%x\n",
                        __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
                return -EINVAL;
@@ -221,19 +221,19 @@ static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
 static int sti_sas_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+               return snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
                                            SPDIF_BIPHASE_ENABLE_MASK,
                                            SPDIF_BIPHASE_ENABLE_MASK);
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
+               return snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
                                            SPDIF_BIPHASE_ENABLE_MASK,
                                            0);
        default:
@@ -260,8 +260,8 @@ static bool sti_sas_volatile_register(struct device *dev, unsigned int reg)
 static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
                              unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = dai->component;
+       struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
 
        if (dir == SND_SOC_CLOCK_OUT)
                return 0;
@@ -285,20 +285,20 @@ static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int sti_sas_prepare(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = dai->component;
+       struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
        struct snd_pcm_runtime *runtime = substream->runtime;
 
        switch (dai->id) {
        case STI_SAS_DAI_SPDIF_OUT:
                if ((drvdata->spdif.mclk / runtime->rate) != 128) {
-                       dev_err(codec->dev, "unexpected mclk-fs ratio\n");
+                       dev_err(component->dev, "unexpected mclk-fs ratio\n");
                        return -EINVAL;
                }
                break;
        case STI_SAS_DAI_ANALOG_OUT:
                if ((drvdata->dac.mclk / runtime->rate) != 256) {
-                       dev_err(codec->dev, "unexpected mclk-fs ratio\n");
+                       dev_err(component->dev, "unexpected mclk-fs ratio\n");
                        return -EINVAL;
                }
                break;
@@ -375,29 +375,33 @@ static struct snd_soc_dai_driver sti_sas_dai[] = {
 };
 
 #ifdef CONFIG_PM_SLEEP
-static int sti_sas_resume(struct snd_soc_codec *codec)
+static int sti_sas_resume(struct snd_soc_component *component)
 {
-       struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+       struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
 
-       return sti_sas_init_sas_registers(codec, drvdata);
+       return sti_sas_init_sas_registers(component, drvdata);
 }
 #else
 #define sti_sas_resume NULL
 #endif
 
-static int sti_sas_codec_probe(struct snd_soc_codec *codec)
+static int sti_sas_component_probe(struct snd_soc_component *component)
 {
-       struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
+       struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
        int ret;
 
-       ret = sti_sas_init_sas_registers(codec, drvdata);
+       ret = sti_sas_init_sas_registers(component, drvdata);
 
        return ret;
 }
 
-static struct snd_soc_codec_driver sti_sas_driver = {
-       .probe = sti_sas_codec_probe,
-       .resume = sti_sas_resume,
+static struct snd_soc_component_driver sti_sas_driver = {
+       .probe                  = sti_sas_component_probe,
+       .resume                 = sti_sas_resume,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id sti_sas_dev_match[] = {
@@ -452,34 +456,26 @@ static int sti_sas_driver_probe(struct platform_device *pdev)
        sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
 
        /* Set dapms*/
-       sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
-       sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
+       sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
+       sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
 
-       sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes;
-       sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
+       sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes;
+       sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
 
        /* Store context */
        dev_set_drvdata(&pdev->dev, drvdata);
 
-       return snd_soc_register_codec(&pdev->dev, &sti_sas_driver,
+       return devm_snd_soc_register_component(&pdev->dev, &sti_sas_driver,
                                        sti_sas_dai,
                                        ARRAY_SIZE(sti_sas_dai));
 }
 
-static int sti_sas_driver_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-
-       return 0;
-}
-
 static struct platform_driver sti_sas_platform_driver = {
        .driver = {
                .name = "sti-sas-codec",
                .of_match_table = sti_sas_dev_match,
        },
        .probe = sti_sas_driver_probe,
-       .remove = sti_sas_driver_remove,
 };
 
 module_platform_driver(sti_sas_platform_driver);
index 87307dd0f12e8feab5a3e163a4cdec60d8333750..355ecafb7c0f844c2b8c697caa1a45f0115d9b86 100644 (file)
@@ -70,7 +70,7 @@ static const char *tas2552_supply_names[TAS2552_NUM_SUPPLIES] = {
 };
 
 struct tas2552_data {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regmap *regmap;
        struct i2c_client *tas2552_client;
        struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
@@ -88,22 +88,22 @@ struct tas2552_data {
 static int tas2552_post_event(struct snd_soc_dapm_widget *w,
                              struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_write(codec, TAS2552_RESERVED_0D, 0xc0);
-               snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5),
+               snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xc0);
+               snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5),
                                    (1 << 5));
-               snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 0);
-               snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS, 0);
+               snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 0);
+               snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS, 0);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS,
+               snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_SWS,
                                    TAS2552_SWS);
-               snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 1);
-               snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
-               snd_soc_write(codec, TAS2552_RESERVED_0D, 0xbe);
+               snd_soc_component_update_bits(component, TAS2552_CFG_2, 1, 1);
+               snd_soc_component_update_bits(component, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
+               snd_soc_component_write(component, TAS2552_RESERVED_0D, 0xbe);
                break;
        }
        return 0;
@@ -149,21 +149,21 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas2552, int sw_shutdown)
 {
        u8 cfg1_reg = 0;
 
-       if (!tas2552->codec)
+       if (!tas2552->component)
                return;
 
        if (sw_shutdown)
                cfg1_reg = TAS2552_SWS;
 
-       snd_soc_update_bits(tas2552->codec, TAS2552_CFG_1, TAS2552_SWS,
+       snd_soc_component_update_bits(tas2552->component, TAS2552_CFG_1, TAS2552_SWS,
                            cfg1_reg);
 }
 #endif
 
-static int tas2552_setup_pll(struct snd_soc_codec *codec,
+static int tas2552_setup_pll(struct snd_soc_component *component,
                             struct snd_pcm_hw_params *params)
 {
-       struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+       struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
        bool bypass_pll = false;
        unsigned int pll_clk = params_rate(params) * 512;
        unsigned int pll_clkin = tas2552->pll_clkin;
@@ -177,15 +177,15 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec,
                pll_clkin += tas2552->tdm_delay;
        }
 
-       pll_enable = snd_soc_read(codec, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
-       snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
+       pll_enable = snd_soc_component_read32(component, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
+       snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
 
        if (pll_clkin == pll_clk)
                bypass_pll = true;
 
        if (bypass_pll) {
                /* By pass the PLL configuration */
-               snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
+               snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_2,
                                    TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
        } else {
                /* Fill in the PLL control registers for J & D
@@ -195,7 +195,7 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec,
                unsigned int d, q, t;
                u8 j;
                u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
-               u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
+               u8 p = snd_soc_component_read32(component, TAS2552_PLL_CTRL_1);
 
                p = (p >> 7);
 
@@ -221,20 +221,20 @@ recalc:
                        goto recalc;
                }
 
-               snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
+               snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
                                    pll_sel);
 
-               snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
+               snd_soc_component_update_bits(component, TAS2552_PLL_CTRL_1,
                                    TAS2552_PLL_J_MASK, j);
                /* Will clear the PLL_BYPASS bit */
-               snd_soc_write(codec, TAS2552_PLL_CTRL_2,
+               snd_soc_component_write(component, TAS2552_PLL_CTRL_2,
                              TAS2552_PLL_D_UPPER(d));
-               snd_soc_write(codec, TAS2552_PLL_CTRL_3,
+               snd_soc_component_write(component, TAS2552_PLL_CTRL_3,
                              TAS2552_PLL_D_LOWER(d));
        }
 
        /* Restore PLL status */
-       snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
+       snd_soc_component_update_bits(component, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
                            pll_enable);
 
        return 0;
@@ -244,8 +244,8 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = dai->component;
+       struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
        int cpf;
        u8 ser_ctrl1_reg, wclk_rate;
 
@@ -267,7 +267,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
                cpf = 64 + tas2552->tdm_delay;
                break;
        default:
-               dev_err(codec->dev, "Not supported sample size: %d\n",
+               dev_err(component->dev, "Not supported sample size: %d\n",
                        params_width(params));
                return -EINVAL;
        }
@@ -281,7 +281,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
        else
                ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;
 
-       snd_soc_update_bits(codec, TAS2552_SER_CTRL_1,
+       snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1,
                            TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
                            ser_ctrl1_reg);
 
@@ -316,15 +316,15 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
                wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
                break;
        default:
-               dev_err(codec->dev, "Not supported sample rate: %d\n",
+               dev_err(component->dev, "Not supported sample rate: %d\n",
                        params_rate(params));
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
+       snd_soc_component_update_bits(component, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
                            wclk_rate);
 
-       return tas2552_setup_pll(codec, params);
+       return tas2552_setup_pll(component, params);
 }
 
 #define TAS2552_DAI_FMT_MASK   (TAS2552_BCLKDIR | \
@@ -333,8 +333,8 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 static int tas2552_prepare(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
        int delay = 0;
 
        /* TDM slot selection only valid in DSP_A/_B mode */
@@ -344,15 +344,15 @@ static int tas2552_prepare(struct snd_pcm_substream *substream,
                delay += tas2552->tdm_delay;
 
        /* Configure data delay */
-       snd_soc_write(codec, TAS2552_SER_CTRL_2, delay);
+       snd_soc_component_write(component, TAS2552_SER_CTRL_2, delay);
 
        return 0;
 }
 
 static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = dai->component;
+       struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
        u8 serial_format;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -369,7 +369,7 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR);
                break;
        default:
-               dev_vdbg(codec->dev, "DAI Format master is not found\n");
+               dev_vdbg(component->dev, "DAI Format master is not found\n");
                return -EINVAL;
        }
 
@@ -388,12 +388,12 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                serial_format |= TAS2552_DATAFORMAT_LEFT_J;
                break;
        default:
-               dev_vdbg(codec->dev, "DAI Format is not found\n");
+               dev_vdbg(component->dev, "DAI Format is not found\n");
                return -EINVAL;
        }
        tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
-       snd_soc_update_bits(codec, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
+       snd_soc_component_update_bits(component, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
                            serial_format);
        return 0;
 }
@@ -401,8 +401,8 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                                  unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = dai->component;
+       struct tas2552_data *tas2552 = dev_get_drvdata(component->dev);
        u8 reg, mask, val;
 
        switch (clk_id) {
@@ -410,7 +410,7 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
        case TAS2552_PLL_CLKIN_IVCLKIN:
                if (freq < 512000 || freq > 24576000) {
                        /* out of range PLL_CLKIN, fall back to use BCLK */
-                       dev_warn(codec->dev, "Out of range PLL_CLKIN: %u\n",
+                       dev_warn(component->dev, "Out of range PLL_CLKIN: %u\n",
                                 freq);
                        clk_id = TAS2552_PLL_CLKIN_BCLK;
                        freq = 0;
@@ -435,11 +435,11 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
                tas2552->pdm_clk = freq;
                break;
        default:
-               dev_err(codec->dev, "Invalid clk id: %d\n", clk_id);
+               dev_err(component->dev, "Invalid clk id: %d\n", clk_id);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, reg, mask, val);
+       snd_soc_component_update_bits(component, reg, mask, val);
 
        return 0;
 }
@@ -448,26 +448,26 @@ static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
                                    unsigned int tx_mask, unsigned int rx_mask,
                                    int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
        unsigned int lsb;
 
        if (unlikely(!tx_mask)) {
-               dev_err(codec->dev, "tx masks need to be non 0\n");
+               dev_err(component->dev, "tx masks need to be non 0\n");
                return -EINVAL;
        }
 
        /* TDM based on DSP mode requires slots to be adjacent */
        lsb = __ffs(tx_mask);
        if ((lsb + 1) != __fls(tx_mask)) {
-               dev_err(codec->dev, "Invalid mask, slots must be adjacent\n");
+               dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
                return -EINVAL;
        }
 
        tas2552->tdm_delay = lsb * slot_width;
 
        /* DOUT in high-impedance on inactive bit clocks */
-       snd_soc_update_bits(codec, TAS2552_DOUT,
+       snd_soc_component_update_bits(component, TAS2552_DOUT,
                            TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);
 
        return 0;
@@ -476,12 +476,12 @@ static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
 static int tas2552_mute(struct snd_soc_dai *dai, int mute)
 {
        u8 cfg1_reg = 0;
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        if (mute)
                cfg1_reg |= TAS2552_MUTE;
 
-       snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
+       snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
 
        return 0;
 }
@@ -570,41 +570,41 @@ static const struct snd_kcontrol_new tas2552_snd_controls[] = {
        SOC_ENUM("DIN source", tas2552_din_source_enum),
 };
 
-static int tas2552_codec_probe(struct snd_soc_codec *codec)
+static int tas2552_component_probe(struct snd_soc_component *component)
 {
-       struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+       struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       tas2552->codec = codec;
+       tas2552->component = component;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
                                    tas2552->supplies);
 
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n",
+               dev_err(component->dev, "Failed to enable supplies: %d\n",
                        ret);
                return ret;
        }
 
        gpiod_set_value(tas2552->enable_gpio, 1);
 
-       ret = pm_runtime_get_sync(codec->dev);
+       ret = pm_runtime_get_sync(component->dev);
        if (ret < 0) {
-               dev_err(codec->dev, "Enabling device failed: %d\n",
+               dev_err(component->dev, "Enabling device failed: %d\n",
                        ret);
                goto probe_fail;
        }
 
-       snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
-       snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
+       snd_soc_component_update_bits(component, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
+       snd_soc_component_write(component, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
                                            TAS2552_DIN_SRC_SEL_AVG_L_R);
-       snd_soc_write(codec, TAS2552_OUTPUT_DATA,
+       snd_soc_component_write(component, TAS2552_OUTPUT_DATA,
                      TAS2552_PDM_DATA_SEL_V_I |
                      TAS2552_R_DATA_OUT(TAS2552_DATA_OUT_V_DATA));
-       snd_soc_write(codec, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
+       snd_soc_component_write(component, TAS2552_BOOST_APT_CTRL, TAS2552_APT_DELAY_200 |
                                                     TAS2552_APT_THRESH_20_17);
 
-       snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
+       snd_soc_component_write(component, TAS2552_CFG_2, TAS2552_BOOST_EN | TAS2552_APT_EN |
                                            TAS2552_LIM_EN);
 
        return 0;
@@ -617,42 +617,40 @@ probe_fail:
        return ret;
 }
 
-static int tas2552_codec_remove(struct snd_soc_codec *codec)
+static void tas2552_component_remove(struct snd_soc_component *component)
 {
-       struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+       struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
 
-       pm_runtime_put(codec->dev);
+       pm_runtime_put(component->dev);
 
        gpiod_set_value(tas2552->enable_gpio, 0);
-
-       return 0;
 };
 
 #ifdef CONFIG_PM
-static int tas2552_suspend(struct snd_soc_codec *codec)
+static int tas2552_suspend(struct snd_soc_component *component)
 {
-       struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+       struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
                                        tas2552->supplies);
 
        if (ret != 0)
-               dev_err(codec->dev, "Failed to disable supplies: %d\n",
+               dev_err(component->dev, "Failed to disable supplies: %d\n",
                        ret);
        return ret;
 }
 
-static int tas2552_resume(struct snd_soc_codec *codec)
+static int tas2552_resume(struct snd_soc_component *component)
 {
-       struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+       struct tas2552_data *tas2552 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(tas2552->supplies),
                                    tas2552->supplies);
 
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n",
+               dev_err(component->dev, "Failed to enable supplies: %d\n",
                        ret);
        }
 
@@ -663,21 +661,20 @@ static int tas2552_resume(struct snd_soc_codec *codec)
 #define tas2552_resume NULL
 #endif
 
-static const struct snd_soc_codec_driver soc_codec_dev_tas2552 = {
-       .probe = tas2552_codec_probe,
-       .remove = tas2552_codec_remove,
-       .suspend =      tas2552_suspend,
-       .resume = tas2552_resume,
-       .ignore_pmdown_time = true,
-
-       .component_driver = {
-               .controls               = tas2552_snd_controls,
-               .num_controls           = ARRAY_SIZE(tas2552_snd_controls),
-               .dapm_widgets           = tas2552_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tas2552_dapm_widgets),
-               .dapm_routes            = tas2552_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(tas2552_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_tas2552 = {
+       .probe                  = tas2552_component_probe,
+       .remove                 = tas2552_component_remove,
+       .suspend                = tas2552_suspend,
+       .resume                 = tas2552_resume,
+       .controls               = tas2552_snd_controls,
+       .num_controls           = ARRAY_SIZE(tas2552_snd_controls),
+       .dapm_widgets           = tas2552_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tas2552_dapm_widgets),
+       .dapm_routes            = tas2552_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(tas2552_audio_map),
+       .idle_bias_on           = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config tas2552_regmap_config = {
@@ -736,18 +733,17 @@ static int tas2552_probe(struct i2c_client *client,
 
        dev_set_drvdata(&client->dev, data);
 
-       ret = snd_soc_register_codec(&client->dev,
-                                     &soc_codec_dev_tas2552,
+       ret = devm_snd_soc_register_component(&client->dev,
+                                     &soc_component_dev_tas2552,
                                      tas2552_dai, ARRAY_SIZE(tas2552_dai));
        if (ret < 0)
-               dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&client->dev, "Failed to register component: %d\n", ret);
 
        return ret;
 }
 
 static int tas2552_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        pm_runtime_disable(&client->dev);
        return 0;
 }
index 199272d5cb6a84cff97e74acd750b24ffe7b230d..5efc4b7145d441313f49d48c16545a29ed4463b4 100644 (file)
@@ -261,9 +261,9 @@ struct tas5086_private {
 
 static int tas5086_deemph[] = { 0, 32000, 44100, 48000 };
 
-static int tas5086_set_deemph(struct snd_soc_codec *codec)
+static int tas5086_set_deemph(struct snd_soc_component *component)
 {
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
        int i, val = 0;
 
        if (priv->deemph) {
@@ -282,8 +282,8 @@ static int tas5086_set_deemph(struct snd_soc_codec *codec)
 static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = priv->deemph;
 
@@ -293,20 +293,20 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol,
 static int tas5086_put_deemph(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
        priv->deemph = ucontrol->value.integer.value[0];
 
-       return tas5086_set_deemph(codec);
+       return tas5086_set_deemph(component);
 }
 
 
 static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case TAS5086_CLK_IDX_MCLK:
@@ -323,12 +323,12 @@ static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai,
                               unsigned int format)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
        /* The TAS5086 can only be slave to all clocks */
        if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-               dev_err(codec->dev, "Invalid clocking mode\n");
+               dev_err(component->dev, "Invalid clocking mode\n");
                return -EINVAL;
        }
 
@@ -361,8 +361,8 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
        int val;
        int ret;
 
@@ -373,7 +373,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
                             ARRAY_SIZE(tas5086_sample_rates), priv->rate);
 
        if (val < 0) {
-               dev_err(codec->dev, "Invalid sample rate\n");
+               dev_err(component->dev, "Invalid sample rate\n");
                return -EINVAL;
        }
 
@@ -387,7 +387,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
        val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios),
                             priv->mclk / priv->rate);
        if (val < 0) {
-               dev_err(codec->dev, "Invalid MCLK / Fs ratio\n");
+               dev_err(component->dev, "Invalid MCLK / Fs ratio\n");
                return -EINVAL;
        }
 
@@ -424,7 +424,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
                val = 0x06;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI format\n");
+               dev_err(component->dev, "Invalid DAI format\n");
                return -EINVAL;
        }
 
@@ -440,7 +440,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
                val += 2;
                break;
        default:
-               dev_err(codec->dev, "Invalid bit width\n");
+               dev_err(component->dev, "Invalid bit width\n");
                return -EINVAL;
        }
 
@@ -454,13 +454,13 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       return tas5086_set_deemph(codec);
+       return tas5086_set_deemph(component);
 }
 
 static int tas5086_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
 
        if (mute)
@@ -773,9 +773,9 @@ static struct snd_soc_dai_driver tas5086_dai = {
 };
 
 #ifdef CONFIG_PM
-static int tas5086_soc_suspend(struct snd_soc_codec *codec)
+static int tas5086_soc_suspend(struct snd_soc_component *component)
 {
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        /* Shut down all channels */
@@ -788,9 +788,9 @@ static int tas5086_soc_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int tas5086_soc_resume(struct snd_soc_codec *codec)
+static int tas5086_soc_resume(struct snd_soc_component *component)
 {
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
@@ -800,7 +800,7 @@ static int tas5086_soc_resume(struct snd_soc_codec *codec)
        tas5086_reset(priv);
        regcache_mark_dirty(priv->regmap);
 
-       ret = tas5086_init(codec->dev, priv);
+       ret = tas5086_init(component->dev, priv);
        if (ret < 0)
                return ret;
 
@@ -823,22 +823,22 @@ static const struct of_device_id tas5086_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, tas5086_dt_ids);
 #endif
 
-static int tas5086_probe(struct snd_soc_codec *codec)
+static int tas5086_probe(struct snd_soc_component *component)
 {
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
        int i, ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
+               dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
                return ret;
        }
 
        priv->pwm_start_mid_z = 0;
        priv->charge_period = 1300000; /* hardware default is 1300 ms */
 
-       if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) {
-               struct device_node *of_node = codec->dev->of_node;
+       if (of_match_device(of_match_ptr(tas5086_dt_ids), component->dev)) {
+               struct device_node *of_node = component->dev->of_node;
 
                of_property_read_u32(of_node, "ti,charge-period",
                                     &priv->charge_period);
@@ -855,7 +855,7 @@ static int tas5086_probe(struct snd_soc_codec *codec)
        }
 
        tas5086_reset(priv);
-       ret = tas5086_init(codec->dev, priv);
+       ret = tas5086_init(component->dev, priv);
        if (ret < 0)
                goto exit_disable_regulators;
 
@@ -872,32 +872,32 @@ exit_disable_regulators:
        return ret;
 }
 
-static int tas5086_remove(struct snd_soc_codec *codec)
+static void tas5086_remove(struct snd_soc_component *component)
 {
-       struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct tas5086_private *priv = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(priv->gpio_nreset))
                /* Set codec to the reset state */
                gpio_set_value(priv->gpio_nreset, 0);
 
        regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
-
-       return 0;
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
+static const struct snd_soc_component_driver soc_component_dev_tas5086 = {
        .probe                  = tas5086_probe,
        .remove                 = tas5086_remove,
        .suspend                = tas5086_soc_suspend,
        .resume                 = tas5086_soc_resume,
-       .component_driver = {
-               .controls               = tas5086_controls,
-               .num_controls           = ARRAY_SIZE(tas5086_controls),
-               .dapm_widgets           = tas5086_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tas5086_dapm_widgets),
-               .dapm_routes            = tas5086_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(tas5086_dapm_routes),
-       },
+       .controls               = tas5086_controls,
+       .num_controls           = ARRAY_SIZE(tas5086_controls),
+       .dapm_widgets           = tas5086_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tas5086_dapm_widgets),
+       .dapm_routes            = tas5086_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(tas5086_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct i2c_device_id tas5086_i2c_id[] = {
@@ -985,7 +985,8 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
        regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
 
        if (ret == 0)
-               ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tas5086,
+               ret = devm_snd_soc_register_component(&i2c->dev,
+                                            &soc_component_dev_tas5086,
                                             &tas5086_dai, 1);
 
        return ret;
@@ -993,7 +994,6 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
 
 static int tas5086_i2c_remove(struct i2c_client *i2c)
 {
-       snd_soc_unregister_codec(&i2c->dev);
        return 0;
 }
 
index a09499977be4d0ab4be645c41c6f0dcd614dcf71..52f34c94ec25691c496b70602dff9dacfa568da5 100644 (file)
@@ -51,7 +51,7 @@ struct tas571x_private {
        unsigned int                    format;
        struct gpio_desc                *reset_gpio;
        struct gpio_desc                *pdn_gpio;
-       struct snd_soc_codec_driver     codec_driver;
+       struct snd_soc_component_driver component_driver;
 };
 
 static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
@@ -242,8 +242,8 @@ static int tas571x_coefficient_info(struct snd_kcontrol *kcontrol,
 static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct i2c_client *i2c = to_i2c_client(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct i2c_client *i2c = to_i2c_client(component->dev);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
 
@@ -254,8 +254,8 @@ static int tas571x_coefficient_get(struct snd_kcontrol *kcontrol,
 static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct i2c_client *i2c = to_i2c_client(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct i2c_client *i2c = to_i2c_client(component->dev);
        int numcoef = kcontrol->private_value >> 16;
        int index = kcontrol->private_value & 0xffff;
 
@@ -265,7 +265,7 @@ static int tas571x_coefficient_put(struct snd_kcontrol *kcontrol,
 
 static int tas571x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
 {
-       struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
 
        priv->format = format;
 
@@ -276,7 +276,7 @@ static int tas571x_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct tas571x_private *priv = snd_soc_codec_get_drvdata(dai->codec);
+       struct tas571x_private *priv = snd_soc_component_get_drvdata(dai->component);
        u32 val;
 
        switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -304,13 +304,13 @@ static int tas571x_hw_params(struct snd_pcm_substream *substream,
 
 static int tas571x_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 sysctl2;
        int ret;
 
        sysctl2 = mute ? TAS571X_SYS_CTRL_2_SDN_MASK : 0;
 
-       ret = snd_soc_update_bits(codec,
+       ret = snd_soc_component_update_bits(component,
                            TAS571X_SYS_CTRL_2_REG,
                     TAS571X_SYS_CTRL_2_SDN_MASK,
                     sysctl2);
@@ -319,10 +319,10 @@ static int tas571x_mute(struct snd_soc_dai *dai, int mute)
        return ret;
 }
 
-static int tas571x_set_bias_level(struct snd_soc_codec *codec,
+static int tas571x_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct tas571x_private *priv = snd_soc_codec_get_drvdata(codec);
+       struct tas571x_private *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -331,11 +331,11 @@ static int tas571x_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        if (!IS_ERR(priv->mclk)) {
                                ret = clk_prepare_enable(priv->mclk);
                                if (ret) {
-                                       dev_err(codec->dev,
+                                       dev_err(component->dev,
                                                "Failed to enable master clock: %d\n",
                                                ret);
                                        return ret;
@@ -643,16 +643,15 @@ static const struct snd_soc_dapm_route tas571x_dapm_routes[] = {
        { "OUT_D", NULL, "DACR" },
 };
 
-static const struct snd_soc_codec_driver tas571x_codec = {
-       .set_bias_level = tas571x_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .dapm_widgets           = tas571x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tas571x_dapm_widgets),
-               .dapm_routes            = tas571x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(tas571x_dapm_routes),
-       },
+static const struct snd_soc_component_driver tas571x_component = {
+       .set_bias_level         = tas571x_set_bias_level,
+       .dapm_widgets           = tas571x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tas571x_dapm_widgets),
+       .dapm_routes            = tas571x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(tas571x_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct snd_soc_dai_driver tas571x_dai = {
@@ -746,9 +745,9 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
        usleep_range(50000, 60000);
 
-       memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
-       priv->codec_driver.component_driver.controls = priv->chip->controls;
-       priv->codec_driver.component_driver.num_controls = priv->chip->num_controls;
+       memcpy(&priv->component_driver, &tas571x_component, sizeof(priv->component_driver));
+       priv->component_driver.controls = priv->chip->controls;
+       priv->component_driver.num_controls = priv->chip->num_controls;
 
        if (priv->chip->vol_reg_size == 2) {
                /*
@@ -761,7 +760,8 @@ static int tas571x_i2c_probe(struct i2c_client *client,
                        return ret;
        }
 
-       return snd_soc_register_codec(&client->dev, &priv->codec_driver,
+       return devm_snd_soc_register_component(&client->dev,
+                                     &priv->component_driver,
                                      &tas571x_dai, 1);
 }
 
@@ -769,7 +769,6 @@ static int tas571x_i2c_remove(struct i2c_client *client)
 {
        struct tas571x_private *priv = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
        regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
 
        return 0;
index f3006f301fe8c7cf0cd10b364c7159a07238e598..ae3d032ac35a3349249c0370ba6f7725d5747ce5 100644 (file)
@@ -49,7 +49,7 @@ static const char * const tas5720_supply_names[] = {
 #define TAS5720_NUM_SUPPLIES   ARRAY_SIZE(tas5720_supply_names)
 
 struct tas5720_data {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regmap *regmap;
        struct i2c_client *tas5720_client;
        enum tas572x_type devtype;
@@ -62,7 +62,7 @@ static int tas5720_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int rate = params_rate(params);
        bool ssz_ds;
        int ret;
@@ -77,14 +77,14 @@ static int tas5720_hw_params(struct snd_pcm_substream *substream,
                ssz_ds = true;
                break;
        default:
-               dev_err(codec->dev, "unsupported sample rate: %u\n", rate);
+               dev_err(component->dev, "unsupported sample rate: %u\n", rate);
                return -EINVAL;
        }
 
-       ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL1_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
                                  TAS5720_SSZ_DS, ssz_ds);
        if (ret < 0) {
-               dev_err(codec->dev, "error setting sample rate: %d\n", ret);
+               dev_err(component->dev, "error setting sample rate: %d\n", ret);
                return ret;
        }
 
@@ -93,12 +93,12 @@ static int tas5720_hw_params(struct snd_pcm_substream *substream,
 
 static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 serial_format;
        int ret;
 
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
-               dev_vdbg(codec->dev, "DAI Format master is not found\n");
+               dev_vdbg(component->dev, "DAI Format master is not found\n");
                return -EINVAL;
        }
 
@@ -132,15 +132,15 @@ static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                serial_format = TAS5720_SAIF_LEFTJ;
                break;
        default:
-               dev_vdbg(codec->dev, "DAI Format is not found\n");
+               dev_vdbg(component->dev, "DAI Format is not found\n");
                return -EINVAL;
        }
 
-       ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL1_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
                                  TAS5720_SAIF_FORMAT_MASK,
                                  serial_format);
        if (ret < 0) {
-               dev_err(codec->dev, "error setting SAIF format: %d\n", ret);
+               dev_err(component->dev, "error setting SAIF format: %d\n", ret);
                return ret;
        }
 
@@ -151,12 +151,12 @@ static int tas5720_set_dai_tdm_slot(struct snd_soc_dai *dai,
                                    unsigned int tx_mask, unsigned int rx_mask,
                                    int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int first_slot;
        int ret;
 
        if (!tx_mask) {
-               dev_err(codec->dev, "tx masks must not be 0\n");
+               dev_err(component->dev, "tx masks must not be 0\n");
                return -EINVAL;
        }
 
@@ -168,39 +168,39 @@ static int tas5720_set_dai_tdm_slot(struct snd_soc_dai *dai,
        first_slot = __ffs(tx_mask);
 
        if (first_slot > 7) {
-               dev_err(codec->dev, "slot selection out of bounds (%u)\n",
+               dev_err(component->dev, "slot selection out of bounds (%u)\n",
                        first_slot);
                return -EINVAL;
        }
 
        /* Enable manual TDM slot selection (instead of I2C ID based) */
-       ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL1_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
                                  TAS5720_TDM_CFG_SRC, TAS5720_TDM_CFG_SRC);
        if (ret < 0)
-               goto error_snd_soc_update_bits;
+               goto error_snd_soc_component_update_bits;
 
        /* Configure the TDM slot to process audio from */
-       ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
                                  TAS5720_TDM_SLOT_SEL_MASK, first_slot);
        if (ret < 0)
-               goto error_snd_soc_update_bits;
+               goto error_snd_soc_component_update_bits;
 
        return 0;
 
-error_snd_soc_update_bits:
-       dev_err(codec->dev, "error configuring TDM mode: %d\n", ret);
+error_snd_soc_component_update_bits:
+       dev_err(component->dev, "error configuring TDM mode: %d\n", ret);
        return ret;
 }
 
 static int tas5720_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int ret;
 
-       ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
                                  TAS5720_MUTE, mute ? TAS5720_MUTE : 0);
        if (ret < 0) {
-               dev_err(codec->dev, "error (un-)muting device: %d\n", ret);
+               dev_err(component->dev, "error (un-)muting device: %d\n", ret);
                return ret;
        }
 
@@ -211,7 +211,7 @@ static void tas5720_fault_check_work(struct work_struct *work)
 {
        struct tas5720_data *tas5720 = container_of(work, struct tas5720_data,
                        fault_check_work.work);
-       struct device *dev = tas5720->codec->dev;
+       struct device *dev = tas5720->component->dev;
        unsigned int curr_fault;
        int ret;
 
@@ -267,18 +267,18 @@ out:
                              msecs_to_jiffies(TAS5720_FAULT_CHECK_INTERVAL));
 }
 
-static int tas5720_codec_probe(struct snd_soc_codec *codec)
+static int tas5720_codec_probe(struct snd_soc_component *component)
 {
-       struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+       struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
        unsigned int device_id, expected_device_id;
        int ret;
 
-       tas5720->codec = codec;
+       tas5720->component = component;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies),
                                    tas5720->supplies);
        if (ret != 0) {
-               dev_err(codec->dev, "failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "failed to enable supplies: %d\n", ret);
                return ret;
        }
 
@@ -289,7 +289,7 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
         */
        ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id);
        if (ret < 0) {
-               dev_err(codec->dev, "failed to read device ID register: %d\n",
+               dev_err(component->dev, "failed to read device ID register: %d\n",
                        ret);
                goto probe_fail;
        }
@@ -302,19 +302,19 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
                expected_device_id = TAS5722_DEVICE_ID;
                break;
        default:
-               dev_err(codec->dev, "unexpected private driver data\n");
+               dev_err(component->dev, "unexpected private driver data\n");
                return -EINVAL;
        }
 
        if (device_id != expected_device_id)
-               dev_warn(codec->dev, "wrong device ID. expected: %u read: %u\n",
+               dev_warn(component->dev, "wrong device ID. expected: %u read: %u\n",
                         expected_device_id, device_id);
 
        /* Set device to mute */
-       ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
                                  TAS5720_MUTE, TAS5720_MUTE);
        if (ret < 0)
-               goto error_snd_soc_update_bits;
+               goto error_snd_soc_component_update_bits;
 
        /*
         * Enter shutdown mode - our default when not playing audio - to
@@ -322,17 +322,17 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
         * side doing so as all device registers are preserved and the wakeup
         * of the codec is rather quick which we do using a dapm widget.
         */
-       ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
+       ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG,
                                  TAS5720_SDZ, 0);
        if (ret < 0)
-               goto error_snd_soc_update_bits;
+               goto error_snd_soc_component_update_bits;
 
        INIT_DELAYED_WORK(&tas5720->fault_check_work, tas5720_fault_check_work);
 
        return 0;
 
-error_snd_soc_update_bits:
-       dev_err(codec->dev, "error configuring device registers: %d\n", ret);
+error_snd_soc_component_update_bits:
+       dev_err(component->dev, "error configuring device registers: %d\n", ret);
 
 probe_fail:
        regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies),
@@ -340,9 +340,9 @@ probe_fail:
        return ret;
 }
 
-static int tas5720_codec_remove(struct snd_soc_codec *codec)
+static void tas5720_codec_remove(struct snd_soc_component *component)
 {
-       struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+       struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
        int ret;
 
        cancel_delayed_work_sync(&tas5720->fault_check_work);
@@ -350,24 +350,22 @@ static int tas5720_codec_remove(struct snd_soc_codec *codec)
        ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies),
                                     tas5720->supplies);
        if (ret < 0)
-               dev_err(codec->dev, "failed to disable supplies: %d\n", ret);
-
-       return ret;
+               dev_err(component->dev, "failed to disable supplies: %d\n", ret);
 };
 
 static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
        int ret;
 
        if (event & SND_SOC_DAPM_POST_PMU) {
                /* Take TAS5720 out of shutdown mode */
-               ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
+               ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG,
                                          TAS5720_SDZ, TAS5720_SDZ);
                if (ret < 0) {
-                       dev_err(codec->dev, "error waking codec: %d\n", ret);
+                       dev_err(component->dev, "error waking component: %d\n", ret);
                        return ret;
                }
 
@@ -390,10 +388,10 @@ static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
                cancel_delayed_work_sync(&tas5720->fault_check_work);
 
                /* Place TAS5720 in shutdown mode to minimize current draw */
-               ret = snd_soc_update_bits(codec, TAS5720_POWER_CTRL_REG,
+               ret = snd_soc_component_update_bits(component, TAS5720_POWER_CTRL_REG,
                                          TAS5720_SDZ, 0);
                if (ret < 0) {
-                       dev_err(codec->dev, "error shutting down codec: %d\n",
+                       dev_err(component->dev, "error shutting down component: %d\n",
                                ret);
                        return ret;
                }
@@ -403,9 +401,9 @@ static int tas5720_dac_event(struct snd_soc_dapm_widget *w,
 }
 
 #ifdef CONFIG_PM
-static int tas5720_suspend(struct snd_soc_codec *codec)
+static int tas5720_suspend(struct snd_soc_component *component)
 {
-       struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+       struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
        int ret;
 
        regcache_cache_only(tas5720->regmap, true);
@@ -414,20 +412,20 @@ static int tas5720_suspend(struct snd_soc_codec *codec)
        ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies),
                                     tas5720->supplies);
        if (ret < 0)
-               dev_err(codec->dev, "failed to disable supplies: %d\n", ret);
+               dev_err(component->dev, "failed to disable supplies: %d\n", ret);
 
        return ret;
 }
 
-static int tas5720_resume(struct snd_soc_codec *codec)
+static int tas5720_resume(struct snd_soc_component *component)
 {
-       struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
+       struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies),
                                    tas5720->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "failed to enable supplies: %d\n", ret);
                return ret;
        }
 
@@ -435,7 +433,7 @@ static int tas5720_resume(struct snd_soc_codec *codec)
 
        ret = regcache_sync(tas5720->regmap);
        if (ret < 0) {
-               dev_err(codec->dev, "failed to sync regcache: %d\n", ret);
+               dev_err(component->dev, "failed to sync regcache: %d\n", ret);
                return ret;
        }
 
@@ -512,20 +510,21 @@ static const struct snd_soc_dapm_route tas5720_audio_map[] = {
        { "OUT", NULL, "DAC" },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_tas5720 = {
-       .probe = tas5720_codec_probe,
-       .remove = tas5720_codec_remove,
-       .suspend = tas5720_suspend,
-       .resume = tas5720_resume,
-
-       .component_driver = {
-               .controls               = tas5720_snd_controls,
-               .num_controls           = ARRAY_SIZE(tas5720_snd_controls),
-               .dapm_widgets           = tas5720_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tas5720_dapm_widgets),
-               .dapm_routes            = tas5720_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(tas5720_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_tas5720 = {
+       .probe                  = tas5720_codec_probe,
+       .remove                 = tas5720_codec_remove,
+       .suspend                = tas5720_suspend,
+       .resume                 = tas5720_resume,
+       .controls               = tas5720_snd_controls,
+       .num_controls           = ARRAY_SIZE(tas5720_snd_controls),
+       .dapm_widgets           = tas5720_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tas5720_dapm_widgets),
+       .dapm_routes            = tas5720_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(tas5720_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /* PCM rates supported by the TAS5720 driver */
@@ -614,26 +613,17 @@ static int tas5720_probe(struct i2c_client *client,
 
        dev_set_drvdata(dev, data);
 
-       ret = snd_soc_register_codec(&client->dev,
-                                    &soc_codec_dev_tas5720,
+       ret = devm_snd_soc_register_component(&client->dev,
+                                    &soc_component_dev_tas5720,
                                     tas5720_dai, ARRAY_SIZE(tas5720_dai));
        if (ret < 0) {
-               dev_err(dev, "failed to register codec: %d\n", ret);
+               dev_err(dev, "failed to register component: %d\n", ret);
                return ret;
        }
 
        return 0;
 }
 
-static int tas5720_remove(struct i2c_client *client)
-{
-       struct device *dev = &client->dev;
-
-       snd_soc_unregister_codec(dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id tas5720_id[] = {
        { "tas5720", TAS5720 },
        { "tas5722", TAS5722 },
@@ -656,7 +646,6 @@ static struct i2c_driver tas5720_i2c_driver = {
                .of_match_table = of_match_ptr(tas5720_of_match),
        },
        .probe = tas5720_probe,
-       .remove = tas5720_remove,
        .id_table = tas5720_id,
 };
 
index 49b87f6e85bf2329f3611c37485e62727c54a972..4f3a16c520a2c3158f0d5e77e60dca8098366559 100644 (file)
@@ -66,10 +66,10 @@ static const struct snd_kcontrol_new tas6424_snd_controls[] = {
 static int tas6424_dac_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s() event=0x%0x\n", __func__, event);
+       dev_dbg(component->dev, "%s() event=0x%0x\n", __func__, event);
 
        if (event & SND_SOC_DAPM_POST_PMU) {
                /* Observe codec shutdown-to-active time */
@@ -105,12 +105,12 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int rate = params_rate(params);
        unsigned int width = params_width(params);
        u8 sap_ctrl = 0;
 
-       dev_dbg(codec->dev, "%s() rate=%u width=%u\n", __func__, rate, width);
+       dev_dbg(component->dev, "%s() rate=%u width=%u\n", __func__, rate, width);
 
        switch (rate) {
        case 44100:
@@ -123,7 +123,7 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
                sap_ctrl |= TAS6424_SAP_RATE_96000;
                break;
        default:
-               dev_err(codec->dev, "unsupported sample rate: %u\n", rate);
+               dev_err(component->dev, "unsupported sample rate: %u\n", rate);
                return -EINVAL;
        }
 
@@ -134,11 +134,11 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
        case 24:
                break;
        default:
-               dev_err(codec->dev, "unsupported sample width: %u\n", width);
+               dev_err(component->dev, "unsupported sample width: %u\n", width);
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, TAS6424_SAP_CTRL,
+       snd_soc_component_update_bits(component, TAS6424_SAP_CTRL,
                            TAS6424_SAP_RATE_MASK |
                            TAS6424_SAP_TDM_SLOT_SZ_16,
                            sap_ctrl);
@@ -148,17 +148,17 @@ static int tas6424_hw_params(struct snd_pcm_substream *substream,
 
 static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 serial_format = 0;
 
-       dev_dbg(codec->dev, "%s() fmt=0x%0x\n", __func__, fmt);
+       dev_dbg(component->dev, "%s() fmt=0x%0x\n", __func__, fmt);
 
        /* clock masters */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI master/slave interface\n");
+               dev_err(component->dev, "Invalid DAI master/slave interface\n");
                return -EINVAL;
        }
 
@@ -167,7 +167,7 @@ static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        case SND_SOC_DAIFMT_NB_NF:
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI clock signal polarity\n");
+               dev_err(component->dev, "Invalid DAI clock signal polarity\n");
                return -EINVAL;
        }
 
@@ -191,11 +191,11 @@ static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                serial_format |= TAS6424_SAP_LEFTJ;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI interface format\n");
+               dev_err(component->dev, "Invalid DAI interface format\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, TAS6424_SAP_CTRL,
+       snd_soc_component_update_bits(component, TAS6424_SAP_CTRL,
                            TAS6424_SAP_FMT_MASK, serial_format);
 
        return 0;
@@ -205,11 +205,11 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
                                    unsigned int tx_mask, unsigned int rx_mask,
                                    int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int first_slot, last_slot;
        bool sap_tdm_slot_last;
 
-       dev_dbg(codec->dev, "%s() tx_mask=%d rx_mask=%d\n", __func__,
+       dev_dbg(component->dev, "%s() tx_mask=%d rx_mask=%d\n", __func__,
                tx_mask, rx_mask);
 
        if (!tx_mask || !rx_mask)
@@ -224,7 +224,7 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
        last_slot = __fls(rx_mask);
 
        if (last_slot - first_slot != 4) {
-               dev_err(codec->dev, "tdm mask must cover 4 contiguous slots\n");
+               dev_err(component->dev, "tdm mask must cover 4 contiguous slots\n");
                return -EINVAL;
        }
 
@@ -236,11 +236,11 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
                sap_tdm_slot_last = true;
                break;
        default:
-               dev_err(codec->dev, "tdm mask must start at slot 0 or 4\n");
+               dev_err(component->dev, "tdm mask must start at slot 0 or 4\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, TAS6424_SAP_CTRL, TAS6424_SAP_TDM_SLOT_LAST,
+       snd_soc_component_update_bits(component, TAS6424_SAP_CTRL, TAS6424_SAP_TDM_SLOT_LAST,
                            sap_tdm_slot_last ? TAS6424_SAP_TDM_SLOT_LAST : 0);
 
        return 0;
@@ -248,27 +248,27 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
 
 static int tas6424_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val;
 
-       dev_dbg(codec->dev, "%s() mute=%d\n", __func__, mute);
+       dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute);
 
        if (mute)
                val = TAS6424_ALL_STATE_MUTE;
        else
                val = TAS6424_ALL_STATE_PLAY;
 
-       snd_soc_write(codec, TAS6424_CH_STATE_CTRL, val);
+       snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, val);
 
        return 0;
 }
 
-static int tas6424_power_off(struct snd_soc_codec *codec)
+static int tas6424_power_off(struct snd_soc_component *component)
 {
-       struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);
+       struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       snd_soc_write(codec, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_HIZ);
+       snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_HIZ);
 
        regcache_cache_only(tas6424->regmap, true);
        regcache_mark_dirty(tas6424->regmap);
@@ -276,22 +276,22 @@ static int tas6424_power_off(struct snd_soc_codec *codec)
        ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),
                                     tas6424->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "failed to disable supplies: %d\n", ret);
+               dev_err(component->dev, "failed to disable supplies: %d\n", ret);
                return ret;
        }
 
        return 0;
 }
 
-static int tas6424_power_on(struct snd_soc_codec *codec)
+static int tas6424_power_on(struct snd_soc_component *component)
 {
-       struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec);
+       struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),
                                    tas6424->supplies);
        if (ret < 0) {
-               dev_err(codec->dev, "failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "failed to enable supplies: %d\n", ret);
                return ret;
        }
 
@@ -299,11 +299,11 @@ static int tas6424_power_on(struct snd_soc_codec *codec)
 
        ret = regcache_sync(tas6424->regmap);
        if (ret < 0) {
-               dev_err(codec->dev, "failed to sync regcache: %d\n", ret);
+               dev_err(component->dev, "failed to sync regcache: %d\n", ret);
                return ret;
        }
 
-       snd_soc_write(codec, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE);
+       snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE);
 
        /* any time we come out of HIZ, the output channels automatically run DC
         * load diagnostics, wait here until this completes
@@ -313,39 +313,38 @@ static int tas6424_power_on(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int tas6424_set_bias_level(struct snd_soc_codec *codec,
+static int tas6424_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       dev_dbg(codec->dev, "%s() level=%d\n", __func__, level);
+       dev_dbg(component->dev, "%s() level=%d\n", __func__, level);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-                       tas6424_power_on(codec);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+                       tas6424_power_on(component);
                break;
        case SND_SOC_BIAS_OFF:
-               tas6424_power_off(codec);
+               tas6424_power_off(component);
                break;
        }
 
        return 0;
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_tas6424 = {
-       .set_bias_level = tas6424_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls = tas6424_snd_controls,
-               .num_controls = ARRAY_SIZE(tas6424_snd_controls),
-               .dapm_widgets = tas6424_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(tas6424_dapm_widgets),
-               .dapm_routes = tas6424_audio_map,
-               .num_dapm_routes = ARRAY_SIZE(tas6424_audio_map),
-       },
+static struct snd_soc_component_driver soc_codec_dev_tas6424 = {
+       .set_bias_level         = tas6424_set_bias_level,
+       .controls               = tas6424_snd_controls,
+       .num_controls           = ARRAY_SIZE(tas6424_snd_controls),
+       .dapm_widgets           = tas6424_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tas6424_dapm_widgets),
+       .dapm_routes            = tas6424_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(tas6424_audio_map),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct snd_soc_dai_ops tas6424_speaker_dai_ops = {
@@ -654,7 +653,7 @@ static int tas6424_i2c_probe(struct i2c_client *client,
 
        INIT_DELAYED_WORK(&tas6424->fault_check_work, tas6424_fault_check_work);
 
-       ret = snd_soc_register_codec(dev, &soc_codec_dev_tas6424,
+       ret = devm_snd_soc_register_component(dev, &soc_codec_dev_tas6424,
                                     tas6424_dai, ARRAY_SIZE(tas6424_dai));
        if (ret < 0) {
                dev_err(dev, "unable to register codec: %d\n", ret);
@@ -670,8 +669,6 @@ static int tas6424_i2c_remove(struct i2c_client *client)
        struct tas6424_data *tas6424 = dev_get_drvdata(dev);
        int ret;
 
-       snd_soc_unregister_codec(dev);
-
        cancel_delayed_work_sync(&tas6424->fault_check_work);
 
        ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),
diff --git a/sound/soc/codecs/tda7419.c b/sound/soc/codecs/tda7419.c
new file mode 100644 (file)
index 0000000..225c210
--- /dev/null
@@ -0,0 +1,654 @@
+/*
+ * TDA7419 audio processor driver
+ *
+ * Copyright 2018 Konsulko Group
+ *
+ * Author: Matt Porter <mporter@konsulko.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/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#define TDA7419_MAIN_SRC_REG           0x00
+#define TDA7419_LOUDNESS_REG           0x01
+#define TDA7419_MUTE_CLK_REG           0x02
+#define TDA7419_VOLUME_REG             0x03
+#define TDA7419_TREBLE_REG             0x04
+#define TDA7419_MIDDLE_REG             0x05
+#define TDA7419_BASS_REG               0x06
+#define TDA7419_SECOND_SRC_REG         0x07
+#define TDA7419_SUB_MID_BASS_REG       0x08
+#define TDA7419_MIXING_GAIN_REG                0x09
+#define TDA7419_ATTENUATOR_LF_REG      0x0a
+#define TDA7419_ATTENUATOR_RF_REG      0x0b
+#define TDA7419_ATTENUATOR_LR_REG      0x0c
+#define TDA7419_ATTENUATOR_RR_REG      0x0d
+#define TDA7419_MIXING_LEVEL_REG       0x0e
+#define TDA7419_ATTENUATOR_SUB_REG     0x0f
+#define TDA7419_SA_CLK_AC_REG          0x10
+#define TDA7419_TESTING_REG            0x11
+
+#define TDA7419_MAIN_SRC_SEL           0
+#define TDA7419_MAIN_SRC_GAIN          3
+#define TDA7419_MAIN_SRC_AUTOZERO      7
+
+#define TDA7419_LOUDNESS_ATTEN         0
+#define TDA7419_LOUDNESS_CENTER_FREQ   4
+#define TDA7419_LOUDNESS_BOOST         6
+#define TDA7419_LOUDNESS_SOFT_STEP     7
+
+#define TDA7419_VOLUME_SOFT_STEP       7
+
+#define TDA7419_SOFT_MUTE              0
+#define TDA7419_MUTE_INFLUENCE         1
+#define TDA7419_SOFT_MUTE_TIME         2
+#define TDA7419_SOFT_STEP_TIME         4
+#define TDA7419_CLK_FAST_MODE          7
+
+#define TDA7419_TREBLE_CENTER_FREQ     5
+#define TDA7419_REF_OUT_SELECT         7
+
+#define TDA7419_MIDDLE_Q_FACTOR                5
+#define TDA7419_MIDDLE_SOFT_STEP       7
+
+#define TDA7419_BASS_Q_FACTOR          5
+#define TDA7419_BASS_SOFT_STEP         7
+
+#define TDA7419_SECOND_SRC_SEL         0
+#define TDA7419_SECOND_SRC_GAIN                3
+#define TDA7419_REAR_SPKR_SRC          7
+
+#define TDA7419_SUB_CUT_OFF_FREQ       0
+#define TDA7419_MIDDLE_CENTER_FREQ     2
+#define TDA7419_BASS_CENTER_FREQ       4
+#define TDA7419_BASS_DC_MODE           6
+#define TDA7419_SMOOTHING_FILTER       7
+
+#define TDA7419_MIX_LF                 0
+#define TDA7419_MIX_RF                 1
+#define TDA7419_MIX_ENABLE             2
+#define TDA7419_SUB_ENABLE             3
+#define TDA7419_HPF_GAIN               4
+
+#define TDA7419_SA_Q_FACTOR            0
+#define TDA7419_RESET_MODE             1
+#define TDA7419_SA_SOURCE              2
+#define TDA7419_SA_RUN                 3
+#define TDA7419_RESET                  4
+#define TDA7419_CLK_SOURCE             5
+#define TDA7419_COUPLING_MODE          6
+
+struct tda7419_data {
+       struct regmap *regmap;
+};
+
+static bool tda7419_readable_reg(struct device *dev, unsigned int reg)
+{
+       return false;
+}
+
+static const struct reg_default tda7419_regmap_defaults[] = {
+       { TDA7419_MAIN_SRC_REG, 0xfe },
+       { TDA7419_LOUDNESS_REG, 0xfe },
+       { TDA7419_MUTE_CLK_REG, 0xfe },
+       { TDA7419_VOLUME_REG, 0xfe },
+       { TDA7419_TREBLE_REG, 0xfe },
+       { TDA7419_MIDDLE_REG, 0xfe },
+       { TDA7419_BASS_REG, 0xfe },
+       { TDA7419_SECOND_SRC_REG, 0xfe },
+       { TDA7419_SUB_MID_BASS_REG, 0xfe },
+       { TDA7419_MIXING_GAIN_REG, 0xfe },
+       { TDA7419_ATTENUATOR_LF_REG, 0xfe },
+       { TDA7419_ATTENUATOR_RF_REG, 0xfe },
+       { TDA7419_ATTENUATOR_LR_REG, 0xfe },
+       { TDA7419_ATTENUATOR_RR_REG, 0xfe },
+       { TDA7419_MIXING_LEVEL_REG, 0xfe },
+       { TDA7419_ATTENUATOR_SUB_REG, 0xfe },
+       { TDA7419_SA_CLK_AC_REG, 0xfe },
+       { TDA7419_TESTING_REG, 0xfe },
+};
+
+static const struct regmap_config tda7419_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = TDA7419_TESTING_REG,
+       .cache_type = REGCACHE_RBTREE,
+       .readable_reg = tda7419_readable_reg,
+       .reg_defaults = tda7419_regmap_defaults,
+       .num_reg_defaults = ARRAY_SIZE(tda7419_regmap_defaults),
+};
+
+struct tda7419_vol_control {
+       int min, max;
+       unsigned int reg, rreg, mask, thresh;
+       unsigned int invert:1;
+};
+
+static inline bool tda7419_vol_is_stereo(struct tda7419_vol_control *tvc)
+{
+       if (tvc->reg == tvc->rreg)
+               return 0;
+
+       return 1;
+}
+
+static int tda7419_vol_info(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_info *uinfo)
+{
+       struct tda7419_vol_control *tvc =
+               (struct tda7419_vol_control *)kcontrol->private_value;
+
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = tda7419_vol_is_stereo(tvc) ? 2 : 1;
+       uinfo->value.integer.min = tvc->min;
+       uinfo->value.integer.max = tvc->max;
+
+       return 0;
+}
+
+static inline int tda7419_vol_get_value(int val, unsigned int mask,
+                                       int min, int thresh,
+                                       unsigned int invert)
+{
+       val &= mask;
+       if (val < thresh) {
+               if (invert)
+                       val = 0 - val;
+       } else if (val > thresh) {
+               if (invert)
+                       val = val - thresh;
+               else
+                       val = thresh - val;
+       }
+
+       if (val < min)
+               val = min;
+
+       return val;
+}
+
+static int tda7419_vol_get(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct tda7419_vol_control *tvc =
+               (struct tda7419_vol_control *)kcontrol->private_value;
+       unsigned int reg = tvc->reg;
+       unsigned int rreg = tvc->rreg;
+       unsigned int mask = tvc->mask;
+       int min = tvc->min;
+       int thresh = tvc->thresh;
+       unsigned int invert = tvc->invert;
+       int val;
+       int ret;
+
+       ret = snd_soc_component_read(component, reg, &val);
+       if (ret < 0)
+               return ret;
+       ucontrol->value.integer.value[0] =
+               tda7419_vol_get_value(val, mask, min, thresh, invert);
+
+       if (tda7419_vol_is_stereo(tvc)) {
+               ret = snd_soc_component_read(component, rreg, &val);
+               if (ret < 0)
+                       return ret;
+               ucontrol->value.integer.value[1] =
+                       tda7419_vol_get_value(val, mask, min, thresh, invert);
+       }
+
+       return 0;
+}
+
+static inline int tda7419_vol_put_value(int val, int thresh,
+                                       unsigned int invert)
+{
+       if (val < 0) {
+               if (invert)
+                       val = abs(val);
+               else
+                       val = thresh - val;
+       } else if ((val > 0) && invert) {
+               val += thresh;
+       }
+
+       return val;
+}
+
+static int tda7419_vol_put(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component =
+               snd_kcontrol_chip(kcontrol);
+       struct tda7419_vol_control *tvc =
+               (struct tda7419_vol_control *)kcontrol->private_value;
+       unsigned int reg = tvc->reg;
+       unsigned int rreg = tvc->rreg;
+       unsigned int mask = tvc->mask;
+       int thresh = tvc->thresh;
+       unsigned int invert = tvc->invert;
+       int val;
+       int ret;
+
+       val = tda7419_vol_put_value(ucontrol->value.integer.value[0],
+                                   thresh, invert);
+       ret = snd_soc_component_update_bits(component, reg,
+                                           mask, val);
+       if (ret < 0)
+               return ret;
+
+       if (tda7419_vol_is_stereo(tvc)) {
+               val = tda7419_vol_put_value(ucontrol->value.integer.value[1],
+                                           thresh, invert);
+               ret = snd_soc_component_update_bits(component, rreg,
+                                                   mask, val);
+       }
+
+       return ret;
+}
+
+#define TDA7419_SINGLE_VALUE(xreg, xmask, xmin, xmax, xthresh, xinvert) \
+       ((unsigned long)&(struct tda7419_vol_control) \
+       {.reg = xreg, .rreg = xreg, .mask = xmask, .min = xmin, \
+        .max = xmax, .thresh = xthresh, .invert = xinvert})
+
+#define TDA7419_DOUBLE_R_VALUE(xregl, xregr, xmask, xmin, xmax, xthresh, \
+                              xinvert) \
+       ((unsigned long)&(struct tda7419_vol_control) \
+       {.reg = xregl, .rreg = xregr, .mask = xmask, .min = xmin, \
+        .max = xmax, .thresh = xthresh, .invert = xinvert})
+
+#define TDA7419_SINGLE_TLV(xname, xreg, xmask, xmin, xmax, xthresh, \
+                          xinvert, xtlv_array) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+       .name = xname, \
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+               SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+       .tlv.p = (xtlv_array), \
+       .info = tda7419_vol_info, \
+       .get = tda7419_vol_get, \
+       .put = tda7419_vol_put, \
+       .private_value = TDA7419_SINGLE_VALUE(xreg, xmask, xmin, \
+                                             xmax, xthresh, xinvert), \
+}
+
+#define TDA7419_DOUBLE_R_TLV(xname, xregl, xregr, xmask, xmin, xmax, \
+                            xthresh, xinvert, xtlv_array) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+       .name = xname, \
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+               SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+       .tlv.p = (xtlv_array), \
+       .info = tda7419_vol_info, \
+       .get = tda7419_vol_get, \
+       .put = tda7419_vol_put, \
+       .private_value = TDA7419_DOUBLE_R_VALUE(xregl, xregr, xmask, \
+                                               xmin, xmax, xthresh, \
+                                               xinvert), \
+}
+
+static const char * const enum_src_sel[] = {
+       "QD", "SE1", "SE2", "SE3", "SE", "Mute", "Mute", "Mute"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_main_src_sel,
+       TDA7419_MAIN_SRC_REG, TDA7419_MAIN_SRC_SEL, enum_src_sel);
+static const struct snd_kcontrol_new soc_mux_main_src_sel =
+       SOC_DAPM_ENUM("Main Source Select", soc_enum_main_src_sel);
+static DECLARE_TLV_DB_SCALE(tlv_src_gain, 0, 100, 0);
+static DECLARE_TLV_DB_SCALE(tlv_loudness_atten, -1500, 100, 0);
+static const char * const enum_loudness_center_freq[] = {
+       "Flat", "400 Hz", "800 Hz", "2400 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_loudness_center_freq,
+       TDA7419_LOUDNESS_REG, TDA7419_LOUDNESS_CENTER_FREQ,
+       enum_loudness_center_freq);
+static const char * const enum_mute_influence[] = {
+       "Pin and IIC", "IIC"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_mute_influence,
+       TDA7419_MUTE_CLK_REG, TDA7419_MUTE_INFLUENCE, enum_mute_influence);
+static const char * const enum_soft_mute_time[] = {
+       "0.48 ms", "0.96 ms", "123 ms", "123 ms"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_soft_mute_time,
+       TDA7419_MUTE_CLK_REG, TDA7419_SOFT_MUTE_TIME, enum_soft_mute_time);
+static const char * const enum_soft_step_time[] = {
+       "0.160 ms", "0.321 ms", "0.642 ms", "1.28 ms",
+       "2.56 ms", "5.12 ms", "10.24 ms", "20.48 ms"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_soft_step_time,
+       TDA7419_MUTE_CLK_REG, TDA7419_SOFT_STEP_TIME, enum_soft_step_time);
+static DECLARE_TLV_DB_SCALE(tlv_volume, -8000, 100, 1);
+static const char * const enum_treble_center_freq[] = {
+       "10.0 kHz", "12.5 kHz", "15.0 kHz", "17.5 kHz"};
+static DECLARE_TLV_DB_SCALE(tlv_filter, -1500, 100, 0);
+static SOC_ENUM_SINGLE_DECL(soc_enum_treble_center_freq,
+       TDA7419_TREBLE_REG, TDA7419_TREBLE_CENTER_FREQ,
+       enum_treble_center_freq);
+static const char * const enum_ref_out_select[] = {
+       "External Vref (4 V)", "Internal Vref (3.3 V)"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_ref_out_select,
+       TDA7419_TREBLE_REG, TDA7419_REF_OUT_SELECT, enum_ref_out_select);
+static const char * const enum_middle_q_factor[] = {
+       "0.5", "0.75", "1.0", "1.25"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_middle_q_factor,
+       TDA7419_MIDDLE_REG, TDA7419_MIDDLE_Q_FACTOR, enum_middle_q_factor);
+static const char * const enum_bass_q_factor[] = {
+       "1.0", "1.25", "1.5", "2.0"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bass_q_factor,
+       TDA7419_BASS_REG, TDA7419_BASS_Q_FACTOR, enum_bass_q_factor);
+static SOC_ENUM_SINGLE_DECL(soc_enum_second_src_sel,
+       TDA7419_SECOND_SRC_REG, TDA7419_SECOND_SRC_SEL, enum_src_sel);
+static const struct snd_kcontrol_new soc_mux_second_src_sel =
+       SOC_DAPM_ENUM("Second Source Select", soc_enum_second_src_sel);
+static const char * const enum_rear_spkr_src[] = {
+       "Main", "Second"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_rear_spkr_src,
+       TDA7419_SECOND_SRC_REG, TDA7419_REAR_SPKR_SRC, enum_rear_spkr_src);
+static const struct snd_kcontrol_new soc_mux_rear_spkr_src =
+       SOC_DAPM_ENUM("Rear Speaker Source", soc_enum_rear_spkr_src);
+static const char * const enum_sub_cut_off_freq[] = {
+       "Flat", "80 Hz", "120 Hz", "160 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_sub_cut_off_freq,
+       TDA7419_SUB_MID_BASS_REG, TDA7419_SUB_CUT_OFF_FREQ,
+       enum_sub_cut_off_freq);
+static const char * const enum_middle_center_freq[] = {
+       "500 Hz", "1000 Hz", "1500 Hz", "2500 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_middle_center_freq,
+       TDA7419_SUB_MID_BASS_REG, TDA7419_MIDDLE_CENTER_FREQ,
+       enum_middle_center_freq);
+static const char * const enum_bass_center_freq[] = {
+       "60 Hz", "80 Hz", "100 Hz", "200 Hz"};
+static SOC_ENUM_SINGLE_DECL(soc_enum_bass_center_freq,
+       TDA7419_SUB_MID_BASS_REG, TDA7419_BASS_CENTER_FREQ,
+       enum_bass_center_freq);
+static const char * const enum_sa_q_factor[] = {
+       "3.5", "1.75" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_sa_q_factor,
+       TDA7419_SA_CLK_AC_REG, TDA7419_SA_Q_FACTOR, enum_sa_q_factor);
+static const char * const enum_reset_mode[] = {
+       "IIC", "Auto" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_reset_mode,
+       TDA7419_SA_CLK_AC_REG, TDA7419_RESET_MODE, enum_reset_mode);
+static const char * const enum_sa_src[] = {
+       "Bass", "In Gain" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_sa_src,
+       TDA7419_SA_CLK_AC_REG, TDA7419_SA_SOURCE, enum_sa_src);
+static const char * const enum_clk_src[] = {
+       "Internal", "External" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_clk_src,
+       TDA7419_SA_CLK_AC_REG, TDA7419_CLK_SOURCE, enum_clk_src);
+static const char * const enum_coupling_mode[] = {
+       "DC Coupling (without HPF)", "AC Coupling after In Gain",
+       "DC Coupling (with HPF)", "AC Coupling after Bass" };
+static SOC_ENUM_SINGLE_DECL(soc_enum_coupling_mode,
+       TDA7419_SA_CLK_AC_REG, TDA7419_COUPLING_MODE, enum_coupling_mode);
+
+/* ASoC Controls */
+static struct snd_kcontrol_new tda7419_controls[] = {
+SOC_SINGLE_TLV("Main Source Capture Volume", TDA7419_MAIN_SRC_REG,
+              TDA7419_MAIN_SRC_GAIN, 15, 0, tlv_src_gain),
+SOC_SINGLE("Main Source AutoZero Switch", TDA7419_MAIN_SRC_REG,
+          TDA7419_MAIN_SRC_AUTOZERO, 1, 1),
+SOC_SINGLE_TLV("Loudness Playback Volume", TDA7419_LOUDNESS_REG,
+              TDA7419_LOUDNESS_ATTEN, 15, 1, tlv_loudness_atten),
+SOC_ENUM("Loudness Center Frequency", soc_enum_loudness_center_freq),
+SOC_SINGLE("Loudness High Boost Switch", TDA7419_LOUDNESS_REG,
+          TDA7419_LOUDNESS_BOOST, 1, 1),
+SOC_SINGLE("Loudness Soft Step Switch", TDA7419_LOUDNESS_REG,
+          TDA7419_LOUDNESS_SOFT_STEP, 1, 1),
+SOC_SINGLE("Soft Mute Switch", TDA7419_MUTE_CLK_REG, TDA7419_SOFT_MUTE, 1, 1),
+SOC_ENUM("Mute Influence", soc_enum_mute_influence),
+SOC_ENUM("Soft Mute Time", soc_enum_soft_mute_time),
+SOC_ENUM("Soft Step Time", soc_enum_soft_step_time),
+SOC_SINGLE("Clock Fast Mode Switch", TDA7419_MUTE_CLK_REG,
+          TDA7419_CLK_FAST_MODE, 1, 1),
+TDA7419_SINGLE_TLV("Master Playback Volume", TDA7419_VOLUME_REG,
+                  0x7f, -80, 15, 0x10, 0, tlv_volume),
+SOC_SINGLE("Volume Soft Step Switch", TDA7419_VOLUME_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Treble Playback Volume", TDA7419_TREBLE_REG,
+                  0x1f, -15, 15, 0x10, 1, tlv_filter),
+SOC_ENUM("Treble Center Frequency", soc_enum_treble_center_freq),
+SOC_ENUM("Reference Output Select", soc_enum_ref_out_select),
+TDA7419_SINGLE_TLV("Middle Playback Volume", TDA7419_MIDDLE_REG,
+                  0x1f, -15, 15, 0x10, 1, tlv_filter),
+SOC_ENUM("Middle Q Factor", soc_enum_middle_q_factor),
+SOC_SINGLE("Middle Soft Step Switch", TDA7419_MIDDLE_REG,
+          TDA7419_MIDDLE_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Bass Playback Volume", TDA7419_BASS_REG,
+                  0x1f, -15, 15, 0x10, 1, tlv_filter),
+SOC_ENUM("Bass Q Factor", soc_enum_bass_q_factor),
+SOC_SINGLE("Bass Soft Step Switch", TDA7419_BASS_REG,
+          TDA7419_BASS_SOFT_STEP, 1, 1),
+SOC_SINGLE_TLV("Second Source Capture Volume", TDA7419_SECOND_SRC_REG,
+              TDA7419_SECOND_SRC_GAIN, 15, 0, tlv_src_gain),
+SOC_ENUM("Subwoofer Cut-off Frequency", soc_enum_sub_cut_off_freq),
+SOC_ENUM("Middle Center Frequency", soc_enum_middle_center_freq),
+SOC_ENUM("Bass Center Frequency", soc_enum_bass_center_freq),
+SOC_SINGLE("Bass DC Mode Switch", TDA7419_SUB_MID_BASS_REG,
+          TDA7419_BASS_DC_MODE, 1, 1),
+SOC_SINGLE("Smoothing Filter Switch", TDA7419_SUB_MID_BASS_REG,
+          TDA7419_SMOOTHING_FILTER, 1, 1),
+TDA7419_DOUBLE_R_TLV("Front Speaker Playback Volume", TDA7419_ATTENUATOR_LF_REG,
+                    TDA7419_ATTENUATOR_RF_REG, 0x7f, -80, 15, 0x10, 0,
+                    tlv_volume),
+SOC_SINGLE("Left Front Soft Step Switch", TDA7419_ATTENUATOR_LF_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+SOC_SINGLE("Right Front Soft Step Switch", TDA7419_ATTENUATOR_RF_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_DOUBLE_R_TLV("Rear Speaker Playback Volume", TDA7419_ATTENUATOR_LR_REG,
+                    TDA7419_ATTENUATOR_RR_REG, 0x7f, -80, 15, 0x10, 0,
+                    tlv_volume),
+SOC_SINGLE("Left Rear Soft Step Switch", TDA7419_ATTENUATOR_LR_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+SOC_SINGLE("Right Rear Soft Step Switch", TDA7419_ATTENUATOR_RR_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Mixing Capture Volume", TDA7419_MIXING_LEVEL_REG,
+                  0x7f, -80, 15, 0x10, 0, tlv_volume),
+SOC_SINGLE("Mixing Level Soft Step Switch", TDA7419_MIXING_LEVEL_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+TDA7419_SINGLE_TLV("Subwoofer Playback Volume", TDA7419_ATTENUATOR_SUB_REG,
+                  0x7f, -80, 15, 0x10, 0, tlv_volume),
+SOC_SINGLE("Subwoofer Soft Step Switch", TDA7419_ATTENUATOR_SUB_REG,
+          TDA7419_VOLUME_SOFT_STEP, 1, 1),
+SOC_ENUM("Spectrum Analyzer Q Factor", soc_enum_sa_q_factor),
+SOC_ENUM("Spectrum Analyzer Reset Mode", soc_enum_reset_mode),
+SOC_ENUM("Spectrum Analyzer Source", soc_enum_sa_src),
+SOC_SINGLE("Spectrum Analyzer Run Switch", TDA7419_SA_CLK_AC_REG,
+          TDA7419_SA_RUN, 1, 1),
+SOC_SINGLE("Spectrum Analyzer Reset Switch", TDA7419_SA_CLK_AC_REG,
+          TDA7419_RESET, 1, 1),
+SOC_ENUM("Clock Source", soc_enum_clk_src),
+SOC_ENUM("Coupling Mode", soc_enum_coupling_mode),
+};
+
+static const struct snd_kcontrol_new soc_mixer_lf_output_controls[] = {
+       SOC_DAPM_SINGLE("Mix to LF Speaker Switch",
+                       TDA7419_MIXING_GAIN_REG,
+                       TDA7419_MIX_LF, 1, 1),
+};
+
+static const struct snd_kcontrol_new soc_mixer_rf_output_controls[] = {
+       SOC_DAPM_SINGLE("Mix to RF Speaker Switch",
+                       TDA7419_MIXING_GAIN_REG,
+                       TDA7419_MIX_RF, 1, 1),
+};
+
+static const struct snd_kcontrol_new soc_mix_enable_switch_controls[] = {
+       SOC_DAPM_SINGLE("Switch", TDA7419_MIXING_GAIN_REG,
+                       TDA7419_MIX_ENABLE, 1, 1),
+};
+
+static const struct snd_kcontrol_new soc_sub_enable_switch_controls[] = {
+       SOC_DAPM_SINGLE("Switch", TDA7419_MIXING_GAIN_REG,
+                       TDA7419_MIX_ENABLE, 1, 1),
+};
+
+static const struct snd_soc_dapm_widget tda7419_dapm_widgets[] = {
+       SND_SOC_DAPM_INPUT("SE3L"),
+       SND_SOC_DAPM_INPUT("SE3R"),
+       SND_SOC_DAPM_INPUT("SE2L"),
+       SND_SOC_DAPM_INPUT("SE2R"),
+       SND_SOC_DAPM_INPUT("SE1L"),
+       SND_SOC_DAPM_INPUT("SE1R"),
+       SND_SOC_DAPM_INPUT("DIFFL"),
+       SND_SOC_DAPM_INPUT("DIFFR"),
+       SND_SOC_DAPM_INPUT("MIX"),
+
+       SND_SOC_DAPM_MUX("Main Source Select", SND_SOC_NOPM,
+                        0, 0, &soc_mux_main_src_sel),
+       SND_SOC_DAPM_MUX("Second Source Select", SND_SOC_NOPM,
+                        0, 0, &soc_mux_second_src_sel),
+       SND_SOC_DAPM_MUX("Rear Speaker Source", SND_SOC_NOPM,
+                        0, 0, &soc_mux_rear_spkr_src),
+
+       SND_SOC_DAPM_SWITCH("Mix Enable", SND_SOC_NOPM,
+                       0, 0, &soc_mix_enable_switch_controls[0]),
+       SND_SOC_DAPM_MIXER_NAMED_CTL("LF Output Mixer", SND_SOC_NOPM,
+                       0, 0, &soc_mixer_lf_output_controls[0],
+                       ARRAY_SIZE(soc_mixer_lf_output_controls)),
+       SND_SOC_DAPM_MIXER_NAMED_CTL("RF Output Mixer", SND_SOC_NOPM,
+                       0, 0, &soc_mixer_rf_output_controls[0],
+                       ARRAY_SIZE(soc_mixer_rf_output_controls)),
+
+       SND_SOC_DAPM_SWITCH("Subwoofer Enable",
+                       SND_SOC_NOPM, 0, 0,
+                       &soc_sub_enable_switch_controls[0]),
+
+       SND_SOC_DAPM_OUTPUT("OUTLF"),
+       SND_SOC_DAPM_OUTPUT("OUTRF"),
+       SND_SOC_DAPM_OUTPUT("OUTLR"),
+       SND_SOC_DAPM_OUTPUT("OUTRR"),
+       SND_SOC_DAPM_OUTPUT("OUTSW"),
+};
+
+static const struct snd_soc_dapm_route tda7419_dapm_routes[] = {
+       {"Main Source Select", "SE3", "SE3L"},
+       {"Main Source Select", "SE3", "SE3R"},
+       {"Main Source Select", "SE2", "SE2L"},
+       {"Main Source Select", "SE2", "SE2R"},
+       {"Main Source Select", "SE1", "SE1L"},
+       {"Main Source Select", "SE1", "SE1R"},
+       {"Main Source Select", "SE", "DIFFL"},
+       {"Main Source Select", "SE", "DIFFR"},
+       {"Main Source Select", "QD", "DIFFL"},
+       {"Main Source Select", "QD", "DIFFR"},
+
+       {"Second Source Select", "SE3", "SE3L"},
+       {"Second Source Select", "SE3", "SE3R"},
+       {"Second Source Select", "SE2", "SE2L"},
+       {"Second Source Select", "SE2", "SE2R"},
+       {"Second Source Select", "SE1", "SE1L"},
+       {"Second Source Select", "SE1", "SE1R"},
+       {"Second Source Select", "SE", "DIFFL"},
+       {"Second Source Select", "SE", "DIFFR"},
+       {"Second Source Select", "QD", "DIFFL"},
+       {"Second Source Select", "QD", "DIFFR"},
+
+       {"Rear Speaker Source", "Main", "Main Source Select"},
+       {"Rear Speaker Source", "Second", "Second Source Select"},
+
+       {"Subwoofer Enable", "Switch", "Main Source Select"},
+
+       {"Mix Enable", "Switch", "MIX"},
+
+       {"LF Output Mixer", NULL, "Main Source Select"},
+       {"LF Output Mixer", "Mix to LF Speaker Switch", "Mix Enable"},
+       {"RF Output Mixer", NULL, "Main Source Select"},
+       {"RF Output Mixer", "Mix to RF Speaker Switch", "Mix Enable"},
+
+       {"OUTLF", NULL, "LF Output Mixer"},
+       {"OUTRF", NULL, "RF Output Mixer"},
+       {"OUTLR", NULL, "Rear Speaker Source"},
+       {"OUTRR", NULL, "Rear Speaker Source"},
+       {"OUTSW", NULL, "Subwoofer Enable"},
+};
+
+static const struct snd_soc_component_driver tda7419_component_driver = {
+       .name                   = "tda7419",
+       .controls               = tda7419_controls,
+       .num_controls           = ARRAY_SIZE(tda7419_controls),
+       .dapm_widgets           = tda7419_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tda7419_dapm_widgets),
+       .dapm_routes            = tda7419_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(tda7419_dapm_routes),
+};
+
+static int tda7419_probe(struct i2c_client *i2c,
+                        const struct i2c_device_id *id)
+{
+       struct tda7419_data *tda7419;
+       int i, ret;
+
+       tda7419 = devm_kzalloc(&i2c->dev,
+                              sizeof(struct tda7419_data),
+                              GFP_KERNEL);
+       if (tda7419 == NULL)
+               return -ENOMEM;
+
+       i2c_set_clientdata(i2c, tda7419);
+
+       tda7419->regmap = devm_regmap_init_i2c(i2c, &tda7419_regmap_config);
+       if (IS_ERR(tda7419->regmap)) {
+               ret = PTR_ERR(tda7419->regmap);
+               dev_err(&i2c->dev, "error initializing regmap: %d\n",
+                               ret);
+               return ret;
+       }
+
+       /*
+        * Reset registers to power-on defaults. The part does not provide a
+        * soft-reset function and the registers are not readable. This ensures
+        * that the cache matches register contents even if the registers have
+        * been previously initialized and not power cycled before probe.
+        */
+       for (i = 0; i < ARRAY_SIZE(tda7419_regmap_defaults); i++)
+               regmap_write(tda7419->regmap,
+                            tda7419_regmap_defaults[i].reg,
+                            tda7419_regmap_defaults[i].def);
+
+       ret = devm_snd_soc_register_component(&i2c->dev,
+               &tda7419_component_driver, NULL, 0);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "error registering component: %d\n",
+                               ret);
+       }
+
+       return ret;
+}
+
+static const struct i2c_device_id tda7419_i2c_id[] = {
+       { "tda7419", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tda7419_i2c_id);
+
+static const struct of_device_id tda7419_of_match[] = {
+       { .compatible = "st,tda7419" },
+       { },
+};
+
+static struct i2c_driver tda7419_driver = {
+       .driver = {
+               .name   = "tda7419",
+               .of_match_table = tda7419_of_match,
+       },
+       .probe          = tda7419_probe,
+       .id_table       = tda7419_i2c_id,
+};
+
+module_i2c_driver(tda7419_driver);
+
+MODULE_AUTHOR("Matt Porter <mporter@konsulko.com>");
+MODULE_DESCRIPTION("TDA7419 audio processor driver");
+MODULE_LICENSE("GPL");
index e7ca764b57295fef26ecf6d3d113b594ef578cb9..6d213c6d3920749d9f46ea83c0068d00e4bafe46 100644 (file)
@@ -30,8 +30,8 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tfa9879_priv *tfa9879 = snd_soc_component_get_drvdata(component);
        int fs;
        int i2s_set = 0;
 
@@ -88,11 +88,11 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (tfa9879->lsb_justified)
-               snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+               snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
                                    TFA9879_I2S_SET_MASK,
                                    i2s_set << TFA9879_I2S_SET_SHIFT);
 
-       snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+       snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
                            TFA9879_I2S_FS_MASK,
                            fs << TFA9879_I2S_FS_SHIFT);
        return 0;
@@ -100,9 +100,9 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
 
 static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       snd_soc_update_bits(codec, TFA9879_MISC_CONTROL,
+       snd_soc_component_update_bits(component, TFA9879_MISC_CONTROL,
                            TFA9879_S_MUTE_MASK,
                            !!mute << TFA9879_S_MUTE_SHIFT);
 
@@ -111,8 +111,8 @@ static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute)
 
 static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tfa9879_priv *tfa9879 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tfa9879_priv *tfa9879 = snd_soc_component_get_drvdata(component);
        int i2s_set;
        int sck_pol;
 
@@ -151,10 +151,10 @@ static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+       snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
                            TFA9879_SCK_POL_MASK,
                            sck_pol << TFA9879_SCK_POL_SHIFT);
-       snd_soc_update_bits(codec, TFA9879_SERIAL_INTERFACE_1,
+       snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
                            TFA9879_I2S_SET_MASK,
                            i2s_set << TFA9879_I2S_SET_SHIFT);
        return 0;
@@ -230,15 +230,17 @@ static const struct snd_soc_dapm_route tfa9879_dapm_routes[] = {
        { "DAC", NULL, "POWER" },
 };
 
-static const struct snd_soc_codec_driver tfa9879_codec = {
-       .component_driver = {
-               .controls               = tfa9879_controls,
-               .num_controls           = ARRAY_SIZE(tfa9879_controls),
-               .dapm_widgets           = tfa9879_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tfa9879_dapm_widgets),
-               .dapm_routes            = tfa9879_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(tfa9879_dapm_routes),
-       },
+static const struct snd_soc_component_driver tfa9879_component = {
+       .controls               = tfa9879_controls,
+       .num_controls           = ARRAY_SIZE(tfa9879_controls),
+       .dapm_widgets           = tfa9879_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tfa9879_dapm_widgets),
+       .dapm_routes            = tfa9879_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(tfa9879_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config tfa9879_regmap = {
@@ -295,17 +297,10 @@ static int tfa9879_i2c_probe(struct i2c_client *i2c,
                regmap_write(tfa9879->regmap,
                             tfa9879_regs[i].reg, tfa9879_regs[i].def);
 
-       return snd_soc_register_codec(&i2c->dev, &tfa9879_codec,
+       return devm_snd_soc_register_component(&i2c->dev, &tfa9879_component,
                                      &tfa9879_dai, 1);
 }
 
-static int tfa9879_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id tfa9879_i2c_id[] = {
        { "tfa9879", 0 },
        { }
@@ -324,7 +319,6 @@ static struct i2c_driver tfa9879_i2c_driver = {
                .of_match_table = tfa9879_of_match,
        },
        .probe = tfa9879_i2c_probe,
-       .remove = tfa9879_i2c_remove,
        .id_table = tfa9879_i2c_id,
 };
 
index 78a94af65518596ae3c25e36602cd946155bb0a2..1d7c117316fb4e75cf061cd9a2b2eee271495b57 100644 (file)
@@ -31,12 +31,6 @@ static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
        return tlv320aic23_probe(&i2c->dev, regmap);
 }
 
-static int tlv320aic23_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-       return 0;
-}
-
 static const struct i2c_device_id tlv320aic23_id[] = {
        {"tlv320aic23", 0},
        {}
@@ -56,7 +50,6 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
                   .of_match_table = of_match_ptr(tlv320aic23_of_match),
                   },
        .probe = tlv320aic23_i2c_probe,
-       .remove = tlv320aic23_i2c_remove,
        .id_table = tlv320aic23_id,
 };
 
index f801ae05165876300a234d5c8d81194e1275b308..d8c9ec1e92014991b1ea7194acb5c4ac9310da8d 100644 (file)
@@ -34,18 +34,11 @@ static int aic23_spi_probe(struct spi_device *spi)
        return tlv320aic23_probe(&spi->dev, regmap);
 }
 
-static int aic23_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver aic23_spi = {
        .driver = {
                .name = "tlv320aic23",
        },
        .probe = aic23_spi_probe,
-       .remove = aic23_spi_remove,
 };
 
 module_spi_driver(aic23_spi);
index 74909211c608849e8eb81318db0f97292d301e61..47480cb4d078943e58137faea245ddbee4c5d102 100644 (file)
@@ -82,7 +82,7 @@ static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
 static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        u16 val, reg;
 
        val = (ucontrol->value.integer.value[0] & 0x07);
@@ -96,8 +96,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
        */
        val = (val >= 4) ? 4  : (3 - val);
 
-       reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
-       snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
+       reg = snd_soc_component_read32(component, TLV320AIC23_ANLG) & (~0x1C0);
+       snd_soc_component_write(component, TLV320AIC23_ANLG, reg | (val << 6));
 
        return 0;
 }
@@ -105,10 +105,10 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
 static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        u16 val;
 
-       val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
+       val = snd_soc_component_read32(component, TLV320AIC23_ANLG) & (0x1C0);
        val = val >> 6;
        val = (val >= 4) ? 4  : (3 -  val);
        ucontrol->value.integer.value[0] = val;
@@ -296,10 +296,10 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac)
 }
 
 #ifdef DEBUG
-static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
+static void get_current_sample_rates(struct snd_soc_component *component, int mclk,
                u32 *sample_rate_adc, u32 *sample_rate_dac)
 {
-       int src = snd_soc_read(codec, TLV320AIC23_SRATE);
+       int src = snd_soc_component_read32(component, TLV320AIC23_SRATE);
        int sr = (src >> 2) & 0x0f;
        int val = (mclk / bosr_usb_divisor_table[src & 3]);
        int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
@@ -313,7 +313,7 @@ static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
 }
 #endif
 
-static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
+static int set_sample_rate_control(struct snd_soc_component *component, int mclk,
                u32 sample_rate_adc, u32 sample_rate_dac)
 {
        /* Search for the right sample rate */
@@ -323,11 +323,11 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
                                __func__, sample_rate_adc, sample_rate_dac);
                return -EINVAL;
        }
-       snd_soc_write(codec, TLV320AIC23_SRATE, data);
+       snd_soc_component_write(component, TLV320AIC23_SRATE, data);
 #ifdef DEBUG
        {
                u32 adc, dac;
-               get_current_sample_rates(codec, mclk, &adc, &dac);
+               get_current_sample_rates(component, mclk, &adc, &dac);
                printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
                        adc, dac, data);
        }
@@ -339,10 +339,10 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 iface_reg;
        int ret;
-       struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+       struct aic23 *aic23 = snd_soc_component_get_drvdata(component);
        u32 sample_rate_adc = aic23->requested_adc;
        u32 sample_rate_dac = aic23->requested_dac;
        u32 sample_rate = params_rate(params);
@@ -356,12 +356,12 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
                if (!sample_rate_dac)
                        sample_rate_dac = sample_rate;
        }
-       ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
+       ret = set_sample_rate_control(component, aic23->mclk, sample_rate_adc,
                        sample_rate_dac);
        if (ret < 0)
                return ret;
 
-       iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
+       iface_reg = snd_soc_component_read32(component, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
 
        switch (params_width(params)) {
        case 16:
@@ -376,7 +376,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
                iface_reg |= (0x03 << 2);
                break;
        }
-       snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
+       snd_soc_component_write(component, TLV320AIC23_DIGT_FMT, iface_reg);
 
        return 0;
 }
@@ -384,10 +384,10 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
 static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        /* set active */
-       snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
+       snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x0001);
 
        return 0;
 }
@@ -395,13 +395,13 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
 static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct aic23 *aic23 = snd_soc_component_get_drvdata(component);
 
        /* deactivate */
-       if (!snd_soc_codec_is_active(codec)) {
+       if (!snd_soc_component_is_active(component)) {
                udelay(50);
-               snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
+               snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x0);
        }
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                aic23->requested_dac = 0;
@@ -411,17 +411,17 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
 
 static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u16 reg;
 
-       reg = snd_soc_read(codec, TLV320AIC23_DIGT);
+       reg = snd_soc_component_read32(component, TLV320AIC23_DIGT);
        if (mute)
                reg |= TLV320AIC23_DACM_MUTE;
 
        else
                reg &= ~TLV320AIC23_DACM_MUTE;
 
-       snd_soc_write(codec, TLV320AIC23_DIGT, reg);
+       snd_soc_component_write(component, TLV320AIC23_DIGT, reg);
 
        return 0;
 }
@@ -429,10 +429,10 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
 static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
                                   unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 iface_reg;
 
-       iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
+       iface_reg = snd_soc_component_read32(component, TLV320AIC23_DIGT_FMT) & (~0x03);
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -468,7 +468,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
        }
 
-       snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
+       snd_soc_component_write(component, TLV320AIC23_DIGT_FMT, iface_reg);
 
        return 0;
 }
@@ -481,29 +481,29 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
+static int tlv320aic23_set_bias_level(struct snd_soc_component *component,
                                      enum snd_soc_bias_level level)
 {
-       u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f;
+       u16 reg = snd_soc_component_read32(component, TLV320AIC23_PWR) & 0x17f;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                /* vref/mid, osc on, dac unmute */
                reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
                        TLV320AIC23_DAC_OFF);
-               snd_soc_write(codec, TLV320AIC23_PWR, reg);
+               snd_soc_component_write(component, TLV320AIC23_PWR, reg);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
                /* everything off except vref/vmid, */
-               snd_soc_write(codec, TLV320AIC23_PWR,
+               snd_soc_component_write(component, TLV320AIC23_PWR,
                              reg | TLV320AIC23_CLK_OFF);
                break;
        case SND_SOC_BIAS_OFF:
                /* everything off, dac mute, inactive */
-               snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
-               snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff);
+               snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x0);
+               snd_soc_component_write(component, TLV320AIC23_PWR, 0x1ff);
                break;
        }
        return 0;
@@ -539,58 +539,59 @@ static struct snd_soc_dai_driver tlv320aic23_dai = {
        .ops = &tlv320aic23_dai_ops,
 };
 
-static int tlv320aic23_resume(struct snd_soc_codec *codec)
+static int tlv320aic23_resume(struct snd_soc_component *component)
 {
-       struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+       struct aic23 *aic23 = snd_soc_component_get_drvdata(component);
        regcache_mark_dirty(aic23->regmap);
        regcache_sync(aic23->regmap);
 
        return 0;
 }
 
-static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
+static int tlv320aic23_component_probe(struct snd_soc_component *component)
 {
        /* Reset codec */
-       snd_soc_write(codec, TLV320AIC23_RESET, 0);
+       snd_soc_component_write(component, TLV320AIC23_RESET, 0);
 
-       snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
+       snd_soc_component_write(component, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
 
        /* Unmute input */
-       snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
+       snd_soc_component_update_bits(component, TLV320AIC23_LINVOL,
                            TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
 
-       snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
+       snd_soc_component_update_bits(component, TLV320AIC23_RINVOL,
                            TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
 
-       snd_soc_update_bits(codec, TLV320AIC23_ANLG,
+       snd_soc_component_update_bits(component, TLV320AIC23_ANLG,
                            TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
                            0);
 
        /* Default output volume */
-       snd_soc_write(codec, TLV320AIC23_LCHNVOL,
+       snd_soc_component_write(component, TLV320AIC23_LCHNVOL,
                      TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
-       snd_soc_write(codec, TLV320AIC23_RCHNVOL,
+       snd_soc_component_write(component, TLV320AIC23_RCHNVOL,
                      TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
 
-       snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
+       snd_soc_component_write(component, TLV320AIC23_ACTIVE, 0x1);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
-       .probe = tlv320aic23_codec_probe,
-       .resume = tlv320aic23_resume,
-       .set_bias_level = tlv320aic23_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = tlv320aic23_snd_controls,
-               .num_controls           = ARRAY_SIZE(tlv320aic23_snd_controls),
-               .dapm_widgets           = tlv320aic23_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tlv320aic23_dapm_widgets),
-               .dapm_routes            = tlv320aic23_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(tlv320aic23_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_tlv320aic23 = {
+       .probe                  = tlv320aic23_component_probe,
+       .resume                 = tlv320aic23_resume,
+       .set_bias_level         = tlv320aic23_set_bias_level,
+       .controls               = tlv320aic23_snd_controls,
+       .num_controls           = ARRAY_SIZE(tlv320aic23_snd_controls),
+       .dapm_widgets           = tlv320aic23_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tlv320aic23_dapm_widgets),
+       .dapm_routes            = tlv320aic23_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(tlv320aic23_intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
@@ -608,7 +609,8 @@ int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
 
        dev_set_drvdata(dev, aic23);
 
-       return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
+       return devm_snd_soc_register_component(dev,
+                                     &soc_component_dev_tlv320aic23,
                                      &tlv320aic23_dai, 1);
 }
 EXPORT_SYMBOL(tlv320aic23_probe);
index 89421caaeb707709a3ee6a9c4876f71677cdd1d7..b91b8d5f1ba36b2ca0d52469de8570ef51b945fb 100644 (file)
@@ -30,7 +30,7 @@ MODULE_LICENSE("GPL");
 struct aic26 {
        struct spi_device *spi;
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        int master;
        int datfm;
        int mclk;
@@ -64,8 +64,8 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
                           struct snd_pcm_hw_params *params,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
        int fsref, divisor, wlen, pval, jval, dval, qval;
        u16 reg;
 
@@ -112,20 +112,20 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
        dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
        qval = 0;
        reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
-       snd_soc_write(codec, AIC26_REG_PLL_PROG1, reg);
+       snd_soc_component_write(component, AIC26_REG_PLL_PROG1, reg);
        reg = dval << 2;
-       snd_soc_write(codec, AIC26_REG_PLL_PROG2, reg);
+       snd_soc_component_write(component, AIC26_REG_PLL_PROG2, reg);
 
        /* Audio Control 3 (master mode, fsref rate) */
        if (aic26->master)
                reg = 0x0800;
        if (fsref == 48000)
                reg = 0x2000;
-       snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL3, 0xf800, reg);
+       snd_soc_component_update_bits(component, AIC26_REG_AUDIO_CTRL3, 0xf800, reg);
 
        /* Audio Control 1 (FSref divisor) */
        reg = wlen | aic26->datfm | (divisor << 3) | divisor;
-       snd_soc_update_bits(codec, AIC26_REG_AUDIO_CTRL1, 0xfff, reg);
+       snd_soc_component_update_bits(component, AIC26_REG_AUDIO_CTRL1, 0xfff, reg);
 
        return 0;
 }
@@ -135,8 +135,8 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
  */
 static int aic26_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
        u16 reg;
 
        dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
@@ -146,7 +146,7 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
                reg = 0x8080;
        else
                reg = 0;
-       snd_soc_update_bits(codec, AIC26_REG_DAC_GAIN, 0x8000, reg);
+       snd_soc_component_update_bits(component, AIC26_REG_DAC_GAIN, 0x8000, reg);
 
        return 0;
 }
@@ -154,8 +154,8 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
 static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
                            int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
 
        dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
                " freq=%i, dir=%i)\n",
@@ -171,8 +171,8 @@ static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
 
 static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic26 *aic26 = snd_soc_component_get_drvdata(component);
 
        dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
                codec_dai, fmt);
@@ -265,7 +265,7 @@ static ssize_t aic26_keyclick_show(struct device *dev,
        struct aic26 *aic26 = dev_get_drvdata(dev);
        int val, amp, freq, len;
 
-       val = snd_soc_read(aic26->codec, AIC26_REG_AUDIO_CTRL2);
+       val = snd_soc_component_read32(aic26->component, AIC26_REG_AUDIO_CTRL2);
        amp = (val >> 12) & 0x7;
        freq = (125 << ((val >> 8) & 0x7)) >> 1;
        len = 2 * (1 + ((val >> 4) & 0xf));
@@ -280,7 +280,7 @@ static ssize_t aic26_keyclick_set(struct device *dev,
 {
        struct aic26 *aic26 = dev_get_drvdata(dev);
 
-       snd_soc_update_bits(aic26->codec, AIC26_REG_AUDIO_CTRL2,
+       snd_soc_component_update_bits(aic26->component, AIC26_REG_AUDIO_CTRL2,
                            0x8000, 0x800);
 
        return count;
@@ -291,44 +291,46 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
 /* ---------------------------------------------------------------------
  * SoC CODEC portion of driver: probe and release routines
  */
-static int aic26_probe(struct snd_soc_codec *codec)
+static int aic26_probe(struct snd_soc_component *component)
 {
-       struct aic26 *aic26 = dev_get_drvdata(codec->dev);
+       struct aic26 *aic26 = dev_get_drvdata(component->dev);
        int ret, reg;
 
-       aic26->codec = codec;
+       aic26->component = component;
 
        /* Reset the codec to power on defaults */
-       snd_soc_write(codec, AIC26_REG_RESET, 0xBB00);
+       snd_soc_component_write(component, AIC26_REG_RESET, 0xBB00);
 
        /* Power up CODEC */
-       snd_soc_write(codec, AIC26_REG_POWER_CTRL, 0);
+       snd_soc_component_write(component, AIC26_REG_POWER_CTRL, 0);
 
        /* Audio Control 3 (master mode, fsref rate) */
-       reg = snd_soc_read(codec, AIC26_REG_AUDIO_CTRL3);
+       reg = snd_soc_component_read32(component, AIC26_REG_AUDIO_CTRL3);
        reg &= ~0xf800;
        reg |= 0x0800; /* set master mode */
-       snd_soc_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
+       snd_soc_component_write(component, AIC26_REG_AUDIO_CTRL3, reg);
 
        /* Register the sysfs files for debugging */
        /* Create SysFS files */
-       ret = device_create_file(codec->dev, &dev_attr_keyclick);
+       ret = device_create_file(component->dev, &dev_attr_keyclick);
        if (ret)
-               dev_info(codec->dev, "error creating sysfs files\n");
+               dev_info(component->dev, "error creating sysfs files\n");
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver aic26_soc_codec_dev = {
-       .probe = aic26_probe,
-       .component_driver = {
-               .controls               = aic26_snd_controls,
-               .num_controls           = ARRAY_SIZE(aic26_snd_controls),
-               .dapm_widgets           = tlv320aic26_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(tlv320aic26_dapm_widgets),
-               .dapm_routes            = tlv320aic26_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(tlv320aic26_dapm_routes),
-       },
+static const struct snd_soc_component_driver aic26_soc_component_dev = {
+       .probe                  = aic26_probe,
+       .controls               = aic26_snd_controls,
+       .num_controls           = ARRAY_SIZE(aic26_snd_controls),
+       .dapm_widgets           = tlv320aic26_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tlv320aic26_dapm_widgets),
+       .dapm_routes            = tlv320aic26_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(tlv320aic26_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config aic26_regmap = {
@@ -361,23 +363,16 @@ static int aic26_spi_probe(struct spi_device *spi)
        dev_set_drvdata(&spi->dev, aic26);
        aic26->master = 1;
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &aic26_soc_codec_dev, &aic26_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &aic26_soc_component_dev, &aic26_dai, 1);
        return ret;
 }
 
-static int aic26_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver aic26_spi = {
        .driver = {
                .name = "tlv320aic26-codec",
        },
        .probe = aic26_spi_probe,
-       .remove = aic26_spi_remove,
 };
 
 module_spi_driver(aic26_spi);
index 858cb8be445f7c4b06a438ac0d8b603f80879d45..bf92d36b8f8ab06ee1f3559981c1c9d510cb8129 100644 (file)
@@ -153,7 +153,7 @@ struct aic31xx_disable_nb {
 };
 
 struct aic31xx_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        u8 i2c_regs_status;
        struct device *dev;
        struct regmap *regmap;
@@ -166,6 +166,7 @@ struct aic31xx_priv {
        unsigned int sysclk;
        u8 p_div;
        int rate_div_line;
+       bool master_dapm_route_applied;
 };
 
 struct aic31xx_rate_divs {
@@ -348,8 +349,8 @@ static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
 static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
                                    struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        unsigned int reg = AIC31XX_DACFLAG1;
        unsigned int mask;
 
@@ -377,7 +378,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
                reg = AIC31XX_ADCFLAG;
                break;
        default:
-               dev_err(codec->dev, "Unknown widget '%s' calling %s\n",
+               dev_err(component->dev, "Unknown widget '%s' calling %s\n",
                        w->name, __func__);
                return -EINVAL;
        }
@@ -388,7 +389,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_POST_PMD:
                return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
        default:
-               dev_dbg(codec->dev,
+               dev_dbg(component->dev,
                        "Unhandled dapm widget event %d from %s\n",
                        event, w->name);
        }
@@ -444,30 +445,30 @@ static const struct snd_kcontrol_new aic31xx_dapm_spr_switch =
 static int mic_bias_event(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* change mic bias voltage to user defined */
-               snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+               snd_soc_component_update_bits(component, AIC31XX_MICBIAS,
                                    AIC31XX_MICBIAS_MASK,
                                    aic31xx->micbias_vg <<
                                    AIC31XX_MICBIAS_SHIFT);
-               dev_dbg(codec->dev, "%s: turned on\n", __func__);
+               dev_dbg(component->dev, "%s: turned on\n", __func__);
                break;
        case SND_SOC_DAPM_PRE_PMD:
                /* turn mic bias off */
-               snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+               snd_soc_component_update_bits(component, AIC31XX_MICBIAS,
                                    AIC31XX_MICBIAS_MASK, 0);
-               dev_dbg(codec->dev, "%s: turned off\n", __func__);
+               dev_dbg(component->dev, "%s: turned off\n", __func__);
                break;
        }
        return 0;
 }
 
 static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = {
-       SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_IN("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0),
 
        SND_SOC_DAPM_MUX("DAC Left Input",
                         SND_SOC_NOPM, 0, 0, &ldac_in_control),
@@ -500,6 +501,10 @@ static const struct snd_soc_dapm_widget common31xx_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event,
                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
+       /* Keep BCLK/WCLK enabled even if DAC/ADC is powered down */
+       SND_SOC_DAPM_SUPPLY("Activate I2S clocks", AIC31XX_IFACE2, 2, 0,
+                           NULL, 0),
+
        /* Outputs */
        SND_SOC_DAPM_OUTPUT("HPL"),
        SND_SOC_DAPM_OUTPUT("HPR"),
@@ -552,6 +557,8 @@ static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
        SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
                           aic31xx_right_output_switches,
                           ARRAY_SIZE(aic31xx_right_output_switches)),
+
+       SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
 };
 
 static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = {
@@ -583,12 +590,12 @@ static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = {
 static const struct snd_soc_dapm_route
 common31xx_audio_map[] = {
        /* DAC Input Routing */
-       {"DAC Left Input", "Left Data", "DAC IN"},
-       {"DAC Left Input", "Right Data", "DAC IN"},
-       {"DAC Left Input", "Mono", "DAC IN"},
-       {"DAC Right Input", "Left Data", "DAC IN"},
-       {"DAC Right Input", "Right Data", "DAC IN"},
-       {"DAC Right Input", "Mono", "DAC IN"},
+       {"DAC Left Input", "Left Data", "AIF IN"},
+       {"DAC Left Input", "Right Data", "AIF IN"},
+       {"DAC Left Input", "Mono", "AIF IN"},
+       {"DAC Right Input", "Left Data", "AIF IN"},
+       {"DAC Right Input", "Right Data", "AIF IN"},
+       {"DAC Right Input", "Mono", "AIF IN"},
        {"DAC Left", NULL, "DAC Left Input"},
        {"DAC Right", NULL, "DAC Right Input"},
 
@@ -639,6 +646,8 @@ aic31xx_audio_map[] = {
 
        {"ADC", NULL, "MIC_GAIN_CTL"},
 
+       {"AIF OUT", NULL, "ADC"},
+
        /* Left Output */
        {"Output Left", "From Left DAC", "DAC Left"},
        {"Output Left", "From MIC1LP", "MIC1LP"},
@@ -670,34 +679,61 @@ aic310x_audio_map[] = {
        {"SPK", NULL, "SPK ClassD"},
 };
 
-static int aic31xx_add_controls(struct snd_soc_codec *codec)
+/*
+ * Always connected DAPM routes for codec clock master modes.
+ * If the codec is the master on the I2S bus, we need to power up components
+ * to have valid DAC_CLK.
+ *
+ * In order to have the I2S clocks on the bus either the DACs/ADC need to be
+ * enabled, or the P0/R29/D2 (Keep bclk/wclk in power down) need to be set.
+ *
+ * Otherwise the codec will not generate clocks on the bus.
+ */
+static const struct snd_soc_dapm_route
+common31xx_cm_audio_map[] = {
+       {"HPL", NULL, "AIF IN"},
+       {"HPR", NULL, "AIF IN"},
+
+       {"AIF IN", NULL, "Activate I2S clocks"},
+};
+
+static const struct snd_soc_dapm_route
+aic31xx_cm_audio_map[] = {
+       {"AIF OUT", NULL, "MIC1LP"},
+       {"AIF OUT", NULL, "MIC1RP"},
+       {"AIF OUT", NULL, "MIC1LM"},
+
+       {"AIF OUT", NULL, "Activate I2S clocks"},
+};
+
+static int aic31xx_add_controls(struct snd_soc_component *component)
 {
        int ret = 0;
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 
        if (!(aic31xx->codec_type & DAC31XX_BIT))
-               ret = snd_soc_add_codec_controls(
-                       codec, aic31xx_snd_controls,
+               ret = snd_soc_add_component_controls(
+                       component, aic31xx_snd_controls,
                        ARRAY_SIZE(aic31xx_snd_controls));
        if (ret)
                return ret;
 
        if (aic31xx->codec_type & AIC31XX_STEREO_CLASS_D_BIT)
-               ret = snd_soc_add_codec_controls(
-                       codec, aic311x_snd_controls,
+               ret = snd_soc_add_component_controls(
+                       component, aic311x_snd_controls,
                        ARRAY_SIZE(aic311x_snd_controls));
        else
-               ret = snd_soc_add_codec_controls(
-                       codec, aic310x_snd_controls,
+               ret = snd_soc_add_component_controls(
+                       component, aic310x_snd_controls,
                        ARRAY_SIZE(aic310x_snd_controls));
 
        return ret;
 }
 
-static int aic31xx_add_widgets(struct snd_soc_codec *codec)
+static int aic31xx_add_widgets(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if (aic31xx->codec_type & DAC31XX_BIT) {
@@ -751,10 +787,10 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int aic31xx_setup_pll(struct snd_soc_codec *codec,
+static int aic31xx_setup_pll(struct snd_soc_component *component,
                             struct snd_pcm_hw_params *params)
 {
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        int bclk_score = snd_soc_params_to_frame_size(params);
        int mclk_p;
        int bclk_n = 0;
@@ -762,15 +798,15 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
        int i;
 
        if (!aic31xx->sysclk || !aic31xx->p_div) {
-               dev_err(codec->dev, "Master clock not supplied\n");
+               dev_err(component->dev, "Master clock not supplied\n");
                return -EINVAL;
        }
        mclk_p = aic31xx->sysclk / aic31xx->p_div;
 
        /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
-       snd_soc_update_bits(codec, AIC31XX_CLKMUX,
+       snd_soc_component_update_bits(component, AIC31XX_CLKMUX,
                            AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL);
-       snd_soc_update_bits(codec, AIC31XX_IFACE2,
+       snd_soc_component_update_bits(component, AIC31XX_IFACE2,
                            AIC31XX_BDIVCLK_MASK, AIC31XX_DAC2BCLK);
 
        for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
@@ -789,14 +825,14 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
        }
 
        if (match == -1) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: Sample rate (%u) and format not supported\n",
                        __func__, params_rate(params));
                /* See bellow for details how fix this. */
                return -EINVAL;
        }
        if (bclk_score != 0) {
-               dev_warn(codec->dev, "Can not produce exact bitclock");
+               dev_warn(component->dev, "Can not produce exact bitclock");
                /* This is fine if using dsp format, but if using i2s
                   there may be trouble. To fix the issue edit the
                   aic31xx_divs table for your mclk and sample
@@ -808,39 +844,39 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
        i = match;
 
        /* PLL configuration */
-       snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
+       snd_soc_component_update_bits(component, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
                            (aic31xx->p_div << 4) | 0x01);
-       snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
+       snd_soc_component_write(component, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
 
-       snd_soc_write(codec, AIC31XX_PLLDMSB,
+       snd_soc_component_write(component, AIC31XX_PLLDMSB,
                      aic31xx_divs[i].pll_d >> 8);
-       snd_soc_write(codec, AIC31XX_PLLDLSB,
+       snd_soc_component_write(component, AIC31XX_PLLDLSB,
                      aic31xx_divs[i].pll_d & 0xff);
 
        /* DAC dividers configuration */
-       snd_soc_update_bits(codec, AIC31XX_NDAC, AIC31XX_PLL_MASK,
+       snd_soc_component_update_bits(component, AIC31XX_NDAC, AIC31XX_PLL_MASK,
                            aic31xx_divs[i].ndac);
-       snd_soc_update_bits(codec, AIC31XX_MDAC, AIC31XX_PLL_MASK,
+       snd_soc_component_update_bits(component, AIC31XX_MDAC, AIC31XX_PLL_MASK,
                            aic31xx_divs[i].mdac);
 
-       snd_soc_write(codec, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8);
-       snd_soc_write(codec, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff);
+       snd_soc_component_write(component, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8);
+       snd_soc_component_write(component, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff);
 
        /* ADC dividers configuration. Write reset value 1 if not used. */
-       snd_soc_update_bits(codec, AIC31XX_NADC, AIC31XX_PLL_MASK,
+       snd_soc_component_update_bits(component, AIC31XX_NADC, AIC31XX_PLL_MASK,
                            aic31xx_divs[i].nadc ? aic31xx_divs[i].nadc : 1);
-       snd_soc_update_bits(codec, AIC31XX_MADC, AIC31XX_PLL_MASK,
+       snd_soc_component_update_bits(component, AIC31XX_MADC, AIC31XX_PLL_MASK,
                            aic31xx_divs[i].madc ? aic31xx_divs[i].madc : 1);
 
-       snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr);
+       snd_soc_component_write(component, AIC31XX_AOSR, aic31xx_divs[i].aosr);
 
        /* Bit clock divider configuration. */
-       snd_soc_update_bits(codec, AIC31XX_BCLKN,
+       snd_soc_component_update_bits(component, AIC31XX_BCLKN,
                            AIC31XX_PLL_MASK, bclk_n);
 
        aic31xx->rate_div_line = i;
 
-       dev_dbg(codec->dev,
+       dev_dbg(component->dev,
                "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n",
                aic31xx_divs[i].pll_j,
                aic31xx_divs[i].pll_d,
@@ -861,10 +897,10 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        u8 data = 0;
 
-       dev_dbg(codec->dev, "## %s: width %d rate %d\n",
+       dev_dbg(component->dev, "## %s: width %d rate %d\n",
                __func__, params_width(params),
                params_rate(params));
 
@@ -884,43 +920,90 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
                        AIC31XX_IFACE1_DATALEN_SHIFT);
                break;
        default:
-               dev_err(codec->dev, "%s: Unsupported width %d\n",
+               dev_err(component->dev, "%s: Unsupported width %d\n",
                        __func__, params_width(params));
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AIC31XX_IFACE1,
+       snd_soc_component_update_bits(component, AIC31XX_IFACE1,
                            AIC31XX_IFACE1_DATALEN_MASK,
                            data);
 
-       return aic31xx_setup_pll(codec, params);
+       return aic31xx_setup_pll(component, params);
 }
 
 static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        if (mute) {
-               snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+               snd_soc_component_update_bits(component, AIC31XX_DACMUTE,
                                    AIC31XX_DACMUTE_MASK,
                                    AIC31XX_DACMUTE_MASK);
        } else {
-               snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+               snd_soc_component_update_bits(component, AIC31XX_DACMUTE,
                                    AIC31XX_DACMUTE_MASK, 0x0);
        }
 
        return 0;
 }
 
+static int aic31xx_clock_master_routes(struct snd_soc_component *component,
+                                      unsigned int fmt)
+{
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
+       int ret;
+
+       fmt &= SND_SOC_DAIFMT_MASTER_MASK;
+       if (fmt == SND_SOC_DAIFMT_CBS_CFS &&
+           aic31xx->master_dapm_route_applied) {
+               /*
+                * Remove the DAPM route(s) for codec clock master modes,
+                * if applied
+                */
+               ret = snd_soc_dapm_del_routes(dapm, common31xx_cm_audio_map,
+                                       ARRAY_SIZE(common31xx_cm_audio_map));
+               if (!ret && !(aic31xx->codec_type & DAC31XX_BIT))
+                       ret = snd_soc_dapm_del_routes(dapm,
+                                       aic31xx_cm_audio_map,
+                                       ARRAY_SIZE(aic31xx_cm_audio_map));
+
+               if (ret)
+                       return ret;
+
+               aic31xx->master_dapm_route_applied = false;
+       } else if (fmt != SND_SOC_DAIFMT_CBS_CFS &&
+                  !aic31xx->master_dapm_route_applied) {
+               /*
+                * Add the needed DAPM route(s) for codec clock master modes,
+                * if it is not done already
+                */
+               ret = snd_soc_dapm_add_routes(dapm, common31xx_cm_audio_map,
+                                       ARRAY_SIZE(common31xx_cm_audio_map));
+               if (!ret && !(aic31xx->codec_type & DAC31XX_BIT))
+                       ret = snd_soc_dapm_add_routes(dapm,
+                                       aic31xx_cm_audio_map,
+                                       ARRAY_SIZE(aic31xx_cm_audio_map));
+
+               if (ret)
+                       return ret;
+
+               aic31xx->master_dapm_route_applied = true;
+       }
+
+       return 0;
+}
+
 static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
                               unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 iface_reg1 = 0;
        u8 iface_reg2 = 0;
        u8 dsp_a_val = 0;
 
-       dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
+       dev_dbg(component->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -936,7 +1019,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
        case SND_SOC_DAIFMT_CBS_CFS:
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI master/slave interface\n");
+               dev_err(component->dev, "Invalid DAI master/slave interface\n");
                return -EINVAL;
        }
 
@@ -948,7 +1031,7 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
                iface_reg2 |= AIC31XX_BCLKINV_MASK;
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI clock signal polarity\n");
+               dev_err(component->dev, "Invalid DAI clock signal polarity\n");
                return -EINVAL;
        }
 
@@ -977,32 +1060,32 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
                               AIC31XX_IFACE1_DATATYPE_SHIFT);
                break;
        default:
-               dev_err(codec->dev, "Invalid DAI interface format\n");
+               dev_err(component->dev, "Invalid DAI interface format\n");
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AIC31XX_IFACE1,
+       snd_soc_component_update_bits(component, AIC31XX_IFACE1,
                            AIC31XX_IFACE1_DATATYPE_MASK |
                            AIC31XX_IFACE1_MASTER_MASK,
                            iface_reg1);
-       snd_soc_update_bits(codec, AIC31XX_DATA_OFFSET,
+       snd_soc_component_update_bits(component, AIC31XX_DATA_OFFSET,
                            AIC31XX_DATA_OFFSET_MASK,
                            dsp_a_val);
-       snd_soc_update_bits(codec, AIC31XX_IFACE2,
+       snd_soc_component_update_bits(component, AIC31XX_IFACE2,
                            AIC31XX_BCLKINV_MASK,
                            iface_reg2);
 
-       return 0;
+       return aic31xx_clock_master_routes(component, fmt);
 }
 
 static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        int i;
 
-       dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
+       dev_dbg(component->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
                __func__, clk_id, freq, dir);
 
        for (i = 1; i < 8; i++)
@@ -1025,7 +1108,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        }
 
        /* set clock on MCLK, BCLK, or GPIO1 as PLL input */
-       snd_soc_update_bits(codec, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
+       snd_soc_component_update_bits(component, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
                            clk_id << AIC31XX_PLL_CLKIN_SHIFT);
 
        aic31xx->sysclk = freq;
@@ -1071,42 +1154,42 @@ static int aic31xx_reset(struct aic31xx_priv *aic31xx)
        return ret;
 }
 
-static void aic31xx_clk_on(struct snd_soc_codec *codec)
+static void aic31xx_clk_on(struct snd_soc_component *component)
 {
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        u8 mask = AIC31XX_PM_MASK;
        u8 on = AIC31XX_PM_MASK;
 
-       dev_dbg(codec->dev, "codec clock -> on (rate %d)\n",
+       dev_dbg(component->dev, "codec clock -> on (rate %d)\n",
                aic31xx_divs[aic31xx->rate_div_line].rate);
-       snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, on);
+       snd_soc_component_update_bits(component, AIC31XX_PLLPR, mask, on);
        mdelay(10);
-       snd_soc_update_bits(codec, AIC31XX_NDAC, mask, on);
-       snd_soc_update_bits(codec, AIC31XX_MDAC, mask, on);
+       snd_soc_component_update_bits(component, AIC31XX_NDAC, mask, on);
+       snd_soc_component_update_bits(component, AIC31XX_MDAC, mask, on);
        if (aic31xx_divs[aic31xx->rate_div_line].nadc)
-               snd_soc_update_bits(codec, AIC31XX_NADC, mask, on);
+               snd_soc_component_update_bits(component, AIC31XX_NADC, mask, on);
        if (aic31xx_divs[aic31xx->rate_div_line].madc)
-               snd_soc_update_bits(codec, AIC31XX_MADC, mask, on);
-       snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, on);
+               snd_soc_component_update_bits(component, AIC31XX_MADC, mask, on);
+       snd_soc_component_update_bits(component, AIC31XX_BCLKN, mask, on);
 }
 
-static void aic31xx_clk_off(struct snd_soc_codec *codec)
+static void aic31xx_clk_off(struct snd_soc_component *component)
 {
        u8 mask = AIC31XX_PM_MASK;
        u8 off = 0;
 
-       dev_dbg(codec->dev, "codec clock -> off\n");
-       snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, off);
-       snd_soc_update_bits(codec, AIC31XX_MADC, mask, off);
-       snd_soc_update_bits(codec, AIC31XX_NADC, mask, off);
-       snd_soc_update_bits(codec, AIC31XX_MDAC, mask, off);
-       snd_soc_update_bits(codec, AIC31XX_NDAC, mask, off);
-       snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, off);
+       dev_dbg(component->dev, "codec clock -> off\n");
+       snd_soc_component_update_bits(component, AIC31XX_BCLKN, mask, off);
+       snd_soc_component_update_bits(component, AIC31XX_MADC, mask, off);
+       snd_soc_component_update_bits(component, AIC31XX_NADC, mask, off);
+       snd_soc_component_update_bits(component, AIC31XX_MDAC, mask, off);
+       snd_soc_component_update_bits(component, AIC31XX_NDAC, mask, off);
+       snd_soc_component_update_bits(component, AIC31XX_PLLPR, mask, off);
 }
 
-static int aic31xx_power_on(struct snd_soc_codec *codec)
+static int aic31xx_power_on(struct snd_soc_component *component)
 {
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies),
@@ -1123,7 +1206,7 @@ static int aic31xx_power_on(struct snd_soc_codec *codec)
 
        ret = regcache_sync(aic31xx->regmap);
        if (ret) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Failed to restore cache: %d\n", ret);
                regcache_cache_only(aic31xx->regmap, true);
                regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
@@ -1134,57 +1217,57 @@ static int aic31xx_power_on(struct snd_soc_codec *codec)
        return 0;
 }
 
-static void aic31xx_power_off(struct snd_soc_codec *codec)
+static void aic31xx_power_off(struct snd_soc_component *component)
 {
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
 
        regcache_cache_only(aic31xx->regmap, true);
        regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
                               aic31xx->supplies);
 }
 
-static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
+static int aic31xx_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
-               snd_soc_codec_get_bias_level(codec), level);
+       dev_dbg(component->dev, "## %s: %d -> %d\n", __func__,
+               snd_soc_component_get_bias_level(component), level);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
        case SND_SOC_BIAS_PREPARE:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
-                       aic31xx_clk_on(codec);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
+                       aic31xx_clk_on(component);
                break;
        case SND_SOC_BIAS_STANDBY:
-               switch (snd_soc_codec_get_bias_level(codec)) {
+               switch (snd_soc_component_get_bias_level(component)) {
                case SND_SOC_BIAS_OFF:
-                       aic31xx_power_on(codec);
+                       aic31xx_power_on(component);
                        break;
                case SND_SOC_BIAS_PREPARE:
-                       aic31xx_clk_off(codec);
+                       aic31xx_clk_off(component);
                        break;
                default:
                        BUG();
                }
                break;
        case SND_SOC_BIAS_OFF:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY)
-                       aic31xx_power_off(codec);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY)
+                       aic31xx_power_off(component);
                break;
        }
 
        return 0;
 }
 
-static int aic31xx_codec_probe(struct snd_soc_codec *codec)
+static int aic31xx_codec_probe(struct snd_soc_component *component)
 {
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        int i, ret;
 
        dev_dbg(aic31xx->dev, "## %s\n", __func__);
 
-       aic31xx->codec = codec;
+       aic31xx->component = component;
 
        for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
                aic31xx->disable_nb[i].nb.notifier_call =
@@ -1193,7 +1276,7 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec)
                ret = regulator_register_notifier(aic31xx->supplies[i].consumer,
                                                  &aic31xx->disable_nb[i].nb);
                if (ret) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to request regulator notifier: %d\n",
                                ret);
                        return ret;
@@ -1203,43 +1286,42 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec)
        regcache_cache_only(aic31xx->regmap, true);
        regcache_mark_dirty(aic31xx->regmap);
 
-       ret = aic31xx_add_controls(codec);
+       ret = aic31xx_add_controls(component);
        if (ret)
                return ret;
 
-       ret = aic31xx_add_widgets(codec);
+       ret = aic31xx_add_widgets(component);
        if (ret)
                return ret;
 
        return 0;
 }
 
-static int aic31xx_codec_remove(struct snd_soc_codec *codec)
+static void aic31xx_codec_remove(struct snd_soc_component *component)
 {
-       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
                regulator_unregister_notifier(aic31xx->supplies[i].consumer,
                                              &aic31xx->disable_nb[i].nb);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_driver_aic31xx = {
+static const struct snd_soc_component_driver soc_codec_driver_aic31xx = {
        .probe                  = aic31xx_codec_probe,
        .remove                 = aic31xx_codec_remove,
        .set_bias_level         = aic31xx_set_bias_level,
-       .suspend_bias_off       = true,
-
-       .component_driver = {
-               .controls               = common31xx_snd_controls,
-               .num_controls           = ARRAY_SIZE(common31xx_snd_controls),
-               .dapm_widgets           = common31xx_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(common31xx_dapm_widgets),
-               .dapm_routes            = common31xx_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(common31xx_audio_map),
-       },
+       .controls               = common31xx_snd_controls,
+       .num_controls           = ARRAY_SIZE(common31xx_snd_controls),
+       .dapm_widgets           = common31xx_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(common31xx_dapm_widgets),
+       .dapm_routes            = common31xx_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(common31xx_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct snd_soc_dai_ops aic31xx_dai_ops = {
@@ -1375,23 +1457,17 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
        }
 
        if (aic31xx->codec_type & DAC31XX_BIT)
-               return snd_soc_register_codec(&i2c->dev,
+               return devm_snd_soc_register_component(&i2c->dev,
                                &soc_codec_driver_aic31xx,
                                dac31xx_dai_driver,
                                ARRAY_SIZE(dac31xx_dai_driver));
        else
-               return snd_soc_register_codec(&i2c->dev,
+               return devm_snd_soc_register_component(&i2c->dev,
                                &soc_codec_driver_aic31xx,
                                aic31xx_dai_driver,
                                ARRAY_SIZE(aic31xx_dai_driver));
 }
 
-static int aic31xx_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-       return 0;
-}
-
 static const struct i2c_device_id aic31xx_i2c_id[] = {
        { "tlv320aic310x", AIC3100 },
        { "tlv320aic311x", AIC3110 },
@@ -1412,7 +1488,6 @@ static struct i2c_driver aic31xx_i2c_driver = {
                .acpi_match_table = ACPI_PTR(aic31xx_acpi_match),
        },
        .probe          = aic31xx_i2c_probe,
-       .remove         = aic31xx_i2c_remove,
        .id_table       = aic31xx_i2c_id,
 };
 module_i2c_driver(aic31xx_i2c_driver);
index 15ac7cba86fe83a2c4d9363bb9c080b73cfa0c52..0b587585b38bbae23b7b016354533f7818f420ce 100644 (file)
@@ -160,6 +160,7 @@ struct aic31xx_pdata {
 #define AIC31XX_DACMOD2BCLK            0x01
 #define AIC31XX_ADC2BCLK               0x02
 #define AIC31XX_ADCMOD2BCLK            0x03
+#define AIC31XX_KEEP_I2SCLK            BIT(2)
 
 /* AIC31XX_ADCFLAG */
 #define AIC31XX_ADCPWRSTATUS_MASK      BIT(6)
index fea019343c3bfd5656e172c14c6e48eb531c530a..e2b5a11b16d1901775ff0fe8cedce8c2d5c7e5f2 100644 (file)
@@ -82,10 +82,10 @@ struct aic32x4_priv {
 static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        u8 val;
 
-       val = snd_soc_read(codec, AIC32X4_DINCTL);
+       val = snd_soc_component_read32(component, AIC32X4_DINCTL);
 
        ucontrol->value.integer.value[0] = (val & 0x01);
 
@@ -95,11 +95,11 @@ static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        u8 val;
        u8 gpio_check;
 
-       val = snd_soc_read(codec, AIC32X4_DOUTCTL);
+       val = snd_soc_component_read32(component, AIC32X4_DOUTCTL);
        gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
        if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
                printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n",
@@ -115,7 +115,7 @@ static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
        else
                val &= ~AIC32X4_MFP2_GPIO_OUT_HIGH;
 
-       snd_soc_write(codec, AIC32X4_DOUTCTL, val);
+       snd_soc_component_write(component, AIC32X4_DOUTCTL, val);
 
        return 0;
 };
@@ -123,10 +123,10 @@ static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        u8 val;
 
-       val = snd_soc_read(codec, AIC32X4_SCLKCTL);
+       val = snd_soc_component_read32(component, AIC32X4_SCLKCTL);
 
        ucontrol->value.integer.value[0] = (val & 0x01);
 
@@ -136,11 +136,11 @@ static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        u8 val;
        u8 gpio_check;
 
-       val = snd_soc_read(codec, AIC32X4_MISOCTL);
+       val = snd_soc_component_read32(component, AIC32X4_MISOCTL);
        gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED);
        if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) {
                printk(KERN_ERR "%s: MFP4 is not configure as a GPIO output\n",
@@ -156,7 +156,7 @@ static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
        else
                val &= ~AIC32X4_MFP5_GPIO_OUT_HIGH;
 
-       snd_soc_write(codec, AIC32X4_MISOCTL, val);
+       snd_soc_component_write(component, AIC32X4_MISOCTL, val);
 
        return 0;
 };
@@ -164,10 +164,10 @@ static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        u8 val;
 
-       val = snd_soc_read(codec, AIC32X4_GPIOCTL);
+       val = snd_soc_component_read32(component, AIC32X4_GPIOCTL);
        ucontrol->value.integer.value[0] = ((val & 0x2) >> 1);
 
        return 0;
@@ -176,11 +176,11 @@ static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol,
 static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        u8 val;
        u8 gpio_check;
 
-       val = snd_soc_read(codec, AIC32X4_GPIOCTL);
+       val = snd_soc_component_read32(component, AIC32X4_GPIOCTL);
        gpio_check = (val & AIC32X4_MFP5_GPIO_OUTPUT);
        if (gpio_check != AIC32X4_MFP5_GPIO_OUTPUT) {
                printk(KERN_ERR "%s: MFP5 is not configure as a GPIO output\n",
@@ -196,7 +196,7 @@ static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol,
        else
                val &= 0xfe;
 
-       snd_soc_write(codec, AIC32X4_GPIOCTL, val);
+       snd_soc_component_write(component, AIC32X4_GPIOCTL, val);
 
        return 0;
 };
@@ -597,8 +597,8 @@ static inline int aic32x4_get_divs(int mclk, int rate)
 static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case 12000000:
@@ -613,7 +613,7 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u8 iface_reg_1 = 0;
        u8 iface_reg_2 = 0;
        u8 iface_reg_3 = 0;
@@ -657,12 +657,12 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, AIC32X4_IFACE1,
+       snd_soc_component_update_bits(component, AIC32X4_IFACE1,
                            AIC32X4_IFACE1_DATATYPE_MASK |
                            AIC32X4_IFACE1_MASTER_MASK, iface_reg_1);
-       snd_soc_update_bits(codec, AIC32X4_IFACE2,
+       snd_soc_component_update_bits(component, AIC32X4_IFACE2,
                            AIC32X4_DATA_OFFSET_MASK, iface_reg_2);
-       snd_soc_update_bits(codec, AIC32X4_IFACE3,
+       snd_soc_component_update_bits(component, AIC32X4_IFACE3,
                            AIC32X4_BCLKINV_MASK, iface_reg_3);
 
        return 0;
@@ -672,8 +672,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
        u8 iface1_reg = 0;
        u8 dacsetup_reg = 0;
        int i;
@@ -685,54 +685,54 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* MCLK as PLL_CLKIN */
-       snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK,
+       snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK,
                            AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT);
        /* PLL as CODEC_CLKIN */
-       snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK,
+       snd_soc_component_update_bits(component, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK,
                            AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT);
        /* DAC_MOD_CLK as BDIV_CLKIN */
-       snd_soc_update_bits(codec, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK,
+       snd_soc_component_update_bits(component, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK,
                            AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT);
 
        /* We will fix R value to 1 and will make P & J=K.D as variable */
-       snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01);
+       snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01);
 
        /* PLL P value */
-       snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK,
+       snd_soc_component_update_bits(component, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK,
                            aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT);
 
        /* PLL J value */
-       snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
+       snd_soc_component_write(component, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
 
        /* PLL D value */
-       snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
-       snd_soc_write(codec, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff));
+       snd_soc_component_write(component, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
+       snd_soc_component_write(component, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff));
 
        /* NDAC divider value */
-       snd_soc_update_bits(codec, AIC32X4_NDAC,
+       snd_soc_component_update_bits(component, AIC32X4_NDAC,
                            AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac);
 
        /* MDAC divider value */
-       snd_soc_update_bits(codec, AIC32X4_MDAC,
+       snd_soc_component_update_bits(component, AIC32X4_MDAC,
                            AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac);
 
        /* DOSR MSB & LSB values */
-       snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
-       snd_soc_write(codec, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff));
+       snd_soc_component_write(component, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
+       snd_soc_component_write(component, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff));
 
        /* NADC divider value */
-       snd_soc_update_bits(codec, AIC32X4_NADC,
+       snd_soc_component_update_bits(component, AIC32X4_NADC,
                            AIC32X4_NADC_MASK, aic32x4_divs[i].nadc);
 
        /* MADC divider value */
-       snd_soc_update_bits(codec, AIC32X4_MADC,
+       snd_soc_component_update_bits(component, AIC32X4_MADC,
                            AIC32X4_MADC_MASK, aic32x4_divs[i].madc);
 
        /* AOSR value */
-       snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
+       snd_soc_component_write(component, AIC32X4_AOSR, aic32x4_divs[i].aosr);
 
        /* BCLK N divider */
-       snd_soc_update_bits(codec, AIC32X4_BCLKN,
+       snd_soc_component_update_bits(component, AIC32X4_BCLKN,
                            AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N);
 
        switch (params_width(params)) {
@@ -753,7 +753,7 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
                               AIC32X4_IFACE1_DATALEN_SHIFT);
                break;
        }
-       snd_soc_update_bits(codec, AIC32X4_IFACE1,
+       snd_soc_component_update_bits(component, AIC32X4_IFACE1,
                            AIC32X4_IFACE1_DATALEN_MASK, iface1_reg);
 
        if (params_channels(params) == 1) {
@@ -764,7 +764,7 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
                else
                        dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN;
        }
-       snd_soc_update_bits(codec, AIC32X4_DACSETUP,
+       snd_soc_component_update_bits(component, AIC32X4_DACSETUP,
                            AIC32X4_DAC_CHAN_MASK, dacsetup_reg);
 
        return 0;
@@ -772,18 +772,18 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream,
 
 static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
-       snd_soc_update_bits(codec, AIC32X4_DACMUTE,
+       snd_soc_component_update_bits(component, AIC32X4_DACMUTE,
                            AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0);
 
        return 0;
 }
 
-static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
+static int aic32x4_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+       struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -791,59 +791,59 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
                /* Switch on master clock */
                ret = clk_prepare_enable(aic32x4->mclk);
                if (ret) {
-                       dev_err(codec->dev, "Failed to enable master clock\n");
+                       dev_err(component->dev, "Failed to enable master clock\n");
                        return ret;
                }
 
                /* Switch on PLL */
-               snd_soc_update_bits(codec, AIC32X4_PLLPR,
+               snd_soc_component_update_bits(component, AIC32X4_PLLPR,
                                    AIC32X4_PLLEN, AIC32X4_PLLEN);
 
                /* Switch on NDAC Divider */
-               snd_soc_update_bits(codec, AIC32X4_NDAC,
+               snd_soc_component_update_bits(component, AIC32X4_NDAC,
                                    AIC32X4_NDACEN, AIC32X4_NDACEN);
 
                /* Switch on MDAC Divider */
-               snd_soc_update_bits(codec, AIC32X4_MDAC,
+               snd_soc_component_update_bits(component, AIC32X4_MDAC,
                                    AIC32X4_MDACEN, AIC32X4_MDACEN);
 
                /* Switch on NADC Divider */
-               snd_soc_update_bits(codec, AIC32X4_NADC,
+               snd_soc_component_update_bits(component, AIC32X4_NADC,
                                    AIC32X4_NADCEN, AIC32X4_NADCEN);
 
                /* Switch on MADC Divider */
-               snd_soc_update_bits(codec, AIC32X4_MADC,
+               snd_soc_component_update_bits(component, AIC32X4_MADC,
                                    AIC32X4_MADCEN, AIC32X4_MADCEN);
 
                /* Switch on BCLK_N Divider */
-               snd_soc_update_bits(codec, AIC32X4_BCLKN,
+               snd_soc_component_update_bits(component, AIC32X4_BCLKN,
                                    AIC32X4_BCLKEN, AIC32X4_BCLKEN);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
                /* Switch off BCLK_N Divider */
-               snd_soc_update_bits(codec, AIC32X4_BCLKN,
+               snd_soc_component_update_bits(component, AIC32X4_BCLKN,
                                    AIC32X4_BCLKEN, 0);
 
                /* Switch off MADC Divider */
-               snd_soc_update_bits(codec, AIC32X4_MADC,
+               snd_soc_component_update_bits(component, AIC32X4_MADC,
                                    AIC32X4_MADCEN, 0);
 
                /* Switch off NADC Divider */
-               snd_soc_update_bits(codec, AIC32X4_NADC,
+               snd_soc_component_update_bits(component, AIC32X4_NADC,
                                    AIC32X4_NADCEN, 0);
 
                /* Switch off MDAC Divider */
-               snd_soc_update_bits(codec, AIC32X4_MDAC,
+               snd_soc_component_update_bits(component, AIC32X4_MDAC,
                                    AIC32X4_MDACEN, 0);
 
                /* Switch off NDAC Divider */
-               snd_soc_update_bits(codec, AIC32X4_NDAC,
+               snd_soc_component_update_bits(component, AIC32X4_NDAC,
                                    AIC32X4_NDACEN, 0);
 
                /* Switch off PLL */
-               snd_soc_update_bits(codec, AIC32X4_PLLPR,
+               snd_soc_component_update_bits(component, AIC32X4_PLLPR,
                                    AIC32X4_PLLEN, 0);
 
                /* Switch off master clock */
@@ -884,55 +884,55 @@ static struct snd_soc_dai_driver aic32x4_dai = {
        .symmetric_rates = 1,
 };
 
-static void aic32x4_setup_gpios(struct snd_soc_codec *codec)
+static void aic32x4_setup_gpios(struct snd_soc_component *component)
 {
-       struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+       struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 
        /* setup GPIO functions */
        /* MFP1 */
        if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) {
-               snd_soc_write(codec, AIC32X4_DINCTL,
+               snd_soc_component_write(component, AIC32X4_DINCTL,
                      aic32x4->setup->gpio_func[0]);
-               snd_soc_add_codec_controls(codec, aic32x4_mfp1,
+               snd_soc_add_component_controls(component, aic32x4_mfp1,
                        ARRAY_SIZE(aic32x4_mfp1));
        }
 
        /* MFP2 */
        if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) {
-               snd_soc_write(codec, AIC32X4_DOUTCTL,
+               snd_soc_component_write(component, AIC32X4_DOUTCTL,
                      aic32x4->setup->gpio_func[1]);
-               snd_soc_add_codec_controls(codec, aic32x4_mfp2,
+               snd_soc_add_component_controls(component, aic32x4_mfp2,
                        ARRAY_SIZE(aic32x4_mfp2));
        }
 
        /* MFP3 */
        if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) {
-               snd_soc_write(codec, AIC32X4_SCLKCTL,
+               snd_soc_component_write(component, AIC32X4_SCLKCTL,
                      aic32x4->setup->gpio_func[2]);
-               snd_soc_add_codec_controls(codec, aic32x4_mfp3,
+               snd_soc_add_component_controls(component, aic32x4_mfp3,
                        ARRAY_SIZE(aic32x4_mfp3));
        }
 
        /* MFP4 */
        if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) {
-               snd_soc_write(codec, AIC32X4_MISOCTL,
+               snd_soc_component_write(component, AIC32X4_MISOCTL,
                      aic32x4->setup->gpio_func[3]);
-               snd_soc_add_codec_controls(codec, aic32x4_mfp4,
+               snd_soc_add_component_controls(component, aic32x4_mfp4,
                        ARRAY_SIZE(aic32x4_mfp4));
        }
 
        /* MFP5 */
        if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) {
-               snd_soc_write(codec, AIC32X4_GPIOCTL,
+               snd_soc_component_write(component, AIC32X4_GPIOCTL,
                      aic32x4->setup->gpio_func[4]);
-               snd_soc_add_codec_controls(codec, aic32x4_mfp5,
+               snd_soc_add_component_controls(component, aic32x4_mfp5,
                        ARRAY_SIZE(aic32x4_mfp5));
        }
 }
 
-static int aic32x4_codec_probe(struct snd_soc_codec *codec)
+static int aic32x4_component_probe(struct snd_soc_component *component)
 {
-       struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
+       struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
        u32 tmp_reg;
 
        if (gpio_is_valid(aic32x4->rstn_gpio)) {
@@ -940,42 +940,42 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec)
                gpio_set_value(aic32x4->rstn_gpio, 1);
        }
 
-       snd_soc_write(codec, AIC32X4_RESET, 0x01);
+       snd_soc_component_write(component, AIC32X4_RESET, 0x01);
 
        if (aic32x4->setup)
-               aic32x4_setup_gpios(codec);
+               aic32x4_setup_gpios(component);
 
        /* Power platform configuration */
        if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
-               snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
+               snd_soc_component_write(component, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
                                                      AIC32X4_MICBIAS_2075V);
        }
        if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
-               snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
+               snd_soc_component_write(component, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
 
        tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
                        AIC32X4_LDOCTLEN : 0;
-       snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);
+       snd_soc_component_write(component, AIC32X4_LDOCTL, tmp_reg);
 
-       tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
+       tmp_reg = snd_soc_component_read32(component, AIC32X4_CMMODE);
        if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
                tmp_reg |= AIC32X4_LDOIN_18_36;
        if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
                tmp_reg |= AIC32X4_LDOIN2HP;
-       snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
+       snd_soc_component_write(component, AIC32X4_CMMODE, tmp_reg);
 
        /* Mic PGA routing */
        if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K)
-               snd_soc_write(codec, AIC32X4_LMICPGANIN,
+               snd_soc_component_write(component, AIC32X4_LMICPGANIN,
                                AIC32X4_LMICPGANIN_IN2R_10K);
        else
-               snd_soc_write(codec, AIC32X4_LMICPGANIN,
+               snd_soc_component_write(component, AIC32X4_LMICPGANIN,
                                AIC32X4_LMICPGANIN_CM1L_10K);
        if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K)
-               snd_soc_write(codec, AIC32X4_RMICPGANIN,
+               snd_soc_component_write(component, AIC32X4_RMICPGANIN,
                                AIC32X4_RMICPGANIN_IN1L_10K);
        else
-               snd_soc_write(codec, AIC32X4_RMICPGANIN,
+               snd_soc_component_write(component, AIC32X4_RMICPGANIN,
                                AIC32X4_RMICPGANIN_CM1R_10K);
 
        /*
@@ -983,27 +983,28 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec)
         * and down for the first capture to work properly. It seems related to
         * a HW BUG or some kind of behavior not documented in the datasheet.
         */
-       tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP);
-       snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg |
+       tmp_reg = snd_soc_component_read32(component, AIC32X4_ADCSETUP);
+       snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg |
                                AIC32X4_LADC_EN | AIC32X4_RADC_EN);
-       snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg);
+       snd_soc_component_write(component, AIC32X4_ADCSETUP, tmp_reg);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
-       .probe = aic32x4_codec_probe,
-       .set_bias_level = aic32x4_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = aic32x4_snd_controls,
-               .num_controls           = ARRAY_SIZE(aic32x4_snd_controls),
-               .dapm_widgets           = aic32x4_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(aic32x4_dapm_widgets),
-               .dapm_routes            = aic32x4_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(aic32x4_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_aic32x4 = {
+       .probe                  = aic32x4_component_probe,
+       .set_bias_level         = aic32x4_set_bias_level,
+       .controls               = aic32x4_snd_controls,
+       .num_controls           = ARRAY_SIZE(aic32x4_snd_controls),
+       .dapm_widgets           = aic32x4_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(aic32x4_dapm_widgets),
+       .dapm_routes            = aic32x4_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(aic32x4_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
@@ -1181,10 +1182,10 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap)
                return ret;
        }
 
-       ret = snd_soc_register_codec(dev,
-                       &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
+       ret = devm_snd_soc_register_component(dev,
+                       &soc_component_dev_aic32x4, &aic32x4_dai, 1);
        if (ret) {
-               dev_err(dev, "Failed to register codec\n");
+               dev_err(dev, "Failed to register component\n");
                aic32x4_disable_regulators(aic32x4);
                return ret;
        }
@@ -1199,8 +1200,6 @@ int aic32x4_remove(struct device *dev)
 
        aic32x4_disable_regulators(aic32x4);
 
-       snd_soc_unregister_codec(dev);
-
        return 0;
 }
 EXPORT_SYMBOL(aic32x4_remove);
index b751cad545da40d5e605ec4da2dd659b7cf19194..6a271e6e6b8fc0149de7c00407decce4524308e0 100644 (file)
@@ -72,7 +72,7 @@ struct aic3x_disable_nb {
 
 /* codec private data */
 struct aic3x_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regmap *regmap;
        struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
        struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
@@ -162,8 +162,8 @@ static const struct regmap_config aic3x_regmap = {
 static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
                                        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int reg = mc->reg;
@@ -172,7 +172,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
        unsigned int mask = (1 << fls(max)) - 1;
        unsigned int invert = mc->invert;
        unsigned short val;
-       struct snd_soc_dapm_update update = { 0 };
+       struct snd_soc_dapm_update update = {};
        int connect, change;
 
        val = (ucontrol->value.integer.value[0] & mask);
@@ -189,7 +189,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
        mask <<= shift;
        val <<= shift;
 
-       change = snd_soc_test_bits(codec, reg, mask, val);
+       change = snd_soc_component_test_bits(component, reg, mask, val);
        if (change) {
                update.kcontrol = kcontrol;
                update.reg = reg;
@@ -215,19 +215,19 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 static int mic_bias_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* change mic bias voltage to user defined */
-               snd_soc_update_bits(codec, MICBIAS_CTRL,
+               snd_soc_component_update_bits(component, MICBIAS_CTRL,
                                MICBIAS_LEVEL_MASK,
                                aic3x->micbias_vg << MICBIAS_LEVEL_SHIFT);
                break;
 
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(codec, MICBIAS_CTRL,
+               snd_soc_component_update_bits(component, MICBIAS_CTRL,
                                MICBIAS_LEVEL_MASK, 0);
                break;
        }
@@ -993,10 +993,10 @@ static const struct snd_soc_dapm_route intercon_3007[] = {
        {"SPOM", NULL, "Right Class-D Out"},
 };
 
-static int aic3x_add_widgets(struct snd_soc_codec *codec)
+static int aic3x_add_widgets(struct snd_soc_component *component)
 {
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        switch (aic3x->model) {
        case AIC3X_MODEL_3X:
@@ -1035,8 +1035,8 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
                           struct snd_pcm_hw_params *params,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
        u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
        u16 d, pll_d = 1;
@@ -1047,7 +1047,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
                width = params_width(params);
 
        /* select data word length */
-       data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
+       data = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
        switch (width) {
        case 16:
                break;
@@ -1061,7 +1061,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
                data |= (0x03 << 4);
                break;
        }
-       snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
+       snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLB, data);
 
        /* Fsref can be 44100 or 48000 */
        fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
@@ -1076,15 +1076,15 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
 
        if (bypass_pll) {
                pll_q &= 0xf;
-               snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
-               snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
+               snd_soc_component_write(component, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
+               snd_soc_component_write(component, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
                /* disable PLL if it is bypassed */
-               snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
+               snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
 
        } else {
-               snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
+               snd_soc_component_write(component, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
                /* enable PLL when it is used */
-               snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+               snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG,
                                    PLL_ENABLE, PLL_ENABLE);
        }
 
@@ -1094,7 +1094,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
        data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
        if (params_rate(params) >= 64000)
                data |= DUAL_RATE_MODE;
-       snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
+       snd_soc_component_write(component, AIC3X_CODEC_DATAPATH_REG, data);
 
        /* codec sample rate select */
        data = (fsref * 20) / params_rate(params);
@@ -1103,7 +1103,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
        data /= 5;
        data -= 2;
        data |= (data << 4);
-       snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
+       snd_soc_component_write(component, AIC3X_SAMPLE_RATE_SEL_REG, data);
 
        if (bypass_pll)
                return 0;
@@ -1172,13 +1172,13 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
        }
 
 found:
-       snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
-       snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
+       snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
+       snd_soc_component_write(component, AIC3X_OVRF_STATUS_AND_PLLR_REG,
                      pll_r << PLLR_SHIFT);
-       snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
-       snd_soc_write(codec, AIC3X_PLL_PROGC_REG,
+       snd_soc_component_write(component, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
+       snd_soc_component_write(component, AIC3X_PLL_PROGC_REG,
                      (pll_d >> 6) << PLLD_MSB_SHIFT);
-       snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
+       snd_soc_component_write(component, AIC3X_PLL_PROGD_REG,
                      (pll_d & 0x3F) << PLLD_LSB_SHIFT);
 
        return 0;
@@ -1187,8 +1187,8 @@ found:
 static int aic3x_prepare(struct snd_pcm_substream *substream,
                         struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        int delay = 0;
        int width = aic3x->slot_width;
 
@@ -1202,23 +1202,23 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
                delay += aic3x->tdm_delay*width;
 
        /* Configure data delay */
-       snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
+       snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLC, delay);
 
        return 0;
 }
 
 static int aic3x_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
-       u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
+       struct snd_soc_component *component = dai->component;
+       u8 ldac_reg = snd_soc_component_read32(component, LDAC_VOL) & ~MUTE_ON;
+       u8 rdac_reg = snd_soc_component_read32(component, RDAC_VOL) & ~MUTE_ON;
 
        if (mute) {
-               snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
-               snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
+               snd_soc_component_write(component, LDAC_VOL, ldac_reg | MUTE_ON);
+               snd_soc_component_write(component, RDAC_VOL, rdac_reg | MUTE_ON);
        } else {
-               snd_soc_write(codec, LDAC_VOL, ldac_reg);
-               snd_soc_write(codec, RDAC_VOL, rdac_reg);
+               snd_soc_component_write(component, LDAC_VOL, ldac_reg);
+               snd_soc_component_write(component, RDAC_VOL, rdac_reg);
        }
 
        return 0;
@@ -1227,13 +1227,13 @@ static int aic3x_mute(struct snd_soc_dai *dai, int mute)
 static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
        /* set clock on MCLK or GPIO2 or BCLK */
-       snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
+       snd_soc_component_update_bits(component, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
                                clk_id << PLLCLK_IN_SHIFT);
-       snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
+       snd_soc_component_update_bits(component, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
                                clk_id << CLKDIV_IN_SHIFT);
 
        aic3x->sysclk = freq;
@@ -1243,12 +1243,12 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                             unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        u8 iface_areg, iface_breg;
 
-       iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
-       iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
+       iface_areg = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLA) & 0x3f;
+       iface_breg = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLB) & 0x3f;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1289,8 +1289,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
        aic3x->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 
        /* set iface */
-       snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
-       snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
+       snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLA, iface_areg);
+       snd_soc_component_write(component, AIC3X_ASD_INTF_CTRLB, iface_breg);
 
        return 0;
 }
@@ -1299,24 +1299,24 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
                                  unsigned int tx_mask, unsigned int rx_mask,
                                  int slots, int slot_width)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        unsigned int lsb;
 
        if (tx_mask != rx_mask) {
-               dev_err(codec->dev, "tx and rx masks must be symmetric\n");
+               dev_err(component->dev, "tx and rx masks must be symmetric\n");
                return -EINVAL;
        }
 
        if (unlikely(!tx_mask)) {
-               dev_err(codec->dev, "tx and rx masks need to be non 0\n");
+               dev_err(component->dev, "tx and rx masks need to be non 0\n");
                return -EINVAL;
        }
 
        /* TDM based on DSP mode requires slots to be adjacent */
        lsb = __ffs(tx_mask);
        if ((lsb + 1) != __fls(tx_mask)) {
-               dev_err(codec->dev, "Invalid mask, slots must be adjacent\n");
+               dev_err(component->dev, "Invalid mask, slots must be adjacent\n");
                return -EINVAL;
        }
 
@@ -1327,7 +1327,7 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
        case 32:
                break;
        default:
-               dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
+               dev_err(component->dev, "Unsupported slot width %d\n", slot_width);
                return -EINVAL;
        }
 
@@ -1336,7 +1336,7 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
        aic3x->slot_width = slot_width;
 
        /* DOUT in high-impedance on inactive bit clocks */
-       snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
+       snd_soc_component_update_bits(component, AIC3X_ASD_INTF_CTRLA,
                            DOUT_TRISTATE, DOUT_TRISTATE);
 
        return 0;
@@ -1362,9 +1362,9 @@ static int aic3x_regulator_event(struct notifier_block *nb,
        return 0;
 }
 
-static int aic3x_set_power(struct snd_soc_codec *codec, int power)
+static int aic3x_set_power(struct snd_soc_component *component, int power)
 {
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        unsigned int pll_c, pll_d;
        int ret;
 
@@ -1388,12 +1388,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
                 * writing one of them and thus caused other one also not
                 * being written
                 */
-               pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG);
-               pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG);
+               pll_c = snd_soc_component_read32(component, AIC3X_PLL_PROGC_REG);
+               pll_d = snd_soc_component_read32(component, AIC3X_PLL_PROGD_REG);
                if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def ||
                        pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) {
-                       snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
-                       snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
+                       snd_soc_component_write(component, AIC3X_PLL_PROGC_REG, pll_c);
+                       snd_soc_component_write(component, AIC3X_PLL_PROGD_REG, pll_d);
                }
 
                /*
@@ -1407,7 +1407,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
                 * possible VDD leakage currents in case the supply regulators
                 * remain on
                 */
-               snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
+               snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);
                regcache_mark_dirty(aic3x->regmap);
                aic3x->power = 0;
                /* HW writes are needless when bias is off */
@@ -1419,35 +1419,35 @@ out:
        return ret;
 }
 
-static int aic3x_set_bias_level(struct snd_soc_codec *codec,
+static int aic3x_set_bias_level(struct snd_soc_component *component,
                                enum snd_soc_bias_level level)
 {
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
        case SND_SOC_BIAS_PREPARE:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY &&
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY &&
                    aic3x->master) {
                        /* enable pll */
-                       snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+                       snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG,
                                            PLL_ENABLE, PLL_ENABLE);
                }
                break;
        case SND_SOC_BIAS_STANDBY:
                if (!aic3x->power)
-                       aic3x_set_power(codec, 1);
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE &&
+                       aic3x_set_power(component, 1);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE &&
                    aic3x->master) {
                        /* disable pll */
-                       snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+                       snd_soc_component_update_bits(component, AIC3X_PLL_PROGA_REG,
                                            PLL_ENABLE, 0);
                }
                break;
        case SND_SOC_BIAS_OFF:
                if (aic3x->power)
-                       aic3x_set_power(codec, 0);
+                       aic3x_set_power(component, 0);
                break;
        }
 
@@ -1486,96 +1486,96 @@ static struct snd_soc_dai_driver aic3x_dai = {
        .symmetric_rates = 1,
 };
 
-static void aic3x_mono_init(struct snd_soc_codec *codec)
+static void aic3x_mono_init(struct snd_soc_component *component)
 {
        /* DAC to Mono Line Out default volume and route to Output mixer */
-       snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
-       snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
 
        /* unmute all outputs */
-       snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, MONOLOPM_CTRL, UNMUTE, UNMUTE);
 
        /* PGA to Mono Line Out default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
 
        /* Line2 to Mono Out default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
 }
 
 /*
  * initialise the AIC3X driver
  * register the mixer and dsp interfaces with the kernel
  */
-static int aic3x_init(struct snd_soc_codec *codec)
+static int aic3x_init(struct snd_soc_component *component)
 {
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
 
-       snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
-       snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
+       snd_soc_component_write(component, AIC3X_PAGE_SELECT, PAGE0_SELECT);
+       snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);
 
        /* DAC default volume and mute */
-       snd_soc_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
-       snd_soc_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
+       snd_soc_component_write(component, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
+       snd_soc_component_write(component, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
 
        /* DAC to HP default volume and route to Output mixer */
-       snd_soc_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
-       snd_soc_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
-       snd_soc_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
-       snd_soc_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
        /* DAC to Line Out default volume and route to Output mixer */
-       snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
-       snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
+       snd_soc_component_write(component, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
 
        /* unmute all outputs */
-       snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE);
-       snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE);
-       snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
-       snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE);
-       snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
-       snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, LLOPM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, RLOPM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, HPLOUT_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, HPROUT_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, HPLCOM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_component_update_bits(component, HPRCOM_CTRL, UNMUTE, UNMUTE);
 
        /* ADC default volume and unmute */
-       snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
-       snd_soc_write(codec, RADC_VOL, DEFAULT_GAIN);
+       snd_soc_component_write(component, LADC_VOL, DEFAULT_GAIN);
+       snd_soc_component_write(component, RADC_VOL, DEFAULT_GAIN);
        /* By default route Line1 to ADC PGA mixer */
-       snd_soc_write(codec, LINE1L_2_LADC_CTRL, 0x0);
-       snd_soc_write(codec, LINE1R_2_RADC_CTRL, 0x0);
+       snd_soc_component_write(component, LINE1L_2_LADC_CTRL, 0x0);
+       snd_soc_component_write(component, LINE1R_2_RADC_CTRL, 0x0);
 
        /* PGA to HP Bypass default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
        /* PGA to Line Out default volume, disconnect from Output Mixer */
-       snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
-       snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
+       snd_soc_component_write(component, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
 
        /* On tlv320aic3104, these registers are reserved and must not be written */
        if (aic3x->model != AIC3X_MODEL_3104) {
                /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
-               snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
-               snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
-               snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
-               snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
+               snd_soc_component_write(component, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
+               snd_soc_component_write(component, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
+               snd_soc_component_write(component, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
+               snd_soc_component_write(component, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
                /* Line2 Line Out default volume, disconnect from Output Mixer */
-               snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
-               snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
+               snd_soc_component_write(component, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
+               snd_soc_component_write(component, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
        }
 
        switch (aic3x->model) {
        case AIC3X_MODEL_3X:
        case AIC3X_MODEL_33:
-               aic3x_mono_init(codec);
+               aic3x_mono_init(component);
                break;
        case AIC3X_MODEL_3007:
-               snd_soc_write(codec, CLASSD_CTRL, 0);
+               snd_soc_component_write(component, CLASSD_CTRL, 0);
                break;
        }
 
        /*  Output common-mode voltage = 1.5 V */
-       snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK,
+       snd_soc_component_update_bits(component, HPOUT_SC, HPOUT_SC_OCMV_MASK,
                            aic3x->ocmv << HPOUT_SC_OCMV_SHIFT);
 
        return 0;
@@ -1594,13 +1594,13 @@ static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
        return false;
 }
 
-static int aic3x_probe(struct snd_soc_codec *codec)
+static int aic3x_probe(struct snd_soc_component *component)
 {
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        int ret, i;
 
        INIT_LIST_HEAD(&aic3x->list);
-       aic3x->codec = codec;
+       aic3x->component = component;
 
        for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
                aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
@@ -1608,7 +1608,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
                ret = regulator_register_notifier(aic3x->supplies[i].consumer,
                                                  &aic3x->disable_nb[i].nb);
                if (ret) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to request regulator notifier: %d\n",
                                 ret);
                        goto err_notif;
@@ -1616,32 +1616,32 @@ static int aic3x_probe(struct snd_soc_codec *codec)
        }
 
        regcache_mark_dirty(aic3x->regmap);
-       aic3x_init(codec);
+       aic3x_init(component);
 
        if (aic3x->setup) {
                if (aic3x->model != AIC3X_MODEL_3104) {
                        /* setup GPIO functions */
-                       snd_soc_write(codec, AIC3X_GPIO1_REG,
+                       snd_soc_component_write(component, AIC3X_GPIO1_REG,
                                      (aic3x->setup->gpio_func[0] & 0xf) << 4);
-                       snd_soc_write(codec, AIC3X_GPIO2_REG,
+                       snd_soc_component_write(component, AIC3X_GPIO2_REG,
                                      (aic3x->setup->gpio_func[1] & 0xf) << 4);
                } else {
-                       dev_warn(codec->dev, "GPIO functionality is not supported on tlv320aic3104\n");
+                       dev_warn(component->dev, "GPIO functionality is not supported on tlv320aic3104\n");
                }
        }
 
        switch (aic3x->model) {
        case AIC3X_MODEL_3X:
        case AIC3X_MODEL_33:
-               snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls,
+               snd_soc_add_component_controls(component, aic3x_extra_snd_controls,
                                ARRAY_SIZE(aic3x_extra_snd_controls));
-               snd_soc_add_codec_controls(codec, aic3x_mono_controls,
+               snd_soc_add_component_controls(component, aic3x_mono_controls,
                                ARRAY_SIZE(aic3x_mono_controls));
                break;
        case AIC3X_MODEL_3007:
-               snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls,
+               snd_soc_add_component_controls(component, aic3x_extra_snd_controls,
                                ARRAY_SIZE(aic3x_extra_snd_controls));
-               snd_soc_add_codec_controls(codec,
+               snd_soc_add_component_controls(component,
                                &aic3x_classd_amp_gain_ctrl, 1);
                break;
        case AIC3X_MODEL_3104:
@@ -1653,7 +1653,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
        case AIC3X_MICBIAS_2_0V:
        case AIC3X_MICBIAS_2_5V:
        case AIC3X_MICBIAS_AVDDV:
-               snd_soc_update_bits(codec, MICBIAS_CTRL,
+               snd_soc_component_update_bits(component, MICBIAS_CTRL,
                                    MICBIAS_LEVEL_MASK,
                                    (aic3x->micbias_vg) << MICBIAS_LEVEL_SHIFT);
                break;
@@ -1666,7 +1666,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
                break;
        }
 
-       aic3x_add_widgets(codec);
+       aic3x_add_widgets(component);
 
        return 0;
 
@@ -1677,32 +1677,30 @@ err_notif:
        return ret;
 }
 
-static int aic3x_remove(struct snd_soc_codec *codec)
+static void aic3x_remove(struct snd_soc_component *component)
 {
-       struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+       struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
        int i;
 
        list_del(&aic3x->list);
        for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
                regulator_unregister_notifier(aic3x->supplies[i].consumer,
                                              &aic3x->disable_nb[i].nb);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_aic3x = {
-       .set_bias_level = aic3x_set_bias_level,
-       .idle_bias_off = true,
-       .probe = aic3x_probe,
-       .remove = aic3x_remove,
-       .component_driver = {
-               .controls               = aic3x_snd_controls,
-               .num_controls           = ARRAY_SIZE(aic3x_snd_controls),
-               .dapm_widgets           = aic3x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(aic3x_dapm_widgets),
-               .dapm_routes            = intercon,
-               .num_dapm_routes        = ARRAY_SIZE(intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_aic3x = {
+       .set_bias_level         = aic3x_set_bias_level,
+       .probe                  = aic3x_probe,
+       .remove                 = aic3x_remove,
+       .controls               = aic3x_snd_controls,
+       .num_controls           = ARRAY_SIZE(aic3x_snd_controls),
+       .dapm_widgets           = aic3x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(aic3x_dapm_widgets),
+       .dapm_routes            = intercon,
+       .num_dapm_routes        = ARRAY_SIZE(intercon),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static void aic3x_configure_ocmv(struct i2c_client *client)
@@ -1876,8 +1874,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
                                ret);
        }
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_aic3x, &aic3x_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_aic3x, &aic3x_dai, 1);
 
        if (ret != 0)
                goto err_gpio;
@@ -1898,7 +1896,6 @@ static int aic3x_i2c_remove(struct i2c_client *client)
 {
        struct aic3x_priv *aic3x = i2c_get_clientdata(client);
 
-       snd_soc_unregister_codec(&client->dev);
        if (gpio_is_valid(aic3x->gpio_reset) &&
            !aic3x_is_shared_reset(aic3x)) {
                gpio_set_value(aic3x->gpio_reset, 0);
index 8c71d2f876ff3de954c1b3637405e09840ed7f3f..a957eaeb7bc137e97c6809810f40a1f557a64cd8 100644 (file)
@@ -63,9 +63,9 @@
        (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
 
 static void dac33_calculate_times(struct snd_pcm_substream *substream,
-                                 struct snd_soc_codec *codec);
+                                 struct snd_soc_component *component);
 static int dac33_prepare_chip(struct snd_pcm_substream *substream,
-                             struct snd_soc_codec *codec);
+                             struct snd_soc_component *component);
 
 enum dac33_state {
        DAC33_IDLE = 0,
@@ -91,7 +91,7 @@ static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
 struct tlv320dac33_priv {
        struct mutex mutex;
        struct work_struct work;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
        struct snd_pcm_substream *substream;
        int power_gpio;
@@ -171,10 +171,10 @@ static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
 };
 
 /* Register read and write */
-static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
+static inline unsigned int dac33_read_reg_cache(struct snd_soc_component *component,
                                                unsigned reg)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        u8 *cache = dac33->reg_cache;
        if (reg >= DAC33_CACHEREGNUM)
                return 0;
@@ -182,10 +182,10 @@ static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
        return cache[reg];
 }
 
-static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
+static inline void dac33_write_reg_cache(struct snd_soc_component *component,
                                         u8 reg, u8 value)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        u8 *cache = dac33->reg_cache;
        if (reg >= DAC33_CACHEREGNUM)
                return;
@@ -193,10 +193,10 @@ static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
        cache[reg] = value;
 }
 
-static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_read(struct snd_soc_component *component, unsigned int reg,
                      u8 *value)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        int val, ret = 0;
 
        *value = reg & 0xff;
@@ -205,24 +205,24 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
        if (dac33->chip_power) {
                val = i2c_smbus_read_byte_data(dac33->i2c, value[0]);
                if (val < 0) {
-                       dev_err(codec->dev, "Read failed (%d)\n", val);
-                       value[0] = dac33_read_reg_cache(codec, reg);
+                       dev_err(component->dev, "Read failed (%d)\n", val);
+                       value[0] = dac33_read_reg_cache(component, reg);
                        ret = val;
                } else {
                        value[0] = val;
-                       dac33_write_reg_cache(codec, reg, val);
+                       dac33_write_reg_cache(component, reg, val);
                }
        } else {
-               value[0] = dac33_read_reg_cache(codec, reg);
+               value[0] = dac33_read_reg_cache(component, reg);
        }
 
        return ret;
 }
 
-static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_write(struct snd_soc_component *component, unsigned int reg,
                       unsigned int value)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        u8 data[2];
        int ret = 0;
 
@@ -234,11 +234,11 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
        data[0] = reg & 0xff;
        data[1] = value & 0xff;
 
-       dac33_write_reg_cache(codec, data[0], data[1]);
+       dac33_write_reg_cache(component, data[0], data[1]);
        if (dac33->chip_power) {
                ret = i2c_master_send(dac33->i2c, data, 2);
                if (ret != 2)
-                       dev_err(codec->dev, "Write failed (%d)\n", ret);
+                       dev_err(component->dev, "Write failed (%d)\n", ret);
                else
                        ret = 0;
        }
@@ -246,24 +246,24 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
        return ret;
 }
 
-static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_write_locked(struct snd_soc_component *component, unsigned int reg,
                              unsigned int value)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&dac33->mutex);
-       ret = dac33_write(codec, reg, value);
+       ret = dac33_write(component, reg, value);
        mutex_unlock(&dac33->mutex);
 
        return ret;
 }
 
 #define DAC33_I2C_ADDR_AUTOINC 0x80
-static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
+static int dac33_write16(struct snd_soc_component *component, unsigned int reg,
                       unsigned int value)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        u8 data[3];
        int ret = 0;
 
@@ -277,15 +277,15 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
        data[1] = (value >> 8) & 0xff;
        data[2] = value & 0xff;
 
-       dac33_write_reg_cache(codec, data[0], data[1]);
-       dac33_write_reg_cache(codec, data[0] + 1, data[2]);
+       dac33_write_reg_cache(component, data[0], data[1]);
+       dac33_write_reg_cache(component, data[0] + 1, data[2]);
 
        if (dac33->chip_power) {
                /* We need to set autoincrement mode for 16 bit writes */
                data[0] |= DAC33_I2C_ADDR_AUTOINC;
                ret = i2c_master_send(dac33->i2c, data, 3);
                if (ret != 3)
-                       dev_err(codec->dev, "Write failed (%d)\n", ret);
+                       dev_err(component->dev, "Write failed (%d)\n", ret);
                else
                        ret = 0;
        }
@@ -293,52 +293,52 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
        return ret;
 }
 
-static void dac33_init_chip(struct snd_soc_codec *codec)
+static void dac33_init_chip(struct snd_soc_component *component)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        if (unlikely(!dac33->chip_power))
                return;
 
        /* A : DAC sample rate Fsref/1.5 */
-       dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
+       dac33_write(component, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
        /* B : DAC src=normal, not muted */
-       dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
+       dac33_write(component, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
                                             DAC33_DACSRCL_LEFT);
        /* C : (defaults) */
-       dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
+       dac33_write(component, DAC33_DAC_CTRL_C, 0x00);
 
        /* 73 : volume soft stepping control,
         clock source = internal osc (?) */
-       dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
+       dac33_write(component, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
 
        /* Restore only selected registers (gains mostly) */
-       dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
-                   dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
-       dac33_write(codec, DAC33_RDAC_DIG_VOL_CTRL,
-                   dac33_read_reg_cache(codec, DAC33_RDAC_DIG_VOL_CTRL));
-
-       dac33_write(codec, DAC33_LINEL_TO_LLO_VOL,
-                   dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
-       dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
-                   dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
-
-       dac33_write(codec, DAC33_OUT_AMP_CTRL,
-                   dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL));
-
-       dac33_write(codec, DAC33_LDAC_PWR_CTRL,
-                   dac33_read_reg_cache(codec, DAC33_LDAC_PWR_CTRL));
-       dac33_write(codec, DAC33_RDAC_PWR_CTRL,
-                   dac33_read_reg_cache(codec, DAC33_RDAC_PWR_CTRL));
+       dac33_write(component, DAC33_LDAC_DIG_VOL_CTRL,
+                   dac33_read_reg_cache(component, DAC33_LDAC_DIG_VOL_CTRL));
+       dac33_write(component, DAC33_RDAC_DIG_VOL_CTRL,
+                   dac33_read_reg_cache(component, DAC33_RDAC_DIG_VOL_CTRL));
+
+       dac33_write(component, DAC33_LINEL_TO_LLO_VOL,
+                   dac33_read_reg_cache(component, DAC33_LINEL_TO_LLO_VOL));
+       dac33_write(component, DAC33_LINER_TO_RLO_VOL,
+                   dac33_read_reg_cache(component, DAC33_LINER_TO_RLO_VOL));
+
+       dac33_write(component, DAC33_OUT_AMP_CTRL,
+                   dac33_read_reg_cache(component, DAC33_OUT_AMP_CTRL));
+
+       dac33_write(component, DAC33_LDAC_PWR_CTRL,
+                   dac33_read_reg_cache(component, DAC33_LDAC_PWR_CTRL));
+       dac33_write(component, DAC33_RDAC_PWR_CTRL,
+                   dac33_read_reg_cache(component, DAC33_RDAC_PWR_CTRL));
 }
 
-static inline int dac33_read_id(struct snd_soc_codec *codec)
+static inline int dac33_read_id(struct snd_soc_component *component)
 {
        int i, ret = 0;
        u8 reg;
 
        for (i = 0; i < 3; i++) {
-               ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, &reg);
+               ret = dac33_read(component, DAC33_DEVICE_ID_MSB + i, &reg);
                if (ret < 0)
                        break;
        }
@@ -346,44 +346,44 @@ static inline int dac33_read_id(struct snd_soc_codec *codec)
        return ret;
 }
 
-static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
+static inline void dac33_soft_power(struct snd_soc_component *component, int power)
 {
        u8 reg;
 
-       reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+       reg = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
        if (power)
                reg |= DAC33_PDNALLB;
        else
                reg &= ~(DAC33_PDNALLB | DAC33_OSCPDNB |
                         DAC33_DACRPDNB | DAC33_DACLPDNB);
-       dac33_write(codec, DAC33_PWR_CTRL, reg);
+       dac33_write(component, DAC33_PWR_CTRL, reg);
 }
 
-static inline void dac33_disable_digital(struct snd_soc_codec *codec)
+static inline void dac33_disable_digital(struct snd_soc_component *component)
 {
        u8 reg;
 
        /* Stop the DAI clock */
-       reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+       reg = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
        reg &= ~DAC33_BCLKON;
-       dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
+       dac33_write(component, DAC33_SER_AUDIOIF_CTRL_B, reg);
 
        /* Power down the Oscillator, and DACs */
-       reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+       reg = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
        reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
-       dac33_write(codec, DAC33_PWR_CTRL, reg);
+       dac33_write(component, DAC33_PWR_CTRL, reg);
 }
 
-static int dac33_hard_power(struct snd_soc_codec *codec, int power)
+static int dac33_hard_power(struct snd_soc_component *component, int power)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        mutex_lock(&dac33->mutex);
 
        /* Safety check */
        if (unlikely(power == dac33->chip_power)) {
-               dev_dbg(codec->dev, "Trying to set the same power state: %s\n",
+               dev_dbg(component->dev, "Trying to set the same power state: %s\n",
                        power ? "ON" : "OFF");
                goto exit;
        }
@@ -392,7 +392,7 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
                ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
                                          dac33->supplies);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to enable supplies: %d\n", ret);
                                goto exit;
                }
@@ -402,14 +402,14 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
 
                dac33->chip_power = 1;
        } else {
-               dac33_soft_power(codec, 0);
+               dac33_soft_power(component, 0);
                if (dac33->power_gpio >= 0)
                        gpio_set_value(dac33->power_gpio, 0);
 
                ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
                                             dac33->supplies);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to disable supplies: %d\n", ret);
                        goto exit;
                }
@@ -425,18 +425,18 @@ exit:
 static int dac33_playback_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                if (likely(dac33->substream)) {
-                       dac33_calculate_times(dac33->substream, codec);
-                       dac33_prepare_chip(dac33->substream, codec);
+                       dac33_calculate_times(dac33->substream, component);
+                       dac33_prepare_chip(dac33->substream, component);
                }
                break;
        case SND_SOC_DAPM_POST_PMD:
-               dac33_disable_digital(codec);
+               dac33_disable_digital(component);
                break;
        }
        return 0;
@@ -445,8 +445,8 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w,
 static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.enumerated.item[0] = dac33->fifo_mode;
 
@@ -456,14 +456,14 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
 static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if (dac33->fifo_mode == ucontrol->value.enumerated.item[0])
                return 0;
        /* Do not allow changes while stream is running*/
-       if (snd_soc_codec_is_active(codec))
+       if (snd_soc_component_is_active(component))
                return -EPERM;
 
        if (ucontrol->value.enumerated.item[0] >= DAC33_FIFO_LAST_MODE)
@@ -623,7 +623,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"RIGHT_LO", NULL, "Codec Power"},
 };
 
-static int dac33_set_bias_level(struct snd_soc_codec *codec,
+static int dac33_set_bias_level(struct snd_soc_component *component,
                                enum snd_soc_bias_level level)
 {
        int ret;
@@ -634,20 +634,20 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       /* Coming from OFF, switch on the codec */
-                       ret = dac33_hard_power(codec, 1);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       /* Coming from OFF, switch on the component */
+                       ret = dac33_hard_power(component, 1);
                        if (ret != 0)
                                return ret;
 
-                       dac33_init_chip(codec);
+                       dac33_init_chip(component);
                }
                break;
        case SND_SOC_BIAS_OFF:
-               /* Do not power off, when the codec is already off */
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               /* Do not power off, when the component is already off */
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        return 0;
-               ret = dac33_hard_power(codec, 0);
+               ret = dac33_hard_power(component, 0);
                if (ret != 0)
                        return ret;
                break;
@@ -658,13 +658,13 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
 
 static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 {
-       struct snd_soc_codec *codec = dac33->codec;
+       struct snd_soc_component *component = dac33->component;
        unsigned int delay;
        unsigned long flags;
 
        switch (dac33->fifo_mode) {
        case DAC33_FIFO_MODE1:
-               dac33_write16(codec, DAC33_NSAMPLE_MSB,
+               dac33_write16(component, DAC33_NSAMPLE_MSB,
                        DAC33_THRREG(dac33->nsample));
 
                /* Take the timestamps */
@@ -673,13 +673,13 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
                dac33->t_stamp1 = dac33->t_stamp2;
                spin_unlock_irqrestore(&dac33->lock, flags);
 
-               dac33_write16(codec, DAC33_PREFILL_MSB,
+               dac33_write16(component, DAC33_PREFILL_MSB,
                                DAC33_THRREG(dac33->alarm_threshold));
                /* Enable Alarm Threshold IRQ with a delay */
                delay = SAMPLES_TO_US(dac33->burst_rate,
                                     dac33->alarm_threshold) + 1000;
                usleep_range(delay, delay + 500);
-               dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
+               dac33_write(component, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
                break;
        case DAC33_FIFO_MODE7:
                /* Take the timestamp */
@@ -689,14 +689,14 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
                dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
                spin_unlock_irqrestore(&dac33->lock, flags);
 
-               dac33_write16(codec, DAC33_PREFILL_MSB,
+               dac33_write16(component, DAC33_PREFILL_MSB,
                                DAC33_THRREG(DAC33_MODE7_MARGIN));
 
                /* Enable Upper Threshold IRQ */
-               dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
+               dac33_write(component, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
                break;
        default:
-               dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+               dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
                                                        dac33->fifo_mode);
                break;
        }
@@ -704,7 +704,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
 
 static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 {
-       struct snd_soc_codec *codec = dac33->codec;
+       struct snd_soc_component *component = dac33->component;
        unsigned long flags;
 
        switch (dac33->fifo_mode) {
@@ -714,14 +714,14 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
                dac33->t_stamp2 = ktime_to_us(ktime_get());
                spin_unlock_irqrestore(&dac33->lock, flags);
 
-               dac33_write16(codec, DAC33_NSAMPLE_MSB,
+               dac33_write16(component, DAC33_NSAMPLE_MSB,
                                DAC33_THRREG(dac33->nsample));
                break;
        case DAC33_FIFO_MODE7:
                /* At the moment we are not using interrupts in mode7 */
                break;
        default:
-               dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+               dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
                                                        dac33->fifo_mode);
                break;
        }
@@ -729,12 +729,12 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
 
 static void dac33_work(struct work_struct *work)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct tlv320dac33_priv *dac33;
        u8 reg;
 
        dac33 = container_of(work, struct tlv320dac33_priv, work);
-       codec = dac33->codec;
+       component = dac33->component;
 
        mutex_lock(&dac33->mutex);
        switch (dac33->state) {
@@ -750,12 +750,12 @@ static void dac33_work(struct work_struct *work)
        case DAC33_FLUSH:
                dac33->state = DAC33_IDLE;
                /* Mask all interrupts from dac33 */
-               dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
+               dac33_write(component, DAC33_FIFO_IRQ_MASK, 0);
 
                /* flush fifo */
-               reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
+               reg = dac33_read_reg_cache(component, DAC33_FIFO_CTRL_A);
                reg |= DAC33_FIFOFLUSH;
-               dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
+               dac33_write(component, DAC33_FIFO_CTRL_A, reg);
                break;
        }
        mutex_unlock(&dac33->mutex);
@@ -763,8 +763,8 @@ static void dac33_work(struct work_struct *work)
 
 static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
 {
-       struct snd_soc_codec *codec = dev;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dev;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        unsigned long flags;
 
        spin_lock_irqsave(&dac33->lock, flags);
@@ -778,25 +778,25 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
        return IRQ_HANDLED;
 }
 
-static void dac33_oscwait(struct snd_soc_codec *codec)
+static void dac33_oscwait(struct snd_soc_component *component)
 {
        int timeout = 60;
        u8 reg;
 
        do {
                usleep_range(1000, 2000);
-               dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
+               dac33_read(component, DAC33_INT_OSC_STATUS, &reg);
        } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
        if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "internal oscillator calibration failed\n");
 }
 
 static int dac33_startup(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        /* Stream started, save the substream pointer */
        dac33->substream = substream;
@@ -807,8 +807,8 @@ static int dac33_startup(struct snd_pcm_substream *substream,
 static void dac33_shutdown(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        dac33->substream = NULL;
 }
@@ -819,8 +819,8 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
                           struct snd_pcm_hw_params *params,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        /* Check parameters for validity */
        switch (params_rate(params)) {
@@ -828,7 +828,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
        case 48000:
                break;
        default:
-               dev_err(codec->dev, "unsupported rate %d\n",
+               dev_err(component->dev, "unsupported rate %d\n",
                        params_rate(params));
                return -EINVAL;
        }
@@ -843,7 +843,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
                dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64);
                break;
        default:
-               dev_err(codec->dev, "unsupported width %d\n",
+               dev_err(component->dev, "unsupported width %d\n",
                        params_width(params));
                return -EINVAL;
        }
@@ -862,9 +862,9 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
  * Use the known, working sequence of register writes to initialize the dac33.
  */
 static int dac33_prepare_chip(struct snd_pcm_substream *substream,
-                             struct snd_soc_codec *codec)
+                             struct snd_soc_component *component)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
        u8 aictrl_a, aictrl_b, fifoctrl_a;
 
@@ -876,16 +876,16 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
                                         dac33->refclk);
                break;
        default:
-               dev_err(codec->dev, "unsupported rate %d\n",
+               dev_err(component->dev, "unsupported rate %d\n",
                        substream->runtime->rate);
                return -EINVAL;
        }
 
 
-       aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
+       aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A);
        aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
        /* Read FIFO control A, and clear FIFO flush bit */
-       fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
+       fifoctrl_a = dac33_read_reg_cache(component, DAC33_FIFO_CTRL_A);
        fifoctrl_a &= ~DAC33_FIFOFLUSH;
 
        fifoctrl_a &= ~DAC33_WIDTH;
@@ -898,7 +898,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
                aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24);
                break;
        default:
-               dev_err(codec->dev, "unsupported format %d\n",
+               dev_err(component->dev, "unsupported format %d\n",
                        substream->runtime->format);
                return -EINVAL;
        }
@@ -914,57 +914,57 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
                return 0;
        }
 
-       dac33_soft_power(codec, 0);
-       dac33_soft_power(codec, 1);
+       dac33_soft_power(component, 0);
+       dac33_soft_power(component, 1);
 
-       reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
-       dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
+       reg_tmp = dac33_read_reg_cache(component, DAC33_INT_OSC_CTRL);
+       dac33_write(component, DAC33_INT_OSC_CTRL, reg_tmp);
 
        /* Write registers 0x08 and 0x09 (MSB, LSB) */
-       dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
+       dac33_write16(component, DAC33_INT_OSC_FREQ_RAT_A, oscset);
 
        /* OSC calibration time */
-       dac33_write(codec, DAC33_CALIB_TIME, 96);
+       dac33_write(component, DAC33_CALIB_TIME, 96);
 
        /* adjustment treshold & step */
-       dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
+       dac33_write(component, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
                                                 DAC33_ADJSTEP(1));
 
        /* div=4 / gain=1 / div */
-       dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
+       dac33_write(component, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
 
-       pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
+       pwr_ctrl = dac33_read_reg_cache(component, DAC33_PWR_CTRL);
        pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
-       dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
+       dac33_write(component, DAC33_PWR_CTRL, pwr_ctrl);
 
-       dac33_oscwait(codec);
+       dac33_oscwait(component);
 
        if (dac33->fifo_mode) {
                /* Generic for all FIFO modes */
                /* 50-51 : ASRC Control registers */
-               dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
-               dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
+               dac33_write(component, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1));
+               dac33_write(component, DAC33_ASRC_CTRL_B, 1); /* ??? */
 
                /* Write registers 0x34 and 0x35 (MSB, LSB) */
-               dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
+               dac33_write16(component, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
 
                /* Set interrupts to high active */
-               dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
+               dac33_write(component, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
        } else {
                /* FIFO bypass mode */
                /* 50-51 : ASRC Control registers */
-               dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
-               dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
+               dac33_write(component, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
+               dac33_write(component, DAC33_ASRC_CTRL_B, 0); /* ??? */
        }
 
        /* Interrupt behaviour configuration */
        switch (dac33->fifo_mode) {
        case DAC33_FIFO_MODE1:
-               dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
+               dac33_write(component, DAC33_FIFO_IRQ_MODE_B,
                            DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
                break;
        case DAC33_FIFO_MODE7:
-               dac33_write(codec, DAC33_FIFO_IRQ_MODE_A,
+               dac33_write(component, DAC33_FIFO_IRQ_MODE_A,
                        DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
                break;
        default:
@@ -972,7 +972,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
                break;
        }
 
-       aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+       aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
 
        switch (dac33->fifo_mode) {
        case DAC33_FIFO_MODE1:
@@ -1014,9 +1014,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
                break;
        }
 
-       dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
-       dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
-       dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
+       dac33_write(component, DAC33_FIFO_CTRL_A, fifoctrl_a);
+       dac33_write(component, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
+       dac33_write(component, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
 
        /*
         * BCLK divide ratio
@@ -1028,17 +1028,17 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
         * 255: 255
         */
        if (dac33->fifo_mode)
-               dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
+               dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C,
                                                        dac33->burst_bclkdiv);
        else
                if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE)
-                       dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
+                       dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C, 32);
                else
-                       dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16);
+                       dac33_write(component, DAC33_SER_AUDIOIF_CTRL_C, 16);
 
        switch (dac33->fifo_mode) {
        case DAC33_FIFO_MODE1:
-               dac33_write16(codec, DAC33_ATHR_MSB,
+               dac33_write16(component, DAC33_ATHR_MSB,
                              DAC33_THRREG(dac33->alarm_threshold));
                break;
        case DAC33_FIFO_MODE7:
@@ -1046,8 +1046,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
                 * Configure the threshold levels, and leave 10 sample space
                 * at the bottom, and also at the top of the FIFO
                 */
-               dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
-               dac33_write16(codec, DAC33_LTHR_MSB,
+               dac33_write16(component, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
+               dac33_write16(component, DAC33_LTHR_MSB,
                              DAC33_THRREG(DAC33_MODE7_MARGIN));
                break;
        default:
@@ -1060,9 +1060,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream,
 }
 
 static void dac33_calculate_times(struct snd_pcm_substream *substream,
-                                 struct snd_soc_codec *codec)
+                                 struct snd_soc_component *component)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        unsigned int period_size = substream->runtime->period_size;
        unsigned int rate = substream->runtime->rate;
        unsigned int nsample_limit;
@@ -1119,8 +1119,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream,
 static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (cmd) {
@@ -1151,8 +1151,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
                        struct snd_pcm_substream *substream,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        unsigned long long t0, t1, t_now;
        unsigned int time_delta, uthr;
        int samples_out, samples_in, samples;
@@ -1284,7 +1284,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
                }
                break;
        default:
-               dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
+               dev_warn(component->dev, "Unhandled FIFO mode: %d\n",
                                                        dac33->fifo_mode);
                break;
        }
@@ -1295,12 +1295,12 @@ out:
 static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        u8 ioc_reg, asrcb_reg;
 
-       ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
-       asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
+       ioc_reg = dac33_read_reg_cache(component, DAC33_INT_OSC_CTRL);
+       asrcb_reg = dac33_read_reg_cache(component, DAC33_ASRC_CTRL_B);
        switch (clk_id) {
        case TLV320DAC33_MCLK:
                ioc_reg |= DAC33_REFSEL;
@@ -1311,13 +1311,13 @@ static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                asrcb_reg &= ~DAC33_SRCREFSEL;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
+               dev_err(component->dev, "Invalid clock ID (%d)\n", clk_id);
                break;
        }
        dac33->refclk = freq;
 
-       dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
-       dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
+       dac33_write_reg_cache(component, DAC33_INT_OSC_CTRL, ioc_reg);
+       dac33_write_reg_cache(component, DAC33_ASRC_CTRL_B, asrcb_reg);
 
        return 0;
 }
@@ -1325,12 +1325,12 @@ static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
                             unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        u8 aictrl_a, aictrl_b;
 
-       aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
-       aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
+       aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A);
+       aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B);
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -1340,7 +1340,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
        case SND_SOC_DAIFMT_CBS_CFS:
                /* Codec Slave */
                if (dac33->fifo_mode) {
-                       dev_err(codec->dev, "FIFO mode requires master mode\n");
+                       dev_err(component->dev, "FIFO mode requires master mode\n");
                        return -EINVAL;
                } else
                        aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
@@ -1366,35 +1366,35 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
                aictrl_a |= DAC33_AFMT_LEFT_J;
                break;
        default:
-               dev_err(codec->dev, "Unsupported format (%u)\n",
+               dev_err(component->dev, "Unsupported format (%u)\n",
                        fmt & SND_SOC_DAIFMT_FORMAT_MASK);
                return -EINVAL;
        }
 
-       dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
-       dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
+       dac33_write_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
+       dac33_write_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
 
        return 0;
 }
 
-static int dac33_soc_probe(struct snd_soc_codec *codec)
+static int dac33_soc_probe(struct snd_soc_component *component)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
-       dac33->codec = codec;
+       dac33->component = component;
 
        /* Read the tlv320dac33 ID registers */
-       ret = dac33_hard_power(codec, 1);
+       ret = dac33_hard_power(component, 1);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
+               dev_err(component->dev, "Failed to power up component: %d\n", ret);
                goto err_power;
        }
-       ret = dac33_read_id(codec);
-       dac33_hard_power(codec, 0);
+       ret = dac33_read_id(component);
+       dac33_hard_power(component, 0);
 
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to read chip ID: %d\n", ret);
+               dev_err(component->dev, "Failed to read chip ID: %d\n", ret);
                ret = -ENODEV;
                goto err_power;
        }
@@ -1403,9 +1403,9 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
        if (dac33->irq >= 0) {
                ret = request_irq(dac33->irq, dac33_interrupt_handler,
                                  IRQF_TRIGGER_RISING,
-                                 codec->component.name, codec);
+                                 component->name, component);
                if (ret < 0) {
-                       dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
+                       dev_err(component->dev, "Could not request IRQ%d (%d)\n",
                                                dac33->irq, ret);
                        dac33->irq = -1;
                }
@@ -1416,41 +1416,38 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
 
        /* Only add the FIFO controls, if we have valid IRQ number */
        if (dac33->irq >= 0)
-               snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
+               snd_soc_add_component_controls(component, dac33_mode_snd_controls,
                                     ARRAY_SIZE(dac33_mode_snd_controls));
 
 err_power:
        return ret;
 }
 
-static int dac33_soc_remove(struct snd_soc_codec *codec)
+static void dac33_soc_remove(struct snd_soc_component *component)
 {
-       struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
+       struct tlv320dac33_priv *dac33 = snd_soc_component_get_drvdata(component);
 
        if (dac33->irq >= 0) {
-               free_irq(dac33->irq, dac33->codec);
+               free_irq(dac33->irq, dac33->component);
                flush_work(&dac33->work);
        }
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
-       .read = dac33_read_reg_cache,
-       .write = dac33_write_locked,
-       .set_bias_level = dac33_set_bias_level,
-       .idle_bias_off = true,
-
-       .probe = dac33_soc_probe,
-       .remove = dac33_soc_remove,
-
-       .component_driver = {
-               .controls               = dac33_snd_controls,
-               .num_controls           = ARRAY_SIZE(dac33_snd_controls),
-               .dapm_widgets           = dac33_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(dac33_dapm_widgets),
-               .dapm_routes            = audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_tlv320dac33 = {
+       .read                   = dac33_read_reg_cache,
+       .write                  = dac33_write_locked,
+       .set_bias_level         = dac33_set_bias_level,
+       .probe                  = dac33_soc_probe,
+       .remove                 = dac33_soc_remove,
+       .controls               = dac33_snd_controls,
+       .num_controls           = ARRAY_SIZE(dac33_snd_controls),
+       .dapm_widgets           = dac33_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(dac33_dapm_widgets),
+       .dapm_routes            = audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(audio_map),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 #define DAC33_RATES    (SNDRV_PCM_RATE_44100 | \
@@ -1544,8 +1541,8 @@ static int dac33_i2c_probe(struct i2c_client *client,
                goto err_get;
        }
 
-       ret = snd_soc_register_codec(&client->dev,
-                       &soc_codec_dev_tlv320dac33, &dac33_dai, 1);
+       ret = devm_snd_soc_register_component(&client->dev,
+                       &soc_component_dev_tlv320dac33, &dac33_dai, 1);
        if (ret < 0)
                goto err_get;
 
@@ -1562,12 +1559,11 @@ static int dac33_i2c_remove(struct i2c_client *client)
        struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
 
        if (unlikely(dac33->chip_power))
-               dac33_hard_power(dac33->codec, 0);
+               dac33_hard_power(dac33->component, 0);
 
        if (dac33->power_gpio >= 0)
                gpio_free(dac33->power_gpio);
 
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index e7661d0315e62b862a15ed7c93485f7558a85a15..bbfc73a79b18497d39270f77c034c34fc7fe35a8 100644 (file)
@@ -3,14 +3,19 @@
 // Copyright 2017 Tempo Semiconductor, Inc.
 // Author: Steven Eckhoff <steven.eckhoff.opensource@gmail.com>
 
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
 #include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/string.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/mutex.h>
-#include <linux/regmap.h>
+#include <sound/tlv.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
-#include <sound/tlv.h>
 
 #include "tscs42xx.h"
 
@@ -91,15 +96,15 @@ static const struct regmap_config tscs42xx_regmap = {
 };
 
 #define MAX_PLL_LOCK_20MS_WAITS 1
-static bool plls_locked(struct snd_soc_codec *codec)
+static bool plls_locked(struct snd_soc_component *component)
 {
        int ret;
        int count = MAX_PLL_LOCK_20MS_WAITS;
 
        do {
-               ret = snd_soc_read(codec, R_PLLCTL0);
+               ret = snd_soc_component_read32(component, R_PLLCTL0);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to read PLL lock status (%d)\n", ret);
                        return false;
                } else if (ret > 0) {
@@ -131,10 +136,10 @@ static int sample_rate_to_pll_freq_out(int sample_rate)
 }
 
 #define DACCRSTAT_MAX_TRYS 10
-static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
+static int write_coeff_ram(struct snd_soc_component *component, u8 *coeff_ram,
        unsigned int addr, unsigned int coeff_cnt)
 {
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        int cnt;
        int trys;
        int ret;
@@ -142,9 +147,9 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
        for (cnt = 0; cnt < coeff_cnt; cnt++, addr++) {
 
                for (trys = 0; trys < DACCRSTAT_MAX_TRYS; trys++) {
-                       ret = snd_soc_read(codec, R_DACCRSTAT);
+                       ret = snd_soc_component_read32(component, R_DACCRSTAT);
                        if (ret < 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to read stat (%d)\n", ret);
                                return ret;
                        }
@@ -154,14 +159,14 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
 
                if (trys == DACCRSTAT_MAX_TRYS) {
                        ret = -EIO;
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "dac coefficient write error (%d)\n", ret);
                        return ret;
                }
 
                ret = regmap_write(tscs42xx->regmap, R_DACCRADDR, addr);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to write dac ram address (%d)\n", ret);
                        return ret;
                }
@@ -170,7 +175,7 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
                        &coeff_ram[addr * COEFF_SIZE],
                        COEFF_SIZE);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to write dac ram (%d)\n", ret);
                        return ret;
                }
@@ -179,9 +184,9 @@ static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram,
        return 0;
 }
 
-static int power_up_audio_plls(struct snd_soc_codec *codec)
+static int power_up_audio_plls(struct snd_soc_component *component)
 {
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        int freq_out;
        int ret;
        unsigned int mask;
@@ -199,20 +204,20 @@ static int power_up_audio_plls(struct snd_soc_codec *codec)
                break;
        default:
                ret = -EINVAL;
-               dev_err(codec->dev, "Unrecognized PLL output freq (%d)\n", ret);
+               dev_err(component->dev, "Unrecognized PLL output freq (%d)\n", ret);
                return ret;
        }
 
        mutex_lock(&tscs42xx->pll_lock);
 
-       ret = snd_soc_update_bits(codec, R_PLLCTL1C, mask, val);
+       ret = snd_soc_component_update_bits(component, R_PLLCTL1C, mask, val);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to turn PLL on (%d)\n", ret);
+               dev_err(component->dev, "Failed to turn PLL on (%d)\n", ret);
                goto exit;
        }
 
-       if (!plls_locked(codec)) {
-               dev_err(codec->dev, "Failed to lock plls\n");
+       if (!plls_locked(component)) {
+               dev_err(component->dev, "Failed to lock plls\n");
                ret = -ENOMSG;
                goto exit;
        }
@@ -224,25 +229,25 @@ exit:
        return ret;
 }
 
-static int power_down_audio_plls(struct snd_soc_codec *codec)
+static int power_down_audio_plls(struct snd_soc_component *component)
 {
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&tscs42xx->pll_lock);
 
-       ret = snd_soc_update_bits(codec, R_PLLCTL1C,
+       ret = snd_soc_component_update_bits(component, R_PLLCTL1C,
                        RM_PLLCTL1C_PDB_PLL1,
                        RV_PLLCTL1C_PDB_PLL1_DISABLE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to turn PLL off (%d)\n", ret);
+               dev_err(component->dev, "Failed to turn PLL off (%d)\n", ret);
                goto exit;
        }
-       ret = snd_soc_update_bits(codec, R_PLLCTL1C,
+       ret = snd_soc_component_update_bits(component, R_PLLCTL1C,
                        RM_PLLCTL1C_PDB_PLL2,
                        RV_PLLCTL1C_PDB_PLL2_DISABLE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to turn PLL off (%d)\n", ret);
+               dev_err(component->dev, "Failed to turn PLL off (%d)\n", ret);
                goto exit;
        }
 
@@ -256,8 +261,8 @@ exit:
 static int coeff_ram_get(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        struct coeff_ram_ctl *ctl =
                (struct coeff_ram_ctl *)kcontrol->private_value;
        struct soc_bytes_ext *params = &ctl->bytes_ext;
@@ -275,8 +280,8 @@ static int coeff_ram_get(struct snd_kcontrol *kcontrol,
 static int coeff_ram_put(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        struct coeff_ram_ctl *ctl =
                (struct coeff_ram_ctl *)kcontrol->private_value;
        struct soc_bytes_ext *params = &ctl->bytes_ext;
@@ -292,11 +297,11 @@ static int coeff_ram_put(struct snd_kcontrol *kcontrol,
 
        mutex_lock(&tscs42xx->pll_lock);
 
-       if (plls_locked(codec)) {
-               ret = write_coeff_ram(codec, tscs42xx->coeff_ram,
+       if (plls_locked(component)) {
+               ret = write_coeff_ram(component, tscs42xx->coeff_ram,
                        ctl->addr, coeff_cnt);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to flush coeff ram cache (%d)\n", ret);
                        goto exit;
                }
@@ -358,13 +363,13 @@ static int dapm_micb_event(struct snd_soc_dapm_widget *w,
 static int pll_event(struct snd_soc_dapm_widget *w,
                     struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        int ret;
 
        if (SND_SOC_DAPM_EVENT_ON(event))
-               ret = power_up_audio_plls(codec);
+               ret = power_up_audio_plls(component);
        else
-               ret = power_down_audio_plls(codec);
+               ret = power_down_audio_plls(component);
 
        return ret;
 }
@@ -372,14 +377,14 @@ static int pll_event(struct snd_soc_dapm_widget *w,
 static int dac_event(struct snd_soc_dapm_widget *w,
                     struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        int ret;
 
        mutex_lock(&tscs42xx->coeff_ram_lock);
 
        if (tscs42xx->coeff_ram_synced == false) {
-               ret = write_coeff_ram(codec, tscs42xx->coeff_ram, 0x00,
+               ret = write_coeff_ram(component, tscs42xx->coeff_ram, 0x00,
                        COEFF_RAM_COEFF_COUNT);
                if (ret < 0)
                        goto exit;
@@ -790,7 +795,7 @@ static const struct snd_kcontrol_new tscs42xx_snd_controls[] = {
                R_DACMBCREL3L, 2),
 };
 
-static int setup_sample_format(struct snd_soc_codec *codec,
+static int setup_sample_format(struct snd_soc_component *component,
                snd_pcm_format_t format)
 {
        unsigned int width;
@@ -811,21 +816,21 @@ static int setup_sample_format(struct snd_soc_codec *codec,
                break;
        default:
                ret = -EINVAL;
-               dev_err(codec->dev, "Unsupported format width (%d)\n", ret);
+               dev_err(component->dev, "Unsupported format width (%d)\n", ret);
                return ret;
        }
-       ret = snd_soc_update_bits(codec, R_AIC1, RM_AIC1_WL, width);
+       ret = snd_soc_component_update_bits(component, R_AIC1, RM_AIC1_WL, width);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set sample width (%d)\n", ret);
+               dev_err(component->dev, "Failed to set sample width (%d)\n", ret);
                return ret;
        }
 
        return 0;
 }
 
-static int setup_sample_rate(struct snd_soc_codec *codec, unsigned int rate)
+static int setup_sample_rate(struct snd_soc_component *component, unsigned int rate)
 {
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        unsigned int br, bm;
        int ret;
 
@@ -871,29 +876,29 @@ static int setup_sample_rate(struct snd_soc_codec *codec, unsigned int rate)
                bm = RV_DACSR_DBM_2;
                break;
        default:
-               dev_err(codec->dev, "Unsupported sample rate %d\n", rate);
+               dev_err(component->dev, "Unsupported sample rate %d\n", rate);
                return -EINVAL;
        }
 
        /* DAC and ADC share bit and frame clock */
-       ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBR, br);
+       ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBR, br);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+               dev_err(component->dev, "Failed to update register (%d)\n", ret);
                return ret;
        }
-       ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBM, bm);
+       ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBM, bm);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+               dev_err(component->dev, "Failed to update register (%d)\n", ret);
                return ret;
        }
-       ret = snd_soc_update_bits(codec, R_ADCSR, RM_DACSR_DBR, br);
+       ret = snd_soc_component_update_bits(component, R_ADCSR, RM_DACSR_DBR, br);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+               dev_err(component->dev, "Failed to update register (%d)\n", ret);
                return ret;
        }
-       ret = snd_soc_update_bits(codec, R_ADCSR, RM_DACSR_DBM, bm);
+       ret = snd_soc_component_update_bits(component, R_ADCSR, RM_DACSR_DBM, bm);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to update register (%d)\n", ret);
+               dev_err(component->dev, "Failed to update register (%d)\n", ret);
                return ret;
        }
 
@@ -1025,7 +1030,7 @@ static const struct pll_ctl *get_pll_ctl(int input_freq)
        return pll_ctl;
 }
 
-static int set_pll_ctl_from_input_freq(struct snd_soc_codec *codec,
+static int set_pll_ctl_from_input_freq(struct snd_soc_component *component,
                const int input_freq)
 {
        int ret;
@@ -1035,18 +1040,18 @@ static int set_pll_ctl_from_input_freq(struct snd_soc_codec *codec,
        pll_ctl = get_pll_ctl(input_freq);
        if (!pll_ctl) {
                ret = -EINVAL;
-               dev_err(codec->dev, "No PLL input entry for %d (%d)\n",
+               dev_err(component->dev, "No PLL input entry for %d (%d)\n",
                        input_freq, ret);
                return ret;
        }
 
        for (i = 0; i < PLL_REG_SETTINGS_COUNT; ++i) {
-               ret = snd_soc_update_bits(codec,
+               ret = snd_soc_component_update_bits(component,
                        pll_ctl->settings[i].addr,
                        pll_ctl->settings[i].mask,
                        pll_ctl->settings[i].val);
                if (ret < 0) {
-                       dev_err(codec->dev, "Failed to set pll ctl (%d)\n",
+                       dev_err(component->dev, "Failed to set pll ctl (%d)\n",
                                ret);
                        return ret;
                }
@@ -1059,33 +1064,33 @@ static int tscs42xx_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *codec_dai)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int ret;
 
-       ret = setup_sample_format(codec, params_format(params));
+       ret = setup_sample_format(component, params_format(params));
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to setup sample format (%d)\n",
+               dev_err(component->dev, "Failed to setup sample format (%d)\n",
                        ret);
                return ret;
        }
 
-       ret = setup_sample_rate(codec, params_rate(params));
+       ret = setup_sample_rate(component, params_rate(params));
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to setup sample rate (%d)\n", ret);
+               dev_err(component->dev, "Failed to setup sample rate (%d)\n", ret);
                return ret;
        }
 
        return 0;
 }
 
-static inline int dac_mute(struct snd_soc_codec *codec)
+static inline int dac_mute(struct snd_soc_component *component)
 {
        int ret;
 
-       ret = snd_soc_update_bits(codec, R_CNVRTR1, RM_CNVRTR1_DACMU,
+       ret = snd_soc_component_update_bits(component, R_CNVRTR1, RM_CNVRTR1_DACMU,
                RV_CNVRTR1_DACMU_ENABLE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to mute DAC (%d)\n",
+               dev_err(component->dev, "Failed to mute DAC (%d)\n",
                                ret);
                return ret;
        }
@@ -1093,14 +1098,14 @@ static inline int dac_mute(struct snd_soc_codec *codec)
        return 0;
 }
 
-static inline int dac_unmute(struct snd_soc_codec *codec)
+static inline int dac_unmute(struct snd_soc_component *component)
 {
        int ret;
 
-       ret = snd_soc_update_bits(codec, R_CNVRTR1, RM_CNVRTR1_DACMU,
+       ret = snd_soc_component_update_bits(component, R_CNVRTR1, RM_CNVRTR1_DACMU,
                RV_CNVRTR1_DACMU_DISABLE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to unmute DAC (%d)\n",
+               dev_err(component->dev, "Failed to unmute DAC (%d)\n",
                                ret);
                return ret;
        }
@@ -1108,14 +1113,14 @@ static inline int dac_unmute(struct snd_soc_codec *codec)
        return 0;
 }
 
-static inline int adc_mute(struct snd_soc_codec *codec)
+static inline int adc_mute(struct snd_soc_component *component)
 {
        int ret;
 
-       ret = snd_soc_update_bits(codec, R_CNVRTR0, RM_CNVRTR0_ADCMU,
+       ret = snd_soc_component_update_bits(component, R_CNVRTR0, RM_CNVRTR0_ADCMU,
                RV_CNVRTR0_ADCMU_ENABLE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to mute ADC (%d)\n",
+               dev_err(component->dev, "Failed to mute ADC (%d)\n",
                                ret);
                return ret;
        }
@@ -1123,14 +1128,14 @@ static inline int adc_mute(struct snd_soc_codec *codec)
        return 0;
 }
 
-static inline int adc_unmute(struct snd_soc_codec *codec)
+static inline int adc_unmute(struct snd_soc_component *component)
 {
        int ret;
 
-       ret = snd_soc_update_bits(codec, R_CNVRTR0, RM_CNVRTR0_ADCMU,
+       ret = snd_soc_component_update_bits(component, R_CNVRTR0, RM_CNVRTR0_ADCMU,
                RV_CNVRTR0_ADCMU_DISABLE);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to unmute ADC (%d)\n",
+               dev_err(component->dev, "Failed to unmute ADC (%d)\n",
                                ret);
                return ret;
        }
@@ -1140,19 +1145,19 @@ static inline int adc_unmute(struct snd_soc_codec *codec)
 
 static int tscs42xx_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int ret;
 
        if (mute)
                if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       ret = dac_mute(codec);
+                       ret = dac_mute(component);
                else
-                       ret = adc_mute(codec);
+                       ret = adc_mute(component);
        else
                if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       ret = dac_unmute(codec);
+                       ret = dac_unmute(component);
                else
-                       ret = adc_unmute(codec);
+                       ret = adc_unmute(component);
 
        return ret;
 }
@@ -1160,23 +1165,23 @@ static int tscs42xx_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 static int tscs42xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int ret;
 
        /* Slave mode not supported since it needs always-on frame clock */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               ret = snd_soc_update_bits(codec, R_AIC1, RM_AIC1_MS,
+               ret = snd_soc_component_update_bits(component, R_AIC1, RM_AIC1_MS,
                                RV_AIC1_MS_MASTER);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set codec DAI master (%d)\n", ret);
                        return ret;
                }
                break;
        default:
                ret = -EINVAL;
-               dev_err(codec->dev, "Unsupported format (%d)\n", ret);
+               dev_err(component->dev, "Unsupported format (%d)\n", ret);
                return ret;
        }
 
@@ -1186,8 +1191,8 @@ static int tscs42xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
                unsigned int ratio)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
        unsigned int value;
        int ret = 0;
 
@@ -1202,18 +1207,18 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
                value = RV_DACSR_DBCM_64;
                break;
        default:
-               dev_err(codec->dev, "Unsupported bclk ratio (%d)\n", ret);
+               dev_err(component->dev, "Unsupported bclk ratio (%d)\n", ret);
                return -EINVAL;
        }
 
-       ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBCM, value);
+       ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBCM, value);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set DAC BCLK ratio (%d)\n", ret);
+               dev_err(component->dev, "Failed to set DAC BCLK ratio (%d)\n", ret);
                return ret;
        }
-       ret = snd_soc_update_bits(codec, R_ADCSR, RM_ADCSR_ABCM, value);
+       ret = snd_soc_component_update_bits(component, R_ADCSR, RM_ADCSR_ABCM, value);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set ADC BCLK ratio (%d)\n", ret);
+               dev_err(component->dev, "Failed to set ADC BCLK ratio (%d)\n", ret);
                return ret;
        }
 
@@ -1229,40 +1234,40 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
 static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int ret;
 
        switch (clk_id) {
        case TSCS42XX_PLL_SRC_XTAL:
        case TSCS42XX_PLL_SRC_MCLK1:
-               ret = snd_soc_write(codec, R_PLLREFSEL,
+               ret = snd_soc_component_write(component, R_PLLREFSEL,
                                RV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 |
                                RV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set pll reference input (%d)\n",
                                ret);
                        return ret;
                }
                break;
        case TSCS42XX_PLL_SRC_MCLK2:
-               ret = snd_soc_write(codec, R_PLLREFSEL,
+               ret = snd_soc_component_write(component, R_PLLREFSEL,
                                RV_PLLREFSEL_PLL1_REF_SEL_MCLK2 |
                                RV_PLLREFSEL_PLL2_REF_SEL_MCLK2);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to set PLL reference (%d)\n", ret);
                        return ret;
                }
                break;
        default:
-               dev_err(codec->dev, "pll src is unsupported\n");
+               dev_err(component->dev, "pll src is unsupported\n");
                return -EINVAL;
        }
 
-       ret = set_pll_ctl_from_input_freq(codec, freq);
+       ret = set_pll_ctl_from_input_freq(component, freq);
        if (ret < 0) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Failed to setup PLL input freq (%d)\n", ret);
                return ret;
        }
@@ -1304,24 +1309,28 @@ static int part_is_valid(struct tscs42xx *tscs42xx)
        };
 }
 
-static struct snd_soc_codec_driver soc_codec_dev_tscs42xx = {
-       .component_driver = {
-               .dapm_widgets = tscs42xx_dapm_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(tscs42xx_dapm_widgets),
-               .dapm_routes = tscs42xx_intercon,
-               .num_dapm_routes = ARRAY_SIZE(tscs42xx_intercon),
-               .controls =     tscs42xx_snd_controls,
-               .num_controls = ARRAY_SIZE(tscs42xx_snd_controls),
-       },
+static struct snd_soc_component_driver soc_codec_dev_tscs42xx = {
+       .dapm_widgets           = tscs42xx_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tscs42xx_dapm_widgets),
+       .dapm_routes            = tscs42xx_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(tscs42xx_intercon),
+       .controls               = tscs42xx_snd_controls,
+       .num_controls           = ARRAY_SIZE(tscs42xx_snd_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static inline void init_coeff_ram_cache(struct tscs42xx *tscs42xx)
 {
-       const u8 norm_addrs[] = { 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1f,
-               0x20, 0x25, 0x2a, 0x2f, 0x34, 0x39, 0x3f, 0x40, 0x45, 0x4a,
-               0x4f, 0x54, 0x59, 0x5f, 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79,
-               0x7f, 0x80, 0x85, 0x8c, 0x91, 0x96, 0x97, 0x9c, 0xa3, 0xa8,
-               0xad, 0xaf, 0xb0, 0xb5, 0xba, 0xbf, 0xc4, 0xc9, };
+       static const u8 norm_addrs[] = {
+               0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1f, 0x20, 0x25, 0x2a,
+               0x2f, 0x34, 0x39, 0x3f, 0x40, 0x45, 0x4a, 0x4f, 0x54, 0x59,
+               0x5f, 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7f, 0x80, 0x85,
+               0x8c, 0x91, 0x96, 0x97, 0x9c, 0xa3, 0xa8, 0xad, 0xaf, 0xb0,
+               0xb5, 0xba, 0xbf, 0xc4, 0xc9,
+       };
        u8 *coeff_ram = tscs42xx->coeff_ram;
        int i;
 
@@ -1407,7 +1416,7 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
        mutex_init(&tscs42xx->coeff_ram_lock);
        mutex_init(&tscs42xx->pll_lock);
 
-       ret = snd_soc_register_codec(tscs42xx->dev, &soc_codec_dev_tscs42xx,
+       ret = devm_snd_soc_register_component(tscs42xx->dev, &soc_codec_dev_tscs42xx,
                        &tscs42xx_dai, 1);
        if (ret) {
                dev_err(tscs42xx->dev, "Failed to register codec (%d)\n", ret);
@@ -1417,13 +1426,6 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
        return 0;
 }
 
-static int tscs42xx_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id tscs42xx_i2c_id[] = {
        { "tscs42A1", 0 },
        { "tscs42A2", 0 },
@@ -1441,11 +1443,9 @@ MODULE_DEVICE_TABLE(of, tscs42xx_of_match);
 static struct i2c_driver tscs42xx_i2c_driver = {
        .driver = {
                .name = "tscs42xx",
-               .owner = THIS_MODULE,
                .of_match_table = tscs42xx_of_match,
        },
        .probe =    tscs42xx_i2c_probe,
-       .remove =   tscs42xx_i2c_remove,
        .id_table = tscs42xx_i2c_id,
 };
 
index e4d7f397d361411bd7acc5d9a44f9908a6d0c51a..25b752caf95e91bcf7bc3889d7f1ed84004f06dc 100644 (file)
@@ -86,9 +86,9 @@ static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030)
        }
 }
 
-static unsigned int twl4030_read(struct snd_soc_codec *codec, unsigned int reg)
+static unsigned int twl4030_read(struct snd_soc_component *component, unsigned int reg)
 {
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 value = 0;
 
        if (reg >= TWL4030_CACHEREGNUM)
@@ -151,10 +151,10 @@ static bool twl4030_can_write_to_chip(struct twl4030_priv *twl4030,
        return write_to_reg;
 }
 
-static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg,
+static int twl4030_write(struct snd_soc_component *component, unsigned int reg,
                         unsigned int value)
 {
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        /* Update the ctl cache */
        switch (reg) {
@@ -186,9 +186,9 @@ static inline void twl4030_wait_ms(int time)
        }
 }
 
-static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
+static void twl4030_codec_enable(struct snd_soc_component *component, int enable)
 {
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        int mode;
 
        if (enable == twl4030->codec_powered)
@@ -227,16 +227,16 @@ static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
                pdata->hs_extmute = 1;
 }
 
-static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
+static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_component *component)
 {
-       struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+       struct twl4030_codec_data *pdata = dev_get_platdata(component->dev);
        struct device_node *twl4030_codec_node = NULL;
 
-       twl4030_codec_node = of_get_child_by_name(codec->dev->parent->of_node,
+       twl4030_codec_node = of_get_child_by_name(component->dev->parent->of_node,
                                                  "codec");
 
        if (!pdata && twl4030_codec_node) {
-               pdata = devm_kzalloc(codec->dev,
+               pdata = devm_kzalloc(component->dev,
                                     sizeof(struct twl4030_codec_data),
                                     GFP_KERNEL);
                if (!pdata) {
@@ -250,28 +250,28 @@ static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
        return pdata;
 }
 
-static void twl4030_init_chip(struct snd_soc_codec *codec)
+static void twl4030_init_chip(struct snd_soc_component *component)
 {
        struct twl4030_codec_data *pdata;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 reg, byte;
        int i = 0;
 
-       pdata = twl4030_get_pdata(codec);
+       pdata = twl4030_get_pdata(component);
 
        if (pdata && pdata->hs_extmute) {
                if (gpio_is_valid(pdata->hs_extmute_gpio)) {
                        int ret;
 
                        if (!pdata->hs_extmute_gpio)
-                               dev_warn(codec->dev,
+                               dev_warn(component->dev,
                                        "Extmute GPIO is 0 is this correct?\n");
 
                        ret = gpio_request_one(pdata->hs_extmute_gpio,
                                               GPIOF_OUT_INIT_LOW,
                                               "hs_extmute");
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to get hs_extmute GPIO\n");
                                pdata->hs_extmute_gpio = -1;
                        }
@@ -292,16 +292,16 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
        tw4030_init_ctl_cache(twl4030);
 
        /* anti-pop when changing analog gain */
-       reg = twl4030_read(codec, TWL4030_REG_MISC_SET_1);
-       twl4030_write(codec, TWL4030_REG_MISC_SET_1,
+       reg = twl4030_read(component, TWL4030_REG_MISC_SET_1);
+       twl4030_write(component, TWL4030_REG_MISC_SET_1,
                      reg | TWL4030_SMOOTH_ANAVOL_EN);
 
-       twl4030_write(codec, TWL4030_REG_OPTION,
+       twl4030_write(component, TWL4030_REG_OPTION,
                      TWL4030_ATXL1_EN | TWL4030_ATXR1_EN |
                      TWL4030_ARXL2_EN | TWL4030_ARXR2_EN);
 
        /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */
-       twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
+       twl4030_write(component, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
 
        /* Machine dependent setup */
        if (!pdata)
@@ -309,18 +309,18 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
 
        twl4030->pdata = pdata;
 
-       reg = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
+       reg = twl4030_read(component, TWL4030_REG_HS_POPN_SET);
        reg &= ~TWL4030_RAMP_DELAY;
        reg |= (pdata->ramp_delay_value << 2);
-       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, reg);
+       twl4030_write(component, TWL4030_REG_HS_POPN_SET, reg);
 
        /* initiate offset cancellation */
-       twl4030_codec_enable(codec, 1);
+       twl4030_codec_enable(component, 1);
 
-       reg = twl4030_read(codec, TWL4030_REG_ANAMICL);
+       reg = twl4030_read(component, TWL4030_REG_ANAMICL);
        reg &= ~TWL4030_OFFSET_CNCL_SEL;
        reg |= pdata->offset_cncl_path;
-       twl4030_write(codec, TWL4030_REG_ANAMICL,
+       twl4030_write(component, TWL4030_REG_ANAMICL,
                      reg | TWL4030_CNCL_OFFSET_START);
 
        /*
@@ -339,12 +339,12 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
                 ((byte & TWL4030_CNCL_OFFSET_START) ==
                  TWL4030_CNCL_OFFSET_START));
 
-       twl4030_codec_enable(codec, 0);
+       twl4030_codec_enable(component, 0);
 }
 
-static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
+static void twl4030_apll_enable(struct snd_soc_component *component, int enable)
 {
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        if (enable) {
                twl4030->apll_enabled++;
@@ -567,13 +567,13 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
 static int pin_name##pga_event(struct snd_soc_dapm_widget *w,          \
                               struct snd_kcontrol *kcontrol, int event) \
 {                                                                      \
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);   \
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); \
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);       \
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); \
                                                                        \
        switch (event) {                                                \
        case SND_SOC_DAPM_POST_PMU:                                     \
                twl4030->pin_name##_enabled = 1;                        \
-               twl4030_write(codec, reg, twl4030_read(codec, reg));    \
+               twl4030_write(component, reg, twl4030_read(component, reg));    \
                break;                                                  \
        case SND_SOC_DAPM_POST_PMD:                                     \
                twl4030->pin_name##_enabled = 0;                        \
@@ -589,47 +589,47 @@ TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
 TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
 TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
 
-static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
+static void handsfree_ramp(struct snd_soc_component *component, int reg, int ramp)
 {
        unsigned char hs_ctl;
 
-       hs_ctl = twl4030_read(codec, reg);
+       hs_ctl = twl4030_read(component, reg);
 
        if (ramp) {
                /* HF ramp-up */
                hs_ctl |= TWL4030_HF_CTL_REF_EN;
-               twl4030_write(codec, reg, hs_ctl);
+               twl4030_write(component, reg, hs_ctl);
                udelay(10);
                hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
-               twl4030_write(codec, reg, hs_ctl);
+               twl4030_write(component, reg, hs_ctl);
                udelay(40);
                hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
                hs_ctl |= TWL4030_HF_CTL_HB_EN;
-               twl4030_write(codec, reg, hs_ctl);
+               twl4030_write(component, reg, hs_ctl);
        } else {
                /* HF ramp-down */
                hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN;
                hs_ctl &= ~TWL4030_HF_CTL_HB_EN;
-               twl4030_write(codec, reg, hs_ctl);
+               twl4030_write(component, reg, hs_ctl);
                hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN;
-               twl4030_write(codec, reg, hs_ctl);
+               twl4030_write(component, reg, hs_ctl);
                udelay(40);
                hs_ctl &= ~TWL4030_HF_CTL_REF_EN;
-               twl4030_write(codec, reg, hs_ctl);
+               twl4030_write(component, reg, hs_ctl);
        }
 }
 
 static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 1);
+               handsfree_ramp(component, TWL4030_REG_HFL_CTL, 1);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 0);
+               handsfree_ramp(component, TWL4030_REG_HFL_CTL, 0);
                break;
        }
        return 0;
@@ -638,14 +638,14 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
 static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 1);
+               handsfree_ramp(component, TWL4030_REG_HFR_CTL, 1);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 0);
+               handsfree_ramp(component, TWL4030_REG_HFR_CTL, 0);
                break;
        }
        return 0;
@@ -654,23 +654,23 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
 static int vibramux_event(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
-       twl4030_write(codec, TWL4030_REG_VIBRA_SET, 0xff);
+       twl4030_write(component, TWL4030_REG_VIBRA_SET, 0xff);
        return 0;
 }
 
 static int apll_event(struct snd_soc_dapm_widget *w,
                      struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               twl4030_apll_enable(codec, 1);
+               twl4030_apll_enable(component, 1);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               twl4030_apll_enable(codec, 0);
+               twl4030_apll_enable(component, 0);
                break;
        }
        return 0;
@@ -679,41 +679,41 @@ static int apll_event(struct snd_soc_dapm_widget *w,
 static int aif_event(struct snd_soc_dapm_widget *w,
                     struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        u8 audio_if;
 
-       audio_if = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+       audio_if = twl4030_read(component, TWL4030_REG_AUDIO_IF);
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
                /* Enable AIF */
                /* enable the PLL before we use it to clock the DAI */
-               twl4030_apll_enable(codec, 1);
+               twl4030_apll_enable(component, 1);
 
-               twl4030_write(codec, TWL4030_REG_AUDIO_IF,
+               twl4030_write(component, TWL4030_REG_AUDIO_IF,
                              audio_if | TWL4030_AIF_EN);
                break;
        case SND_SOC_DAPM_POST_PMD:
                /* disable the DAI before we stop it's source PLL */
-               twl4030_write(codec, TWL4030_REG_AUDIO_IF,
+               twl4030_write(component, TWL4030_REG_AUDIO_IF,
                              audio_if &  ~TWL4030_AIF_EN);
-               twl4030_apll_enable(codec, 0);
+               twl4030_apll_enable(component, 0);
                break;
        }
        return 0;
 }
 
-static void headset_ramp(struct snd_soc_codec *codec, int ramp)
+static void headset_ramp(struct snd_soc_component *component, int ramp)
 {
        unsigned char hs_gain, hs_pop;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        struct twl4030_codec_data *pdata = twl4030->pdata;
        /* Base values for ramp delay calculation: 2^19 - 2^26 */
        unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
                                    8388608, 16777216, 33554432, 67108864};
        unsigned int delay;
 
-       hs_gain = twl4030_read(codec, TWL4030_REG_HS_GAIN_SET);
-       hs_pop = twl4030_read(codec, TWL4030_REG_HS_POPN_SET);
+       hs_gain = twl4030_read(component, TWL4030_REG_HS_GAIN_SET);
+       hs_pop = twl4030_read(component, TWL4030_REG_HS_POPN_SET);
        delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
                twl4030->sysclk) + 1;
 
@@ -724,26 +724,26 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
                        gpio_set_value(pdata->hs_extmute_gpio, 1);
                } else {
                        hs_pop |= TWL4030_EXTMUTE;
-                       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+                       twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
                }
        }
 
        if (ramp) {
                /* Headset ramp-up according to the TRM */
                hs_pop |= TWL4030_VMID_EN;
-               twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+               twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
                /* Actually write to the register */
                twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain,
                                 TWL4030_REG_HS_GAIN_SET);
                hs_pop |= TWL4030_RAMP_EN;
-               twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+               twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
                /* Wait ramp delay time + 1, so the VMID can settle */
                twl4030_wait_ms(delay);
        } else {
                /* Headset ramp-down _not_ according to
                 * the TRM, but in a way that it is working */
                hs_pop &= ~TWL4030_RAMP_EN;
-               twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+               twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
                /* Wait ramp delay time + 1, so the VMID can settle */
                twl4030_wait_ms(delay);
                /* Bypass the reg_cache to mute the headset */
@@ -751,7 +751,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
                                 TWL4030_REG_HS_GAIN_SET);
 
                hs_pop &= ~TWL4030_VMID_EN;
-               twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+               twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
        }
 
        /* Disable external mute */
@@ -760,7 +760,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
                        gpio_set_value(pdata->hs_extmute_gpio, 0);
                } else {
                        hs_pop &= ~TWL4030_EXTMUTE;
-                       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
+                       twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop);
                }
        }
 }
@@ -768,21 +768,21 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
 static int headsetlpga_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* Do the ramp-up only once */
                if (!twl4030->hsr_enabled)
-                       headset_ramp(codec, 1);
+                       headset_ramp(component, 1);
 
                twl4030->hsl_enabled = 1;
                break;
        case SND_SOC_DAPM_POST_PMD:
                /* Do the ramp-down only if both headsetL/R is disabled */
                if (!twl4030->hsr_enabled)
-                       headset_ramp(codec, 0);
+                       headset_ramp(component, 0);
 
                twl4030->hsl_enabled = 0;
                break;
@@ -793,21 +793,21 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w,
 static int headsetrpga_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* Do the ramp-up only once */
                if (!twl4030->hsl_enabled)
-                       headset_ramp(codec, 1);
+                       headset_ramp(component, 1);
 
                twl4030->hsr_enabled = 1;
                break;
        case SND_SOC_DAPM_POST_PMD:
                /* Do the ramp-down only if both headsetL/R is disabled */
                if (!twl4030->hsl_enabled)
-                       headset_ramp(codec, 0);
+                       headset_ramp(component, 0);
 
                twl4030->hsr_enabled = 0;
                break;
@@ -818,8 +818,8 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
 static int digimic_event(struct snd_soc_dapm_widget *w,
                         struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        struct twl4030_codec_data *pdata = twl4030->pdata;
 
        if (pdata && pdata->digimic_delay)
@@ -842,7 +842,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int shift = mc->shift;
        unsigned int rshift = mc->rshift;
@@ -850,14 +850,14 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
        int mask = (1 << fls(max)) - 1;
 
        ucontrol->value.integer.value[0] =
-               (twl4030_read(codec, reg) >> shift) & mask;
+               (twl4030_read(component, reg) >> shift) & mask;
        if (ucontrol->value.integer.value[0])
                ucontrol->value.integer.value[0] =
                        max + 1 - ucontrol->value.integer.value[0];
 
        if (shift != rshift) {
                ucontrol->value.integer.value[1] =
-                       (twl4030_read(codec, reg) >> rshift) & mask;
+                       (twl4030_read(component, reg) >> rshift) & mask;
                if (ucontrol->value.integer.value[1])
                        ucontrol->value.integer.value[1] =
                                max + 1 - ucontrol->value.integer.value[1];
@@ -871,7 +871,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int shift = mc->shift;
        unsigned int rshift = mc->rshift;
@@ -892,7 +892,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
                        val2 = max + 1 - val2;
                val |= val2 << rshift;
        }
-       return snd_soc_update_bits(codec, reg, val_mask, val);
+       return snd_soc_component_update_bits(component, reg, val_mask, val);
 }
 
 static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
@@ -900,7 +900,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        unsigned int shift = mc->shift;
@@ -908,9 +908,9 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
        int mask = (1<<fls(max))-1;
 
        ucontrol->value.integer.value[0] =
-               (twl4030_read(codec, reg) >> shift) & mask;
+               (twl4030_read(component, reg) >> shift) & mask;
        ucontrol->value.integer.value[1] =
-               (twl4030_read(codec, reg2) >> shift) & mask;
+               (twl4030_read(component, reg2) >> shift) & mask;
 
        if (ucontrol->value.integer.value[0])
                ucontrol->value.integer.value[0] =
@@ -927,7 +927,7 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        unsigned int shift = mc->shift;
@@ -948,11 +948,11 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
        val = val << shift;
        val2 = val2 << shift;
 
-       err = snd_soc_update_bits(codec, reg, val_mask, val);
+       err = snd_soc_component_update_bits(component, reg, val_mask, val);
        if (err < 0)
                return err;
 
-       err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+       err = snd_soc_component_update_bits(component, reg2, val_mask, val2);
        return err;
 }
 
@@ -968,11 +968,11 @@ static SOC_ENUM_SINGLE_DECL(twl4030_op_modes_enum,
 static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        if (twl4030->configured) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "operation mode cannot be changed on-the-fly\n");
                return -EBUSY;
        }
@@ -1579,7 +1579,7 @@ static const struct snd_soc_dapm_route intercon[] = {
 
 };
 
-static int twl4030_set_bias_level(struct snd_soc_codec *codec,
+static int twl4030_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
        switch (level) {
@@ -1588,11 +1588,11 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
-                       twl4030_codec_enable(codec, 1);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
+                       twl4030_codec_enable(component, 1);
                break;
        case SND_SOC_BIAS_OFF:
-               twl4030_codec_enable(codec, 0);
+               twl4030_codec_enable(component, 0);
                break;
        }
 
@@ -1628,12 +1628,12 @@ static void twl4030_constraints(struct twl4030_priv *twl4030,
 
 /* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for
  * capture has to be enabled/disabled. */
-static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
+static void twl4030_tdm_enable(struct snd_soc_component *component, int direction,
                               int enable)
 {
        u8 reg, mask;
 
-       reg = twl4030_read(codec, TWL4030_REG_OPTION);
+       reg = twl4030_read(component, TWL4030_REG_OPTION);
 
        if (direction == SNDRV_PCM_STREAM_PLAYBACK)
                mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN;
@@ -1645,14 +1645,14 @@ static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
        else
                reg &= ~mask;
 
-       twl4030_write(codec, TWL4030_REG_OPTION, reg);
+       twl4030_write(component, TWL4030_REG_OPTION, reg);
 }
 
 static int twl4030_startup(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        if (twl4030->master_substream) {
                twl4030->slave_substream = substream;
@@ -1662,7 +1662,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
                if (twl4030->configured)
                        twl4030_constraints(twl4030, twl4030->master_substream);
        } else {
-               if (!(twl4030_read(codec, TWL4030_REG_CODEC_MODE) &
+               if (!(twl4030_read(component, TWL4030_REG_CODEC_MODE) &
                        TWL4030_OPTION_1)) {
                        /* In option2 4 channel is not supported, set the
                         * constraint for the first stream for channels, the
@@ -1680,8 +1680,8 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
 static void twl4030_shutdown(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        if (twl4030->master_substream == substream)
                twl4030->master_substream = twl4030->slave_substream;
@@ -1697,27 +1697,27 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
 
         /* If the closing substream had 4 channel, do the necessary cleanup */
        if (substream->runtime->channels == 4)
-               twl4030_tdm_enable(codec, substream->stream, 0);
+               twl4030_tdm_enable(component, substream->stream, 0);
 }
 
 static int twl4030_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 mode, old_mode, format, old_format;
 
         /* If the substream has 4 channel, do the necessary setup */
        if (params_channels(params) == 4) {
-               format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
-               mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE);
+               format = twl4030_read(component, TWL4030_REG_AUDIO_IF);
+               mode = twl4030_read(component, TWL4030_REG_CODEC_MODE);
 
                /* Safety check: are we in the correct operating mode and
                 * the interface is in TDM mode? */
                if ((mode & TWL4030_OPTION_1) &&
                    ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM))
-                       twl4030_tdm_enable(codec, substream->stream, 1);
+                       twl4030_tdm_enable(component, substream->stream, 1);
                else
                        return -EINVAL;
        }
@@ -1727,7 +1727,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
                return 0;
 
        /* bit rate */
-       old_mode = twl4030_read(codec,
+       old_mode = twl4030_read(component,
                                TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
        mode = old_mode & ~TWL4030_APLL_RATE;
 
@@ -1763,13 +1763,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
                mode |= TWL4030_APLL_RATE_96000;
                break;
        default:
-               dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
+               dev_err(component->dev, "%s: unknown rate %d\n", __func__,
                        params_rate(params));
                return -EINVAL;
        }
 
        /* sample size */
-       old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+       old_format = twl4030_read(component, TWL4030_REG_AUDIO_IF);
        format = old_format;
        format &= ~TWL4030_DATA_WIDTH;
        switch (params_width(params)) {
@@ -1780,7 +1780,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
                format |= TWL4030_DATA_WIDTH_32S_24W;
                break;
        default:
-               dev_err(codec->dev, "%s: unsupported bits/sample %d\n",
+               dev_err(component->dev, "%s: unsupported bits/sample %d\n",
                        __func__, params_width(params));
                return -EINVAL;
        }
@@ -1791,13 +1791,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
                         * If the codec is powered, than we need to toggle the
                         * codec power.
                         */
-                       twl4030_codec_enable(codec, 0);
-                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
-                       twl4030_codec_enable(codec, 1);
+                       twl4030_codec_enable(component, 0);
+                       twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
+                       twl4030_codec_enable(component, 1);
                } else {
-                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+                       twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
                }
        }
 
@@ -1821,8 +1821,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
                                  unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case 19200000:
@@ -1830,12 +1830,12 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
        case 38400000:
                break;
        default:
-               dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
+               dev_err(component->dev, "Unsupported HFCLKIN: %u\n", freq);
                return -EINVAL;
        }
 
        if ((freq / 1000) != twl4030->sysclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Mismatch in HFCLKIN: %u (configured: %u)\n",
                        freq, twl4030->sysclk * 1000);
                return -EINVAL;
@@ -1846,12 +1846,12 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 
 static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 old_format, format;
 
        /* get format */
-       old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+       old_format = twl4030_read(component, TWL4030_REG_AUDIO_IF);
        format = old_format;
 
        /* set master/slave audio interface */
@@ -1887,11 +1887,11 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                         * If the codec is powered, than we need to toggle the
                         * codec power.
                         */
-                       twl4030_codec_enable(codec, 0);
-                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
-                       twl4030_codec_enable(codec, 1);
+                       twl4030_codec_enable(component, 0);
+                       twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
+                       twl4030_codec_enable(component, 1);
                } else {
-                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+                       twl4030_write(component, TWL4030_REG_AUDIO_IF, format);
                }
        }
 
@@ -1900,25 +1900,25 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u8 reg = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
+       struct snd_soc_component *component = dai->component;
+       u8 reg = twl4030_read(component, TWL4030_REG_AUDIO_IF);
 
        if (tristate)
                reg |= TWL4030_AIF_TRI_EN;
        else
                reg &= ~TWL4030_AIF_TRI_EN;
 
-       return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
+       return twl4030_write(component, TWL4030_REG_AUDIO_IF, reg);
 }
 
 /* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
  * (VTXL, VTXR) for uplink has to be enabled/disabled. */
-static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
+static void twl4030_voice_enable(struct snd_soc_component *component, int direction,
                                 int enable)
 {
        u8 reg, mask;
 
-       reg = twl4030_read(codec, TWL4030_REG_OPTION);
+       reg = twl4030_read(component, TWL4030_REG_OPTION);
 
        if (direction == SNDRV_PCM_STREAM_PLAYBACK)
                mask = TWL4030_ARXL1_VRX_EN;
@@ -1930,21 +1930,21 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
        else
                reg &= ~mask;
 
-       twl4030_write(codec, TWL4030_REG_OPTION, reg);
+       twl4030_write(component, TWL4030_REG_OPTION, reg);
 }
 
 static int twl4030_voice_startup(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 mode;
 
        /* If the system master clock is not 26MHz, the voice PCM interface is
         * not available.
         */
        if (twl4030->sysclk != 26000) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
                        __func__, twl4030->sysclk);
                return -EINVAL;
@@ -1953,11 +1953,11 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
        /* If the codec mode is not option2, the voice PCM interface is not
         * available.
         */
-       mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE)
+       mode = twl4030_read(component, TWL4030_REG_CODEC_MODE)
                & TWL4030_OPT_MODE;
 
        if (mode != TWL4030_OPTION_2) {
-               dev_err(codec->dev, "%s: the codec mode is not option2\n",
+               dev_err(component->dev, "%s: the codec mode is not option2\n",
                        __func__);
                return -EINVAL;
        }
@@ -1968,25 +1968,25 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
 static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        /* Enable voice digital filters */
-       twl4030_voice_enable(codec, substream->stream, 0);
+       twl4030_voice_enable(component, substream->stream, 0);
 }
 
 static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 old_mode, mode;
 
        /* Enable voice digital filters */
-       twl4030_voice_enable(codec, substream->stream, 1);
+       twl4030_voice_enable(component, substream->stream, 1);
 
        /* bit rate */
-       old_mode = twl4030_read(codec,
+       old_mode = twl4030_read(component,
                                TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
        mode = old_mode;
 
@@ -1998,7 +1998,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
                mode |= TWL4030_SEL_16K;
                break;
        default:
-               dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
+               dev_err(component->dev, "%s: unknown rate %d\n", __func__,
                        params_rate(params));
                return -EINVAL;
        }
@@ -2009,11 +2009,11 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
                         * If the codec is powered, than we need to toggle the
                         * codec power.
                         */
-                       twl4030_codec_enable(codec, 0);
-                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-                       twl4030_codec_enable(codec, 1);
+                       twl4030_codec_enable(component, 0);
+                       twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_codec_enable(component, 1);
                } else {
-                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_write(component, TWL4030_REG_CODEC_MODE, mode);
                }
        }
 
@@ -2023,17 +2023,17 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
 static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                        int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
 
        if (freq != 26000000) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
                        __func__, freq / 1000);
                return -EINVAL;
        }
        if ((freq / 1000) != twl4030->sysclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Mismatch in HFCLKIN: %u (configured: %u)\n",
                        freq, twl4030->sysclk * 1000);
                return -EINVAL;
@@ -2044,12 +2044,12 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
                                     unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        u8 old_format, format;
 
        /* get format */
-       old_format = twl4030_read(codec, TWL4030_REG_VOICE_IF);
+       old_format = twl4030_read(component, TWL4030_REG_VOICE_IF);
        format = old_format;
 
        /* set master/slave audio interface */
@@ -2082,11 +2082,11 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
                         * If the codec is powered, than we need to toggle the
                         * codec power.
                         */
-                       twl4030_codec_enable(codec, 0);
-                       twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
-                       twl4030_codec_enable(codec, 1);
+                       twl4030_codec_enable(component, 0);
+                       twl4030_write(component, TWL4030_REG_VOICE_IF, format);
+                       twl4030_codec_enable(component, 1);
                } else {
-                       twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
+                       twl4030_write(component, TWL4030_REG_VOICE_IF, format);
                }
        }
 
@@ -2095,15 +2095,15 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
 static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u8 reg = twl4030_read(codec, TWL4030_REG_VOICE_IF);
+       struct snd_soc_component *component = dai->component;
+       u8 reg = twl4030_read(component, TWL4030_REG_VOICE_IF);
 
        if (tristate)
                reg |= TWL4030_VIF_TRI_EN;
        else
                reg &= ~TWL4030_VIF_TRI_EN;
 
-       return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
+       return twl4030_write(component, TWL4030_REG_VOICE_IF, reg);
 }
 
 #define TWL4030_RATES   (SNDRV_PCM_RATE_8000_48000)
@@ -2164,69 +2164,60 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
 },
 };
 
-static int twl4030_soc_probe(struct snd_soc_codec *codec)
+static int twl4030_soc_probe(struct snd_soc_component *component)
 {
        struct twl4030_priv *twl4030;
 
-       twl4030 = devm_kzalloc(codec->dev, sizeof(struct twl4030_priv),
+       twl4030 = devm_kzalloc(component->dev, sizeof(struct twl4030_priv),
                               GFP_KERNEL);
        if (!twl4030)
                return -ENOMEM;
-       snd_soc_codec_set_drvdata(codec, twl4030);
+       snd_soc_component_set_drvdata(component, twl4030);
        /* Set the defaults, and power up the codec */
        twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
 
-       twl4030_init_chip(codec);
+       twl4030_init_chip(component);
 
        return 0;
 }
 
-static int twl4030_soc_remove(struct snd_soc_codec *codec)
+static void twl4030_soc_remove(struct snd_soc_component *component)
 {
-       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+       struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component);
        struct twl4030_codec_data *pdata = twl4030->pdata;
 
        if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio))
                gpio_free(pdata->hs_extmute_gpio);
-
-       return 0;
 }
 
-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,
-
-       .component_driver = {
-               .controls               = twl4030_snd_controls,
-               .num_controls           = ARRAY_SIZE(twl4030_snd_controls),
-               .dapm_widgets           = twl4030_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(twl4030_dapm_widgets),
-               .dapm_routes            = intercon,
-               .num_dapm_routes        = ARRAY_SIZE(intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_twl4030 = {
+       .probe                  = twl4030_soc_probe,
+       .remove                 = twl4030_soc_remove,
+       .read                   = twl4030_read,
+       .write                  = twl4030_write,
+       .set_bias_level         = twl4030_set_bias_level,
+       .controls               = twl4030_snd_controls,
+       .num_controls           = ARRAY_SIZE(twl4030_snd_controls),
+       .dapm_widgets           = twl4030_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(twl4030_dapm_widgets),
+       .dapm_routes            = intercon,
+       .num_dapm_routes        = ARRAY_SIZE(intercon),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int twl4030_codec_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &soc_component_dev_twl4030,
                                      twl4030_dai, ARRAY_SIZE(twl4030_dai));
 }
 
-static int twl4030_codec_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 MODULE_ALIAS("platform:twl4030-codec");
 
 static struct platform_driver twl4030_codec_driver = {
        .probe          = twl4030_codec_probe,
-       .remove         = twl4030_codec_remove,
        .driver         = {
                .name   = "twl4030-codec",
        },
index 573a523ed0b3abe17eeb89e436f87d0584d82fa8..bfd1abd7225377bb381ad967c54b22450aec3a57 100644 (file)
@@ -76,7 +76,7 @@ struct twl6040_data {
        unsigned int clk_in;
        unsigned int sysclk;
        struct twl6040_jack_data hs_jack;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct mutex mutex;
 };
 
@@ -106,12 +106,12 @@ static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = {
        { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, },
 };
 
-#define to_twl6040(codec)      dev_get_drvdata((codec)->dev->parent)
+#define to_twl6040(component)  dev_get_drvdata((component)->dev->parent)
 
-static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg)
+static unsigned int twl6040_read(struct snd_soc_component *component, unsigned int reg)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
-       struct twl6040 *twl6040 = to_twl6040(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
+       struct twl6040 *twl6040 = to_twl6040(component);
        u8 value;
 
        if (reg >= TWL6040_CACHEREGNUM)
@@ -133,10 +133,10 @@ static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg)
        return value;
 }
 
-static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec,
+static bool twl6040_can_write_to_chip(struct snd_soc_component *component,
                                  unsigned int reg)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        switch (reg) {
        case TWL6040_REG_HSLCTL:
@@ -152,10 +152,10 @@ static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec,
        }
 }
 
-static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec,
+static inline void twl6040_update_dl12_cache(struct snd_soc_component *component,
                                             u8 reg, u8 value)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        switch (reg) {
        case TWL6040_REG_HSLCTL:
@@ -170,54 +170,54 @@ static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec,
        }
 }
 
-static int twl6040_write(struct snd_soc_codec *codec,
+static int twl6040_write(struct snd_soc_component *component,
                        unsigned int reg, unsigned int value)
 {
-       struct twl6040 *twl6040 = to_twl6040(codec);
+       struct twl6040 *twl6040 = to_twl6040(component);
 
        if (reg >= TWL6040_CACHEREGNUM)
                return -EIO;
 
-       twl6040_update_dl12_cache(codec, reg, value);
-       if (twl6040_can_write_to_chip(codec, reg))
+       twl6040_update_dl12_cache(component, reg, value);
+       if (twl6040_can_write_to_chip(component, reg))
                return twl6040_reg_write(twl6040, reg, value);
        else
                return 0;
 }
 
-static void twl6040_init_chip(struct snd_soc_codec *codec)
+static void twl6040_init_chip(struct snd_soc_component *component)
 {
-       twl6040_read(codec, TWL6040_REG_TRIM1);
-       twl6040_read(codec, TWL6040_REG_TRIM2);
-       twl6040_read(codec, TWL6040_REG_TRIM3);
-       twl6040_read(codec, TWL6040_REG_HSOTRIM);
-       twl6040_read(codec, TWL6040_REG_HFOTRIM);
+       twl6040_read(component, TWL6040_REG_TRIM1);
+       twl6040_read(component, TWL6040_REG_TRIM2);
+       twl6040_read(component, TWL6040_REG_TRIM3);
+       twl6040_read(component, TWL6040_REG_HSOTRIM);
+       twl6040_read(component, TWL6040_REG_HFOTRIM);
 
        /* Change chip defaults */
        /* No imput selected for microphone amplifiers */
-       twl6040_write(codec, TWL6040_REG_MICLCTL, 0x18);
-       twl6040_write(codec, TWL6040_REG_MICRCTL, 0x18);
+       twl6040_write(component, TWL6040_REG_MICLCTL, 0x18);
+       twl6040_write(component, TWL6040_REG_MICRCTL, 0x18);
 
        /*
         * We need to lower the default gain values, so the ramp code
         * can work correctly for the first playback.
         * This reduces the pop noise heard at the first playback.
         */
-       twl6040_write(codec, TWL6040_REG_HSGAIN, 0xff);
-       twl6040_write(codec, TWL6040_REG_EARCTL, 0x1e);
-       twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1d);
-       twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1d);
-       twl6040_write(codec, TWL6040_REG_LINEGAIN, 0);
+       twl6040_write(component, TWL6040_REG_HSGAIN, 0xff);
+       twl6040_write(component, TWL6040_REG_EARCTL, 0x1e);
+       twl6040_write(component, TWL6040_REG_HFLGAIN, 0x1d);
+       twl6040_write(component, TWL6040_REG_HFRGAIN, 0x1d);
+       twl6040_write(component, TWL6040_REG_LINEGAIN, 0);
 }
 
 /* set headset dac and driver power mode */
-static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
+static int headset_power_mode(struct snd_soc_component *component, int high_perf)
 {
        int hslctl, hsrctl;
        int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE;
 
-       hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL);
-       hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL);
+       hslctl = twl6040_read(component, TWL6040_REG_HSLCTL);
+       hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL);
 
        if (high_perf) {
                hslctl &= ~mask;
@@ -227,8 +227,8 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
                hsrctl |= mask;
        }
 
-       twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
-       twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
+       twl6040_write(component, TWL6040_REG_HSLCTL, hslctl);
+       twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl);
 
        return 0;
 }
@@ -236,7 +236,7 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
 static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
                        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        u8 hslctl, hsrctl;
 
        /*
@@ -244,8 +244,8 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
         * Both HS DAC need to be turned on (before the HS driver) and off at
         * the same time.
         */
-       hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL);
-       hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL);
+       hslctl = twl6040_read(component, TWL6040_REG_HSLCTL);
+       hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL);
        if (SND_SOC_DAPM_EVENT_ON(event)) {
                hslctl |= TWL6040_HSDACENA;
                hsrctl |= TWL6040_HSDACENA;
@@ -253,8 +253,8 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
                hslctl &= ~TWL6040_HSDACENA;
                hsrctl &= ~TWL6040_HSDACENA;
        }
-       twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
-       twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
+       twl6040_write(component, TWL6040_REG_HSLCTL, hslctl);
+       twl6040_write(component, TWL6040_REG_HSRCTL, hsrctl);
 
        msleep(1);
        return 0;
@@ -263,17 +263,17 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
 static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
                        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if (SND_SOC_DAPM_EVENT_ON(event)) {
                /* Earphone doesn't support low power mode */
                priv->hs_power_mode_locked = 1;
-               ret = headset_power_mode(codec, 1);
+               ret = headset_power_mode(component, 1);
        } else {
                priv->hs_power_mode_locked = 0;
-               ret = headset_power_mode(codec, priv->hs_power_mode);
+               ret = headset_power_mode(component, priv->hs_power_mode);
        }
 
        msleep(1);
@@ -281,16 +281,16 @@ static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
        return ret;
 }
 
-static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
+static void twl6040_hs_jack_report(struct snd_soc_component *component,
                                   struct snd_soc_jack *jack, int report)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int status;
 
        mutex_lock(&priv->mutex);
 
        /* Sync status */
-       status = twl6040_read(codec, TWL6040_REG_STATUS);
+       status = twl6040_read(component, TWL6040_REG_STATUS);
        if (status & TWL6040_PLUGCOMP)
                snd_soc_jack_report(jack, report, report);
        else
@@ -299,16 +299,16 @@ static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
        mutex_unlock(&priv->mutex);
 }
 
-void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
+void twl6040_hs_jack_detect(struct snd_soc_component *component,
                                struct snd_soc_jack *jack, int report)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        struct twl6040_jack_data *hs_jack = &priv->hs_jack;
 
        hs_jack->jack = jack;
        hs_jack->report = report;
 
-       twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
+       twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report);
 }
 EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
 
@@ -316,17 +316,17 @@ static void twl6040_accessory_work(struct work_struct *work)
 {
        struct twl6040_data *priv = container_of(work,
                                        struct twl6040_data, hs_jack.work.work);
-       struct snd_soc_codec *codec = priv->codec;
+       struct snd_soc_component *component = priv->component;
        struct twl6040_jack_data *hs_jack = &priv->hs_jack;
 
-       twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
+       twl6040_hs_jack_report(component, hs_jack->jack, hs_jack->report);
 }
 
 /* audio interrupt handler */
 static irqreturn_t twl6040_audio_handler(int irq, void *data)
 {
-       struct snd_soc_codec *codec = data;
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = data;
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        queue_delayed_work(system_power_efficient_wq,
                           &priv->hs_jack.work, msecs_to_jiffies(200));
@@ -337,12 +337,12 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
 static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned int val;
 
        /* Do not allow changes while Input/FF efect is running */
-       val = twl6040_read(codec, e->reg);
+       val = twl6040_read(component, e->reg);
        if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL))
                return -EBUSY;
 
@@ -486,8 +486,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum,
 static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.enumerated.item[0] = priv->hs_power_mode;
 
@@ -497,13 +497,13 @@ static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol,
 static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int high_perf = ucontrol->value.enumerated.item[0];
        int ret = 0;
 
        if (!priv->hs_power_mode_locked)
-               ret = headset_power_mode(codec, high_perf);
+               ret = headset_power_mode(component, high_perf);
 
        if (!ret)
                priv->hs_power_mode = high_perf;
@@ -514,8 +514,8 @@ static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol,
 static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.enumerated.item[0] = priv->pll_power_mode;
 
@@ -525,17 +525,17 @@ static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol,
 static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        priv->pll_power_mode = ucontrol->value.enumerated.item[0];
 
        return 0;
 }
 
-int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
+int twl6040_get_dl1_gain(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (snd_soc_dapm_get_pin_status(dapm, "EP"))
                return -1; /* -1dB */
@@ -543,7 +543,7 @@ int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
        if (snd_soc_dapm_get_pin_status(dapm, "HSOR") ||
                snd_soc_dapm_get_pin_status(dapm, "HSOL")) {
 
-               u8 val = twl6040_read(codec, TWL6040_REG_HSLCTL);
+               u8 val = twl6040_read(component, TWL6040_REG_HSLCTL);
                if (val & TWL6040_HSDACMODE)
                        /* HSDACL in LP mode */
                        return -8; /* -8dB */
@@ -555,26 +555,26 @@ int twl6040_get_dl1_gain(struct snd_soc_codec *codec)
 }
 EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain);
 
-int twl6040_get_clk_id(struct snd_soc_codec *codec)
+int twl6040_get_clk_id(struct snd_soc_component *component)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        return priv->pll_power_mode;
 }
 EXPORT_SYMBOL_GPL(twl6040_get_clk_id);
 
-int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
+int twl6040_get_trim_value(struct snd_soc_component *component, enum twl6040_trim trim)
 {
        if (unlikely(trim >= TWL6040_TRIM_INVAL))
                return -EINVAL;
 
-       return twl6040_read(codec, TWL6040_REG_TRIM1 + trim);
+       return twl6040_read(component, TWL6040_REG_TRIM1 + trim);
 }
 EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
 
-int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
+int twl6040_get_hs_step_size(struct snd_soc_component *component)
 {
-       struct twl6040 *twl6040 = to_twl6040(codec);
+       struct twl6040 *twl6040 = to_twl6040(component);
 
        if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3)
                /* For ES under ES_1.3 HS step is 2 mV */
@@ -829,11 +829,11 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"VIBRAR", NULL, "Vibra Right Driver"},
 };
 
-static int twl6040_set_bias_level(struct snd_soc_codec *codec,
+static int twl6040_set_bias_level(struct snd_soc_component *component,
                                enum snd_soc_bias_level level)
 {
-       struct twl6040 *twl6040 = to_twl6040(codec);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040 *twl6040 = to_twl6040(component);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (level) {
@@ -856,7 +856,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
                priv->codec_powered = 1;
 
                /* Set external boost GPO */
-               twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
+               twl6040_write(component, TWL6040_REG_GPOCTL, 0x02);
                break;
        case SND_SOC_BIAS_OFF:
                if (!priv->codec_powered)
@@ -873,8 +873,8 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
 static int twl6040_startup(struct snd_pcm_substream *substream,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        snd_pcm_hw_constraint_list(substream->runtime, 0,
                                SNDRV_PCM_HW_PARAM_RATE,
@@ -887,8 +887,8 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
                        struct snd_pcm_hw_params *params,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int rate;
 
        rate = params_rate(params);
@@ -899,7 +899,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
        case 88200:
                /* These rates are not supported when HPPLL is in use */
                if (unlikely(priv->pll == TWL6040_SYSCLK_SEL_HPPLL)) {
-                       dev_err(codec->dev, "HPPLL does not support rate %d\n",
+                       dev_err(component->dev, "HPPLL does not support rate %d\n",
                                rate);
                        return -EINVAL;
                }
@@ -913,7 +913,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
                priv->sysclk = 19200000;
                break;
        default:
-               dev_err(codec->dev, "unsupported rate %d\n", rate);
+               dev_err(component->dev, "unsupported rate %d\n", rate);
                return -EINVAL;
        }
 
@@ -923,20 +923,20 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
 static int twl6040_prepare(struct snd_pcm_substream *substream,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct twl6040 *twl6040 = to_twl6040(codec);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct twl6040 *twl6040 = to_twl6040(component);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int ret;
 
        if (!priv->sysclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "no mclk configured, call set_sysclk() on init\n");
                return -EINVAL;
        }
 
        ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk);
        if (ret) {
-               dev_err(codec->dev, "Can not set PLL (%d)\n", ret);
+               dev_err(component->dev, "Can not set PLL (%d)\n", ret);
                return -EPERM;
        }
 
@@ -946,8 +946,8 @@ static int twl6040_prepare(struct snd_pcm_substream *substream,
 static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case TWL6040_SYSCLK_SEL_LPPLL:
@@ -956,26 +956,26 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                priv->clk_in = freq;
                break;
        default:
-               dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
+               dev_err(component->dev, "unknown clk_id %d\n", clk_id);
                return -EINVAL;
        }
 
        return 0;
 }
 
-static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id,
+static void twl6040_mute_path(struct snd_soc_component *component, enum twl6040_dai_id id,
                             int mute)
 {
-       struct twl6040 *twl6040 = to_twl6040(codec);
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040 *twl6040 = to_twl6040(component);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
        int hslctl, hsrctl, earctl;
        int hflctl, hfrctl;
 
        switch (id) {
        case TWL6040_DAI_DL1:
-               hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL);
-               hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL);
-               earctl = twl6040_read(codec, TWL6040_REG_EARCTL);
+               hslctl = twl6040_read(component, TWL6040_REG_HSLCTL);
+               hsrctl = twl6040_read(component, TWL6040_REG_HSRCTL);
+               earctl = twl6040_read(component, TWL6040_REG_EARCTL);
 
                if (mute) {
                        /* Power down drivers and DACs */
@@ -991,8 +991,8 @@ static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id i
                priv->dl1_unmuted = !mute;
                break;
        case TWL6040_DAI_DL2:
-               hflctl = twl6040_read(codec, TWL6040_REG_HFLCTL);
-               hfrctl = twl6040_read(codec, TWL6040_REG_HFRCTL);
+               hflctl = twl6040_read(component, TWL6040_REG_HFLCTL);
+               hfrctl = twl6040_read(component, TWL6040_REG_HFRCTL);
 
                if (mute) {
                        /* Power down drivers and DACs */
@@ -1015,12 +1015,12 @@ static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute)
 {
        switch (dai->id) {
        case TWL6040_DAI_LEGACY:
-               twl6040_mute_path(dai->codec, TWL6040_DAI_DL1, mute);
-               twl6040_mute_path(dai->codec, TWL6040_DAI_DL2, mute);
+               twl6040_mute_path(dai->component, TWL6040_DAI_DL1, mute);
+               twl6040_mute_path(dai->component, TWL6040_DAI_DL2, mute);
                break;
        case TWL6040_DAI_DL1:
        case TWL6040_DAI_DL2:
-               twl6040_mute_path(dai->codec, dai->id, mute);
+               twl6040_mute_path(dai->component, dai->id, mute);
                break;
        default:
                break;
@@ -1107,23 +1107,23 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
 },
 };
 
-static int twl6040_probe(struct snd_soc_codec *codec)
+static int twl6040_probe(struct snd_soc_component *component)
 {
        struct twl6040_data *priv;
-       struct platform_device *pdev = to_platform_device(codec->dev);
+       struct platform_device *pdev = to_platform_device(component->dev);
        int ret = 0;
 
-       priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL);
+       priv = devm_kzalloc(component->dev, sizeof(*priv), GFP_KERNEL);
        if (priv == NULL)
                return -ENOMEM;
 
-       snd_soc_codec_set_drvdata(codec, priv);
+       snd_soc_component_set_drvdata(component, priv);
 
-       priv->codec = codec;
+       priv->component = component;
 
        priv->plug_irq = platform_get_irq(pdev, 0);
        if (priv->plug_irq < 0) {
-               dev_err(codec->dev, "invalid irq: %d\n", priv->plug_irq);
+               dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq);
                return priv->plug_irq;
        }
 
@@ -1134,64 +1134,55 @@ static int twl6040_probe(struct snd_soc_codec *codec)
        ret = request_threaded_irq(priv->plug_irq, NULL,
                                        twl6040_audio_handler,
                                        IRQF_NO_SUSPEND | IRQF_ONESHOT,
-                                       "twl6040_irq_plug", codec);
+                                       "twl6040_irq_plug", component);
        if (ret) {
-               dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
+               dev_err(component->dev, "PLUG IRQ request failed: %d\n", ret);
                return ret;
        }
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
-       twl6040_init_chip(codec);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
+       twl6040_init_chip(component);
 
        return 0;
 }
 
-static int twl6040_remove(struct snd_soc_codec *codec)
+static void twl6040_remove(struct snd_soc_component *component)
 {
-       struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
 
-       free_irq(priv->plug_irq, codec);
-
-       return 0;
+       free_irq(priv->plug_irq, component);
 }
 
-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,
-
-       .component_driver = {
-               .controls               = twl6040_snd_controls,
-               .num_controls           = ARRAY_SIZE(twl6040_snd_controls),
-               .dapm_widgets           = twl6040_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(twl6040_dapm_widgets),
-               .dapm_routes            = intercon,
-               .num_dapm_routes        = ARRAY_SIZE(intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_twl6040 = {
+       .probe                  = twl6040_probe,
+       .remove                 = twl6040_remove,
+       .read                   = twl6040_read,
+       .write                  = twl6040_write,
+       .set_bias_level         = twl6040_set_bias_level,
+       .controls               = twl6040_snd_controls,
+       .num_controls           = ARRAY_SIZE(twl6040_snd_controls),
+       .dapm_widgets           = twl6040_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(twl6040_dapm_widgets),
+       .dapm_routes            = intercon,
+       .num_dapm_routes        = ARRAY_SIZE(intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int twl6040_codec_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &soc_component_dev_twl6040,
                                      twl6040_dai, ARRAY_SIZE(twl6040_dai));
 }
 
-static int twl6040_codec_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static struct platform_driver twl6040_codec_driver = {
        .driver = {
                .name = "twl6040-codec",
        },
        .probe = twl6040_codec_probe,
-       .remove = twl6040_codec_remove,
 };
 
 module_platform_driver(twl6040_codec_driver);
index 0611406ca7c0359188575df1e61020c1680e9b4e..3d9f957077efb4a646288eea5aef49417c2836cc 100644 (file)
@@ -34,11 +34,11 @@ enum twl6040_trim {
 #define TWL6040_HSF_TRIM_LEFT(x)       (x & 0x0f)
 #define TWL6040_HSF_TRIM_RIGHT(x)      ((x >> 4) & 0x0f)
 
-int twl6040_get_dl1_gain(struct snd_soc_codec *codec);
-void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
+int twl6040_get_dl1_gain(struct snd_soc_component *component);
+void twl6040_hs_jack_detect(struct snd_soc_component *component,
                            struct snd_soc_jack *jack, int report);
-int twl6040_get_clk_id(struct snd_soc_codec *codec);
-int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
-int twl6040_get_hs_step_size(struct snd_soc_codec *codec);
+int twl6040_get_clk_id(struct snd_soc_component *component);
+int twl6040_get_trim_value(struct snd_soc_component *component, enum twl6040_trim trim);
+int twl6040_get_hs_step_size(struct snd_soc_component *component);
 
 #endif /* End of __TWL6040_H__ */
index 77c9cc4467b82d65f3f595a1cca5d6cddffe8fe8..3c935a941129fe8383eea39797b791a6e6e59258 100644 (file)
@@ -110,9 +110,9 @@ static int uda134x_regmap_write(void *context, unsigned int reg,
        return 0;
 }
 
-static inline void uda134x_reset(struct snd_soc_codec *codec)
+static inline void uda134x_reset(struct snd_soc_component *component)
 {
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
        unsigned int mask = 1<<6;
 
        regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, mask, mask);
@@ -122,7 +122,7 @@ static inline void uda134x_reset(struct snd_soc_codec *codec)
 
 static int uda134x_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(dai->codec);
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(dai->component);
        unsigned int mask = 1<<2;
        unsigned int val;
 
@@ -139,8 +139,8 @@ static int uda134x_mute(struct snd_soc_dai *dai, int mute)
 static int uda134x_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *master_runtime;
 
        if (uda134x->master_substream) {
@@ -168,8 +168,8 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
 static void uda134x_shutdown(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 
        if (uda134x->master_substream == substream)
                uda134x->master_substream = uda134x->slave_substream;
@@ -181,8 +181,8 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
        unsigned int hw_params = 0;
 
        if (substream == uda134x->slave_substream) {
@@ -248,8 +248,8 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
 static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                  int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 
        pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
                 clk_id, freq, dir);
@@ -270,8 +270,8 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                               unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
 
        pr_debug("%s fmt: %08X\n", __func__, fmt);
 
@@ -294,10 +294,10 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int uda134x_set_bias_level(struct snd_soc_codec *codec,
+static int uda134x_set_bias_level(struct snd_soc_component *component,
                                  enum snd_soc_bias_level level)
 {
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
        struct uda134x_platform_data *pd = uda134x->pd;
        pr_debug("%s bias level %d\n", __func__, level);
 
@@ -446,10 +446,10 @@ static struct snd_soc_dai_driver uda134x_dai = {
        .ops = &uda134x_dai_ops,
 };
 
-static int uda134x_soc_probe(struct snd_soc_codec *codec)
+static int uda134x_soc_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component);
        struct uda134x_platform_data *pd = uda134x->pd;
        const struct snd_soc_dapm_widget *widgets;
        unsigned num_widgets;
@@ -473,7 +473,7 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
        if (pd->power)
                pd->power(1);
 
-       uda134x_reset(codec);
+       uda134x_reset(component);
 
        if (pd->model == UDA134X_UDA1341) {
                widgets = uda1341_dapm_widgets;
@@ -493,15 +493,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
        switch (pd->model) {
        case UDA134X_UDA1340:
        case UDA134X_UDA1344:
-               ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls,
+               ret = snd_soc_add_component_controls(component, uda1340_snd_controls,
                                        ARRAY_SIZE(uda1340_snd_controls));
        break;
        case UDA134X_UDA1341:
-               ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls,
+               ret = snd_soc_add_component_controls(component, uda1341_snd_controls,
                                        ARRAY_SIZE(uda1341_snd_controls));
        break;
        case UDA134X_UDA1345:
-               ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls,
+               ret = snd_soc_add_component_controls(component, uda1345_snd_controls,
                                        ARRAY_SIZE(uda1345_snd_controls));
        break;
        default:
@@ -518,17 +518,18 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_uda134x = {
-       .probe =        uda134x_soc_probe,
-       .set_bias_level = uda134x_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .dapm_widgets           = uda134x_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(uda134x_dapm_widgets),
-               .dapm_routes            = uda134x_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(uda134x_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_uda134x = {
+       .probe                  = uda134x_soc_probe,
+       .set_bias_level         = uda134x_set_bias_level,
+       .dapm_widgets           = uda134x_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(uda134x_dapm_widgets),
+       .dapm_routes            = uda134x_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(uda134x_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config uda134x_regmap_config = {
@@ -571,14 +572,8 @@ static int uda134x_codec_probe(struct platform_device *pdev)
        if (IS_ERR(uda134x->regmap))
                return PTR_ERR(uda134x->regmap);
 
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_uda134x, &uda134x_dai, 1);
-}
-
-static int uda134x_codec_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_uda134x, &uda134x_dai, 1);
 }
 
 static struct platform_driver uda134x_codec_driver = {
@@ -586,7 +581,6 @@ static struct platform_driver uda134x_codec_driver = {
                .name = "uda134x-codec",
        },
        .probe = uda134x_codec_probe,
-       .remove = uda134x_codec_remove,
 };
 
 module_platform_driver(uda134x_codec_driver);
index c73e6a19222443e279627450431a80316c2baace..584a032b3cb17f25480e27201a68a2cfc68402a0 100644 (file)
@@ -34,7 +34,7 @@
 
 /* codec private data */
 struct uda1380_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        unsigned int dac_clk;
        struct work_struct work;
        struct i2c_client *i2c;
@@ -61,10 +61,10 @@ static unsigned long uda1380_cache_dirty;
 /*
  * read uda1380 register cache
  */
-static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
+static inline unsigned int uda1380_read_reg_cache(struct snd_soc_component *component,
        unsigned int reg)
 {
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
        u16 *cache = uda1380->reg_cache;
 
        if (reg == UDA1380_RESET)
@@ -77,10 +77,10 @@ static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
 /*
  * write uda1380 register cache
  */
-static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
+static inline void uda1380_write_reg_cache(struct snd_soc_component *component,
        u16 reg, unsigned int value)
 {
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
        u16 *cache = uda1380->reg_cache;
 
        if (reg >= UDA1380_CACHEREGNUM)
@@ -93,10 +93,10 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
 /*
  * write to the UDA1380 register space
  */
-static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
+static int uda1380_write(struct snd_soc_component *component, unsigned int reg,
        unsigned int value)
 {
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
        u8 data[3];
 
        /* data is
@@ -108,12 +108,12 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
        data[1] = (value & 0xff00) >> 8;
        data[2] = value & 0x00ff;
 
-       uda1380_write_reg_cache(codec, reg, value);
+       uda1380_write_reg_cache(component, reg, value);
 
        /* the interpolator & decimator regs must only be written when the
         * codec DAI is active.
         */
-       if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL))
+       if (!snd_soc_component_is_active(component) && (reg >= UDA1380_MVOL))
                return 0;
        pr_debug("uda1380: hw write %x val %x\n", reg, value);
        if (i2c_master_send(uda1380->i2c, data, 3) == 3) {
@@ -133,9 +133,9 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
                return -EIO;
 }
 
-static void uda1380_sync_cache(struct snd_soc_codec *codec)
+static void uda1380_sync_cache(struct snd_soc_component *component)
 {
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
        int reg;
        u8 data[3];
        u16 *cache = uda1380->reg_cache;
@@ -146,15 +146,15 @@ static void uda1380_sync_cache(struct snd_soc_codec *codec)
                data[1] = (cache[reg] & 0xff00) >> 8;
                data[2] = cache[reg] & 0x00ff;
                if (i2c_master_send(uda1380->i2c, data, 3) != 3)
-                       dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
+                       dev_err(component->dev, "%s: write to reg 0x%x failed\n",
                                __func__, reg);
        }
 }
 
-static int uda1380_reset(struct snd_soc_codec *codec)
+static int uda1380_reset(struct snd_soc_component *component)
 {
-       struct uda1380_platform_data *pdata = codec->dev->platform_data;
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+       struct uda1380_platform_data *pdata = component->dev->platform_data;
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
 
        if (gpio_is_valid(pdata->gpio_reset)) {
                gpio_set_value(pdata->gpio_reset, 1);
@@ -168,7 +168,7 @@ static int uda1380_reset(struct snd_soc_codec *codec)
                data[2] = 0;
 
                if (i2c_master_send(uda1380->i2c, data, 3) != 3) {
-                       dev_err(codec->dev, "%s: failed\n", __func__);
+                       dev_err(component->dev, "%s: failed\n", __func__);
                        return -EIO;
                }
        }
@@ -179,15 +179,15 @@ static int uda1380_reset(struct snd_soc_codec *codec)
 static void uda1380_flush_work(struct work_struct *work)
 {
        struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
-       struct snd_soc_codec *uda1380_codec = uda1380->codec;
+       struct snd_soc_component *uda1380_component = uda1380->component;
        int bit, reg;
 
        for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
                reg = 0x10 + bit;
                pr_debug("uda1380: flush reg %x val %x:\n", reg,
-                               uda1380_read_reg_cache(uda1380_codec, reg));
-               uda1380_write(uda1380_codec, reg,
-                               uda1380_read_reg_cache(uda1380_codec, reg));
+                               uda1380_read_reg_cache(uda1380_component, reg));
+               uda1380_write(uda1380_component, reg,
+                               uda1380_read_reg_cache(uda1380_component, reg));
                clear_bit(bit, &uda1380_cache_dirty);
        }
 
@@ -420,11 +420,11 @@ static const struct snd_soc_dapm_route uda1380_dapm_routes[] = {
 static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int iface;
 
        /* set up DAI based upon fmt */
-       iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+       iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
        iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -442,7 +442,7 @@ static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
                return -EINVAL;
 
-       uda1380_write_reg_cache(codec, UDA1380_IFACE, iface);
+       uda1380_write_reg_cache(component, UDA1380_IFACE, iface);
 
        return 0;
 }
@@ -450,11 +450,11 @@ static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai,
 static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int iface;
 
        /* set up DAI based upon fmt */
-       iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+       iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
        iface &= ~R01_SFORI_MASK;
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -472,7 +472,7 @@ static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
                return -EINVAL;
 
-       uda1380_write(codec, UDA1380_IFACE, iface);
+       uda1380_write(component, UDA1380_IFACE, iface);
 
        return 0;
 }
@@ -480,11 +480,11 @@ static int uda1380_set_dai_fmt_playback(struct snd_soc_dai *codec_dai,
 static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        int iface;
 
        /* set up DAI based upon fmt */
-       iface = uda1380_read_reg_cache(codec, UDA1380_IFACE);
+       iface = uda1380_read_reg_cache(component, UDA1380_IFACE);
        iface &= ~(R01_SIM | R01_SFORO_MASK);
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -501,7 +501,7 @@ static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
        if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
                iface |= R01_SIM;
 
-       uda1380_write(codec, UDA1380_IFACE, iface);
+       uda1380_write(component, UDA1380_IFACE, iface);
 
        return 0;
 }
@@ -509,20 +509,20 @@ static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
 static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
-       int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
+       struct snd_soc_component *component = dai->component;
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
+       int mixer = uda1380_read_reg_cache(component, UDA1380_MIXER);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               uda1380_write_reg_cache(codec, UDA1380_MIXER,
+               uda1380_write_reg_cache(component, UDA1380_MIXER,
                                        mixer & ~R14_SILENCE);
                schedule_work(&uda1380->work);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               uda1380_write_reg_cache(codec, UDA1380_MIXER,
+               uda1380_write_reg_cache(component, UDA1380_MIXER,
                                        mixer | R14_SILENCE);
                schedule_work(&uda1380->work);
                break;
@@ -534,13 +534,13 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
+       struct snd_soc_component *component = dai->component;
+       u16 clk = uda1380_read_reg_cache(component, UDA1380_CLK);
 
        /* set WSPLL power and divider if running from this clock */
        if (clk & R00_DAC_CLK) {
                int rate = params_rate(params);
-               u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
+               u16 pm = uda1380_read_reg_cache(component, UDA1380_PM);
                clk &= ~0x3; /* clear SEL_LOOP_DIV */
                switch (rate) {
                case 6250 ... 12500:
@@ -556,7 +556,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
                        clk |= 0x3;
                        break;
                }
-               uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
+               uda1380_write(component, UDA1380_PM, R02_PON_PLL | pm);
        }
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -564,20 +564,20 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
        else
                clk |= R00_EN_ADC | R00_EN_DEC;
 
-       uda1380_write(codec, UDA1380_CLK, clk);
+       uda1380_write(component, UDA1380_CLK, clk);
        return 0;
 }
 
 static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
+       struct snd_soc_component *component = dai->component;
+       u16 clk = uda1380_read_reg_cache(component, UDA1380_CLK);
 
        /* shut down WSPLL power if running from this clock */
        if (clk & R00_DAC_CLK) {
-               u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
-               uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
+               u16 pm = uda1380_read_reg_cache(component, UDA1380_PM);
+               uda1380_write(component, UDA1380_PM, ~R02_PON_PLL & pm);
        }
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -585,33 +585,33 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
        else
                clk &= ~(R00_EN_ADC | R00_EN_DEC);
 
-       uda1380_write(codec, UDA1380_CLK, clk);
+       uda1380_write(component, UDA1380_CLK, clk);
 }
 
-static int uda1380_set_bias_level(struct snd_soc_codec *codec,
+static int uda1380_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
+       int pm = uda1380_read_reg_cache(component, UDA1380_PM);
        int reg;
-       struct uda1380_platform_data *pdata = codec->dev->platform_data;
+       struct uda1380_platform_data *pdata = component->dev->platform_data;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
                /* ADC, DAC on */
-               uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
+               uda1380_write(component, UDA1380_PM, R02_PON_BIAS | pm);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        if (gpio_is_valid(pdata->gpio_power)) {
                                gpio_set_value(pdata->gpio_power, 1);
                                mdelay(1);
-                               uda1380_reset(codec);
+                               uda1380_reset(component);
                        }
 
-                       uda1380_sync_cache(codec);
+                       uda1380_sync_cache(component);
                }
-               uda1380_write(codec, UDA1380_PM, 0x0);
+               uda1380_write(component, UDA1380_PM, 0x0);
                break;
        case SND_SOC_BIAS_OFF:
                if (!gpio_is_valid(pdata->gpio_power))
@@ -694,16 +694,16 @@ static struct snd_soc_dai_driver uda1380_dai[] = {
 },
 };
 
-static int uda1380_probe(struct snd_soc_codec *codec)
+static int uda1380_probe(struct snd_soc_component *component)
 {
-       struct uda1380_platform_data *pdata =codec->dev->platform_data;
-       struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+       struct uda1380_platform_data *pdata =component->dev->platform_data;
+       struct uda1380_priv *uda1380 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       uda1380->codec = codec;
+       uda1380->component = component;
 
        if (!gpio_is_valid(pdata->gpio_power)) {
-               ret = uda1380_reset(codec);
+               ret = uda1380_reset(component);
                if (ret)
                        return ret;
        }
@@ -713,10 +713,10 @@ static int uda1380_probe(struct snd_soc_codec *codec)
        /* set clock input */
        switch (pdata->dac_clk) {
        case UDA1380_DAC_CLK_SYSCLK:
-               uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
+               uda1380_write_reg_cache(component, UDA1380_CLK, 0);
                break;
        case UDA1380_DAC_CLK_WSPLL:
-               uda1380_write_reg_cache(codec, UDA1380_CLK,
+               uda1380_write_reg_cache(component, UDA1380_CLK,
                        R00_DAC_CLK);
                break;
        }
@@ -724,21 +724,22 @@ static int uda1380_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
-       .probe =        uda1380_probe,
-       .read =         uda1380_read_reg_cache,
-       .write =        uda1380_write,
-       .set_bias_level = uda1380_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = uda1380_snd_controls,
-               .num_controls           = ARRAY_SIZE(uda1380_snd_controls),
-               .dapm_widgets           = uda1380_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(uda1380_dapm_widgets),
-               .dapm_routes            = uda1380_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(uda1380_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_uda1380 = {
+       .probe                  = uda1380_probe,
+       .read                   = uda1380_read_reg_cache,
+       .write                  = uda1380_write,
+       .set_bias_level         = uda1380_set_bias_level,
+       .controls               = uda1380_snd_controls,
+       .num_controls           = ARRAY_SIZE(uda1380_snd_controls),
+       .dapm_widgets           = uda1380_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(uda1380_dapm_widgets),
+       .dapm_routes            = uda1380_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(uda1380_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int uda1380_i2c_probe(struct i2c_client *i2c,
@@ -780,17 +781,11 @@ static int uda1380_i2c_probe(struct i2c_client *i2c,
        i2c_set_clientdata(i2c, uda1380);
        uda1380->i2c = i2c;
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
        return ret;
 }
 
-static int uda1380_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-       return 0;
-}
-
 static const struct i2c_device_id uda1380_i2c_id[] = {
        { "uda1380", 0 },
        { }
@@ -809,7 +804,6 @@ static struct i2c_driver uda1380_i2c_driver = {
                .of_match_table = uda1380_of_match,
        },
        .probe =    uda1380_i2c_probe,
-       .remove =   uda1380_i2c_remove,
        .id_table = uda1380_i2c_id,
 };
 
index 942f1644973e8dd52b4b68d71cbc73123b249cd5..929ef1fdbb6956eb7425719fb616a59a1062217e 100644 (file)
@@ -172,8 +172,8 @@ out:
 static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
                                      struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.enumerated.item[0] = wl1273->mode;
 
@@ -190,14 +190,14 @@ static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
 static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
                                      struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
        if (wl1273->mode == ucontrol->value.enumerated.item[0])
                return 0;
 
        /* Do not allow changes while stream is running */
-       if (snd_soc_codec_is_active(codec))
+       if (snd_soc_component_is_active(component))
                return -EPERM;
 
        if (ucontrol->value.enumerated.item[0] >=  ARRAY_SIZE(wl1273_audio_route))
@@ -213,10 +213,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);
 static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s: enter.\n", __func__);
+       dev_dbg(component->dev, "%s: enter.\n", __func__);
 
        ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;
 
@@ -226,11 +226,11 @@ static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
 static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
        int val, r = 0;
 
-       dev_dbg(codec->dev, "%s: enter.\n", __func__);
+       dev_dbg(component->dev, "%s: enter.\n", __func__);
 
        val = ucontrol->value.enumerated.item[0];
        if (wl1273->core->audio_mode == val)
@@ -250,10 +250,10 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);
 static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
                                    struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s: enter.\n", __func__);
+       dev_dbg(component->dev, "%s: enter.\n", __func__);
 
        ucontrol->value.integer.value[0] = wl1273->core->volume;
 
@@ -263,11 +263,11 @@ static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
 static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
                                    struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
        int r;
 
-       dev_dbg(codec->dev, "%s: enter.\n", __func__);
+       dev_dbg(component->dev, "%s: enter.\n", __func__);
 
        r = wl1273->core->set_volume(wl1273->core,
                                     ucontrol->value.integer.value[0]);
@@ -301,8 +301,8 @@ static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
 static int wl1273_startup(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
        switch (wl1273->mode) {
        case WL1273_MODE_BT:
@@ -335,7 +335,7 @@ static int wl1273_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(dai->codec);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(dai->component);
        struct wl1273_core *core = wl1273->core;
        unsigned int rate, width, r;
 
@@ -415,14 +415,14 @@ static struct snd_soc_dai_driver wl1273_dai = {
 };
 
 /* Audio interface format for the soc_card driver */
-int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
+int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt)
 {
        struct wl1273_priv *wl1273;
 
-       if (codec == NULL || fmt == NULL)
+       if (component == NULL || fmt == NULL)
                return -EINVAL;
 
-       wl1273 = snd_soc_codec_get_drvdata(codec);
+       wl1273 = snd_soc_component_get_drvdata(component);
 
        switch (wl1273->mode) {
        case WL1273_MODE_FM_RX:
@@ -446,15 +446,15 @@ int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
 }
 EXPORT_SYMBOL_GPL(wl1273_get_format);
 
-static int wl1273_probe(struct snd_soc_codec *codec)
+static int wl1273_probe(struct snd_soc_component *component)
 {
-       struct wl1273_core **core = codec->dev->platform_data;
+       struct wl1273_core **core = component->dev->platform_data;
        struct wl1273_priv *wl1273;
 
-       dev_dbg(codec->dev, "%s.\n", __func__);
+       dev_dbg(component->dev, "%s.\n", __func__);
 
        if (!core) {
-               dev_err(codec->dev, "Platform data is missing.\n");
+               dev_err(component->dev, "Platform data is missing.\n");
                return -EINVAL;
        }
 
@@ -465,44 +465,43 @@ static int wl1273_probe(struct snd_soc_codec *codec)
        wl1273->mode = WL1273_MODE_BT;
        wl1273->core = *core;
 
-       snd_soc_codec_set_drvdata(codec, wl1273);
+       snd_soc_component_set_drvdata(component, wl1273);
 
        return 0;
 }
 
-static int wl1273_remove(struct snd_soc_codec *codec)
+static void wl1273_remove(struct snd_soc_component *component)
 {
-       struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
+       struct wl1273_priv *wl1273 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "%s\n", __func__);
+       dev_dbg(component->dev, "%s\n", __func__);
        kfree(wl1273);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
-       .probe = wl1273_probe,
-       .remove = wl1273_remove,
-
-       .component_driver = {
-               .controls               = wl1273_controls,
-               .num_controls           = ARRAY_SIZE(wl1273_controls),
-               .dapm_widgets           = wl1273_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wl1273_dapm_widgets),
-               .dapm_routes            = wl1273_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wl1273_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wl1273 = {
+       .probe                  = wl1273_probe,
+       .remove                 = wl1273_remove,
+       .controls               = wl1273_controls,
+       .num_controls           = ARRAY_SIZE(wl1273_controls),
+       .dapm_widgets           = wl1273_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wl1273_dapm_widgets),
+       .dapm_routes            = wl1273_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wl1273_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wl1273_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
+       return devm_snd_soc_register_component(&pdev->dev,
+                                     &soc_component_dev_wl1273,
                                      &wl1273_dai, 1);
 }
 
 static int wl1273_platform_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
index 43ec7e668c51e35b29d86c5bd863cacbea9e1463..43a81d5cab4d8634bba843c1a5db10a11a4adab9 100644 (file)
@@ -25,6 +25,6 @@
 #ifndef __WL1273_CODEC_H__
 #define __WL1273_CODEC_H__
 
-int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt);
+int wl1273_get_format(struct snd_soc_component *component, unsigned int *fmt);
 
 #endif /* End of __WL1273_CODEC_H__ */
index 0147d2fb7b0a28b389069616bfe8cdb2dc21f4e2..abd2defe7530ccc6c1bda8d8e52842f513d207e6 100644 (file)
@@ -90,7 +90,7 @@ enum wm0010_state {
 };
 
 struct wm0010_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 
        struct mutex lock;
        struct device *dev;
@@ -157,9 +157,9 @@ static const char *wm0010_state_to_str(enum wm0010_state state)
 }
 
 /* Called with wm0010->lock held */
-static void wm0010_halt(struct snd_soc_codec *codec)
+static void wm0010_halt(struct snd_soc_component *component)
 {
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
        unsigned long flags;
        enum wm0010_state state;
 
@@ -193,7 +193,7 @@ static void wm0010_halt(struct snd_soc_codec *codec)
 
 struct wm0010_boot_xfer {
        struct list_head list;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct completion *done;
        struct spi_message m;
        struct spi_transfer t;
@@ -218,13 +218,13 @@ static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010)
 static void wm0010_boot_xfer_complete(void *data)
 {
        struct wm0010_boot_xfer *xfer = data;
-       struct snd_soc_codec *codec = xfer->codec;
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = xfer->component;
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
        u32 *out32 = xfer->t.rx_buf;
        int i;
 
        if (xfer->m.status != 0) {
-               dev_err(codec->dev, "SPI transfer failed: %d\n",
+               dev_err(component->dev, "SPI transfer failed: %d\n",
                        xfer->m.status);
                wm0010_mark_boot_failure(wm0010);
                if (xfer->done)
@@ -233,11 +233,11 @@ static void wm0010_boot_xfer_complete(void *data)
        }
 
        for (i = 0; i < xfer->t.len / 4; i++) {
-               dev_dbg(codec->dev, "%d: %04x\n", i, out32[i]);
+               dev_dbg(component->dev, "%d: %04x\n", i, out32[i]);
 
                switch (be32_to_cpu(out32[i])) {
                case 0xe0e0e0e0:
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "%d: ROM error reported in stage 2\n", i);
                        wm0010_mark_boot_failure(wm0010);
                        break;
@@ -245,82 +245,82 @@ static void wm0010_boot_xfer_complete(void *data)
                case 0x55555555:
                        if (wm0010->state < WM0010_STAGE2)
                                break;
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "%d: ROM bootloader running in stage 2\n", i);
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0000:
-                       dev_dbg(codec->dev, "Stage2 loader running\n");
+                       dev_dbg(component->dev, "Stage2 loader running\n");
                        break;
 
                case 0x0fed0007:
-                       dev_dbg(codec->dev, "CODE_HDR packet received\n");
+                       dev_dbg(component->dev, "CODE_HDR packet received\n");
                        break;
 
                case 0x0fed0008:
-                       dev_dbg(codec->dev, "CODE_DATA packet received\n");
+                       dev_dbg(component->dev, "CODE_DATA packet received\n");
                        break;
 
                case 0x0fed0009:
-                       dev_dbg(codec->dev, "Download complete\n");
+                       dev_dbg(component->dev, "Download complete\n");
                        break;
 
                case 0x0fed000c:
-                       dev_dbg(codec->dev, "Application start\n");
+                       dev_dbg(component->dev, "Application start\n");
                        break;
 
                case 0x0fed000e:
-                       dev_dbg(codec->dev, "PLL packet received\n");
+                       dev_dbg(component->dev, "PLL packet received\n");
                        wm0010->pll_running = true;
                        break;
 
                case 0x0fed0025:
-                       dev_err(codec->dev, "Device reports image too long\n");
+                       dev_err(component->dev, "Device reports image too long\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed002c:
-                       dev_err(codec->dev, "Device reports bad SPI packet\n");
+                       dev_err(component->dev, "Device reports bad SPI packet\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0031:
-                       dev_err(codec->dev, "Device reports SPI read overflow\n");
+                       dev_err(component->dev, "Device reports SPI read overflow\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0032:
-                       dev_err(codec->dev, "Device reports SPI underclock\n");
+                       dev_err(component->dev, "Device reports SPI underclock\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0033:
-                       dev_err(codec->dev, "Device reports bad header packet\n");
+                       dev_err(component->dev, "Device reports bad header packet\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0034:
-                       dev_err(codec->dev, "Device reports invalid packet type\n");
+                       dev_err(component->dev, "Device reports invalid packet type\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0035:
-                       dev_err(codec->dev, "Device reports data before header error\n");
+                       dev_err(component->dev, "Device reports data before header error\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                case 0x0fed0038:
-                       dev_err(codec->dev, "Device reports invalid PLL packet\n");
+                       dev_err(component->dev, "Device reports invalid PLL packet\n");
                        break;
 
                case 0x0fed003a:
-                       dev_err(codec->dev, "Device reports packet alignment error\n");
+                       dev_err(component->dev, "Device reports packet alignment error\n");
                        wm0010_mark_boot_failure(wm0010);
                        break;
 
                default:
-                       dev_err(codec->dev, "Unrecognised return 0x%x\n",
+                       dev_err(component->dev, "Unrecognised return 0x%x\n",
                            be32_to_cpu(out32[i]));
                        wm0010_mark_boot_failure(wm0010);
                        break;
@@ -342,10 +342,10 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
                data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
 }
 
-static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
+static int wm0010_firmware_load(const char *name, struct snd_soc_component *component)
 {
-       struct spi_device *spi = to_spi_device(codec->dev);
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct spi_device *spi = to_spi_device(component->dev);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
        struct list_head xfer_list;
        struct wm0010_boot_xfer *xfer;
        int ret;
@@ -359,9 +359,9 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 
        INIT_LIST_HEAD(&xfer_list);
 
-       ret = request_firmware(&fw, name, codec->dev);
+       ret = request_firmware(&fw, name, component->dev);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to request application(%s): %d\n",
+               dev_err(component->dev, "Failed to request application(%s): %d\n",
                        name, ret);
                return ret;
        }
@@ -377,25 +377,25 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
 
        /* First record should be INFO */
        if (rec->command != DFW_CMD_INFO) {
-               dev_err(codec->dev, "First record not INFO\r\n");
+               dev_err(component->dev, "First record not INFO\r\n");
                ret = -EINVAL;
                goto abort;
        }
 
        if (inforec->info_version != INFO_VERSION) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "Unsupported version (%02d) of INFO record\r\n",
                        inforec->info_version);
                ret = -EINVAL;
                goto abort;
        }
 
-       dev_dbg(codec->dev, "Version v%02d INFO record found\r\n",
+       dev_dbg(component->dev, "Version v%02d INFO record found\r\n",
                inforec->info_version);
 
        /* Check it's a DSP file */
        if (dsp != DEVICE_ID_WM0010) {
-               dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
+               dev_err(component->dev, "Not a WM0010 firmware file.\r\n");
                ret = -EINVAL;
                goto abort;
        }
@@ -405,7 +405,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
        rec = (void *)&rec->data[rec->length];
 
        while (offset < fw->size) {
-               dev_dbg(codec->dev,
+               dev_dbg(component->dev,
                        "Packet: command %d, data length = 0x%x\r\n",
                        rec->command, rec->length);
                len = rec->length + 8;
@@ -416,7 +416,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
                        goto abort;
                }
 
-               xfer->codec = codec;
+               xfer->component = component;
                list_add_tail(&xfer->list, &xfer_list);
 
                out = kzalloc(len, GFP_KERNEL | GFP_DMA);
@@ -460,18 +460,18 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
                rec = (void *)&rec->data[rec->length];
 
                if (offset >= fw->size) {
-                       dev_dbg(codec->dev, "All transfers scheduled\n");
+                       dev_dbg(component->dev, "All transfers scheduled\n");
                        xfer->done = &done;
                }
 
                ret = spi_async(spi, &xfer->m);
                if (ret != 0) {
-                       dev_err(codec->dev, "Write failed: %d\n", ret);
+                       dev_err(component->dev, "Write failed: %d\n", ret);
                        goto abort1;
                }
 
                if (wm0010->boot_failed) {
-                       dev_dbg(codec->dev, "Boot fail!\n");
+                       dev_dbg(component->dev, "Boot fail!\n");
                        ret = -EINVAL;
                        goto abort1;
                }
@@ -496,10 +496,10 @@ abort:
        return ret;
 }
 
-static int wm0010_stage2_load(struct snd_soc_codec *codec)
+static int wm0010_stage2_load(struct snd_soc_component *component)
 {
-       struct spi_device *spi = to_spi_device(codec->dev);
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct spi_device *spi = to_spi_device(component->dev);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
        const struct firmware *fw;
        struct spi_message m;
        struct spi_transfer t;
@@ -508,14 +508,14 @@ static int wm0010_stage2_load(struct snd_soc_codec *codec)
        int i;
        int ret = 0;
 
-       ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
+       ret = request_firmware(&fw, "wm0010_stage2.bin", component->dev);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
+               dev_err(component->dev, "Failed to request stage2 loader: %d\n",
                        ret);
                return ret;
        }
 
-       dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
+       dev_dbg(component->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
 
        /* Copy to local buffer first as vmalloc causes problems for dma */
        img = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
@@ -541,19 +541,19 @@ static int wm0010_stage2_load(struct snd_soc_codec *codec)
        t.speed_hz = wm0010->sysclk / 10;
        spi_message_add_tail(&t, &m);
 
-       dev_dbg(codec->dev, "Starting initial download at %dHz\n",
+       dev_dbg(component->dev, "Starting initial download at %dHz\n",
                t.speed_hz);
 
        ret = spi_sync(spi, &m);
        if (ret != 0) {
-               dev_err(codec->dev, "Initial download failed: %d\n", ret);
+               dev_err(component->dev, "Initial download failed: %d\n", ret);
                goto abort;
        }
 
        /* Look for errors from the boot ROM */
        for (i = 0; i < fw->size; i++) {
                if (out[i] != 0x55) {
-                       dev_err(codec->dev, "Boot ROM error: %x in %d\n",
+                       dev_err(component->dev, "Boot ROM error: %x in %d\n",
                                out[i], i);
                        wm0010_mark_boot_failure(wm0010);
                        ret = -EBUSY;
@@ -570,10 +570,10 @@ abort2:
        return ret;
 }
 
-static int wm0010_boot(struct snd_soc_codec *codec)
+static int wm0010_boot(struct snd_soc_component *component)
 {
-       struct spi_device *spi = to_spi_device(codec->dev);
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct spi_device *spi = to_spi_device(component->dev);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
        unsigned long flags;
        int ret;
        struct spi_message m;
@@ -590,7 +590,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
        spin_unlock_irqrestore(&wm0010->irq_lock, flags);
 
        if (wm0010->sysclk > 26000000) {
-               dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
+               dev_err(component->dev, "Max DSP clock frequency is 26MHz\n");
                ret = -ECANCELED;
                goto err;
        }
@@ -598,7 +598,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
        mutex_lock(&wm0010->lock);
        wm0010->pll_running = false;
 
-       dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
+       dev_dbg(component->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
 
        ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
                                    wm0010->core_supplies);
@@ -623,19 +623,19 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 
        if (!wait_for_completion_timeout(&wm0010->boot_completion,
                                         msecs_to_jiffies(20)))
-               dev_err(codec->dev, "Failed to get interrupt from DSP\n");
+               dev_err(component->dev, "Failed to get interrupt from DSP\n");
 
        spin_lock_irqsave(&wm0010->irq_lock, flags);
        wm0010->state = WM0010_BOOTROM;
        spin_unlock_irqrestore(&wm0010->irq_lock, flags);
 
-       ret = wm0010_stage2_load(codec);
+       ret = wm0010_stage2_load(component);
        if (ret)
                goto abort;
 
        if (!wait_for_completion_timeout(&wm0010->boot_completion,
                                         msecs_to_jiffies(20)))
-               dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
+               dev_err(component->dev, "Failed to get interrupt from DSP loader.\n");
 
        spin_lock_irqsave(&wm0010->irq_lock, flags);
        wm0010->state = WM0010_STAGE2;
@@ -676,14 +676,14 @@ static int wm0010_boot(struct snd_soc_codec *codec)
 
                ret = spi_sync(spi, &m);
                if (ret) {
-                       dev_err(codec->dev, "First PLL write failed: %d\n", ret);
+                       dev_err(component->dev, "First PLL write failed: %d\n", ret);
                        goto abort_swap;
                }
 
                /* Use a second send of the message to get the return status */
                ret = spi_sync(spi, &m);
                if (ret) {
-                       dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
+                       dev_err(component->dev, "Second PLL write failed: %d\n", ret);
                        goto abort_swap;
                }
 
@@ -692,7 +692,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
                /* Look for PLL active code from the DSP */
                for (i = 0; i < len / 4; i++) {
                        if (*p == 0x0e00ed0f) {
-                               dev_dbg(codec->dev, "PLL packet received\n");
+                               dev_dbg(component->dev, "PLL packet received\n");
                                wm0010->pll_running = true;
                                break;
                        }
@@ -702,9 +702,9 @@ static int wm0010_boot(struct snd_soc_codec *codec)
                kfree(img_swap);
                kfree(out);
        } else
-               dev_dbg(codec->dev, "Not enabling DSP PLL.");
+               dev_dbg(component->dev, "Not enabling DSP PLL.");
 
-       ret = wm0010_firmware_load("wm0010.dfw", codec);
+       ret = wm0010_firmware_load("wm0010.dfw", component);
 
        if (ret != 0)
                goto abort;
@@ -723,7 +723,7 @@ abort_out:
        kfree(out);
 abort:
        /* Put the chip back into reset */
-       wm0010_halt(codec);
+       wm0010_halt(component);
        mutex_unlock(&wm0010->lock);
        return ret;
 
@@ -735,22 +735,22 @@ err:
        return ret;
 }
 
-static int wm0010_set_bias_level(struct snd_soc_codec *codec,
+static int wm0010_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE)
-                       wm0010_boot(codec);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE)
+                       wm0010_boot(component);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
                        mutex_lock(&wm0010->lock);
-                       wm0010_halt(codec);
+                       wm0010_halt(component);
                        mutex_unlock(&wm0010->lock);
                }
                break;
@@ -761,10 +761,10 @@ static int wm0010_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
+static int wm0010_set_sysclk(struct snd_soc_component *component, int source,
                             int clk_id, unsigned int freq, int dir)
 {
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
        unsigned int i;
 
        wm0010->sysclk = freq;
@@ -783,20 +783,19 @@ static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
        return 0;
 }
 
-static int wm0010_probe(struct snd_soc_codec *codec);
-
-static const struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
-       .probe = wm0010_probe,
-       .set_bias_level = wm0010_set_bias_level,
-       .set_sysclk = wm0010_set_sysclk,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .dapm_widgets           = wm0010_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm0010_dapm_widgets),
-               .dapm_routes            = wm0010_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm0010_dapm_routes),
-       },
+static int wm0010_probe(struct snd_soc_component *component);
+
+static const struct snd_soc_component_driver soc_component_dev_wm0010 = {
+       .probe                  = wm0010_probe,
+       .set_bias_level         = wm0010_set_bias_level,
+       .set_sysclk             = wm0010_set_sysclk,
+       .dapm_widgets           = wm0010_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm0010_dapm_widgets),
+       .dapm_routes            = wm0010_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm0010_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
@@ -860,11 +859,11 @@ static irqreturn_t wm0010_irq(int irq, void *data)
        return IRQ_NONE;
 }
 
-static int wm0010_probe(struct snd_soc_codec *codec)
+static int wm0010_probe(struct snd_soc_component *component)
 {
-       struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+       struct wm0010_priv *wm0010 = snd_soc_component_get_drvdata(component);
 
-       wm0010->codec = codec;
+       wm0010->component = component;
 
        return 0;
 }
@@ -967,8 +966,8 @@ static int wm0010_spi_probe(struct spi_device *spi)
        else
                wm0010->board_max_spi_speed = 0;
 
-       ret = snd_soc_register_codec(&spi->dev,
-                                    &soc_codec_dev_wm0010, wm0010_dai,
+       ret = devm_snd_soc_register_component(&spi->dev,
+                                    &soc_component_dev_wm0010, wm0010_dai,
                                     ARRAY_SIZE(wm0010_dai));
        if (ret < 0)
                return ret;
@@ -980,8 +979,6 @@ static int wm0010_spi_remove(struct spi_device *spi)
 {
        struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
 
-       snd_soc_unregister_codec(&spi->dev);
-
        gpio_set_value_cansleep(wm0010->gpio_reset,
                                wm0010->gpio_reset_value);
 
index cf5f0580df6a852225ef70f39a6af22fe1255cc9..9727eec6d01b9a2a7cce1dbf04d502a5a71c76f0 100644 (file)
@@ -32,10 +32,10 @@ struct wm1250_priv {
        struct gpio gpios[WM1250_EV1_NUM_GPIOS];
 };
 
-static int wm1250_ev1_set_bias_level(struct snd_soc_codec *codec,
+static int wm1250_ev1_set_bias_level(struct snd_soc_component *component,
                                     enum snd_soc_bias_level level)
 {
-       struct wm1250_priv *wm1250 = dev_get_drvdata(codec->dev);
+       struct wm1250_priv *wm1250 = dev_get_drvdata(component->dev);
        int ena;
 
        if (wm1250)
@@ -81,7 +81,7 @@ static int wm1250_ev1_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct wm1250_priv *wm1250 = snd_soc_codec_get_drvdata(dai->codec);
+       struct wm1250_priv *wm1250 = snd_soc_component_get_drvdata(dai->component);
 
        switch (params_rate(params)) {
        case 8000:
@@ -141,15 +141,15 @@ static struct snd_soc_dai_driver wm1250_ev1_dai = {
        .ops = &wm1250_ev1_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
-       .component_driver = {
-               .dapm_widgets           = wm1250_ev1_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
-               .dapm_routes            = wm1250_ev1_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm1250_ev1_dapm_routes),
-       },
-       .set_bias_level = wm1250_ev1_set_bias_level,
-       .idle_bias_off = true,
+static const struct snd_soc_component_driver soc_component_dev_wm1250_ev1 = {
+       .dapm_widgets           = wm1250_ev1_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
+       .dapm_routes            = wm1250_ev1_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm1250_ev1_dapm_routes),
+       .set_bias_level         = wm1250_ev1_set_bias_level,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm1250_ev1_pdata(struct i2c_client *i2c)
@@ -224,7 +224,7 @@ static int wm1250_ev1_probe(struct i2c_client *i2c,
        if (ret != 0)
                return ret;
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
+       ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_wm1250_ev1,
                                     &wm1250_ev1_dai, 1);
        if (ret != 0) {
                dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -237,7 +237,6 @@ static int wm1250_ev1_probe(struct i2c_client *i2c,
 
 static int wm1250_ev1_remove(struct i2c_client *i2c)
 {
-       snd_soc_unregister_codec(&i2c->dev);
        wm1250_ev1_free(i2c);
 
        return 0;
index abfa052c07d83502800cbd84f8d0303ea18a9af8..c5ae07234a0060697c4c161b7fba16a8347c2a06 100644 (file)
@@ -607,8 +607,8 @@ static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
 static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
        ucontrol->value.integer.value[0] = wm2000->anc_active;
 
@@ -618,8 +618,8 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
 static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
        unsigned int anc_active = ucontrol->value.integer.value[0];
        int ret;
 
@@ -640,8 +640,8 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
 static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
        ucontrol->value.integer.value[0] = wm2000->spk_ena;
 
@@ -651,8 +651,8 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
 static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
        unsigned int val = ucontrol->value.integer.value[0];
        int ret;
 
@@ -683,8 +683,8 @@ static const struct snd_kcontrol_new wm2000_controls[] = {
 static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
        int ret;
 
        mutex_lock(&wm2000->lock);
@@ -724,16 +724,16 @@ static const struct snd_soc_dapm_route wm2000_audio_map[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm2000_suspend(struct snd_soc_codec *codec)
+static int wm2000_suspend(struct snd_soc_component *component)
 {
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
        return wm2000_anc_transition(wm2000, ANC_OFF);
 }
 
-static int wm2000_resume(struct snd_soc_codec *codec)
+static int wm2000_resume(struct snd_soc_component *component)
 {
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
        return wm2000_anc_set_mode(wm2000);
 }
@@ -782,9 +782,9 @@ static const struct regmap_config wm2000_regmap = {
        .readable_reg = wm2000_readable_reg,
 };
 
-static int wm2000_probe(struct snd_soc_codec *codec)
+static int wm2000_probe(struct snd_soc_component *component)
 {
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
        /* This will trigger a transition to standby mode by default */
        wm2000_anc_set_mode(wm2000);
@@ -792,27 +792,28 @@ static int wm2000_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int wm2000_remove(struct snd_soc_codec *codec)
+static void wm2000_remove(struct snd_soc_component *component)
 {
-       struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
+       struct wm2000_priv *wm2000 = dev_get_drvdata(component->dev);
 
-       return wm2000_anc_transition(wm2000, ANC_OFF);
+       wm2000_anc_transition(wm2000, ANC_OFF);
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm2000 = {
-       .probe = wm2000_probe,
-       .remove = wm2000_remove,
-       .suspend = wm2000_suspend,
-       .resume = wm2000_resume,
-
-       .component_driver = {
-               .controls               = wm2000_controls,
-               .num_controls           = ARRAY_SIZE(wm2000_controls),
-               .dapm_widgets           = wm2000_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm2000_dapm_widgets),
-               .dapm_routes            = wm2000_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(wm2000_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm2000 = {
+       .probe                  = wm2000_probe,
+       .remove                 = wm2000_remove,
+       .suspend                = wm2000_suspend,
+       .resume                 = wm2000_resume,
+       .controls               = wm2000_controls,
+       .num_controls           = ARRAY_SIZE(wm2000_controls),
+       .dapm_widgets           = wm2000_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm2000_dapm_widgets),
+       .dapm_routes            = wm2000_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(wm2000_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm2000_i2c_probe(struct i2c_client *i2c,
@@ -916,7 +917,8 @@ static int wm2000_i2c_probe(struct i2c_client *i2c,
 
        wm2000_reset(wm2000);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                       &soc_component_dev_wm2000, NULL, 0);
 
 err_supplies:
        regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
@@ -926,13 +928,6 @@ out:
        return ret;
 }
 
-static int wm2000_i2c_remove(struct i2c_client *i2c)
-{
-       snd_soc_unregister_codec(&i2c->dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id wm2000_i2c_id[] = {
        { "wm2000", 0 },
        { }
@@ -944,7 +939,6 @@ static struct i2c_driver wm2000_i2c_driver = {
                .name = "wm2000",
        },
        .probe = wm2000_i2c_probe,
-       .remove = wm2000_i2c_remove,
        .id_table = wm2000_i2c_id,
 };
 
index 5c2f5727244d7914c46531276b295650703e6bd3..d5f4bbf27182b73f192644f8634c0ae9060377b6 100644 (file)
@@ -87,7 +87,7 @@ struct wm2200_priv {
        struct wm_adsp dsp[2];
        struct regmap *regmap;
        struct device *dev;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct wm2200_pdata pdata;
        struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
 
@@ -1550,14 +1550,14 @@ static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
        WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
 };
 
-static int wm2200_probe(struct snd_soc_codec *codec)
+static int wm2200_probe(struct snd_soc_component *component)
 {
-       struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+       struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       wm2200->codec = codec;
+       wm2200->component = component;
 
-       ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2);
+       ret = snd_soc_add_component_controls(component, wm_adsp_fw_controls, 2);
        if (ret != 0)
                return ret;
 
@@ -1566,7 +1566,7 @@ static int wm2200_probe(struct snd_soc_codec *codec)
 
 static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int lrclk, bclk, fmt_val;
 
        lrclk = 0;
@@ -1580,7 +1580,7 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                fmt_val = 2;
                break;
        default:
-               dev_err(codec->dev, "Unsupported DAI format %d\n",
+               dev_err(component->dev, "Unsupported DAI format %d\n",
                        fmt & SND_SOC_DAIFMT_FORMAT_MASK);
                return -EINVAL;
        }
@@ -1599,7 +1599,7 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                bclk |= WM2200_AIF1_BCLK_MSTR;
                break;
        default:
-               dev_err(codec->dev, "Unsupported master mode %d\n",
+               dev_err(component->dev, "Unsupported master mode %d\n",
                        fmt & SND_SOC_DAIFMT_MASTER_MASK);
                return -EINVAL;
        }
@@ -1621,15 +1621,15 @@ static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
+       snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
                            WM2200_AIF1_BCLK_INV, bclk);
-       snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
+       snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2,
                            WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
                            lrclk);
-       snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
+       snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_3,
                            WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
                            lrclk);
-       snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
+       snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_5,
                            WM2200_AIF1_FMT_MASK, fmt_val);
 
        return 0;
@@ -1698,8 +1698,8 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
        int i, bclk, lrclk, wl, fl, sr_code;
        int *bclk_rates;
 
@@ -1711,7 +1711,7 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
        if (fl < 0)
                return fl;
 
-       dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
+       dev_dbg(component->dev, "Word length %d bits, frame length %d bits\n",
                wl, fl);
 
        /* Target BCLK rate */
@@ -1720,7 +1720,7 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
                return bclk;
 
        if (!wm2200->sysclk) {
-               dev_err(codec->dev, "SYSCLK has no rate set\n");
+               dev_err(component->dev, "SYSCLK has no rate set\n");
                return -EINVAL;
        }
 
@@ -1728,13 +1728,13 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
                if (wm2200_sr_code[i] == params_rate(params))
                        break;
        if (i == ARRAY_SIZE(wm2200_sr_code)) {
-               dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
+               dev_err(component->dev, "Unsupported sample rate: %dHz\n",
                        params_rate(params));
                return -EINVAL;
        }
        sr_code = i;
 
-       dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
+       dev_dbg(component->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
                bclk, wm2200->sysclk);
 
        if (wm2200->sysclk % 4000)
@@ -1746,38 +1746,38 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream,
                if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
                        break;
        if (i == WM2200_NUM_BCLK_RATES) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "No valid BCLK for %dHz found from %dHz SYSCLK\n",
                        bclk, wm2200->sysclk);
                return -EINVAL;
        }
 
        bclk = i;
-       dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
-       snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
+       dev_dbg(component->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
+       snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1,
                            WM2200_AIF1_BCLK_DIV_MASK, bclk);
 
        lrclk = bclk_rates[bclk] / params_rate(params);
-       dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
+       dev_dbg(component->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
            wm2200->symmetric_rates)
-               snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
+               snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_7,
                                    WM2200_AIF1RX_BCPF_MASK, lrclk);
        else
-               snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
+               snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_6,
                                    WM2200_AIF1TX_BCPF_MASK, lrclk);
 
        i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
+               snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_9,
                                    WM2200_AIF1RX_WL_MASK |
                                    WM2200_AIF1RX_SLOT_LEN_MASK, i);
        else
-               snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
+               snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_8,
                                    WM2200_AIF1TX_WL_MASK |
                                    WM2200_AIF1TX_SLOT_LEN_MASK, i);
 
-       snd_soc_update_bits(codec, WM2200_CLOCKING_4,
+       snd_soc_component_update_bits(component, WM2200_CLOCKING_4,
                            WM2200_SAMPLE_RATE_1_MASK, sr_code);
 
        return 0;
@@ -1788,10 +1788,10 @@ static const struct snd_soc_dai_ops wm2200_dai_ops = {
        .hw_params = wm2200_hw_params,
 };
 
-static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int wm2200_set_sysclk(struct snd_soc_component *component, int clk_id,
                             int source, unsigned int freq, int dir)
 {
-       struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+       struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
        int fval;
 
        switch (clk_id) {
@@ -1799,7 +1799,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                break;
 
        default:
-               dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+               dev_err(component->dev, "Unknown clock %d\n", clk_id);
                return -EINVAL;
        }
 
@@ -1810,7 +1810,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
        case WM2200_CLKSRC_BCLK1:
                break;
        default:
-               dev_err(codec->dev, "Invalid source %d\n", source);
+               dev_err(component->dev, "Invalid source %d\n", source);
                return -EINVAL;
        }
 
@@ -1820,7 +1820,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                fval = 2;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
+               dev_err(component->dev, "Invalid clock rate: %d\n", freq);
                return -EINVAL;
        }
 
@@ -1828,7 +1828,7 @@ static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
         * match.
         */
 
-       snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
+       snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
                            WM2200_SYSCLK_SRC_MASK,
                            fval << WM2200_SYSCLK_FREQ_SHIFT | source);
 
@@ -1936,23 +1936,23 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
        return 0;
 }
 
-static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int wm2200_set_fll(struct snd_soc_component *component, int fll_id, int source,
                          unsigned int Fref, unsigned int Fout)
 {
-       struct i2c_client *i2c = to_i2c_client(codec->dev);
-       struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+       struct i2c_client *i2c = to_i2c_client(component->dev);
+       struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
        struct _fll_div factors;
        int ret, i, timeout;
        unsigned long time_left;
 
        if (!Fout) {
-               dev_dbg(codec->dev, "FLL disabled");
+               dev_dbg(component->dev, "FLL disabled");
 
                if (wm2200->fll_fout)
-                       pm_runtime_put(codec->dev);
+                       pm_runtime_put(component->dev);
 
                wm2200->fll_fout = 0;
-               snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
+               snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1,
                                    WM2200_FLL_ENA, 0);
                return 0;
        }
@@ -1963,7 +1963,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        case WM2200_FLL_SRC_BCLK:
                break;
        default:
-               dev_err(codec->dev, "Invalid FLL source %d\n", source);
+               dev_err(component->dev, "Invalid FLL source %d\n", source);
                return -EINVAL;
        }
 
@@ -1972,44 +1972,44 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                return ret;
 
        /* Disable the FLL while we reconfigure */
-       snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
+       snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
 
-       snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
+       snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_2,
                            WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
                            (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
                            factors.fll_fratio);
        if (factors.theta) {
-               snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
+               snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3,
                                    WM2200_FLL_FRACN_ENA,
                                    WM2200_FLL_FRACN_ENA);
-               snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
+               snd_soc_component_update_bits(component, WM2200_FLL_EFS_2,
                                    WM2200_FLL_EFS_ENA,
                                    WM2200_FLL_EFS_ENA);
        } else {
-               snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
+               snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3,
                                    WM2200_FLL_FRACN_ENA, 0);
-               snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
+               snd_soc_component_update_bits(component, WM2200_FLL_EFS_2,
                                    WM2200_FLL_EFS_ENA, 0);
        }
 
-       snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
+       snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
                            factors.theta);
-       snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
+       snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
                            factors.n);
-       snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
+       snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_7,
                            WM2200_FLL_CLK_REF_DIV_MASK |
                            WM2200_FLL_CLK_REF_SRC_MASK,
                            (factors.fll_refclk_div
                             << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
-       snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
+       snd_soc_component_update_bits(component, WM2200_FLL_EFS_1,
                            WM2200_FLL_LAMBDA_MASK, factors.lambda);
 
        /* Clear any pending completions */
        try_wait_for_completion(&wm2200->fll_lock);
 
-       pm_runtime_get_sync(codec->dev);
+       pm_runtime_get_sync(component->dev);
 
-       snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
+       snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1,
                            WM2200_FLL_ENA, WM2200_FLL_ENA);
 
        if (i2c->irq)
@@ -2017,7 +2017,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        else
                timeout = 50;
 
-       snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
+       snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
                            WM2200_SYSCLK_ENA);
 
        /* Poll for the lock; will use the interrupt to exit quickly */
@@ -2032,10 +2032,10 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                        msleep(1);
                }
 
-               ret = snd_soc_read(codec,
+               ret = snd_soc_component_read32(component,
                                   WM2200_INTERRUPT_RAW_STATUS_2);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to read FLL status: %d\n",
                                ret);
                        continue;
@@ -2044,8 +2044,8 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                        break;
        }
        if (i == timeout) {
-               dev_err(codec->dev, "FLL lock timed out\n");
-               pm_runtime_put(codec->dev);
+               dev_err(component->dev, "FLL lock timed out\n");
+               pm_runtime_put(component->dev);
                return -ETIMEDOUT;
        }
 
@@ -2053,29 +2053,29 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        wm2200->fll_fref = Fref;
        wm2200->fll_fout = Fout;
 
-       dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
+       dev_dbg(component->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
 
        return 0;
 }
 
 static int wm2200_dai_probe(struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
        unsigned int val = 0;
        int ret;
 
-       ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
+       ret = snd_soc_component_read32(component, WM2200_GPIO_CTRL_1);
        if (ret >= 0) {
                if ((ret & WM2200_GP1_FN_MASK) != 0) {
                        wm2200->symmetric_rates = true;
                        val = WM2200_AIF1TX_LRCLK_SRC;
                }
        } else {
-               dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
+               dev_err(component->dev, "Failed to read GPIO 1 config: %d\n", ret);
        }
 
-       snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
+       snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2,
                            WM2200_AIF1TX_LRCLK_SRC, val);
 
        return 0;
@@ -2106,22 +2106,18 @@ static struct snd_soc_dai_driver wm2200_dai = {
        .ops = &wm2200_dai_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_wm2200 = {
-       .probe = wm2200_probe,
-
-       .idle_bias_off = true,
-       .ignore_pmdown_time = true,
-       .set_sysclk = wm2200_set_sysclk,
-       .set_pll = wm2200_set_fll,
-
-       .component_driver = {
-               .controls               = wm2200_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm2200_snd_controls),
-               .dapm_widgets           = wm2200_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm2200_dapm_widgets),
-               .dapm_routes            = wm2200_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm2200_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_wm2200 = {
+       .probe                  = wm2200_probe,
+       .set_sysclk             = wm2200_set_sysclk,
+       .set_pll                = wm2200_set_fll,
+       .controls               = wm2200_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm2200_snd_controls),
+       .dapm_widgets           = wm2200_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm2200_dapm_widgets),
+       .dapm_routes            = wm2200_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm2200_dapm_routes),
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static irqreturn_t wm2200_irq(int irq, void *data)
@@ -2408,7 +2404,7 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
        pm_runtime_enable(&i2c->dev);
        pm_request_idle(&i2c->dev);
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
+       ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_wm2200,
                                     &wm2200_dai, 1);
        if (ret != 0) {
                dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -2435,7 +2431,6 @@ static int wm2200_i2c_remove(struct i2c_client *i2c)
 {
        struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
 
-       snd_soc_unregister_codec(&i2c->dev);
        if (i2c->irq)
                free_irq(i2c->irq, wm2200);
        if (wm2200->pdata.reset)
index 138a84efdd54cb6047b18645c51377ab2c110570..87f9a99ce9784f5b3141c515a0f5671a31cd32c8 100644 (file)
@@ -55,7 +55,7 @@ struct wm5100_fll {
 struct wm5100_priv {
        struct device *dev;
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 
        struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
 
@@ -118,16 +118,16 @@ static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
        WM5100_CLOCKING_6,
 };
 
-static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
+static int wm5100_alloc_sr(struct snd_soc_component *component, int rate)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        int sr_code, sr_free, i;
 
        for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
                if (wm5100_sr_code[i] == rate)
                        break;
        if (i == ARRAY_SIZE(wm5100_sr_code)) {
-               dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
+               dev_err(component->dev, "Unsupported sample rate: %dHz\n", rate);
                return -EINVAL;
        }
        sr_code = i;
@@ -140,50 +140,50 @@ static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
                                sr_free = i;
                                continue;
                        }
-                       if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
+                       if ((snd_soc_component_read32(component, wm5100_sr_regs[i]) &
                             WM5100_SAMPLE_RATE_1_MASK) == sr_code)
                                break;
                }
 
                if (i < ARRAY_SIZE(wm5100_sr_regs)) {
                        wm5100->sr_ref[i]++;
-                       dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
+                       dev_dbg(component->dev, "SR %dHz, slot %d, ref %d\n",
                                rate, i, wm5100->sr_ref[i]);
                        return i;
                }
 
                if (sr_free == -1) {
-                       dev_err(codec->dev, "All SR slots already in use\n");
+                       dev_err(component->dev, "All SR slots already in use\n");
                        return -EBUSY;
                }
 
-               dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
+               dev_dbg(component->dev, "Allocating SR slot %d for %dHz\n",
                        sr_free, rate);
                wm5100->sr_ref[sr_free]++;
-               snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
+               snd_soc_component_update_bits(component, wm5100_sr_regs[sr_free],
                                    WM5100_SAMPLE_RATE_1_MASK,
                                    sr_code);
 
                return sr_free;
 
        } else {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
                        rate, wm5100->sysclk, wm5100->asyncclk);
                return -EINVAL;
        }
 }
 
-static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
+static void wm5100_free_sr(struct snd_soc_component *component, int rate)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        int i, sr_code;
 
        for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
                if (wm5100_sr_code[i] == rate)
                        break;
        if (i == ARRAY_SIZE(wm5100_sr_code)) {
-               dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
+               dev_err(component->dev, "Unsupported sample rate: %dHz\n", rate);
                return;
        }
        sr_code = wm5100_sr_code[i];
@@ -192,16 +192,16 @@ static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
                if (!wm5100->sr_ref[i])
                        continue;
 
-               if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
+               if ((snd_soc_component_read32(component, wm5100_sr_regs[i]) &
                     WM5100_SAMPLE_RATE_1_MASK) == sr_code)
                        break;
        }
        if (i < ARRAY_SIZE(wm5100_sr_regs)) {
                wm5100->sr_ref[i]--;
-               dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
+               dev_dbg(component->dev, "Dereference SR %dHz, count now %d\n",
                        rate, wm5100->sr_ref[i]);
        } else {
-               dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
+               dev_warn(component->dev, "Freeing unreferenced sample rate %dHz\n",
                         rate);
        }
 }
@@ -733,40 +733,39 @@ WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
 WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
 };
 
-static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
+static void wm5100_seq_notifier(struct snd_soc_component *component,
                                enum snd_soc_dapm_type event, int subseq)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        u16 val, expect, i;
 
        /* Wait for the outputs to flag themselves as enabled */
        if (wm5100->out_ena[0]) {
-               expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
+               expect = snd_soc_component_read32(component, WM5100_CHANNEL_ENABLES_1);
                for (i = 0; i < 200; i++) {
-                       val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
+                       val = snd_soc_component_read32(component, WM5100_OUTPUT_STATUS_1);
                        if (val == expect) {
                                wm5100->out_ena[0] = false;
                                break;
                        }
                }
                if (i == 200) {
-                       dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
+                       dev_err(component->dev, "Timeout waiting for OUTPUT1 %x\n",
                                expect);
                }
        }
 
        if (wm5100->out_ena[1]) {
-               expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
+               expect = snd_soc_component_read32(component, WM5100_OUTPUT_ENABLES_2);
                for (i = 0; i < 200; i++) {
-                       val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
+                       val = snd_soc_component_read32(component, WM5100_OUTPUT_STATUS_2);
                        if (val == expect) {
                                wm5100->out_ena[1] = false;
                                break;
                        }
                }
                if (i == 200) {
-                       dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
+                       dev_err(component->dev, "Timeout waiting for OUTPUT2 %x\n",
                                expect);
                }
        }
@@ -776,8 +775,8 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
                         struct snd_kcontrol *kcontrol,
                         int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 
        switch (w->reg) {
        case WM5100_CHANNEL_ENABLES_1:
@@ -841,17 +840,17 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol,
                          int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        int ret;
 
-       ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
+       ret = snd_soc_component_read32(component, WM5100_INTERRUPT_RAW_STATUS_3);
        ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
                WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
                WM5100_CLKGEN_ERR_ASYNC_STS;
        wm5100_log_status3(wm5100, ret);
 
-       ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
+       ret = snd_soc_component_read32(component, WM5100_INTERRUPT_RAW_STATUS_4);
        wm5100_log_status4(wm5100, ret);
 
        return 0;
@@ -1282,7 +1281,7 @@ static const struct reg_sequence wm5100_reva_patches[] = {
 
 static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int lrclk, bclk, mask, base;
 
        base = dai->driver->base;
@@ -1298,7 +1297,7 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                mask = 2;
                break;
        default:
-               dev_err(codec->dev, "Unsupported DAI format %d\n",
+               dev_err(component->dev, "Unsupported DAI format %d\n",
                        fmt & SND_SOC_DAIFMT_FORMAT_MASK);
                return -EINVAL;
        }
@@ -1317,7 +1316,7 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                bclk |= WM5100_AIF1_BCLK_MSTR;
                break;
        default:
-               dev_err(codec->dev, "Unsupported master mode %d\n",
+               dev_err(component->dev, "Unsupported master mode %d\n",
                        fmt & SND_SOC_DAIFMT_MASTER_MASK);
                return -EINVAL;
        }
@@ -1339,13 +1338,13 @@ static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
+       snd_soc_component_update_bits(component, base + 1, WM5100_AIF1_BCLK_MSTR |
                            WM5100_AIF1_BCLK_INV, bclk);
-       snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
+       snd_soc_component_update_bits(component, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
                            WM5100_AIF1TX_LRCLK_INV, lrclk);
-       snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
+       snd_soc_component_update_bits(component, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
                            WM5100_AIF1TX_LRCLK_INV, lrclk);
-       snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
+       snd_soc_component_update_bits(component, base + 5, WM5100_AIF1_FMT_MASK, mask);
 
        return 0;
 }
@@ -1400,8 +1399,8 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        bool async = wm5100->aif_async[dai->id];
        int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
        int *bclk_rates;
@@ -1416,7 +1415,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
        if (fl < 0)
                return fl;
 
-       dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
+       dev_dbg(component->dev, "Word length %d bits, frame length %d bits\n",
                wl, fl);
 
        /* Target BCLK rate */
@@ -1427,7 +1426,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
        /* Root for BCLK depends on SYS/ASYNCCLK */
        if (!async) {
                aif_rate = wm5100->sysclk;
-               sr = wm5100_alloc_sr(codec, params_rate(params));
+               sr = wm5100_alloc_sr(component, params_rate(params));
                if (sr < 0)
                        return sr;
        } else {
@@ -1439,23 +1438,23 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
                        if (params_rate(params) == wm5100_sr_code[i])
                                break;
                if (i == ARRAY_SIZE(wm5100_sr_code)) {
-                       dev_err(codec->dev, "Invalid rate %dHzn",
+                       dev_err(component->dev, "Invalid rate %dHzn",
                                params_rate(params));
                        return -EINVAL;
                }
 
                /* TODO: We should really check for symmetry */
-               snd_soc_update_bits(codec, WM5100_CLOCKING_8,
+               snd_soc_component_update_bits(component, WM5100_CLOCKING_8,
                                    WM5100_ASYNC_SAMPLE_RATE_MASK, i);
        }
 
        if (!aif_rate) {
-               dev_err(codec->dev, "%s has no rate set\n",
+               dev_err(component->dev, "%s has no rate set\n",
                        async ? "ASYNCCLK" : "SYSCLK");
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
+       dev_dbg(component->dev, "Target BCLK is %dHz, using %dHz %s\n",
                bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
 
        if (aif_rate % 4000)
@@ -1467,37 +1466,37 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
                if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
                        break;
        if (i == WM5100_NUM_BCLK_RATES) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "No valid BCLK for %dHz found from %dHz %s\n",
                        bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
                return -EINVAL;
        }
 
        bclk = i;
-       dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
-       snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
+       dev_dbg(component->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
+       snd_soc_component_update_bits(component, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
 
        lrclk = bclk_rates[bclk] / params_rate(params);
-       dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
+       dev_dbg(component->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
            wm5100->aif_symmetric[dai->id])
-               snd_soc_update_bits(codec, base + 7,
+               snd_soc_component_update_bits(component, base + 7,
                                    WM5100_AIF1RX_BCPF_MASK, lrclk);
        else
-               snd_soc_update_bits(codec, base + 6,
+               snd_soc_component_update_bits(component, base + 6,
                                    WM5100_AIF1TX_BCPF_MASK, lrclk);
 
        i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               snd_soc_update_bits(codec, base + 9,
+               snd_soc_component_update_bits(component, base + 9,
                                    WM5100_AIF1RX_WL_MASK |
                                    WM5100_AIF1RX_SLOT_LEN_MASK, i);
        else
-               snd_soc_update_bits(codec, base + 8,
+               snd_soc_component_update_bits(component, base + 8,
                                    WM5100_AIF1TX_WL_MASK |
                                    WM5100_AIF1TX_SLOT_LEN_MASK, i);
 
-       snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
+       snd_soc_component_update_bits(component, base + 4, WM5100_AIF1_RATE_MASK, sr);
 
        return 0;
 }
@@ -1507,10 +1506,10 @@ static const struct snd_soc_dai_ops wm5100_dai_ops = {
        .hw_params = wm5100_hw_params,
 };
 
-static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+static int wm5100_set_sysclk(struct snd_soc_component *component, int clk_id,
                             int source, unsigned int freq, int dir)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        int *rate_store;
        int fval, audio_rate, ret, reg;
 
@@ -1529,7 +1528,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                case WM5100_CLKSRC_MCLK1:
                case WM5100_CLKSRC_MCLK2:
                case WM5100_CLKSRC_SYSCLK:
-                       snd_soc_update_bits(codec, WM5100_CLOCKING_1,
+                       snd_soc_component_update_bits(component, WM5100_CLOCKING_1,
                                            WM5100_CLK_32K_SRC_MASK,
                                            source);
                        break;
@@ -1550,7 +1549,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                        wm5100->aif_async[clk_id - 1] = true;
                        break;
                default:
-                       dev_err(codec->dev, "Invalid source %d\n", source);
+                       dev_err(component->dev, "Invalid source %d\n", source);
                        return -EINVAL;
                }       
                return 0;
@@ -1559,35 +1558,35 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                switch (freq) {
                case 5644800:
                case 6144000:
-                       snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
+                       snd_soc_component_update_bits(component, WM5100_MISC_GPIO_1,
                                            WM5100_OPCLK_SEL_MASK, 0);
                        break;
                case 11289600:
                case 12288000:
-                       snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
+                       snd_soc_component_update_bits(component, WM5100_MISC_GPIO_1,
                                            WM5100_OPCLK_SEL_MASK, 0);
                        break;
                case 22579200:
                case 24576000:
-                       snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
+                       snd_soc_component_update_bits(component, WM5100_MISC_GPIO_1,
                                            WM5100_OPCLK_SEL_MASK, 0);
                        break;
                default:
-                       dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
+                       dev_err(component->dev, "Unsupported OPCLK %dHz\n",
                                freq);
                        return -EINVAL;
                }
                return 0;
 
        default:
-               dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+               dev_err(component->dev, "Unknown clock %d\n", clk_id);
                return -EINVAL;
        }
 
        switch (source) {
        case WM5100_CLKSRC_SYSCLK:
        case WM5100_CLKSRC_ASYNCCLK:
-               dev_err(codec->dev, "Invalid source %d\n", source);
+               dev_err(component->dev, "Invalid source %d\n", source);
                return -EINVAL;
        }
 
@@ -1605,7 +1604,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                fval = 2;
                break;
        default:
-               dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
+               dev_err(component->dev, "Invalid clock rate: %d\n", freq);
                return -EINVAL;
        }
 
@@ -1632,7 +1631,7 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
         * match.
         */
 
-       snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
+       snd_soc_component_update_bits(component, reg, WM5100_SYSCLK_FREQ_MASK |
                            WM5100_SYSCLK_SRC_MASK,
                            fval << WM5100_SYSCLK_FREQ_SHIFT | source);
 
@@ -1641,13 +1640,13 @@ static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
         * this clock rate.
         */
        if (clk_id == WM5100_CLK_SYSCLK) {
-               dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
+               dev_dbg(component->dev, "Setting primary audio rate to %dHz",
                        audio_rate);
                if (0 && *rate_store)
-                       wm5100_free_sr(codec, audio_rate);
-               ret = wm5100_alloc_sr(codec, audio_rate);
+                       wm5100_free_sr(component, audio_rate);
+               ret = wm5100_alloc_sr(component, audio_rate);
                if (ret != 0)
-                       dev_warn(codec->dev, "Primary audio slot is %d\n",
+                       dev_warn(component->dev, "Primary audio slot is %d\n",
                                 ret);
        }
 
@@ -1755,11 +1754,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
        return 0;
 }
 
-static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+static int wm5100_set_fll(struct snd_soc_component *component, int fll_id, int source,
                          unsigned int Fref, unsigned int Fout)
 {
-       struct i2c_client *i2c = to_i2c_client(codec->dev);
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct i2c_client *i2c = to_i2c_client(component->dev);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        struct _fll_div factors;
        struct wm5100_fll *fll;
        int ret, base, lock, i, timeout;
@@ -1777,16 +1776,16 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                lock = WM5100_FLL2_LOCK_STS;
                break;
        default:
-               dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
+               dev_err(component->dev, "Unknown FLL %d\n",fll_id);
                return -EINVAL;
        }
 
        if (!Fout) {
-               dev_dbg(codec->dev, "FLL%d disabled", fll_id);
+               dev_dbg(component->dev, "FLL%d disabled", fll_id);
                if (fll->fout)
-                       pm_runtime_put(codec->dev);
+                       pm_runtime_put(component->dev);
                fll->fout = 0;
-               snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
+               snd_soc_component_update_bits(component, base + 1, WM5100_FLL1_ENA, 0);
                return 0;
        }
 
@@ -1800,7 +1799,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        case WM5100_FLL_SRC_AIF3BCLK:
                break;
        default:
-               dev_err(codec->dev, "Invalid FLL source %d\n", source);
+               dev_err(component->dev, "Invalid FLL source %d\n", source);
                return -EINVAL;
        }
 
@@ -1809,36 +1808,36 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                return ret;
 
        /* Disable the FLL while we reconfigure */
-       snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
+       snd_soc_component_update_bits(component, base + 1, WM5100_FLL1_ENA, 0);
 
-       snd_soc_update_bits(codec, base + 2,
+       snd_soc_component_update_bits(component, base + 2,
                            WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
                            (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
                            factors.fll_fratio);
-       snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
+       snd_soc_component_update_bits(component, base + 3, WM5100_FLL1_THETA_MASK,
                            factors.theta);
-       snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
-       snd_soc_update_bits(codec, base + 6,
+       snd_soc_component_update_bits(component, base + 5, WM5100_FLL1_N_MASK, factors.n);
+       snd_soc_component_update_bits(component, base + 6,
                            WM5100_FLL1_REFCLK_DIV_MASK |
                            WM5100_FLL1_REFCLK_SRC_MASK,
                            (factors.fll_refclk_div
                             << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
-       snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
+       snd_soc_component_update_bits(component, base + 7, WM5100_FLL1_LAMBDA_MASK,
                            factors.lambda);
 
        /* Clear any pending completions */
        try_wait_for_completion(&fll->lock);
 
-       pm_runtime_get_sync(codec->dev);
+       pm_runtime_get_sync(component->dev);
 
-       snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
+       snd_soc_component_update_bits(component, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
 
        if (i2c->irq)
                timeout = 2;
        else
                timeout = 50;
 
-       snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
+       snd_soc_component_update_bits(component, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
                            WM5100_SYSCLK_ENA);
 
        /* Poll for the lock; will use interrupt when we can test */
@@ -1852,10 +1851,10 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                        msleep(1);
                }
 
-               ret = snd_soc_read(codec,
+               ret = snd_soc_component_read32(component,
                                   WM5100_INTERRUPT_RAW_STATUS_3);
                if (ret < 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to read FLL status: %d\n",
                                ret);
                        continue;
@@ -1864,8 +1863,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
                        break;
        }
        if (i == timeout) {
-               dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
-               pm_runtime_put(codec->dev);
+               dev_err(component->dev, "FLL%d lock timed out\n", fll_id);
+               pm_runtime_put(component->dev);
                return -ETIMEDOUT;
        }
 
@@ -1873,7 +1872,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        fll->fref = Fref;
        fll->fout = Fout;
 
-       dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
+       dev_dbg(component->dev, "FLL%d running %dHz->%dHz\n", fll_id,
                Fref, Fout);
 
        return 0;
@@ -2099,10 +2098,10 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
        }
 }
 
-int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
+int wm5100_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 
        if (jack) {
                wm5100->jack = jack;
@@ -2113,7 +2112,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 
                /* Slowest detection rate, gives debounce for initial
                 * detection */
-               snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
+               snd_soc_component_update_bits(component, WM5100_MIC_DETECT_1,
                                    WM5100_ACCDET_BIAS_STARTTIME_MASK |
                                    WM5100_ACCDET_RATE_MASK,
                                    (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) |
@@ -2132,18 +2131,18 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
                /* We start off just enabling microphone detection - even a
                 * plain headphone will trigger detection.
                 */
-               snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
+               snd_soc_component_update_bits(component, WM5100_MIC_DETECT_1,
                                    WM5100_ACCDET_ENA, WM5100_ACCDET_ENA);
 
-               snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
+               snd_soc_component_update_bits(component, WM5100_INTERRUPT_STATUS_3_MASK,
                                    WM5100_IM_ACCDET_EINT, 0);
        } else {
-               snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
+               snd_soc_component_update_bits(component, WM5100_INTERRUPT_STATUS_3_MASK,
                                    WM5100_IM_HPDET_EINT |
                                    WM5100_IM_ACCDET_EINT,
                                    WM5100_IM_HPDET_EINT |
                                    WM5100_IM_ACCDET_EINT);
-               snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
+               snd_soc_component_update_bits(component, WM5100_MIC_DETECT_1,
                                    WM5100_ACCDET_ENA, 0);
                wm5100->jack = NULL;
        }
@@ -2330,22 +2329,22 @@ static void wm5100_free_gpio(struct i2c_client *i2c)
 }
 #endif
 
-static int wm5100_probe(struct snd_soc_codec *codec)
+static int wm5100_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct i2c_client *i2c = to_i2c_client(codec->dev);
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct i2c_client *i2c = to_i2c_client(component->dev);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
        int ret, i;
 
-       wm5100->codec = codec;
+       wm5100->component = component;
 
        for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
-               snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
+               snd_soc_component_update_bits(component, wm5100_dig_vu[i], WM5100_OUT_VU,
                                    WM5100_OUT_VU);
 
        /* Don't debounce interrupts to support use of SYSCLK only */
-       snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
-       snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
+       snd_soc_component_write(component, WM5100_IRQ_DEBOUNCE_1, 0);
+       snd_soc_component_write(component, WM5100_IRQ_DEBOUNCE_2, 0);
 
        /* TODO: check if we're symmetric */
 
@@ -2370,34 +2369,30 @@ err_gpio:
        return ret;
 }
 
-static int wm5100_remove(struct snd_soc_codec *codec)
+static void wm5100_remove(struct snd_soc_component *component)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
 
        if (wm5100->pdata.hp_pol) {
                gpio_free(wm5100->pdata.hp_pol);
        }
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
-       .probe =        wm5100_probe,
-       .remove =       wm5100_remove,
-
-       .set_sysclk = wm5100_set_sysclk,
-       .set_pll = wm5100_set_fll,
-       .idle_bias_off = 1,
-
-       .seq_notifier = wm5100_seq_notifier,
-       .component_driver = {
-               .controls               = wm5100_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm5100_snd_controls),
-               .dapm_widgets           = wm5100_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm5100_dapm_widgets),
-               .dapm_routes            = wm5100_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm5100_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm5100 = {
+       .probe                  = wm5100_probe,
+       .remove                 = wm5100_remove,
+       .set_sysclk             = wm5100_set_sysclk,
+       .set_pll                = wm5100_set_fll,
+       .seq_notifier           = wm5100_seq_notifier,
+       .controls               = wm5100_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm5100_snd_controls),
+       .dapm_widgets           = wm5100_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm5100_dapm_widgets),
+       .dapm_routes            = wm5100_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm5100_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config wm5100_regmap = {
@@ -2614,8 +2609,8 @@ static int wm5100_i2c_probe(struct i2c_client *i2c,
        pm_runtime_enable(&i2c->dev);
        pm_request_idle(&i2c->dev);
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                                    &soc_codec_dev_wm5100, wm5100_dai,
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_wm5100, wm5100_dai,
                                     ARRAY_SIZE(wm5100_dai));
        if (ret < 0) {
                dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
@@ -2648,7 +2643,6 @@ static int wm5100_i2c_remove(struct i2c_client *i2c)
 {
        struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
 
-       snd_soc_unregister_codec(&i2c->dev);
        if (i2c->irq)
                free_irq(i2c->irq, wm5100);
        wm5100_free_gpio(i2c);
index 935a9b7fb27457e5e91987442df2b6d89ddc423c..6076493cfd678971a9a8a6798bc167cff0df2375 100644 (file)
@@ -17,7 +17,7 @@
 #include <sound/soc.h>
 #include <linux/regmap.h>
 
-int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
+int wm5100_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
 
 #define WM5100_CLK_AIF1     1
 #define WM5100_CLK_AIF2     2
index fc066caa191884fa324c8813915edfcfcf5203d5..1ac83388d1b824747f99a8bed7f5e9a85f272ee2 100644 (file)
@@ -34,6 +34,8 @@
 #include "wm5102.h"
 #include "wm_adsp.h"
 
+#define DRV_NAME "wm5102-codec"
+
 struct wm5102_priv {
        struct arizona_priv core;
        struct arizona_fll fll[2];
@@ -581,8 +583,8 @@ static const struct reg_default wm5102_sysclk_revb_patch[] = {
 static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        struct regmap *regmap = arizona->regmap;
        const struct reg_default *patch = NULL;
        int i, patch_size;
@@ -618,10 +620,10 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
 }
 
 static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
-                  struct snd_kcontrol *kcontrol, int event)
+                               struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        unsigned int v = 0;
        int ret;
 
@@ -629,7 +631,7 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
        case SND_SOC_DAPM_PRE_PMU:
                ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
                if (ret != 0) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to read SYSCLK state: %d\n", ret);
                        return -EIO;
                }
@@ -637,9 +639,9 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
                v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
 
                if (v >= 3) {
-                       ret = arizona_dvfs_up(codec, ARIZONA_DVFS_ADSP1_RQ);
+                       ret = arizona_dvfs_up(component, ARIZONA_DVFS_ADSP1_RQ);
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to raise DVFS: %d\n", ret);
                                return ret;
                        }
@@ -647,9 +649,9 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
                break;
 
        case SND_SOC_DAPM_POST_PMD:
-               ret = arizona_dvfs_down(codec, ARIZONA_DVFS_ADSP1_RQ);
+               ret = arizona_dvfs_down(component, ARIZONA_DVFS_ADSP1_RQ);
                if (ret)
-                       dev_warn(codec->dev,
+                       dev_warn(component->dev,
                                 "Failed to lower DVFS: %d\n", ret);
                break;
 
@@ -663,8 +665,8 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
 static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
        mutex_lock(&arizona->dac_comp_lock);
        put_unaligned_be16(arizona->dac_comp_coeff,
@@ -677,8 +679,8 @@ static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
 static int wm5102_out_comp_coeff_put(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
        mutex_lock(&arizona->dac_comp_lock);
        memcpy(&arizona->dac_comp_coeff, ucontrol->value.bytes.data,
@@ -692,8 +694,8 @@ static int wm5102_out_comp_coeff_put(struct snd_kcontrol *kcontrol,
 static int wm5102_out_comp_switch_get(struct snd_kcontrol *kcontrol,
                                      struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
        mutex_lock(&arizona->dac_comp_lock);
        ucontrol->value.integer.value[0] = arizona->dac_comp_enabled;
@@ -705,8 +707,8 @@ static int wm5102_out_comp_switch_get(struct snd_kcontrol *kcontrol,
 static int wm5102_out_comp_switch_put(struct snd_kcontrol *kcontrol,
                                      struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
 
        mutex_lock(&arizona->dac_comp_lock);
        arizona->dac_comp_enabled = ucontrol->value.integer.value[0];
@@ -715,7 +717,7 @@ static int wm5102_out_comp_switch_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const char *wm5102_osr_text[] = {
+static const char * const wm5102_osr_text[] = {
        "Low power", "Normal", "High performance",
 };
 
@@ -1060,7 +1062,7 @@ ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE);
 
 ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE);
 
-static const char *wm5102_aec_loopback_texts[] = {
+static const char * const wm5102_aec_loopback_texts[] = {
        "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
        "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R",
 };
@@ -1315,8 +1317,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
 ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-                      &wm5102_aec_loopback_mux),
+                ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5102_aec_loopback_mux),
 
 SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
                   ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
@@ -1734,10 +1735,10 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
        { "DRC1 Signal Activity", NULL, "DRC1R" },
 };
 
-static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-                         unsigned int Fref, unsigned int Fout)
+static int wm5102_set_fll(struct snd_soc_component *component, int fll_id,
+                         int source, unsigned int Fref, unsigned int Fout)
 {
-       struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
+       struct wm5102_priv *wm5102 = snd_soc_component_get_drvdata(component);
 
        switch (fll_id) {
        case WM5102_FLL1:
@@ -1910,7 +1911,8 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
 static int wm5102_open(struct snd_compr_stream *stream)
 {
        struct snd_soc_pcm_runtime *rtd = stream->private_data;
-       struct wm5102_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct wm5102_priv *priv = snd_soc_component_get_drvdata(component);
 
        return wm_adsp_compr_open(&priv->core.adsp[0], stream);
 }
@@ -1930,30 +1932,29 @@ static irqreturn_t wm5102_adsp2_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int wm5102_codec_probe(struct snd_soc_codec *codec)
+static int wm5102_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-       struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct wm5102_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->core.arizona;
        int ret;
 
-       snd_soc_codec_init_regmap(codec, arizona->regmap);
+       snd_soc_component_init_regmap(component, arizona->regmap);
 
-       ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);
+       ret = wm_adsp2_component_probe(&priv->core.adsp[0], component);
        if (ret)
                return ret;
 
-       ret = snd_soc_add_codec_controls(codec,
-                                        arizona_adsp2_rate_controls, 1);
+       ret = snd_soc_add_component_controls(component,
+                                            arizona_adsp2_rate_controls, 1);
        if (ret)
                goto err_adsp2_codec_probe;
 
-       ret = arizona_init_spk(codec);
+       ret = arizona_init_spk(component);
        if (ret < 0)
                return ret;
 
-       arizona_init_gpio(codec);
+       arizona_init_gpio(component);
 
        snd_soc_component_disable_pin(component, "HAPTICS");
 
@@ -1962,20 +1963,18 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
        return 0;
 
 err_adsp2_codec_probe:
-       wm_adsp2_codec_remove(&priv->core.adsp[0], codec);
+       wm_adsp2_component_remove(&priv->core.adsp[0], component);
 
        return ret;
 }
 
-static int wm5102_codec_remove(struct snd_soc_codec *codec)
+static void wm5102_component_remove(struct snd_soc_component *component)
 {
-       struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm5102_priv *priv = snd_soc_component_get_drvdata(component);
 
-       wm_adsp2_codec_remove(&priv->core.adsp[0], codec);
+       wm_adsp2_component_remove(&priv->core.adsp[0], component);
 
        priv->core.arizona->dapm = NULL;
-
-       return 0;
 }
 
 #define WM5102_DIG_VU 0x0200
@@ -1992,37 +1991,32 @@ static unsigned int wm5102_digital_vu[] = {
        ARIZONA_DAC_DIGITAL_VOLUME_5R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
-       .probe = wm5102_codec_probe,
-       .remove = wm5102_codec_remove,
-
-       .idle_bias_off = true,
-
-       .set_sysclk = arizona_set_sysclk,
-       .set_pll = wm5102_set_fll,
-
-       .component_driver = {
-               .controls               = wm5102_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm5102_snd_controls),
-               .dapm_widgets           = wm5102_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm5102_dapm_widgets),
-               .dapm_routes            = wm5102_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm5102_dapm_routes),
-       },
-};
-
-static const struct snd_compr_ops wm5102_compr_ops = {
-       .open = wm5102_open,
-       .free = wm_adsp_compr_free,
-       .set_params = wm_adsp_compr_set_params,
-       .get_caps = wm_adsp_compr_get_caps,
-       .trigger = wm_adsp_compr_trigger,
-       .pointer = wm_adsp_compr_pointer,
-       .copy = wm_adsp_compr_copy,
+static struct snd_compr_ops wm5102_compr_ops = {
+       .open           = wm5102_open,
+       .free           = wm_adsp_compr_free,
+       .set_params     = wm_adsp_compr_set_params,
+       .get_caps       = wm_adsp_compr_get_caps,
+       .trigger        = wm_adsp_compr_trigger,
+       .pointer        = wm_adsp_compr_pointer,
+       .copy           = wm_adsp_compr_copy,
 };
 
-static const struct snd_soc_platform_driver wm5102_compr_platform = {
-       .compr_ops = &wm5102_compr_ops,
+static const struct snd_soc_component_driver soc_component_dev_wm5102 = {
+       .probe                  = wm5102_component_probe,
+       .remove                 = wm5102_component_remove,
+       .set_sysclk             = arizona_set_sysclk,
+       .set_pll                = wm5102_set_fll,
+       .name                   = DRV_NAME,
+       .compr_ops              = &wm5102_compr_ops,
+       .controls               = wm5102_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm5102_snd_controls),
+       .dapm_widgets           = wm5102_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm5102_dapm_widgets),
+       .dapm_routes            = wm5102_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm5102_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm5102_probe(struct platform_device *pdev)
@@ -2109,23 +2103,17 @@ static int wm5102_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_dsp_irq;
 
-       ret = snd_soc_register_platform(&pdev->dev, &wm5102_compr_platform);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &soc_component_dev_wm5102,
+                                             wm5102_dai,
+                                             ARRAY_SIZE(wm5102_dai));
        if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
                goto err_spk_irqs;
        }
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
-                                     wm5102_dai, ARRAY_SIZE(wm5102_dai));
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-               goto err_platform;
-       }
-
        return ret;
 
-err_platform:
-       snd_soc_unregister_platform(&pdev->dev);
 err_spk_irqs:
        arizona_free_spk_irqs(arizona);
 err_dsp_irq:
@@ -2139,8 +2127,6 @@ static int wm5102_remove(struct platform_device *pdev)
        struct wm5102_priv *wm5102 = platform_get_drvdata(pdev);
        struct arizona *arizona = wm5102->core.arizona;
 
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_codec(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        wm_adsp2_remove(&wm5102->core.adsp[0]);
index fb0cf9c61f48e8b4fc5af8aa1a1e9e3a0e580f95..fb9835dcd8367cefde27e112a46b535d69bb2141 100644 (file)
@@ -35,6 +35,8 @@
 
 #define WM5110_NUM_ADSP 4
 
+#define DRV_NAME "wm5110-codec"
+
 struct wm5110_priv {
        struct arizona_priv core;
        struct arizona_fll fll[2];
@@ -159,8 +161,8 @@ static const struct reg_default wm5110_sysclk_reve_patch[] = {
 static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        struct regmap *regmap = arizona->regmap;
        const struct reg_default *patch = NULL;
        int i, patch_size;
@@ -196,14 +198,14 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
 static int wm5110_adsp_power_ev(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        unsigned int v;
        int ret;
 
        ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
+               dev_err(component->dev, "Failed to read SYSCLK state: %d\n", ret);
                return ret;
        }
 
@@ -286,10 +288,10 @@ static const struct reg_sequence wm5110_dre_right_enable[] = {
 
 static int wm5110_hp_pre_enable(struct snd_soc_dapm_widget *w)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
-       unsigned int val = snd_soc_read(codec, ARIZONA_DRE_ENABLE);
+       unsigned int val = snd_soc_component_read32(component, ARIZONA_DRE_ENABLE);
        const struct reg_sequence *wseq;
        int nregs;
 
@@ -323,26 +325,32 @@ static int wm5110_hp_pre_enable(struct snd_soc_dapm_widget *w)
 
 static int wm5110_hp_pre_disable(struct snd_soc_dapm_widget *w)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
-       unsigned int val = snd_soc_read(codec, ARIZONA_DRE_ENABLE);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
+       unsigned int val = snd_soc_component_read32(component, ARIZONA_DRE_ENABLE);
 
        switch (w->shift) {
        case ARIZONA_OUT1L_ENA_SHIFT:
                if (!(val & ARIZONA_DRE1L_ENA_MASK)) {
-                       snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-                                           ARIZONA_WS_TRG1, ARIZONA_WS_TRG1);
-                       snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-                                           ARIZONA_WS_TRG1, 0);
+                       snd_soc_component_update_bits(component,
+                                                     ARIZONA_SPARE_TRIGGERS,
+                                                     ARIZONA_WS_TRG1,
+                                                     ARIZONA_WS_TRG1);
+                       snd_soc_component_update_bits(component,
+                                                     ARIZONA_SPARE_TRIGGERS,
+                                                     ARIZONA_WS_TRG1, 0);
                        priv->out_down_delay += 27;
                }
                break;
        case ARIZONA_OUT1R_ENA_SHIFT:
                if (!(val & ARIZONA_DRE1R_ENA_MASK)) {
-                       snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-                                           ARIZONA_WS_TRG2, ARIZONA_WS_TRG2);
-                       snd_soc_update_bits(codec, ARIZONA_SPARE_TRIGGERS,
-                                           ARIZONA_WS_TRG2, 0);
+                       snd_soc_component_update_bits(component,
+                                                     ARIZONA_SPARE_TRIGGERS,
+                                                     ARIZONA_WS_TRG2,
+                                                     ARIZONA_WS_TRG2);
+                       snd_soc_component_update_bits(component,
+                                                     ARIZONA_SPARE_TRIGGERS,
+                                                     ARIZONA_WS_TRG2, 0);
                        priv->out_down_delay += 27;
                }
                break;
@@ -356,8 +364,8 @@ static int wm5110_hp_pre_disable(struct snd_soc_dapm_widget *w)
 static int wm5110_hp_ev(struct snd_soc_dapm_widget *w,
                        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
 
        switch (priv->arizona->rev) {
        case 0 ... 3:
@@ -395,9 +403,9 @@ static int wm5110_clear_pga_volume(struct arizona *arizona, int output)
 static int wm5110_put_dre(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int ena, dre;
@@ -456,8 +464,8 @@ err:
 static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int ret;
 
        /*
@@ -476,8 +484,8 @@ static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
 static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int ret;
 
        /*
@@ -496,9 +504,9 @@ static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
 static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
                               struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
-       struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
+       struct wm5110_priv *wm5110 = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
        unsigned int reg, mask;
        struct reg_sequence analog_seq[] = {
@@ -517,9 +525,9 @@ static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
                wm5110->in_post_pending++;
                return 0;
        case SND_SOC_DAPM_PRE_PMU:
-               wm5110->in_pga_cache[w->shift] = snd_soc_read(codec, reg);
+               wm5110->in_pga_cache[w->shift] = snd_soc_component_read32(component, reg);
 
-               snd_soc_update_bits(codec, reg, mask,
+               snd_soc_component_update_bits(component, reg, mask,
                                    0x40 << ARIZONA_IN1L_PGA_VOL_SHIFT);
 
                wm5110->in_pre_pending--;
@@ -536,8 +544,8 @@ static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
 
                break;
        case SND_SOC_DAPM_POST_PMU:
-               snd_soc_update_bits(codec, reg, mask,
-                                   wm5110->in_pga_cache[w->shift]);
+               snd_soc_component_update_bits(component, reg, mask,
+                                             wm5110->in_pga_cache[w->shift]);
 
                wm5110->in_post_pending--;
                if (wm5110->in_post_pending == 0)
@@ -555,13 +563,13 @@ static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
 static int wm5110_in_ev(struct snd_soc_dapm_widget *w,
                        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->arizona;
 
        switch (arizona->rev) {
        case 0 ... 4:
-               if (arizona_input_analog(codec, w->shift))
+               if (arizona_input_analog(component, w->shift))
                        wm5110_in_analog_ev(w, kcontrol, event);
 
                break;
@@ -861,14 +869,14 @@ SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
           ARIZONA_SPK2R_MUTE_SHIFT, 1, 1),
 
 SOC_DOUBLE_EXT("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE,
-          ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0,
-          snd_soc_get_volsw, wm5110_put_dre),
+              ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0,
+              snd_soc_get_volsw, wm5110_put_dre),
 SOC_DOUBLE_EXT("HPOUT2 DRE Switch", ARIZONA_DRE_ENABLE,
-          ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0,
-          snd_soc_get_volsw, wm5110_put_dre),
+              ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0,
+              snd_soc_get_volsw, wm5110_put_dre),
 SOC_DOUBLE_EXT("HPOUT3 DRE Switch", ARIZONA_DRE_ENABLE,
-          ARIZONA_DRE3L_ENA_SHIFT, ARIZONA_DRE3R_ENA_SHIFT, 1, 0,
-          snd_soc_get_volsw, wm5110_put_dre),
+              ARIZONA_DRE3L_ENA_SHIFT, ARIZONA_DRE3R_ENA_SHIFT, 1, 0,
+              snd_soc_get_volsw, wm5110_put_dre),
 
 SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
 SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
@@ -1034,7 +1042,7 @@ ARIZONA_MUX_ENUMS(ISRC3DEC2, ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ISRC3DEC3, ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ISRC3DEC4, ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE);
 
-static const char *wm5110_aec_loopback_texts[] = {
+static const char * const wm5110_aec_loopback_texts[] = {
        "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
        "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R",
 };
@@ -1272,18 +1280,17 @@ SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
                 ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-                      &wm5110_aec_loopback_mux),
+                ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5110_aec_loopback_mux),
 
 SND_SOC_DAPM_SUPPLY("RXANC NG External Clock", SND_SOC_NOPM,
-                  ARIZONA_EXT_NG_SEL_SET_SHIFT, 0, arizona_anc_ev,
-                  SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+                   ARIZONA_EXT_NG_SEL_SET_SHIFT, 0, arizona_anc_ev,
+                   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_PGA("RXANCL NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_PGA("RXANCR NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
 
 SND_SOC_DAPM_SUPPLY("RXANC NG Clock", SND_SOC_NOPM,
-                  ARIZONA_CLK_NG_ENA_SET_SHIFT, 0, arizona_anc_ev,
-                  SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+                   ARIZONA_CLK_NG_ENA_SET_SHIFT, 0, arizona_anc_ev,
+                   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_PGA("RXANCL NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_PGA("RXANCR NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
 
@@ -2032,10 +2039,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "DSP3 Voice Trigger", "Switch", "DSP3" },
 };
 
-static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-                         unsigned int Fref, unsigned int Fout)
+static int wm5110_set_fll(struct snd_soc_component *component, int fll_id,
+                         int source, unsigned int Fref, unsigned int Fout)
 {
-       struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
+       struct wm5110_priv *wm5110 = snd_soc_component_get_drvdata(component);
 
        switch (fll_id) {
        case WM5110_FLL1:
@@ -2229,7 +2236,8 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
 static int wm5110_open(struct snd_compr_stream *stream)
 {
        struct snd_soc_pcm_runtime *rtd = stream->private_data;
-       struct wm5110_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct wm5110_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->core.arizona;
        int n_adsp;
 
@@ -2275,33 +2283,32 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int wm5110_codec_probe(struct snd_soc_codec *codec)
+static int wm5110_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-       struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct wm5110_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->core.arizona;
        int i, ret;
 
        arizona->dapm = dapm;
-       snd_soc_codec_init_regmap(codec, arizona->regmap);
+       snd_soc_component_init_regmap(component, arizona->regmap);
 
-       ret = arizona_init_spk(codec);
+       ret = arizona_init_spk(component);
        if (ret < 0)
                return ret;
 
-       arizona_init_gpio(codec);
-       arizona_init_mono(codec);
+       arizona_init_gpio(component);
+       arizona_init_mono(component);
 
        for (i = 0; i < WM5110_NUM_ADSP; ++i) {
-               ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec);
+               ret = wm_adsp2_component_probe(&priv->core.adsp[i], component);
                if (ret)
                        goto err_adsp2_codec_probe;
        }
 
-       ret = snd_soc_add_codec_controls(codec,
-                                        arizona_adsp2_rate_controls,
-                                        WM5110_NUM_ADSP);
+       ret = snd_soc_add_component_controls(component,
+                                            arizona_adsp2_rate_controls,
+                                            WM5110_NUM_ADSP);
        if (ret)
                goto err_adsp2_codec_probe;
 
@@ -2311,22 +2318,20 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
 
 err_adsp2_codec_probe:
        for (--i; i >= 0; --i)
-               wm_adsp2_codec_remove(&priv->core.adsp[i], codec);
+               wm_adsp2_component_remove(&priv->core.adsp[i], component);
 
        return ret;
 }
 
-static int wm5110_codec_remove(struct snd_soc_codec *codec)
+static void wm5110_component_remove(struct snd_soc_component *component)
 {
-       struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm5110_priv *priv = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < WM5110_NUM_ADSP; ++i)
-               wm_adsp2_codec_remove(&priv->core.adsp[i], codec);
+               wm_adsp2_component_remove(&priv->core.adsp[i], component);
 
        priv->core.arizona->dapm = NULL;
-
-       return 0;
 }
 
 #define WM5110_DIG_VU 0x0200
@@ -2346,37 +2351,32 @@ static unsigned int wm5110_digital_vu[] = {
        ARIZONA_DAC_DIGITAL_VOLUME_6R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
-       .probe = wm5110_codec_probe,
-       .remove = wm5110_codec_remove,
-
-       .idle_bias_off = true,
-
-       .set_sysclk = arizona_set_sysclk,
-       .set_pll = wm5110_set_fll,
-
-       .component_driver = {
-               .controls               = wm5110_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm5110_snd_controls),
-               .dapm_widgets           = wm5110_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm5110_dapm_widgets),
-               .dapm_routes            = wm5110_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm5110_dapm_routes),
-       },
-};
-
-static const struct snd_compr_ops wm5110_compr_ops = {
-       .open = wm5110_open,
-       .free = wm_adsp_compr_free,
-       .set_params = wm_adsp_compr_set_params,
-       .get_caps = wm_adsp_compr_get_caps,
-       .trigger = wm_adsp_compr_trigger,
-       .pointer = wm_adsp_compr_pointer,
-       .copy = wm_adsp_compr_copy,
+static struct snd_compr_ops wm5110_compr_ops = {
+       .open           = wm5110_open,
+       .free           = wm_adsp_compr_free,
+       .set_params     = wm_adsp_compr_set_params,
+       .get_caps       = wm_adsp_compr_get_caps,
+       .trigger        = wm_adsp_compr_trigger,
+       .pointer        = wm_adsp_compr_pointer,
+       .copy           = wm_adsp_compr_copy,
 };
 
-static const struct snd_soc_platform_driver wm5110_compr_platform = {
-       .compr_ops = &wm5110_compr_ops,
+static const struct snd_soc_component_driver soc_component_dev_wm5110 = {
+       .probe                  = wm5110_component_probe,
+       .remove                 = wm5110_component_remove,
+       .set_sysclk             = arizona_set_sysclk,
+       .set_pll                = wm5110_set_fll,
+       .name                   = DRV_NAME,
+       .compr_ops              = &wm5110_compr_ops,
+       .controls               = wm5110_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm5110_snd_controls),
+       .dapm_widgets           = wm5110_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm5110_dapm_widgets),
+       .dapm_routes            = wm5110_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm5110_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm5110_probe(struct platform_device *pdev)
@@ -2464,23 +2464,17 @@ static int wm5110_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_dsp_irq;
 
-       ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &soc_component_dev_wm5110,
+                                             wm5110_dai,
+                                             ARRAY_SIZE(wm5110_dai));
        if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
                goto err_spk_irqs;
        }
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
-                                     wm5110_dai, ARRAY_SIZE(wm5110_dai));
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-               goto err_platform;
-       }
-
        return ret;
 
-err_platform:
-       snd_soc_unregister_platform(&pdev->dev);
 err_spk_irqs:
        arizona_free_spk_irqs(arizona);
 err_dsp_irq:
@@ -2495,8 +2489,6 @@ static int wm5110_remove(struct platform_device *pdev)
        struct arizona *arizona = wm5110->core.arizona;
        int i;
 
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_codec(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        for (i = 0; i < WM5110_NUM_ADSP; i++)
index fc79c6725d06f93f26efcb3eaf56eba70e872b6a..e92ebe52d485d0c3435436935beaf1c2d6bd708d 100644 (file)
@@ -256,8 +256,8 @@ static void wm8350_pga_work(struct work_struct *work)
 static int pga_event(struct snd_soc_dapm_widget *w,
                     struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
        struct wm8350_output *out;
 
        switch (w->shift) {
@@ -299,8 +299,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
 static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
                                  struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8350_data *wm8350_priv = snd_soc_component_get_drvdata(component);
        struct wm8350_output *out = NULL;
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
@@ -334,16 +334,16 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
                return ret;
 
        /* now hit the volume update bits (always bit 8) */
-       val = snd_soc_read(codec, reg);
-       snd_soc_write(codec, reg, val | WM8350_OUT1_VU);
+       val = snd_soc_component_read32(component, reg);
+       snd_soc_component_write(component, reg, val | WM8350_OUT1_VU);
        return 1;
 }
 
 static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8350_data *wm8350_priv = snd_soc_component_get_drvdata(component);
        struct wm8350_output *out1 = &wm8350_priv->out1;
        struct wm8350_output *out2 = &wm8350_priv->out2;
        struct soc_mixer_control *mc =
@@ -753,8 +753,8 @@ static const struct snd_soc_dapm_route wm8350_dapm_routes[] = {
 static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
        struct wm8350 *wm8350 = wm8350_data->wm8350;
        u16 fll_4;
 
@@ -769,9 +769,9 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        case WM8350_MCLK_SEL_PLL_32K:
                wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
                                WM8350_MCLK_SEL);
-               fll_4 = snd_soc_read(codec, WM8350_FLL_CONTROL_4) &
+               fll_4 = snd_soc_component_read32(component, WM8350_FLL_CONTROL_4) &
                    ~WM8350_FLL_CLK_SRC_MASK;
-               snd_soc_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
+               snd_soc_component_write(component, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
                break;
        }
 
@@ -788,44 +788,44 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
 static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 val;
 
        switch (div_id) {
        case WM8350_ADC_CLKDIV:
-               val = snd_soc_read(codec, WM8350_ADC_DIVIDER) &
+               val = snd_soc_component_read32(component, WM8350_ADC_DIVIDER) &
                    ~WM8350_ADC_CLKDIV_MASK;
-               snd_soc_write(codec, WM8350_ADC_DIVIDER, val | div);
+               snd_soc_component_write(component, WM8350_ADC_DIVIDER, val | div);
                break;
        case WM8350_DAC_CLKDIV:
-               val = snd_soc_read(codec, WM8350_DAC_CLOCK_CONTROL) &
+               val = snd_soc_component_read32(component, WM8350_DAC_CLOCK_CONTROL) &
                    ~WM8350_DAC_CLKDIV_MASK;
-               snd_soc_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
+               snd_soc_component_write(component, WM8350_DAC_CLOCK_CONTROL, val | div);
                break;
        case WM8350_BCLK_CLKDIV:
-               val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
+               val = snd_soc_component_read32(component, WM8350_CLOCK_CONTROL_1) &
                    ~WM8350_BCLK_DIV_MASK;
-               snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+               snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
                break;
        case WM8350_OPCLK_CLKDIV:
-               val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
+               val = snd_soc_component_read32(component, WM8350_CLOCK_CONTROL_1) &
                    ~WM8350_OPCLK_DIV_MASK;
-               snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+               snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
                break;
        case WM8350_SYS_CLKDIV:
-               val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
+               val = snd_soc_component_read32(component, WM8350_CLOCK_CONTROL_1) &
                    ~WM8350_MCLK_DIV_MASK;
-               snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+               snd_soc_component_write(component, WM8350_CLOCK_CONTROL_1, val | div);
                break;
        case WM8350_DACLR_CLKDIV:
-               val = snd_soc_read(codec, WM8350_DAC_LR_RATE) &
+               val = snd_soc_component_read32(component, WM8350_DAC_LR_RATE) &
                    ~WM8350_DACLRC_RATE_MASK;
-               snd_soc_write(codec, WM8350_DAC_LR_RATE, val | div);
+               snd_soc_component_write(component, WM8350_DAC_LR_RATE, val | div);
                break;
        case WM8350_ADCLR_CLKDIV:
-               val = snd_soc_read(codec, WM8350_ADC_LR_RATE) &
+               val = snd_soc_component_read32(component, WM8350_ADC_LR_RATE) &
                    ~WM8350_ADCLRC_RATE_MASK;
-               snd_soc_write(codec, WM8350_ADC_LR_RATE, val | div);
+               snd_soc_component_write(component, WM8350_ADC_LR_RATE, val | div);
                break;
        default:
                return -EINVAL;
@@ -836,14 +836,14 @@ static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
 
 static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 iface = snd_soc_read(codec, WM8350_AI_FORMATING) &
+       struct snd_soc_component *component = codec_dai->component;
+       u16 iface = snd_soc_component_read32(component, WM8350_AI_FORMATING) &
            ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
-       u16 master = snd_soc_read(codec, WM8350_AI_DAC_CONTROL) &
+       u16 master = snd_soc_component_read32(component, WM8350_AI_DAC_CONTROL) &
            ~WM8350_BCLK_MSTR;
-       u16 dac_lrc = snd_soc_read(codec, WM8350_DAC_LR_RATE) &
+       u16 dac_lrc = snd_soc_component_read32(component, WM8350_DAC_LR_RATE) &
            ~WM8350_DACLRC_ENA;
-       u16 adc_lrc = snd_soc_read(codec, WM8350_ADC_LR_RATE) &
+       u16 adc_lrc = snd_soc_component_read32(component, WM8350_ADC_LR_RATE) &
            ~WM8350_ADCLRC_ENA;
 
        /* set master/slave audio interface */
@@ -896,10 +896,10 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8350_AI_FORMATING, iface);
-       snd_soc_write(codec, WM8350_AI_DAC_CONTROL, master);
-       snd_soc_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
-       snd_soc_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
+       snd_soc_component_write(component, WM8350_AI_FORMATING, iface);
+       snd_soc_component_write(component, WM8350_AI_DAC_CONTROL, master);
+       snd_soc_component_write(component, WM8350_DAC_LR_RATE, dac_lrc);
+       snd_soc_component_write(component, WM8350_ADC_LR_RATE, adc_lrc);
        return 0;
 }
 
@@ -907,10 +907,10 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *codec_dai)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8350_data *wm8350_data = snd_soc_component_get_drvdata(component);
        struct wm8350 *wm8350 = wm8350_data->wm8350;
-       u16 iface = snd_soc_read(codec, WM8350_AI_FORMATING) &
+       u16 iface = snd_soc_component_read32(component, WM8350_AI_FORMATING) &
            ~WM8350_AIF_WL_MASK;
 
        /* bit size */
@@ -928,7 +928,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_write(codec, WM8350_AI_FORMATING, iface);
+       snd_soc_component_write(component, WM8350_AI_FORMATING, iface);
 
        /* The sloping stopband filter is recommended for use with
         * lower sample rates to improve performance.
@@ -947,7 +947,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8350_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        unsigned int val;
 
        if (mute)
@@ -955,7 +955,7 @@ static int wm8350_mute(struct snd_soc_dai *dai, int mute)
        else
                val = 0;
 
-       snd_soc_update_bits(codec, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA, val);
+       snd_soc_component_update_bits(component, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA, val);
 
        return 0;
 }
@@ -1024,8 +1024,8 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
                          int pll_id, int source, unsigned int freq_in,
                          unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
        struct wm8350 *wm8350 = priv->wm8350;
        struct _fll_div fll_div;
        int ret = 0;
@@ -1050,17 +1050,17 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
                fll_div.ratio);
 
        /* set up N.K & dividers */
-       fll_1 = snd_soc_read(codec, WM8350_FLL_CONTROL_1) &
+       fll_1 = snd_soc_component_read32(component, WM8350_FLL_CONTROL_1) &
            ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
-       snd_soc_write(codec, WM8350_FLL_CONTROL_1,
+       snd_soc_component_write(component, WM8350_FLL_CONTROL_1,
                           fll_1 | (fll_div.div << 8) | 0x50);
-       snd_soc_write(codec, WM8350_FLL_CONTROL_2,
+       snd_soc_component_write(component, WM8350_FLL_CONTROL_2,
                           (fll_div.ratio << 11) | (fll_div.
                                                    n & WM8350_FLL_N_MASK));
-       snd_soc_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
-       fll_4 = snd_soc_read(codec, WM8350_FLL_CONTROL_4) &
+       snd_soc_component_write(component, WM8350_FLL_CONTROL_3, fll_div.k);
+       fll_4 = snd_soc_component_read32(component, WM8350_FLL_CONTROL_4) &
            ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
-       snd_soc_write(codec, WM8350_FLL_CONTROL_4,
+       snd_soc_component_write(component, WM8350_FLL_CONTROL_4,
                           fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
                           (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
 
@@ -1074,10 +1074,10 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static int wm8350_set_bias_level(struct snd_soc_codec *codec,
+static int wm8350_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
        struct wm8350 *wm8350 = priv->wm8350;
        struct wm8350_audio_platform_data *platform =
                wm8350->codec.platform_data;
@@ -1101,7 +1101,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
                                                    priv->supplies);
                        if (ret != 0)
@@ -1310,7 +1310,7 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
 /**
  * wm8350_hp_jack_detect - Enable headphone jack detection.
  *
- * @codec:  WM8350 codec
+ * @component:  WM8350 component
  * @which:  left or right jack detect signal
  * @jack:   jack to report detection events on
  * @report: value to report
@@ -1318,10 +1318,10 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
  * Enables the headphone jack detection of the WM8350.  If no report
  * is specified then detection is disabled.
  */
-int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
+int wm8350_hp_jack_detect(struct snd_soc_component *component, enum wm8350_jack which,
                          struct snd_soc_jack *jack, int report)
 {
-       struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
        struct wm8350 *wm8350 = priv->wm8350;
        int ena;
 
@@ -1389,7 +1389,7 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
 /**
  * wm8350_mic_jack_detect - Enable microphone jack detection.
  *
- * @codec:         WM8350 codec
+ * @component:         WM8350 component
  * @jack:          jack to report detection events on
  * @detect_report: value to report when presence detected
  * @short_report:  value to report when microphone short detected
@@ -1397,11 +1397,11 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
  * Enables the microphone jack detection of the WM8350.  If both reports
  * are specified as zero then detection is disabled.
  */
-int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
+int wm8350_mic_jack_detect(struct snd_soc_component *component,
                           struct snd_soc_jack *jack,
                           int detect_report, int short_report)
 {
-       struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
        struct wm8350 *wm8350 = priv->wm8350;
 
        priv->mic.jack = jack;
@@ -1455,26 +1455,26 @@ static struct snd_soc_dai_driver wm8350_dai = {
        .ops = &wm8350_dai_ops,
 };
 
-static  int wm8350_codec_probe(struct snd_soc_codec *codec)
+static  int wm8350_component_probe(struct snd_soc_component *component)
 {
-       struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
+       struct wm8350 *wm8350 = dev_get_platdata(component->dev);
        struct wm8350_data *priv;
        struct wm8350_output *out1;
        struct wm8350_output *out2;
        int ret, i;
 
        if (wm8350->codec.platform_data == NULL) {
-               dev_err(codec->dev, "No audio platform data supplied\n");
+               dev_err(component->dev, "No audio platform data supplied\n");
                return -EINVAL;
        }
 
-       priv = devm_kzalloc(codec->dev, sizeof(struct wm8350_data),
+       priv = devm_kzalloc(component->dev, sizeof(struct wm8350_data),
                            GFP_KERNEL);
        if (priv == NULL)
                return -ENOMEM;
 
-       snd_soc_codec_init_regmap(codec, wm8350->regmap);
-       snd_soc_codec_set_drvdata(codec, priv);
+       snd_soc_component_init_regmap(component, wm8350->regmap);
+       snd_soc_component_set_drvdata(component, priv);
 
        priv->wm8350 = wm8350;
 
@@ -1497,9 +1497,9 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
        wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
 
        /* Enable robust clocking mode in ADC */
-       snd_soc_write(codec, WM8350_SECURITY, 0xa7);
-       snd_soc_write(codec, 0xde, 0x13);
-       snd_soc_write(codec, WM8350_SECURITY, 0);
+       snd_soc_component_write(component, WM8350_SECURITY, 0xa7);
+       snd_soc_component_write(component, 0xde, 0x13);
+       snd_soc_component_write(component, WM8350_SECURITY, 0);
 
        /* read OUT1 & OUT2 volumes */
        out1 = &priv->out1;
@@ -1552,10 +1552,10 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int  wm8350_codec_remove(struct snd_soc_codec *codec)
+static void wm8350_component_remove(struct snd_soc_component *component)
 {
-       struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
-       struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
+       struct wm8350_data *priv = snd_soc_component_get_drvdata(component);
+       struct wm8350 *wm8350 = dev_get_platdata(component->dev);
 
        wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
                          WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1578,44 +1578,37 @@ static int  wm8350_codec_remove(struct snd_soc_codec *codec)
        flush_delayed_work(&priv->pga_work);
 
        wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
-       .probe =        wm8350_codec_probe,
-       .remove =       wm8350_codec_remove,
-       .set_bias_level = wm8350_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8350_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8350_snd_controls),
-               .dapm_widgets           = wm8350_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8350_dapm_widgets),
-               .dapm_routes            = wm8350_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8350_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8350 = {
+       .probe                  = wm8350_component_probe,
+       .remove                 = wm8350_component_remove,
+       .set_bias_level         = wm8350_set_bias_level,
+       .controls               = wm8350_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8350_snd_controls),
+       .dapm_widgets           = wm8350_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8350_dapm_widgets),
+       .dapm_routes            = wm8350_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8350_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm8350_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm8350,
                        &wm8350_dai, 1);
 }
 
-static int wm8350_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static struct platform_driver wm8350_codec_driver = {
        .driver = {
                   .name = "wm8350-codec",
                   },
        .probe = wm8350_probe,
-       .remove = wm8350_remove,
 };
 
 module_platform_driver(wm8350_codec_driver);
index 74108eb82938ca29b3caec1156bc8dd22e4931a1..1191326c4a61e669b16ff78a92a9057253b8b694 100644 (file)
@@ -20,9 +20,9 @@ enum wm8350_jack {
        WM8350_JDR = 2,
 };
 
-int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
+int wm8350_hp_jack_detect(struct snd_soc_component *component, enum wm8350_jack which,
                          struct snd_soc_jack *jack, int report);
-int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
+int wm8350_mic_jack_detect(struct snd_soc_component *component,
                           struct snd_soc_jack *jack,
                           int detect_report, int short_report);
 
index a36adf881bcae8f40df5e7b805ebda6c90f9a7e5..57b22065a45df3f77b80e519ccb790d66a187a30 100644 (file)
@@ -65,9 +65,9 @@ struct wm8400_priv {
        int fll_in, fll_out;
 };
 
-static void wm8400_codec_reset(struct snd_soc_codec *codec)
+static void wm8400_component_reset(struct snd_soc_component *component)
 {
-       struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+       struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
 
        wm8400_reset_codec_reg_cache(wm8400->wm8400);
 }
@@ -91,7 +91,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
 static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
         struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        int reg = mc->reg;
@@ -103,8 +103,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
                 return ret;
 
         /* now hit the volume update bits (always bit 8) */
-        val = snd_soc_read(codec, reg);
-        return snd_soc_write(codec, reg, val | 0x0100);
+        val = snd_soc_component_read32(component, reg);
+        return snd_soc_component_write(component, reg, val | 0x0100);
 }
 
 #define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
@@ -324,7 +324,7 @@ SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
 static int outmixer_event (struct snd_soc_dapm_widget *w,
        struct snd_kcontrol * kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        u32 reg_shift = mc->shift;
@@ -333,7 +333,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
 
        switch (reg_shift) {
        case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
-               reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER1);
+               reg = snd_soc_component_read32(component, WM8400_OUTPUT_MIXER1);
                if (reg & WM8400_LDLO) {
                        printk(KERN_WARNING
                        "Cannot set as Output Mixer 1 LDLO Set\n");
@@ -341,7 +341,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
                }
                break;
        case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
-               reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER2);
+               reg = snd_soc_component_read32(component, WM8400_OUTPUT_MIXER2);
                if (reg & WM8400_RDRO) {
                        printk(KERN_WARNING
                        "Cannot set as Output Mixer 2 RDRO Set\n");
@@ -349,7 +349,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
                }
                break;
        case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
-               reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER);
+               reg = snd_soc_component_read32(component, WM8400_SPEAKER_MIXER);
                if (reg & WM8400_LDSPK) {
                        printk(KERN_WARNING
                        "Cannot set as Speaker Mixer LDSPK Set\n");
@@ -357,7 +357,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
                }
                break;
        case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
-               reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER);
+               reg = snd_soc_component_read32(component, WM8400_SPEAKER_MIXER);
                if (reg & WM8400_RDSPK) {
                        printk(KERN_WARNING
                        "Cannot set as Speaker Mixer RDSPK Set\n");
@@ -849,8 +849,8 @@ static const struct snd_soc_dapm_route wm8400_dapm_routes[] = {
 static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
 
        wm8400->sysclk = freq;
        return 0;
@@ -938,8 +938,8 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                              int source, unsigned int freq_in,
                              unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
        struct fll_factors factors;
        int ret;
        u16 reg;
@@ -962,13 +962,13 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        wm8400->fll_in = freq_in;
 
        /* We *must* disable the FLL before any changes */
-       reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_2);
+       reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_2);
        reg &= ~WM8400_FLL_ENA;
-       snd_soc_write(codec, WM8400_POWER_MANAGEMENT_2, reg);
+       snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_2, reg);
 
-       reg = snd_soc_read(codec, WM8400_FLL_CONTROL_1);
+       reg = snd_soc_component_read32(component, WM8400_FLL_CONTROL_1);
        reg &= ~WM8400_FLL_OSC_ENA;
-       snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
+       snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
 
        if (!freq_out)
                return 0;
@@ -976,15 +976,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
        reg |= WM8400_FLL_FRAC | factors.fratio;
        reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
-       snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
+       snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
 
-       snd_soc_write(codec, WM8400_FLL_CONTROL_2, factors.k);
-       snd_soc_write(codec, WM8400_FLL_CONTROL_3, factors.n);
+       snd_soc_component_write(component, WM8400_FLL_CONTROL_2, factors.k);
+       snd_soc_component_write(component, WM8400_FLL_CONTROL_3, factors.n);
 
-       reg = snd_soc_read(codec, WM8400_FLL_CONTROL_4);
+       reg = snd_soc_component_read32(component, WM8400_FLL_CONTROL_4);
        reg &= ~WM8400_FLL_OUTDIV_MASK;
        reg |= factors.outdiv;
-       snd_soc_write(codec, WM8400_FLL_CONTROL_4, reg);
+       snd_soc_component_write(component, WM8400_FLL_CONTROL_4, reg);
 
        return 0;
 }
@@ -995,11 +995,11 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 audio1, audio3;
 
-       audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
-       audio3 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_3);
+       audio1 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_1);
+       audio3 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_3);
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1040,37 +1040,37 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
-       snd_soc_write(codec, WM8400_AUDIO_INTERFACE_3, audio3);
+       snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
+       snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_3, audio3);
        return 0;
 }
 
 static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                int div_id, int div)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 reg;
 
        switch (div_id) {
        case WM8400_MCLK_DIV:
-               reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
+               reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) &
                        ~WM8400_MCLK_DIV_MASK;
-               snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
+               snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
                break;
        case WM8400_DACCLK_DIV:
-               reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
+               reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) &
                        ~WM8400_DAC_CLKDIV_MASK;
-               snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
+               snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
                break;
        case WM8400_ADCCLK_DIV:
-               reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
+               reg = snd_soc_component_read32(component, WM8400_CLOCKING_2) &
                        ~WM8400_ADC_CLKDIV_MASK;
-               snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
+               snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
                break;
        case WM8400_BCLK_DIV:
-               reg = snd_soc_read(codec, WM8400_CLOCKING_1) &
+               reg = snd_soc_component_read32(component, WM8400_CLOCKING_1) &
                        ~WM8400_BCLK_DIV_MASK;
-               snd_soc_write(codec, WM8400_CLOCKING_1, reg | div);
+               snd_soc_component_write(component, WM8400_CLOCKING_1, reg | div);
                break;
        default:
                return -EINVAL;
@@ -1086,8 +1086,8 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
+       struct snd_soc_component *component = dai->component;
+       u16 audio1 = snd_soc_component_read32(component, WM8400_AUDIO_INTERFACE_1);
 
        audio1 &= ~WM8400_AIF_WL_MASK;
        /* bit size */
@@ -1105,28 +1105,28 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
+       snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
        return 0;
 }
 
 static int wm8400_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 val = snd_soc_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
+       struct snd_soc_component *component = dai->component;
+       u16 val = snd_soc_component_read32(component, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
 
        if (mute)
-               snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
+               snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
        else
-               snd_soc_write(codec, WM8400_DAC_CTRL, val);
+               snd_soc_component_write(component, WM8400_DAC_CTRL, val);
 
        return 0;
 }
 
 /* TODO: set bias for best performance at standby */
-static int wm8400_set_bias_level(struct snd_soc_codec *codec,
+static int wm8400_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
+       struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
        u16 val;
        int ret;
 
@@ -1136,13 +1136,13 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_PREPARE:
                /* VMID=2*50k */
-               val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
+               val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1) &
                        ~WM8400_VMID_MODE_MASK;
-               snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2);
+               snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x2);
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(power),
                                                    &power[0]);
                        if (ret != 0) {
@@ -1152,74 +1152,74 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
                                return ret;
                        }
 
-                       snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
+                       snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
                                     WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
 
                        /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
-                       snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+                       snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
                                     WM8400_BUFDCOPEN | WM8400_POBCTRL);
 
                        msleep(50);
 
                        /* Enable VREF & VMID at 2x50k */
-                       val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
+                       val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
                        val |= 0x2 | WM8400_VREF_ENA;
-                       snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+                       snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
                        /* Enable BUFIOEN */
-                       snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+                       snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
                                     WM8400_BUFDCOPEN | WM8400_POBCTRL |
                                     WM8400_BUFIOEN);
 
                        /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-                       snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN);
+                       snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_BUFIOEN);
                }
 
                /* VMID=2*300k */
-               val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
+               val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1) &
                        ~WM8400_VMID_MODE_MASK;
-               snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4);
+               snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x4);
                break;
 
        case SND_SOC_BIAS_OFF:
                /* Enable POBCTRL and SOFT_ST */
-               snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+               snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
                        WM8400_POBCTRL | WM8400_BUFIOEN);
 
                /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
-               snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
+               snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
                        WM8400_BUFDCOPEN | WM8400_POBCTRL |
                        WM8400_BUFIOEN);
 
                /* mute DAC */
-               val = snd_soc_read(codec, WM8400_DAC_CTRL);
-               snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
+               val = snd_soc_component_read32(component, WM8400_DAC_CTRL);
+               snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
 
                /* Enable any disabled outputs */
-               val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
+               val = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
                val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
                        WM8400_OUT4_ENA | WM8400_LOUT_ENA |
                        WM8400_ROUT_ENA;
-               snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+               snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
                /* Disable VMID */
                val &= ~WM8400_VMID_MODE_MASK;
-               snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+               snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
                msleep(300);
 
                /* Enable all output discharge bits */
-               snd_soc_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
+               snd_soc_component_write(component, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
                        WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
                        WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
                        WM8400_DIS_ROUT);
 
                /* Disable VREF */
                val &= ~WM8400_VREF_ENA;
-               snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
+               snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
 
                /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
-               snd_soc_write(codec, WM8400_ANTIPOP2, 0x0);
+               snd_soc_component_write(component, WM8400_ANTIPOP2, 0x0);
 
                ret = regulator_bulk_disable(ARRAY_SIZE(power),
                                             &power[0]);
@@ -1273,93 +1273,86 @@ static struct snd_soc_dai_driver wm8400_dai = {
        .ops = &wm8400_dai_ops,
 };
 
-static int wm8400_codec_probe(struct snd_soc_codec *codec)
+static int wm8400_component_probe(struct snd_soc_component *component)
 {
-       struct wm8400 *wm8400 = dev_get_platdata(codec->dev);
+       struct wm8400 *wm8400 = dev_get_platdata(component->dev);
        struct wm8400_priv *priv;
        int ret;
        u16 reg;
 
-       priv = devm_kzalloc(codec->dev, sizeof(struct wm8400_priv),
+       priv = devm_kzalloc(component->dev, sizeof(struct wm8400_priv),
                            GFP_KERNEL);
        if (priv == NULL)
                return -ENOMEM;
 
-       snd_soc_codec_init_regmap(codec, wm8400->regmap);
-       snd_soc_codec_set_drvdata(codec, priv);
+       snd_soc_component_init_regmap(component, wm8400->regmap);
+       snd_soc_component_set_drvdata(component, priv);
        priv->wm8400 = wm8400;
 
        ret = devm_regulator_bulk_get(wm8400->dev,
                                 ARRAY_SIZE(power), &power[0]);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
+               dev_err(component->dev, "Failed to get regulators: %d\n", ret);
                return ret;
        }
 
-       wm8400_codec_reset(codec);
+       wm8400_component_reset(component);
 
-       reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
-       snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
+       reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
+       snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
 
        /* Latch volume update bits */
-       reg = snd_soc_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
-       snd_soc_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
+       reg = snd_soc_component_read32(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
+       snd_soc_component_write(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
                     reg & WM8400_IPVU);
-       reg = snd_soc_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
-       snd_soc_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
+       reg = snd_soc_component_read32(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
+       snd_soc_component_write(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
                     reg & WM8400_IPVU);
 
-       snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
-       snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
+       snd_soc_component_write(component, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
+       snd_soc_component_write(component, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
        return 0;
 }
 
-static int  wm8400_codec_remove(struct snd_soc_codec *codec)
+static void  wm8400_component_remove(struct snd_soc_component *component)
 {
        u16 reg;
 
-       reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
-       snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
+       reg = snd_soc_component_read32(component, WM8400_POWER_MANAGEMENT_1);
+       snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
                     reg & (~WM8400_CODEC_ENA));
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
-       .probe =        wm8400_codec_probe,
-       .remove =       wm8400_codec_remove,
-       .set_bias_level = wm8400_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8400_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8400_snd_controls),
-               .dapm_widgets           = wm8400_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8400_dapm_widgets),
-               .dapm_routes            = wm8400_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8400_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8400 = {
+       .probe                  = wm8400_component_probe,
+       .remove                 = wm8400_component_remove,
+       .set_bias_level         = wm8400_set_bias_level,
+       .controls               = wm8400_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8400_snd_controls),
+       .dapm_widgets           = wm8400_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8400_dapm_widgets),
+       .dapm_routes            = wm8400_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8400_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm8400_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm8400,
                        &wm8400_dai, 1);
 }
 
-static int wm8400_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static struct platform_driver wm8400_codec_driver = {
        .driver = {
                   .name = "wm8400-codec",
                   },
        .probe = wm8400_probe,
-       .remove = wm8400_remove,
 };
 
 module_platform_driver(wm8400_codec_driver);
index 119ceac684ae136e236c9fe83d1aff8bac646e33..1a2412d73e352667b8663df3c1197174c17caac8 100644 (file)
@@ -106,7 +106,7 @@ static bool wm8510_volatile(struct device *dev, unsigned int reg)
 #define WM8510_POWER1_BIASEN  0x08
 #define WM8510_POWER1_BUFIOEN 0x10
 
-#define wm8510_reset(c)        snd_soc_write(c, WM8510_RESET, 0)
+#define wm8510_reset(c)        snd_soc_component_write(c, WM8510_RESET, 0)
 
 /* codec private data */
 struct wm8510_priv {
@@ -316,32 +316,32 @@ static void pll_factors(unsigned int target, unsigned int source)
 static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 reg;
 
        if (freq_in == 0 || freq_out == 0) {
                /* Clock CODEC directly from MCLK */
-               reg = snd_soc_read(codec, WM8510_CLOCK);
-               snd_soc_write(codec, WM8510_CLOCK, reg & 0x0ff);
+               reg = snd_soc_component_read32(component, WM8510_CLOCK);
+               snd_soc_component_write(component, WM8510_CLOCK, reg & 0x0ff);
 
                /* Turn off PLL */
-               reg = snd_soc_read(codec, WM8510_POWER1);
-               snd_soc_write(codec, WM8510_POWER1, reg & 0x1df);
+               reg = snd_soc_component_read32(component, WM8510_POWER1);
+               snd_soc_component_write(component, WM8510_POWER1, reg & 0x1df);
                return 0;
        }
 
        pll_factors(freq_out*4, freq_in);
 
-       snd_soc_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
-       snd_soc_write(codec, WM8510_PLLK1, pll_div.k >> 18);
-       snd_soc_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
-       snd_soc_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
-       reg = snd_soc_read(codec, WM8510_POWER1);
-       snd_soc_write(codec, WM8510_POWER1, reg | 0x020);
+       snd_soc_component_write(component, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
+       snd_soc_component_write(component, WM8510_PLLK1, pll_div.k >> 18);
+       snd_soc_component_write(component, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
+       snd_soc_component_write(component, WM8510_PLLK3, pll_div.k & 0x1ff);
+       reg = snd_soc_component_read32(component, WM8510_POWER1);
+       snd_soc_component_write(component, WM8510_POWER1, reg | 0x020);
 
        /* Run CODEC from PLL instead of MCLK */
-       reg = snd_soc_read(codec, WM8510_CLOCK);
-       snd_soc_write(codec, WM8510_CLOCK, reg | 0x100);
+       reg = snd_soc_component_read32(component, WM8510_CLOCK);
+       snd_soc_component_write(component, WM8510_CLOCK, reg | 0x100);
 
        return 0;
 }
@@ -352,29 +352,29 @@ static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                int div_id, int div)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 reg;
 
        switch (div_id) {
        case WM8510_OPCLKDIV:
-               reg = snd_soc_read(codec, WM8510_GPIO) & 0x1cf;
-               snd_soc_write(codec, WM8510_GPIO, reg | div);
+               reg = snd_soc_component_read32(component, WM8510_GPIO) & 0x1cf;
+               snd_soc_component_write(component, WM8510_GPIO, reg | div);
                break;
        case WM8510_MCLKDIV:
-               reg = snd_soc_read(codec, WM8510_CLOCK) & 0x11f;
-               snd_soc_write(codec, WM8510_CLOCK, reg | div);
+               reg = snd_soc_component_read32(component, WM8510_CLOCK) & 0x11f;
+               snd_soc_component_write(component, WM8510_CLOCK, reg | div);
                break;
        case WM8510_ADCCLK:
-               reg = snd_soc_read(codec, WM8510_ADC) & 0x1f7;
-               snd_soc_write(codec, WM8510_ADC, reg | div);
+               reg = snd_soc_component_read32(component, WM8510_ADC) & 0x1f7;
+               snd_soc_component_write(component, WM8510_ADC, reg | div);
                break;
        case WM8510_DACCLK:
-               reg = snd_soc_read(codec, WM8510_DAC) & 0x1f7;
-               snd_soc_write(codec, WM8510_DAC, reg | div);
+               reg = snd_soc_component_read32(component, WM8510_DAC) & 0x1f7;
+               snd_soc_component_write(component, WM8510_DAC, reg | div);
                break;
        case WM8510_BCLKDIV:
-               reg = snd_soc_read(codec, WM8510_CLOCK) & 0x1e3;
-               snd_soc_write(codec, WM8510_CLOCK, reg | div);
+               reg = snd_soc_component_read32(component, WM8510_CLOCK) & 0x1e3;
+               snd_soc_component_write(component, WM8510_CLOCK, reg | div);
                break;
        default:
                return -EINVAL;
@@ -386,9 +386,9 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 iface = 0;
-       u16 clk = snd_soc_read(codec, WM8510_CLOCK) & 0x1fe;
+       u16 clk = snd_soc_component_read32(component, WM8510_CLOCK) & 0x1fe;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -435,8 +435,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8510_IFACE, iface);
-       snd_soc_write(codec, WM8510_CLOCK, clk);
+       snd_soc_component_write(component, WM8510_IFACE, iface);
+       snd_soc_component_write(component, WM8510_CLOCK, clk);
        return 0;
 }
 
@@ -444,9 +444,9 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
-       u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
+       struct snd_soc_component *component = dai->component;
+       u16 iface = snd_soc_component_read32(component, WM8510_IFACE) & 0x19f;
+       u16 adn = snd_soc_component_read32(component, WM8510_ADD) & 0x1f1;
 
        /* bit size */
        switch (params_width(params)) {
@@ -485,56 +485,56 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_write(codec, WM8510_IFACE, iface);
-       snd_soc_write(codec, WM8510_ADD, adn);
+       snd_soc_component_write(component, WM8510_IFACE, iface);
+       snd_soc_component_write(component, WM8510_ADD, adn);
        return 0;
 }
 
 static int wm8510_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8510_DAC) & 0xffbf;
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8510_DAC) & 0xffbf;
 
        if (mute)
-               snd_soc_write(codec, WM8510_DAC, mute_reg | 0x40);
+               snd_soc_component_write(component, WM8510_DAC, mute_reg | 0x40);
        else
-               snd_soc_write(codec, WM8510_DAC, mute_reg);
+               snd_soc_component_write(component, WM8510_DAC, mute_reg);
        return 0;
 }
 
 /* liam need to make this lower power with dapm */
-static int wm8510_set_bias_level(struct snd_soc_codec *codec,
+static int wm8510_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
-       u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
+       struct wm8510_priv *wm8510 = snd_soc_component_get_drvdata(component);
+       u16 power1 = snd_soc_component_read32(component, WM8510_POWER1) & ~0x3;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
                power1 |= 0x1;  /* VMID 50k */
-               snd_soc_write(codec, WM8510_POWER1, power1);
+               snd_soc_component_write(component, WM8510_POWER1, power1);
                break;
 
        case SND_SOC_BIAS_STANDBY:
                power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
 
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        regcache_sync(wm8510->regmap);
 
                        /* Initial cap charge at VMID 5k */
-                       snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
+                       snd_soc_component_write(component, WM8510_POWER1, power1 | 0x3);
                        mdelay(100);
                }
 
                power1 |= 0x2;  /* VMID 500k */
-               snd_soc_write(codec, WM8510_POWER1, power1);
+               snd_soc_component_write(component, WM8510_POWER1, power1);
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, WM8510_POWER1, 0);
-               snd_soc_write(codec, WM8510_POWER2, 0);
-               snd_soc_write(codec, WM8510_POWER3, 0);
+               snd_soc_component_write(component, WM8510_POWER1, 0);
+               snd_soc_component_write(component, WM8510_POWER2, 0);
+               snd_soc_component_write(component, WM8510_POWER3, 0);
                break;
        }
 
@@ -574,26 +574,27 @@ static struct snd_soc_dai_driver wm8510_dai = {
        .symmetric_rates = 1,
 };
 
-static int wm8510_probe(struct snd_soc_codec *codec)
+static int wm8510_probe(struct snd_soc_component *component)
 {
-       wm8510_reset(codec);
+       wm8510_reset(component);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
-       .probe =        wm8510_probe,
-       .set_bias_level = wm8510_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8510_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8510_snd_controls),
-               .dapm_widgets           = wm8510_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8510_dapm_widgets),
-               .dapm_routes            = wm8510_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8510_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8510 = {
+       .probe                  = wm8510_probe,
+       .set_bias_level         = wm8510_set_bias_level,
+       .controls               = wm8510_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8510_snd_controls),
+       .dapm_widgets           = wm8510_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8510_dapm_widgets),
+       .dapm_routes            = wm8510_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8510_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8510_of_match[] = {
@@ -631,25 +632,18 @@ static int wm8510_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8510);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_wm8510, &wm8510_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_wm8510, &wm8510_dai, 1);
 
        return ret;
 }
 
-static int wm8510_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver wm8510_spi_driver = {
        .driver = {
                .name   = "wm8510",
                .of_match_table = wm8510_of_match,
        },
        .probe          = wm8510_spi_probe,
-       .remove         = wm8510_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -671,18 +665,12 @@ static int wm8510_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm8510);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8510, &wm8510_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_wm8510, &wm8510_dai, 1);
 
        return ret;
 }
 
-static int wm8510_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8510_i2c_id[] = {
        { "wm8510", 0 },
        { }
@@ -695,7 +683,6 @@ static struct i2c_driver wm8510_i2c_driver = {
                .of_match_table = wm8510_of_match,
        },
        .probe =    wm8510_i2c_probe,
-       .remove =   wm8510_i2c_remove,
        .id_table = wm8510_i2c_id,
 };
 #endif
index c7c33e98fbcb94424cda05b76a9ecc63753719f7..f4a9e25fb3342c998860c4a270d87fee1acac7e9 100644 (file)
@@ -125,14 +125,14 @@ static const struct {
 static int wm8523_startup(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 
        /* The set of sample rates that can be supported depends on the
         * MCLK supplied to the CODEC - enforce this.
         */
        if (!wm8523->sysclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "No MCLK configured, call set_sysclk() on init\n");
                return -EINVAL;
        }
@@ -148,11 +148,11 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
        int i;
-       u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
-       u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
+       u16 aifctrl1 = snd_soc_component_read32(component, WM8523_AIF_CTRL1);
+       u16 aifctrl2 = snd_soc_component_read32(component, WM8523_AIF_CTRL2);
 
        /* Find a supported LRCLK ratio */
        for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
@@ -163,7 +163,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 
        /* Should never happen, should be handled by constraints */
        if (i == ARRAY_SIZE(lrclk_ratios)) {
-               dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
+               dev_err(component->dev, "MCLK/fs ratio %d unsupported\n",
                        wm8523->sysclk / params_rate(params));
                return -EINVAL;
        }
@@ -178,7 +178,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
                                break;
 
                if (i == ARRAY_SIZE(bclk_ratios)) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "No matching BCLK/fs ratio for word length %d\n",
                                params_width(params));
                        return -EINVAL;
@@ -203,8 +203,8 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
-       snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2);
+       snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
+       snd_soc_component_write(component, WM8523_AIF_CTRL2, aifctrl2);
 
        return 0;
 }
@@ -212,8 +212,8 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
 static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
        unsigned int val;
        int i;
 
@@ -239,13 +239,13 @@ static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                case 96000:
                case 176400:
                case 192000:
-                       dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
+                       dev_dbg(component->dev, "Supported sample rate: %dHz\n",
                                val);
                        wm8523->rate_constraint_list[i] = val;
                        wm8523->rate_constraint.count++;
                        break;
                default:
-                       dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
+                       dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
                                val);
                }
        }
@@ -261,8 +261,8 @@ static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
+       struct snd_soc_component *component = codec_dai->component;
+       u16 aifctrl1 = snd_soc_component_read32(component, WM8523_AIF_CTRL1);
 
        aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
                      WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
@@ -312,15 +312,15 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
+       snd_soc_component_write(component, WM8523_AIF_CTRL1, aifctrl1);
 
        return 0;
 }
 
-static int wm8523_set_bias_level(struct snd_soc_codec *codec,
+static int wm8523_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+       struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -329,16 +329,16 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_PREPARE:
                /* Full power on */
-               snd_soc_update_bits(codec, WM8523_PSCTRL1,
+               snd_soc_component_update_bits(component, WM8523_PSCTRL1,
                                    WM8523_SYS_ENA_MASK, 3);
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
                                                    wm8523->supplies);
                        if (ret != 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to enable supplies: %d\n",
                                        ret);
                                return ret;
@@ -348,21 +348,21 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
                        regcache_sync(wm8523->regmap);
 
                        /* Initial power up */
-                       snd_soc_update_bits(codec, WM8523_PSCTRL1,
+                       snd_soc_component_update_bits(component, WM8523_PSCTRL1,
                                            WM8523_SYS_ENA_MASK, 1);
 
                        msleep(100);
                }
 
                /* Power up to mute */
-               snd_soc_update_bits(codec, WM8523_PSCTRL1,
+               snd_soc_component_update_bits(component, WM8523_PSCTRL1,
                                    WM8523_SYS_ENA_MASK, 2);
 
                break;
 
        case SND_SOC_BIAS_OFF:
                /* The chip runs through the power down sequence for us. */
-               snd_soc_update_bits(codec, WM8523_PSCTRL1,
+               snd_soc_component_update_bits(component, WM8523_PSCTRL1,
                                    WM8523_SYS_ENA_MASK, 0);
                msleep(100);
 
@@ -397,35 +397,36 @@ static struct snd_soc_dai_driver wm8523_dai = {
        .ops = &wm8523_dai_ops,
 };
 
-static int wm8523_probe(struct snd_soc_codec *codec)
+static int wm8523_probe(struct snd_soc_component *component)
 {
-       struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+       struct wm8523_priv *wm8523 = snd_soc_component_get_drvdata(component);
 
        wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
        wm8523->rate_constraint.count =
                ARRAY_SIZE(wm8523->rate_constraint_list);
 
        /* Change some default settings - latch VU and enable ZC */
-       snd_soc_update_bits(codec, WM8523_DAC_GAINR,
+       snd_soc_component_update_bits(component, WM8523_DAC_GAINR,
                            WM8523_DACR_VU, WM8523_DACR_VU);
-       snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
+       snd_soc_component_update_bits(component, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
-       .probe =        wm8523_probe,
-       .set_bias_level = wm8523_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8523_controls,
-               .num_controls           = ARRAY_SIZE(wm8523_controls),
-               .dapm_widgets           = wm8523_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8523_dapm_widgets),
-               .dapm_routes            = wm8523_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8523_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8523 = {
+       .probe                  = wm8523_probe,
+       .set_bias_level         = wm8523_set_bias_level,
+       .controls               = wm8523_controls,
+       .num_controls           = ARRAY_SIZE(wm8523_controls),
+       .dapm_widgets           = wm8523_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8523_dapm_widgets),
+       .dapm_routes            = wm8523_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8523_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8523_of_match[] = {
@@ -511,8 +512,8 @@ static int wm8523_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm8523);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8523, &wm8523_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_wm8523, &wm8523_dai, 1);
 
        return ret;
 
@@ -521,12 +522,6 @@ err_enable:
        return ret;
 }
 
-static int wm8523_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8523_i2c_id[] = {
        { "wm8523", 0 },
        { }
@@ -539,7 +534,6 @@ static struct i2c_driver wm8523_i2c_driver = {
                .of_match_table = wm8523_of_match,
        },
        .probe =    wm8523_i2c_probe,
-       .remove =   wm8523_i2c_remove,
        .id_table = wm8523_i2c_id,
 };
 
index 856a6950a451a3c10636c9fd898e390bfe3348ed..fde444d826ca57f1cdc168276c18b52743647e0e 100644 (file)
@@ -62,14 +62,14 @@ static const struct {
 static int wm8524_startup(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 
        /* The set of sample rates that can be supported depends on the
         * MCLK supplied to the CODEC - enforce this.
         */
        if (!wm8524->sysclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "No MCLK configured, call set_sysclk() on init\n");
                return -EINVAL;
        }
@@ -86,8 +86,8 @@ static int wm8524_startup(struct snd_pcm_substream *substream,
 static void wm8524_shutdown(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 
        gpiod_set_value_cansleep(wm8524->mute, 0);
 }
@@ -95,8 +95,8 @@ static void wm8524_shutdown(struct snd_pcm_substream *substream,
 static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
        unsigned int val;
        int i, j = 0;
 
@@ -118,13 +118,13 @@ static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                case 96000:
                case 176400:
                case 192000:
-                       dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
+                       dev_dbg(component->dev, "Supported sample rate: %dHz\n",
                                val);
                        wm8524->rate_constraint_list[j++] = val;
                        wm8524->rate_constraint.count++;
                        break;
                default:
-                       dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
+                       dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
                                val);
                }
        }
@@ -152,7 +152,7 @@ static int wm8524_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 
 static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 {
-       struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(dai->codec);
+       struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(dai->component);
 
        if (wm8524->mute)
                gpiod_set_value_cansleep(wm8524->mute, mute);
@@ -184,9 +184,9 @@ static struct snd_soc_dai_driver wm8524_dai = {
        .ops = &wm8524_dai_ops,
 };
 
-static int wm8524_probe(struct snd_soc_codec *codec)
+static int wm8524_probe(struct snd_soc_component *component)
 {
-       struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec);
+       struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component);
 
        wm8524->rate_constraint.list = &wm8524->rate_constraint_list[0];
        wm8524->rate_constraint.count =
@@ -195,15 +195,16 @@ static int wm8524_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8524 = {
-       .probe =        wm8524_probe,
-
-       .component_driver = {
-               .dapm_widgets           = wm8524_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8524_dapm_widgets),
-               .dapm_routes            = wm8524_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8524_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8524 = {
+       .probe                  = wm8524_probe,
+       .dapm_widgets           = wm8524_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8524_dapm_widgets),
+       .dapm_routes            = wm8524_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8524_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8524_of_match[] = {
@@ -231,23 +232,16 @@ static int wm8524_codec_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret =  snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_wm8524, &wm8524_dai, 1);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm8524, &wm8524_dai, 1);
        if (ret < 0)
-               dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
 
        return ret;
 }
 
-static int wm8524_codec_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
-}
-
 static struct platform_driver wm8524_codec_driver = {
        .probe          = wm8524_codec_probe,
-       .remove         = wm8524_codec_remove,
        .driver         = {
                .name   = "wm8524-codec",
                .of_match_table = wm8524_of_match,
index 910801dddd64d00e299533ff8ae2886a81de1410..fa4ad1b093eb5d45343020dcd386a3ee593ee518 100644 (file)
@@ -262,8 +262,8 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
 {
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
        unsigned int reg = mc->reg;
        unsigned int reg2 = mc->rreg;
        int ret;
@@ -279,8 +279,8 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
                return ret;
 
        /* Now write again with the volume update bit set */
-       snd_soc_update_bits(codec, reg, 0x100, 0x100);
-       snd_soc_update_bits(codec, reg2, 0x100, 0x100);
+       snd_soc_component_update_bits(component, reg, 0x100, 0x100);
+       snd_soc_component_update_bits(component, reg2, 0x100, 0x100);
 
        return 0;
 }
@@ -465,8 +465,8 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
        int offset;
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
        struct pll_state *state;
        struct _pll_div pll_div;
        unsigned int reg;
@@ -505,25 +505,25 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        /* Always disable the PLL - it is not safe to leave it running
         * while reprogramming it.
         */
-       snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask);
+       snd_soc_component_update_bits(component, WM8580_PWRDN2, pwr_mask, pwr_mask);
 
        if (!freq_in || !freq_out)
                return 0;
 
-       snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
-       snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
-       snd_soc_write(codec, WM8580_PLLA3 + offset,
+       snd_soc_component_write(component, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
+       snd_soc_component_write(component, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
+       snd_soc_component_write(component, WM8580_PLLA3 + offset,
                     (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
 
-       reg = snd_soc_read(codec, WM8580_PLLA4 + offset);
+       reg = snd_soc_component_read32(component, WM8580_PLLA4 + offset);
        reg &= ~0x1b;
        reg |= pll_div.prescale | pll_div.postscale << 1 |
                pll_div.freqmode << 3;
 
-       snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
+       snd_soc_component_write(component, WM8580_PLLA4 + offset, reg);
 
        /* All done, turn it on */
-       snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0);
+       snd_soc_component_update_bits(component, WM8580_PWRDN2, pwr_mask, 0);
 
        return 0;
 }
@@ -539,8 +539,8 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
        u16 paifa = 0;
        u16 paifb = 0;
        int i, ratio, osr;
@@ -572,12 +572,12 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                if (ratio == wm8580_sysclk_ratios[i])
                        break;
        if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
-               dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
+               dev_err(component->dev, "Invalid clock ratio %d/%d\n",
                        wm8580->sysclk[dai->driver->id], params_rate(params));
                return -EINVAL;
        }
        paifa |= i;
-       dev_dbg(codec->dev, "Running at %dfs with %dHz clock\n",
+       dev_dbg(component->dev, "Running at %dfs with %dHz clock\n",
                wm8580_sysclk_ratios[i], wm8580->sysclk[dai->driver->id]);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -585,21 +585,21 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                case 128:
                case 192:
                        osr = WM8580_DACOSR;
-                       dev_dbg(codec->dev, "Selecting 64x OSR\n");
+                       dev_dbg(component->dev, "Selecting 64x OSR\n");
                        break;
                default:
                        osr = 0;
-                       dev_dbg(codec->dev, "Selecting 128x OSR\n");
+                       dev_dbg(component->dev, "Selecting 128x OSR\n");
                        break;
                }
 
-               snd_soc_update_bits(codec, WM8580_PAIF3, WM8580_DACOSR, osr);
+               snd_soc_component_update_bits(component, WM8580_PAIF3, WM8580_DACOSR, osr);
        }
 
-       snd_soc_update_bits(codec, WM8580_PAIF1 + dai->driver->id,
+       snd_soc_component_update_bits(component, WM8580_PAIF1 + dai->driver->id,
                            WM8580_AIF_RATE_MASK | WM8580_AIF_BCLKSEL_MASK,
                            paifa);
-       snd_soc_update_bits(codec, WM8580_PAIF3 + dai->driver->id,
+       snd_soc_component_update_bits(component, WM8580_PAIF3 + dai->driver->id,
                            WM8580_AIF_LENGTH_MASK, paifb);
        return 0;
 }
@@ -607,13 +607,13 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
 static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
                                      unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        unsigned int aifa;
        unsigned int aifb;
        int can_invert_lrclk;
 
-       aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
-       aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
+       aifa = snd_soc_component_read32(component, WM8580_PAIF1 + codec_dai->driver->id);
+       aifb = snd_soc_component_read32(component, WM8580_PAIF3 + codec_dai->driver->id);
 
        aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
 
@@ -679,8 +679,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
-       snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
+       snd_soc_component_write(component, WM8580_PAIF1 + codec_dai->driver->id, aifa);
+       snd_soc_component_write(component, WM8580_PAIF3 + codec_dai->driver->id, aifb);
 
        return 0;
 }
@@ -688,12 +688,12 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
 static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                                 int div_id, int div)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        unsigned int reg;
 
        switch (div_id) {
        case WM8580_MCLK:
-               reg = snd_soc_read(codec, WM8580_PLLB4);
+               reg = snd_soc_component_read32(component, WM8580_PLLB4);
                reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
 
                switch (div) {
@@ -715,11 +715,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                default:
                        return -EINVAL;
                }
-               snd_soc_write(codec, WM8580_PLLB4, reg);
+               snd_soc_component_write(component, WM8580_PLLB4, reg);
                break;
 
        case WM8580_CLKOUTSRC:
-               reg = snd_soc_read(codec, WM8580_PLLB4);
+               reg = snd_soc_component_read32(component, WM8580_PLLB4);
                reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
 
                switch (div) {
@@ -741,7 +741,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                default:
                        return -EINVAL;
                }
-               snd_soc_write(codec, WM8580_PLLB4, reg);
+               snd_soc_component_write(component, WM8580_PLLB4, reg);
                break;
 
        default:
@@ -754,8 +754,8 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
                             unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
        int ret, sel, sel_mask, sel_shift;
 
        switch (dai->driver->id) {
@@ -790,14 +790,14 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
                sel = 3 << sel_shift;
                break;
        default:
-               dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+               dev_err(component->dev, "Unknown clock %d\n", clk_id);
                return -EINVAL;
        }
 
        /* We really should validate PLL settings but not yet */
        wm8580->sysclk[dai->driver->id] = freq;
 
-       ret = snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
+       ret = snd_soc_component_update_bits(component, WM8580_CLKSEL, sel_mask, sel);
        if (ret < 0)
                return ret;
 
@@ -806,22 +806,22 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        unsigned int reg;
 
-       reg = snd_soc_read(codec, WM8580_DAC_CONTROL5);
+       reg = snd_soc_component_read32(component, WM8580_DAC_CONTROL5);
 
        if (mute)
                reg |= WM8580_DAC_CONTROL5_MUTEALL;
        else
                reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
 
-       snd_soc_write(codec, WM8580_DAC_CONTROL5, reg);
+       snd_soc_component_write(component, WM8580_DAC_CONTROL5, reg);
 
        return 0;
 }
 
-static int wm8580_set_bias_level(struct snd_soc_codec *codec,
+static int wm8580_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
        switch (level) {
@@ -830,20 +830,20 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Power up and get individual control of the DACs */
-                       snd_soc_update_bits(codec, WM8580_PWRDN1,
+                       snd_soc_component_update_bits(component, WM8580_PWRDN1,
                                            WM8580_PWRDN1_PWDN |
                                            WM8580_PWRDN1_ALLDACPD, 0);
 
                        /* Make VMID high impedance */
-                       snd_soc_update_bits(codec, WM8580_ADC_CONTROL1,
+                       snd_soc_component_update_bits(component, WM8580_ADC_CONTROL1,
                                            0x100, 0);
                }
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, WM8580_PWRDN1,
+               snd_soc_component_update_bits(component, WM8580_PWRDN1,
                                    WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);
                break;
        }
@@ -853,8 +853,8 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
 static int wm8580_playback_startup(struct snd_pcm_substream *substream,
                           struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 
        return snd_pcm_hw_constraint_minmax(substream->runtime,
                SNDRV_PCM_HW_PARAM_CHANNELS, 1, wm8580->drvdata->num_dacs * 2);
@@ -907,15 +907,15 @@ static struct snd_soc_dai_driver wm8580_dai[] = {
        },
 };
 
-static int wm8580_probe(struct snd_soc_codec *codec)
+static int wm8580_probe(struct snd_soc_component *component)
 {
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int ret = 0;
 
        switch (wm8580->drvdata->num_dacs) {
        case 4:
-               snd_soc_add_codec_controls(codec, wm8581_snd_controls,
+               snd_soc_add_component_controls(component, wm8581_snd_controls,
                                        ARRAY_SIZE(wm8581_snd_controls));
                snd_soc_dapm_new_controls(dapm, wm8581_dapm_widgets,
                                        ARRAY_SIZE(wm8581_dapm_widgets));
@@ -929,14 +929,14 @@ static int wm8580_probe(struct snd_soc_codec *codec)
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
                                    wm8580->supplies);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
                goto err_regulator_get;
        }
 
        /* Get the codec into a known state */
-       ret = snd_soc_write(codec, WM8580_RESET, 0);
+       ret = snd_soc_component_write(component, WM8580_RESET, 0);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
+               dev_err(component->dev, "Failed to reset component: %d\n", ret);
                goto err_regulator_enable;
        }
 
@@ -949,28 +949,27 @@ err_regulator_get:
 }
 
 /* power down chip */
-static int wm8580_remove(struct snd_soc_codec *codec)
+static void wm8580_remove(struct snd_soc_component *component)
 {
-       struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+       struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);
 
        regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
-       .probe =        wm8580_probe,
-       .remove =       wm8580_remove,
-       .set_bias_level = wm8580_set_bias_level,
-
-       .component_driver = {
-               .controls               = wm8580_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8580_snd_controls),
-               .dapm_widgets           = wm8580_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8580_dapm_widgets),
-               .dapm_routes            = wm8580_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8580_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8580 = {
+       .probe                  = wm8580_probe,
+       .remove                 = wm8580_remove,
+       .set_bias_level         = wm8580_set_bias_level,
+       .controls               = wm8580_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8580_snd_controls),
+       .dapm_widgets           = wm8580_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8580_dapm_widgets),
+       .dapm_routes            = wm8580_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8580_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config wm8580_regmap = {
@@ -1037,18 +1036,12 @@ static int wm8580_i2c_probe(struct i2c_client *i2c,
                return -EINVAL;
        }
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
 
        return ret;
 }
 
-static int wm8580_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8580_i2c_id[] = {
        { "wm8580", (kernel_ulong_t)&wm8580_data },
        { "wm8581", (kernel_ulong_t)&wm8581_data },
@@ -1062,7 +1055,6 @@ static struct i2c_driver wm8580_i2c_driver = {
                .of_match_table = wm8580_of_match,
        },
        .probe =    wm8580_i2c_probe,
-       .remove =   wm8580_i2c_remove,
        .id_table = wm8580_i2c_id,
 };
 
index 2b376c9c99afa94a85ce205a7550ebc2fd0c1994..1da08d281ae7d383da048631a0c96d4ecb3c97d5 100644 (file)
@@ -58,7 +58,7 @@ static bool wm8711_volatile(struct device *dev, unsigned int reg)
        }
 }
 
-#define wm8711_reset(c)        snd_soc_write(c, WM8711_RESET, 0)
+#define wm8711_reset(c)        snd_soc_component_write(c, WM8711_RESET, 0)
 
 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
 
@@ -159,14 +159,14 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8711_priv *wm8711 =  snd_soc_codec_get_drvdata(codec);
-       u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3;
+       struct snd_soc_component *component = dai->component;
+       struct wm8711_priv *wm8711 =  snd_soc_component_get_drvdata(component);
+       u16 iface = snd_soc_component_read32(component, WM8711_IFACE) & 0xfff3;
        int i = get_coeff(wm8711->sysclk, params_rate(params));
        u16 srate = (coeff_div[i].sr << 2) |
                (coeff_div[i].bosr << 1) | coeff_div[i].usb;
 
-       snd_soc_write(codec, WM8711_SRATE, srate);
+       snd_soc_component_write(component, WM8711_SRATE, srate);
 
        /* bit size */
        switch (params_width(params)) {
@@ -180,17 +180,17 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_write(codec, WM8711_IFACE, iface);
+       snd_soc_component_write(component, WM8711_IFACE, iface);
        return 0;
 }
 
 static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        /* set active */
-       snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
+       snd_soc_component_write(component, WM8711_ACTIVE, 0x0001);
 
        return 0;
 }
@@ -198,24 +198,24 @@ static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
 static void wm8711_shutdown(struct snd_pcm_substream *substream,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        /* deactivate */
-       if (!snd_soc_codec_is_active(codec)) {
+       if (!snd_soc_component_is_active(component)) {
                udelay(50);
-               snd_soc_write(codec, WM8711_ACTIVE, 0x0);
+               snd_soc_component_write(component, WM8711_ACTIVE, 0x0);
        }
 }
 
 static int wm8711_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8711_APDIGI) & 0xfff7;
 
        if (mute)
-               snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
+               snd_soc_component_write(component, WM8711_APDIGI, mute_reg | 0x8);
        else
-               snd_soc_write(codec, WM8711_APDIGI, mute_reg);
+               snd_soc_component_write(component, WM8711_APDIGI, mute_reg);
 
        return 0;
 }
@@ -223,8 +223,8 @@ static int wm8711_mute(struct snd_soc_dai *dai, int mute)
 static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8711_priv *wm8711 =  snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8711_priv *wm8711 =  snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case 11289600:
@@ -241,8 +241,8 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c;
+       struct snd_soc_component *component = codec_dai->component;
+       u16 iface = snd_soc_component_read32(component, WM8711_IFACE) & 0x000c;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -293,31 +293,31 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
        }
 
        /* set iface */
-       snd_soc_write(codec, WM8711_IFACE, iface);
+       snd_soc_component_write(component, WM8711_IFACE, iface);
        return 0;
 }
 
-static int wm8711_set_bias_level(struct snd_soc_codec *codec,
+static int wm8711_set_bias_level(struct snd_soc_component *component,
        enum snd_soc_bias_level level)
 {
-       struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
-       u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
+       struct wm8711_priv *wm8711 = snd_soc_component_get_drvdata(component);
+       u16 reg = snd_soc_component_read32(component, WM8711_PWR) & 0xff7f;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
-               snd_soc_write(codec, WM8711_PWR, reg);
+               snd_soc_component_write(component, WM8711_PWR, reg);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
                        regcache_sync(wm8711->regmap);
 
-               snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
+               snd_soc_component_write(component, WM8711_PWR, reg | 0x0040);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, WM8711_ACTIVE, 0x0);
-               snd_soc_write(codec, WM8711_PWR, 0xffff);
+               snd_soc_component_write(component, WM8711_ACTIVE, 0x0);
+               snd_soc_component_write(component, WM8711_PWR, 0xffff);
                break;
        }
        return 0;
@@ -349,37 +349,38 @@ static struct snd_soc_dai_driver wm8711_dai = {
        .ops = &wm8711_ops,
 };
 
-static int wm8711_probe(struct snd_soc_codec *codec)
+static int wm8711_probe(struct snd_soc_component *component)
 {
        int ret;
 
-       ret = wm8711_reset(codec);
+       ret = wm8711_reset(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
+               dev_err(component->dev, "Failed to issue reset\n");
                return ret;
        }
 
        /* Latch the update bits */
-       snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8711_LOUT1V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8711_ROUT1V, 0x0100, 0x0100);
 
        return ret;
 
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
-       .probe =        wm8711_probe,
-       .set_bias_level = wm8711_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8711_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8711_snd_controls),
-               .dapm_widgets           = wm8711_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8711_dapm_widgets),
-               .dapm_routes            = wm8711_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(wm8711_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8711 = {
+       .probe                  = wm8711_probe,
+       .set_bias_level         = wm8711_set_bias_level,
+       .controls               = wm8711_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8711_snd_controls),
+       .dapm_widgets           = wm8711_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8711_dapm_widgets),
+       .dapm_routes            = wm8711_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(wm8711_intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8711_of_match[] = {
@@ -417,26 +418,18 @@ static int wm8711_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8711);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_wm8711, &wm8711_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_wm8711, &wm8711_dai, 1);
 
        return ret;
 }
 
-static int wm8711_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-
-       return 0;
-}
-
 static struct spi_driver wm8711_spi_driver = {
        .driver = {
                .name   = "wm8711",
                .of_match_table = wm8711_of_match,
        },
        .probe          = wm8711_spi_probe,
-       .remove         = wm8711_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -458,18 +451,12 @@ static int wm8711_i2c_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, wm8711);
 
-       ret =  snd_soc_register_codec(&client->dev,
-                       &soc_codec_dev_wm8711, &wm8711_dai, 1);
+       ret = devm_snd_soc_register_component(&client->dev,
+                       &soc_component_dev_wm8711, &wm8711_dai, 1);
 
        return ret;
 }
 
-static int wm8711_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8711_i2c_id[] = {
        { "wm8711", 0 },
        { }
@@ -482,7 +469,6 @@ static struct i2c_driver wm8711_i2c_driver = {
                .of_match_table = wm8711_of_match,
        },
        .probe =    wm8711_i2c_probe,
-       .remove =   wm8711_i2c_remove,
        .id_table = wm8711_i2c_id,
 };
 #endif
index 7fde077a014be3f59af9d03ddbeaf22d048d91ab..087ec6db8cd015b7f19a0ed86e58f5894db6527a 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/ac97_codec.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
 
@@ -41,7 +40,6 @@ static const struct snd_soc_dapm_route wm8727_dapm_routes[] = {
                        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
                        SNDRV_PCM_RATE_192000)
 
-
 static struct snd_soc_dai_driver wm8727_dai = {
        .name = "wm8727-hifi",
        .playback = {
@@ -53,25 +51,21 @@ static struct snd_soc_dai_driver wm8727_dai = {
                },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8727 = {
-       .component_driver = {
-               .dapm_widgets           = wm8727_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8727_dapm_widgets),
-               .dapm_routes            = wm8727_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8727_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8727 = {
+       .dapm_widgets           = wm8727_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8727_dapm_widgets),
+       .dapm_routes            = wm8727_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8727_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm8727_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_wm8727, &wm8727_dai, 1);
-}
-
-static int wm8727_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm8727, &wm8727_dai, 1);
 }
 
 static struct platform_driver wm8727_codec_driver = {
@@ -80,7 +74,6 @@ static struct platform_driver wm8727_codec_driver = {
        },
 
        .probe = wm8727_probe,
-       .remove = wm8727_remove,
 };
 
 module_platform_driver(wm8727_codec_driver);
index 797cc6e7c70fee2fea6547e2e76efba9a5a17b78..839aee35ab56240b07bb6115ca74f3d116c75617 100644 (file)
@@ -74,13 +74,13 @@ static const struct snd_soc_dapm_route wm8728_intercon[] = {
 
 static int wm8728_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8728_DACCTL);
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8728_DACCTL);
 
        if (mute)
-               snd_soc_write(codec, WM8728_DACCTL, mute_reg | 1);
+               snd_soc_component_write(component, WM8728_DACCTL, mute_reg | 1);
        else
-               snd_soc_write(codec, WM8728_DACCTL, mute_reg & ~1);
+               snd_soc_component_write(component, WM8728_DACCTL, mute_reg & ~1);
 
        return 0;
 }
@@ -89,8 +89,8 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 dac = snd_soc_read(codec, WM8728_DACCTL);
+       struct snd_soc_component *component = dai->component;
+       u16 dac = snd_soc_component_read32(component, WM8728_DACCTL);
 
        dac &= ~0x18;
 
@@ -107,7 +107,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8728_DACCTL, dac);
+       snd_soc_component_write(component, WM8728_DACCTL, dac);
 
        return 0;
 }
@@ -115,8 +115,8 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
 static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 iface = snd_soc_read(codec, WM8728_IFCTL);
+       struct snd_soc_component *component = codec_dai->component;
+       u16 iface = snd_soc_component_read32(component, WM8728_IFCTL);
 
        /* Currently only I2S is supported by the driver, though the
         * hardware is more flexible.
@@ -156,24 +156,24 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8728_IFCTL, iface);
+       snd_soc_component_write(component, WM8728_IFCTL, iface);
        return 0;
 }
 
-static int wm8728_set_bias_level(struct snd_soc_codec *codec,
+static int wm8728_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
+       struct wm8728_priv *wm8728 = snd_soc_component_get_drvdata(component);
        u16 reg;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* Power everything up... */
-                       reg = snd_soc_read(codec, WM8728_DACCTL);
-                       snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
+                       reg = snd_soc_component_read32(component, WM8728_DACCTL);
+                       snd_soc_component_write(component, WM8728_DACCTL, reg & ~0x4);
 
                        /* ..then sync in the register cache. */
                        regcache_sync(wm8728->regmap);
@@ -181,8 +181,8 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               reg = snd_soc_read(codec, WM8728_DACCTL);
-               snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
+               reg = snd_soc_component_read32(component, WM8728_DACCTL);
+               snd_soc_component_write(component, WM8728_DACCTL, reg | 0x4);
                break;
        }
        return 0;
@@ -211,18 +211,19 @@ static struct snd_soc_dai_driver wm8728_dai = {
        .ops = &wm8728_dai_ops,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
-       .set_bias_level = wm8728_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8728_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8728_snd_controls),
-               .dapm_widgets           = wm8728_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8728_dapm_widgets),
-               .dapm_routes            = wm8728_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(wm8728_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8728 = {
+       .set_bias_level         = wm8728_set_bias_level,
+       .controls               = wm8728_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8728_snd_controls),
+       .dapm_widgets           = wm8728_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8728_dapm_widgets),
+       .dapm_routes            = wm8728_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(wm8728_intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8728_of_match[] = {
@@ -258,26 +259,18 @@ static int wm8728_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8728);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_wm8728, &wm8728_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_wm8728, &wm8728_dai, 1);
 
        return ret;
 }
 
-static int wm8728_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-
-       return 0;
-}
-
 static struct spi_driver wm8728_spi_driver = {
        .driver = {
                .name   = "wm8728",
                .of_match_table = wm8728_of_match,
        },
        .probe          = wm8728_spi_probe,
-       .remove         = wm8728_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -299,18 +292,12 @@ static int wm8728_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm8728);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8728, &wm8728_dai, 1);
+       ret =  devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_wm8728, &wm8728_dai, 1);
 
        return ret;
 }
 
-static int wm8728_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8728_i2c_id[] = {
        { "wm8728", 0 },
        { }
@@ -323,7 +310,6 @@ static struct i2c_driver wm8728_i2c_driver = {
                .of_match_table = wm8728_of_match,
        },
        .probe =    wm8728_i2c_probe,
-       .remove =   wm8728_i2c_remove,
        .id_table = wm8728_i2c_id,
 };
 #endif
index 4f9a1eb281204ba3d88380f914658e1b94c57ecf..7c8fad865d6b00c039a46ad34801893b497b4e2c 100644 (file)
@@ -88,9 +88,9 @@ static SOC_ENUM_SINGLE_DECL(wm8731_insel_enum,
 
 static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
 
-static int wm8731_set_deemph(struct snd_soc_codec *codec)
+static int wm8731_set_deemph(struct snd_soc_component *component)
 {
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
        int val, i, best;
 
        /* If we're using deemphasis select the nearest available sample
@@ -110,17 +110,17 @@ static int wm8731_set_deemph(struct snd_soc_codec *codec)
                val = 0;
        }
 
-       dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
+       dev_dbg(component->dev, "Set deemphasis %d (%dHz)\n",
                best, wm8731_deemph[best]);
 
-       return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
+       return snd_soc_component_update_bits(component, WM8731_APDIGI, 0x6, val);
 }
 
 static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = wm8731->deemph;
 
@@ -130,8 +130,8 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
 static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
        unsigned int deemph = ucontrol->value.integer.value[0];
        int ret = 0;
 
@@ -142,7 +142,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
        if (wm8731->deemph != deemph) {
                wm8731->deemph = deemph;
 
-               wm8731_set_deemph(codec);
+               wm8731_set_deemph(component);
 
                ret = 1;
        }
@@ -214,8 +214,8 @@ SND_SOC_DAPM_INPUT("LLINEIN"),
 static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
                            struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 
        return wm8731->sysclk_type == WM8731_SYSCLK_XTAL;
 }
@@ -337,16 +337,16 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
-       u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
+       struct snd_soc_component *component = dai->component;
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
+       u16 iface = snd_soc_component_read32(component, WM8731_IFACE) & 0xfff3;
        int i = get_coeff(wm8731->sysclk, params_rate(params));
        u16 srate = (coeff_div[i].sr << 2) |
                (coeff_div[i].bosr << 1) | coeff_div[i].usb;
 
        wm8731->playback_fs = params_rate(params);
 
-       snd_soc_write(codec, WM8731_SRATE, srate);
+       snd_soc_component_write(component, WM8731_SRATE, srate);
 
        /* bit size */
        switch (params_width(params)) {
@@ -363,30 +363,30 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       wm8731_set_deemph(codec);
+       wm8731_set_deemph(component);
 
-       snd_soc_write(codec, WM8731_IFACE, iface);
+       snd_soc_component_write(component, WM8731_IFACE, iface);
        return 0;
 }
 
 static int wm8731_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8731_APDIGI) & 0xfff7;
 
        if (mute)
-               snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
+               snd_soc_component_write(component, WM8731_APDIGI, mute_reg | 0x8);
        else
-               snd_soc_write(codec, WM8731_APDIGI, mute_reg);
+               snd_soc_component_write(component, WM8731_APDIGI, mute_reg);
        return 0;
 }
 
 static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
 
        switch (clk_id) {
        case WM8731_SYSCLK_XTAL:
@@ -429,7 +429,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 iface = 0;
 
        /* set master/slave audio interface */
@@ -481,14 +481,14 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
        }
 
        /* set iface */
-       snd_soc_write(codec, WM8731_IFACE, iface);
+       snd_soc_component_write(component, WM8731_IFACE, iface);
        return 0;
 }
 
-static int wm8731_set_bias_level(struct snd_soc_codec *codec,
+static int wm8731_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
        int ret;
        u16 reg;
 
@@ -503,7 +503,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
                                                    wm8731->supplies);
                        if (ret != 0)
@@ -513,13 +513,13 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
                }
 
                /* Clear PWROFF, gate CLKOUT, everything else as-is */
-               reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
-               snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
+               reg = snd_soc_component_read32(component, WM8731_PWR) & 0xff7f;
+               snd_soc_component_write(component, WM8731_PWR, reg | 0x0040);
                break;
        case SND_SOC_BIAS_OFF:
                if (wm8731->mclk)
                        clk_disable_unprepare(wm8731->mclk);
-               snd_soc_write(codec, WM8731_PWR, 0xffff);
+               snd_soc_component_write(component, WM8731_PWR, 0xffff);
                regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
                                       wm8731->supplies);
                regcache_mark_dirty(wm8731->regmap);
@@ -531,7 +531,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 static int wm8731_startup(struct snd_pcm_substream *substream,
        struct snd_soc_dai *dai)
 {
-       struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(dai->codec);
+       struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(dai->component);
 
        if (wm8731->constraints)
                snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -628,18 +628,19 @@ err_regulator_enable:
        return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
-       .set_bias_level = wm8731_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8731_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8731_snd_controls),
-               .dapm_widgets           = wm8731_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8731_dapm_widgets),
-               .dapm_routes            = wm8731_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(wm8731_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8731 = {
+       .set_bias_level         = wm8731_set_bias_level,
+       .controls               = wm8731_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8731_snd_controls),
+       .dapm_widgets           = wm8731_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8731_dapm_widgets),
+       .dapm_routes            = wm8731_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(wm8731_intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8731_of_match[] = {
@@ -704,8 +705,8 @@ static int wm8731_spi_probe(struct spi_device *spi)
        if (ret != 0)
                return ret;
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_wm8731, &wm8731_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_wm8731, &wm8731_dai, 1);
        if (ret != 0) {
                dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
                return ret;
@@ -716,7 +717,6 @@ static int wm8731_spi_probe(struct spi_device *spi)
 
 static int wm8731_spi_remove(struct spi_device *spi)
 {
-       snd_soc_unregister_codec(&spi->dev);
        return 0;
 }
 
@@ -775,8 +775,8 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
        if (ret != 0)
                return ret;
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8731, &wm8731_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_wm8731, &wm8731_dai, 1);
        if (ret != 0) {
                dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
                return ret;
@@ -787,7 +787,6 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
 
 static int wm8731_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
        return 0;
 }
 
index f0cb1c4afe3cec6429038af5eaee5e892c478917..e9ae821e76098907aa3da856b0aaa39a656203b8 100644 (file)
@@ -74,9 +74,9 @@ static bool wm8737_volatile(struct device *dev, unsigned int reg)
        }
 }
 
-static int wm8737_reset(struct snd_soc_codec *codec)
+static int wm8737_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, WM8737_RESET, 0);
+       return snd_soc_component_write(component, WM8737_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_RANGE(micboost_tlv,
@@ -328,8 +328,8 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
        int i;
        u16 clocking = 0;
        u16 af = 0;
@@ -348,7 +348,7 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (i == ARRAY_SIZE(coeff_div)) {
-               dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
+               dev_err(component->dev, "%dHz MCLK can't support %dHz\n",
                        wm8737->mclk, params_rate(params));
                return -EINVAL;
        }
@@ -371,8 +371,8 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
-       snd_soc_update_bits(codec, WM8737_CLOCKING,
+       snd_soc_component_update_bits(component, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
+       snd_soc_component_update_bits(component, WM8737_CLOCKING,
                            WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
                            clocking);
 
@@ -382,8 +382,8 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
 static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                 int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
@@ -394,7 +394,7 @@ static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                }
        }
 
-       dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
+       dev_err(component->dev, "MCLK rate %dHz not supported\n", freq);
 
        return -EINVAL;
 }
@@ -403,7 +403,7 @@ static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 af = 0;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -445,16 +445,16 @@ static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
+       snd_soc_component_update_bits(component, WM8737_AUDIO_FORMAT,
                            WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
 
        return 0;
 }
 
-static int wm8737_set_bias_level(struct snd_soc_codec *codec,
+static int wm8737_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+       struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
        int ret;
 
        switch (level) {
@@ -463,16 +463,16 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_PREPARE:
                /* VMID at 2*75k */
-               snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+               snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL,
                                    WM8737_VMIDSEL_MASK, 0);
                break;
 
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
                                                    wm8737->supplies);
                        if (ret != 0) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to enable supplies: %d\n",
                                        ret);
                                return ret;
@@ -481,12 +481,12 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
                        regcache_sync(wm8737->regmap);
 
                        /* Fast VMID ramp at 2*2.5k */
-                       snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+                       snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL,
                                            WM8737_VMIDSEL_MASK,
                                            2 << WM8737_VMIDSEL_SHIFT);
 
                        /* Bring VMID up */
-                       snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+                       snd_soc_component_update_bits(component, WM8737_POWER_MANAGEMENT,
                                            WM8737_VMID_MASK |
                                            WM8737_VREF_MASK,
                                            WM8737_VMID_MASK |
@@ -496,14 +496,14 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
                }
 
                /* VMID at 2*300k */
-               snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
+               snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL,
                                    WM8737_VMIDSEL_MASK,
                                    1 << WM8737_VMIDSEL_SHIFT);
 
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
+               snd_soc_component_update_bits(component, WM8737_POWER_MANAGEMENT,
                                    WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
 
                regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
@@ -537,30 +537,30 @@ static struct snd_soc_dai_driver wm8737_dai = {
        .ops = &wm8737_dai_ops,
 };
 
-static int wm8737_probe(struct snd_soc_codec *codec)
+static int wm8737_probe(struct snd_soc_component *component)
 {
-       struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
+       struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
                                    wm8737->supplies);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
                goto err_get;
        }
 
-       ret = wm8737_reset(codec);
+       ret = wm8737_reset(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
+               dev_err(component->dev, "Failed to issue reset\n");
                goto err_enable;
        }
 
-       snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
+       snd_soc_component_update_bits(component, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
                            WM8737_LVU);
-       snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
+       snd_soc_component_update_bits(component, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
                            WM8737_RVU);
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
@@ -573,19 +573,20 @@ err_get:
        return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
-       .probe          = wm8737_probe,
-       .set_bias_level = wm8737_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8737_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8737_snd_controls),
-               .dapm_widgets           = wm8737_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8737_dapm_widgets),
-               .dapm_routes            = intercon,
-               .num_dapm_routes        = ARRAY_SIZE(intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8737 = {
+       .probe                  = wm8737_probe,
+       .set_bias_level         = wm8737_set_bias_level,
+       .controls               = wm8737_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8737_snd_controls),
+       .dapm_widgets           = wm8737_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8737_dapm_widgets),
+       .dapm_routes            = intercon,
+       .num_dapm_routes        = ARRAY_SIZE(intercon),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8737_of_match[] = {
@@ -635,20 +636,13 @@ static int wm8737_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm8737);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                                     &soc_codec_dev_wm8737, &wm8737_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                               &soc_component_dev_wm8737, &wm8737_dai, 1);
 
        return ret;
 
 }
 
-static int wm8737_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-
-       return 0;
-}
-
 static const struct i2c_device_id wm8737_i2c_id[] = {
        { "wm8737", 0 },
        { }
@@ -661,7 +655,6 @@ static struct i2c_driver wm8737_i2c_driver = {
                .of_match_table = wm8737_of_match,
        },
        .probe =    wm8737_i2c_probe,
-       .remove =   wm8737_i2c_remove,
        .id_table = wm8737_i2c_id,
 };
 #endif
@@ -693,26 +686,18 @@ static int wm8737_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8737);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                                    &soc_codec_dev_wm8737, &wm8737_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                               &soc_component_dev_wm8737, &wm8737_dai, 1);
 
        return ret;
 }
 
-static int wm8737_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-
-       return 0;
-}
-
 static struct spi_driver wm8737_spi_driver = {
        .driver = {
                .name   = "wm8737",
                .of_match_table = wm8737_of_match,
        },
        .probe          = wm8737_spi_probe,
-       .remove         = wm8737_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
index a394dbee77aa39faf3d1ff157d59dc13ff4b8b90..1fedf74da70501e70641abd2faeacbcfeb4b23ee 100644 (file)
@@ -59,9 +59,9 @@ static const struct reg_default wm8741_reg_defaults[] = {
        { 32, 0x0002 },     /* R32 - ADDITONAL_CONTROL_1 */
 };
 
-static int wm8741_reset(struct snd_soc_codec *codec)
+static int wm8741_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, WM8741_RESET, 0);
+       return snd_soc_component_write(component, WM8741_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);
@@ -179,8 +179,8 @@ static const struct snd_pcm_hw_constraint_list constraints_36864 = {
 static int wm8741_startup(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
        if (wm8741->sysclk)
                snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -194,8 +194,8 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
        unsigned int iface;
        int i;
 
@@ -203,7 +203,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
         * MCLK supplied to the CODEC - enforce this.
         */
        if (!wm8741->sysclk) {
-               dev_err(codec->dev,
+               dev_err(component->dev,
                        "No MCLK configured, call set_sysclk() on init or in hw_params\n");
                return -EINVAL;
        }
@@ -215,7 +215,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (i == wm8741->sysclk_constraints->count) {
-               dev_err(codec->dev, "LRCLK %d unsupported with MCLK %d\n",
+               dev_err(component->dev, "LRCLK %d unsupported with MCLK %d\n",
                        params_rate(params), wm8741->sysclk);
                return -EINVAL;
        }
@@ -235,15 +235,15 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
                iface = 0x3;
                break;
        default:
-               dev_dbg(codec->dev, "wm8741_hw_params:    Unsupported bit size param = %d",
+               dev_dbg(component->dev, "wm8741_hw_params:    Unsupported bit size param = %d",
                        params_width(params));
                return -EINVAL;
        }
 
-       dev_dbg(codec->dev, "wm8741_hw_params:    bit size param = %d, rate param = %d",
+       dev_dbg(component->dev, "wm8741_hw_params:    bit size param = %d, rate param = %d",
                params_width(params), params_rate(params));
 
-       snd_soc_update_bits(codec, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,
+       snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,
                            iface);
 
        return 0;
@@ -252,10 +252,10 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
 static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
-       dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
+       dev_dbg(component->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
 
        switch (freq) {
        case 0:
@@ -297,7 +297,7 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        unsigned int iface;
 
        /* check master/slave audio interface */
@@ -347,11 +347,11 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
        }
 
 
-       dev_dbg(codec->dev, "wm8741_set_dai_fmt:    Format=%x, Clock Inv=%x\n",
+       dev_dbg(component->dev, "wm8741_set_dai_fmt:    Format=%x, Clock Inv=%x\n",
                                fmt & SND_SOC_DAIFMT_FORMAT_MASK,
                                ((fmt & SND_SOC_DAIFMT_INV_MASK)));
 
-       snd_soc_update_bits(codec, WM8741_FORMAT_CONTROL,
+       snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL,
                            WM8741_BCP_MASK | WM8741_LRP_MASK | WM8741_FMT_MASK,
                            iface);
 
@@ -386,18 +386,18 @@ static struct snd_soc_dai_driver wm8741_dai = {
 };
 
 #ifdef CONFIG_PM
-static int wm8741_resume(struct snd_soc_codec *codec)
+static int wm8741_resume(struct snd_soc_component *component)
 {
-       snd_soc_cache_sync(codec);
+       snd_soc_component_cache_sync(component);
        return 0;
 }
 #else
 #define wm8741_resume NULL
 #endif
 
-static int wm8741_configure(struct snd_soc_codec *codec)
+static int wm8741_configure(struct snd_soc_component *component)
 {
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
        /* Configure differential mode */
        switch (wm8741->pdata.diff_mode) {
@@ -405,7 +405,7 @@ static int wm8741_configure(struct snd_soc_codec *codec)
        case WM8741_DIFF_MODE_STEREO_REVERSED:
        case WM8741_DIFF_MODE_MONO_LEFT:
        case WM8741_DIFF_MODE_MONO_RIGHT:
-               snd_soc_update_bits(codec, WM8741_MODE_CONTROL_2,
+               snd_soc_component_update_bits(component, WM8741_MODE_CONTROL_2,
                                WM8741_DIFF_MASK,
                                wm8741->pdata.diff_mode << WM8741_DIFF_SHIFT);
                break;
@@ -414,36 +414,36 @@ static int wm8741_configure(struct snd_soc_codec *codec)
        }
 
        /* Change some default settings - latch VU */
-       snd_soc_update_bits(codec, WM8741_DACLLSB_ATTENUATION,
+       snd_soc_component_update_bits(component, WM8741_DACLLSB_ATTENUATION,
                        WM8741_UPDATELL, WM8741_UPDATELL);
-       snd_soc_update_bits(codec, WM8741_DACLMSB_ATTENUATION,
+       snd_soc_component_update_bits(component, WM8741_DACLMSB_ATTENUATION,
                        WM8741_UPDATELM, WM8741_UPDATELM);
-       snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
+       snd_soc_component_update_bits(component, WM8741_DACRLSB_ATTENUATION,
                        WM8741_UPDATERL, WM8741_UPDATERL);
-       snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION,
+       snd_soc_component_update_bits(component, WM8741_DACRMSB_ATTENUATION,
                        WM8741_UPDATERM, WM8741_UPDATERM);
 
        return 0;
 }
 
-static int wm8741_add_controls(struct snd_soc_codec *codec)
+static int wm8741_add_controls(struct snd_soc_component *component)
 {
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
        switch (wm8741->pdata.diff_mode) {
        case WM8741_DIFF_MODE_STEREO:
        case WM8741_DIFF_MODE_STEREO_REVERSED:
-               snd_soc_add_codec_controls(codec,
+               snd_soc_add_component_controls(component,
                                wm8741_snd_controls_stereo,
                                ARRAY_SIZE(wm8741_snd_controls_stereo));
                break;
        case WM8741_DIFF_MODE_MONO_LEFT:
-               snd_soc_add_codec_controls(codec,
+               snd_soc_add_component_controls(component,
                                wm8741_snd_controls_mono_left,
                                ARRAY_SIZE(wm8741_snd_controls_mono_left));
                break;
        case WM8741_DIFF_MODE_MONO_RIGHT:
-               snd_soc_add_codec_controls(codec,
+               snd_soc_add_component_controls(component,
                                wm8741_snd_controls_mono_right,
                                ARRAY_SIZE(wm8741_snd_controls_mono_right));
                break;
@@ -454,37 +454,37 @@ static int wm8741_add_controls(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int wm8741_probe(struct snd_soc_codec *codec)
+static int wm8741_probe(struct snd_soc_component *component)
 {
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
                                    wm8741->supplies);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
                goto err_get;
        }
 
-       ret = wm8741_reset(codec);
+       ret = wm8741_reset(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
+               dev_err(component->dev, "Failed to issue reset\n");
                goto err_enable;
        }
 
-       ret = wm8741_configure(codec);
+       ret = wm8741_configure(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to change default settings\n");
+               dev_err(component->dev, "Failed to change default settings\n");
                goto err_enable;
        }
 
-       ret = wm8741_add_controls(codec);
+       ret = wm8741_add_controls(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to add controls\n");
+               dev_err(component->dev, "Failed to add controls\n");
                goto err_enable;
        }
 
-       dev_dbg(codec->dev, "Successful registration\n");
+       dev_dbg(component->dev, "Successful registration\n");
        return ret;
 
 err_enable:
@@ -493,26 +493,25 @@ err_get:
        return ret;
 }
 
-static int wm8741_remove(struct snd_soc_codec *codec)
+static void wm8741_remove(struct snd_soc_component *component)
 {
-       struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+       struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 
        regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
-       .probe =        wm8741_probe,
-       .remove =       wm8741_remove,
-       .resume =       wm8741_resume,
-
-       .component_driver = {
-               .dapm_widgets           = wm8741_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8741_dapm_widgets),
-               .dapm_routes            = wm8741_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8741_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8741 = {
+       .probe                  = wm8741_probe,
+       .remove                 = wm8741_remove,
+       .resume                 = wm8741_resume,
+       .dapm_widgets           = wm8741_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8741_dapm_widgets),
+       .dapm_routes            = wm8741_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8741_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8741_of_match[] = {
@@ -585,18 +584,12 @@ static int wm8741_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm8741);
 
-       ret = snd_soc_register_codec(&i2c->dev,
-                                    &soc_codec_dev_wm8741, &wm8741_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                                    &soc_component_dev_wm8741, &wm8741_dai, 1);
 
        return ret;
 }
 
-static int wm8741_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8741_i2c_id[] = {
        { "wm8741", 0 },
        { }
@@ -609,7 +602,6 @@ static struct i2c_driver wm8741_i2c_driver = {
                .of_match_table = wm8741_of_match,
        },
        .probe =    wm8741_i2c_probe,
-       .remove =   wm8741_i2c_remove,
        .id_table = wm8741_i2c_id,
 };
 #endif
@@ -650,24 +642,17 @@ static int wm8741_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8741);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_wm8741, &wm8741_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_wm8741, &wm8741_dai, 1);
        return ret;
 }
 
-static int wm8741_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver wm8741_spi_driver = {
        .driver = {
                .name   = "wm8741",
                .of_match_table = wm8741_of_match,
        },
        .probe          = wm8741_spi_probe,
-       .remove         = wm8741_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
index 0da2bbaf06d1f33e89b48497865d477d58696e1c..97239bc9d253f42acddbccc871dde70ce99c86c6 100644 (file)
@@ -86,7 +86,7 @@ struct wm8750_priv {
        unsigned int sysclk;
 };
 
-#define wm8750_reset(c)        snd_soc_write(c, WM8750_RESET, 0)
+#define wm8750_reset(c)        snd_soc_component_write(c, WM8750_RESET, 0)
 
 /*
  * WM8750 Controls
@@ -502,8 +502,8 @@ static inline int get_coeff(int mclk, int rate)
 static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8750_priv *wm8750 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case 11289600:
@@ -520,7 +520,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 iface = 0;
 
        /* set master/slave audio interface */
@@ -571,7 +571,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8750_IFACE, iface);
+       snd_soc_component_write(component, WM8750_IFACE, iface);
        return 0;
 }
 
@@ -579,10 +579,10 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
-       u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
-       u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
+       struct snd_soc_component *component = dai->component;
+       struct wm8750_priv *wm8750 = snd_soc_component_get_drvdata(component);
+       u16 iface = snd_soc_component_read32(component, WM8750_IFACE) & 0x1f3;
+       u16 srate = snd_soc_component_read32(component, WM8750_SRATE) & 0x1c0;
        int coeff = get_coeff(wm8750->sysclk, params_rate(params));
 
        /* bit size */
@@ -601,9 +601,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* set iface & srate */
-       snd_soc_write(codec, WM8750_IFACE, iface);
+       snd_soc_component_write(component, WM8750_IFACE, iface);
        if (coeff >= 0)
-               snd_soc_write(codec, WM8750_SRATE, srate |
+               snd_soc_component_write(component, WM8750_SRATE, srate |
                        (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
 
        return 0;
@@ -611,44 +611,44 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int wm8750_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8750_ADCDAC) & 0xfff7;
 
        if (mute)
-               snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
+               snd_soc_component_write(component, WM8750_ADCDAC, mute_reg | 0x8);
        else
-               snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
+               snd_soc_component_write(component, WM8750_ADCDAC, mute_reg);
        return 0;
 }
 
-static int wm8750_set_bias_level(struct snd_soc_codec *codec,
+static int wm8750_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
+       u16 pwr_reg = snd_soc_component_read32(component, WM8750_PWR1) & 0xfe3e;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                /* set vmid to 50k and unmute dac */
-               snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
+               snd_soc_component_write(component, WM8750_PWR1, pwr_reg | 0x00c0);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
-                       snd_soc_cache_sync(codec);
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
+                       snd_soc_component_cache_sync(component);
 
                        /* Set VMID to 5k */
-                       snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
+                       snd_soc_component_write(component, WM8750_PWR1, pwr_reg | 0x01c1);
 
                        /* ...and ramp */
                        msleep(1000);
                }
 
                /* mute dac and set vmid to 500k, enable VREF */
-               snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
+               snd_soc_component_write(component, WM8750_PWR1, pwr_reg | 0x0141);
                break;
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, WM8750_PWR1, 0x0001);
+               snd_soc_component_write(component, WM8750_PWR1, 0x0001);
                break;
        }
        return 0;
@@ -685,42 +685,43 @@ static struct snd_soc_dai_driver wm8750_dai = {
        .ops = &wm8750_dai_ops,
 };
 
-static int wm8750_probe(struct snd_soc_codec *codec)
+static int wm8750_probe(struct snd_soc_component *component)
 {
        int ret;
 
-       ret = wm8750_reset(codec);
+       ret = wm8750_reset(component);
        if (ret < 0) {
                printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
                return ret;
        }
 
        /* set the update bits */
-       snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_LDAC, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_RDAC, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_LOUT1V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_ROUT1V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_LOUT2V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_ROUT2V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_LINVOL, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8750_RINVOL, 0x0100, 0x0100);
 
        return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
-       .probe =        wm8750_probe,
-       .set_bias_level = wm8750_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8750_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8750_snd_controls),
-               .dapm_widgets           = wm8750_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8750_dapm_widgets),
-               .dapm_routes            = wm8750_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8750_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8750 = {
+       .probe                  = wm8750_probe,
+       .set_bias_level         = wm8750_set_bias_level,
+       .controls               = wm8750_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8750_snd_controls),
+       .dapm_widgets           = wm8750_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8750_dapm_widgets),
+       .dapm_routes            = wm8750_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8750_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8750_of_match[] = {
@@ -758,17 +759,11 @@ static int wm8750_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8750);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                       &soc_codec_dev_wm8750, &wm8750_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                       &soc_component_dev_wm8750, &wm8750_dai, 1);
        return ret;
 }
 
-static int wm8750_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static const struct spi_device_id wm8750_spi_ids[] = {
        { "wm8750", 0 },
        { "wm8987", 0 },
@@ -783,7 +778,6 @@ static struct spi_driver wm8750_spi_driver = {
        },
        .id_table       = wm8750_spi_ids,
        .probe          = wm8750_spi_probe,
-       .remove         = wm8750_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -806,17 +800,11 @@ static int wm8750_i2c_probe(struct i2c_client *i2c,
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
-       ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_wm8750, &wm8750_dai, 1);
+       ret = devm_snd_soc_register_component(&i2c->dev,
+                       &soc_component_dev_wm8750, &wm8750_dai, 1);
        return ret;
 }
 
-static int wm8750_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8750_i2c_id[] = {
        { "wm8750", 0 },
        { "wm8987", 0 },
@@ -830,7 +818,6 @@ static struct i2c_driver wm8750_i2c_driver = {
                .of_match_table = wm8750_of_match,
        },
        .probe =    wm8750_i2c_probe,
-       .remove =   wm8750_i2c_remove,
        .id_table = wm8750_i2c_id,
 };
 #endif
index 0271a5253bd3edf9df189e4e0b31c6bf35eb6fe4..1e2823e2a906e023bdf8366d6171bf5405c6a095 100644 (file)
@@ -55,9 +55,9 @@ static int caps_charge = 2000;
 module_param(caps_charge, int, 0);
 MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
 
-static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_hifi_write_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt);
-static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_voice_write_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt);
 
 /*
@@ -150,7 +150,7 @@ struct wm8753_priv {
        struct delayed_work charge_work;
 };
 
-#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
+#define wm8753_reset(c) snd_soc_component_write(c, WM8753_RESET, 0)
 
 /*
  * WM8753 Controls
@@ -229,8 +229,8 @@ SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase),
 static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.enumerated.item[0] = wm8753->dai_func;
        return 0;
@@ -239,17 +239,17 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
 static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
        u16 ioctl;
 
        if (wm8753->dai_func == ucontrol->value.enumerated.item[0])
                return 0;
 
-       if (snd_soc_codec_is_active(codec))
+       if (snd_soc_component_is_active(component))
                return -EBUSY;
 
-       ioctl = snd_soc_read(codec, WM8753_IOCTL);
+       ioctl = snd_soc_component_read32(component, WM8753_IOCTL);
 
        wm8753->dai_func = ucontrol->value.enumerated.item[0];
 
@@ -257,11 +257,11 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
                return 1;
 
        ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
-       snd_soc_write(codec, WM8753_IOCTL, ioctl);
+       snd_soc_component_write(component, WM8753_IOCTL, ioctl);
 
 
-       wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
-       wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
+       wm8753_hifi_write_dai_fmt(component, wm8753->hifi_fmt);
+       wm8753_voice_write_dai_fmt(component, wm8753->voice_fmt);
 
        return 1;
 }
@@ -745,7 +745,7 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 {
        u16 reg, enable;
        int offset;
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
                return -ENODEV;
@@ -753,17 +753,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        if (pll_id == WM8753_PLL1) {
                offset = 0;
                enable = 0x10;
-               reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
+               reg = snd_soc_component_read32(component, WM8753_CLOCK) & 0xffef;
        } else {
                offset = 4;
                enable = 0x8;
-               reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
+               reg = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfff7;
        }
 
        if (!freq_in || !freq_out) {
                /* disable PLL  */
-               snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
-               snd_soc_write(codec, WM8753_CLOCK, reg);
+               snd_soc_component_write(component, WM8753_PLL1CTL1 + offset, 0x0026);
+               snd_soc_component_write(component, WM8753_CLOCK, reg);
                return 0;
        } else {
                u16 value = 0;
@@ -774,20 +774,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                /* set up N and K PLL divisor ratios */
                /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
                value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
-               snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
+               snd_soc_component_write(component, WM8753_PLL1CTL2 + offset, value);
 
                /* bits 8:0 = PLL_K[17:9] */
                value = (pll_div.k & 0x03fe00) >> 9;
-               snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
+               snd_soc_component_write(component, WM8753_PLL1CTL3 + offset, value);
 
                /* bits 8:0 = PLL_K[8:0] */
                value = pll_div.k & 0x0001ff;
-               snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
+               snd_soc_component_write(component, WM8753_PLL1CTL4 + offset, value);
 
                /* set PLL as input and enable */
-               snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+               snd_soc_component_write(component, WM8753_PLL1CTL1 + offset, 0x0027 |
                        (pll_div.div2 << 3));
-               snd_soc_write(codec, WM8753_CLOCK, reg | enable);
+               snd_soc_component_write(component, WM8753_CLOCK, reg | enable);
        }
        return 0;
 }
@@ -866,8 +866,8 @@ static int get_coeff(int mclk, int rate)
 static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
        switch (freq) {
        case 11289600:
@@ -890,10 +890,10 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 /*
  * Set's ADC and Voice DAC format.
  */
-static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
-       u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
+       u16 voice = snd_soc_component_read32(component, WM8753_PCM) & 0x01ec;
 
        /* interface format */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -915,7 +915,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8753_PCM, voice);
+       snd_soc_component_write(component, WM8753_PCM, voice);
        return 0;
 }
 
@@ -926,10 +926,10 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-       u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
-       u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
+       struct snd_soc_component *component = dai->component;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
+       u16 voice = snd_soc_component_read32(component, WM8753_PCM) & 0x01f3;
+       u16 srate = snd_soc_component_read32(component, WM8753_SRATE1) & 0x017f;
 
        /* bit size */
        switch (params_width(params)) {
@@ -949,22 +949,22 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
        /* sample rate */
        if (params_rate(params) * 384 == wm8753->pcmclk)
                srate |= 0x80;
-       snd_soc_write(codec, WM8753_SRATE1, srate);
+       snd_soc_component_write(component, WM8753_SRATE1, srate);
 
-       snd_soc_write(codec, WM8753_PCM, voice);
+       snd_soc_component_write(component, WM8753_PCM, voice);
        return 0;
 }
 
 /*
  * Set's PCM dai fmt and BCLK.
  */
-static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_pcm_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
        u16 voice, ioctl;
 
-       voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
-       ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
+       voice = snd_soc_component_read32(component, WM8753_PCM) & 0x011f;
+       ioctl = snd_soc_component_read32(component, WM8753_IOCTL) & 0x015d;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1018,29 +1018,29 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8753_PCM, voice);
-       snd_soc_write(codec, WM8753_IOCTL, ioctl);
+       snd_soc_component_write(component, WM8753_PCM, voice);
+       snd_soc_component_write(component, WM8753_IOCTL, ioctl);
        return 0;
 }
 
 static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                int div_id, int div)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        u16 reg;
 
        switch (div_id) {
        case WM8753_PCMDIV:
-               reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
-               snd_soc_write(codec, WM8753_CLOCK, reg | div);
+               reg = snd_soc_component_read32(component, WM8753_CLOCK) & 0x003f;
+               snd_soc_component_write(component, WM8753_CLOCK, reg | div);
                break;
        case WM8753_BCLKDIV:
-               reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
-               snd_soc_write(codec, WM8753_SRATE2, reg | div);
+               reg = snd_soc_component_read32(component, WM8753_SRATE2) & 0x01c7;
+               snd_soc_component_write(component, WM8753_SRATE2, reg | div);
                break;
        case WM8753_VXCLKDIV:
-               reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
-               snd_soc_write(codec, WM8753_SRATE2, reg | div);
+               reg = snd_soc_component_read32(component, WM8753_SRATE2) & 0x003f;
+               snd_soc_component_write(component, WM8753_SRATE2, reg | div);
                break;
        default:
                return -EINVAL;
@@ -1051,10 +1051,10 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 /*
  * Set's HiFi DAC format.
  */
-static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_hdac_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
-       u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
+       u16 hifi = snd_soc_component_read32(component, WM8753_HIFI) & 0x01e0;
 
        /* interface format */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1076,20 +1076,20 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8753_HIFI, hifi);
+       snd_soc_component_write(component, WM8753_HIFI, hifi);
        return 0;
 }
 
 /*
  * Set's I2S DAI format.
  */
-static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_i2s_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
        u16 ioctl, hifi;
 
-       hifi = snd_soc_read(codec, WM8753_HIFI) & 0x013f;
-       ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
+       hifi = snd_soc_component_read32(component, WM8753_HIFI) & 0x013f;
+       ioctl = snd_soc_component_read32(component, WM8753_IOCTL) & 0x00ae;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1143,8 +1143,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
                return -EINVAL;
        }
 
-       snd_soc_write(codec, WM8753_HIFI, hifi);
-       snd_soc_write(codec, WM8753_IOCTL, ioctl);
+       snd_soc_component_write(component, WM8753_HIFI, hifi);
+       snd_soc_component_write(component, WM8753_IOCTL, ioctl);
        return 0;
 }
 
@@ -1155,10 +1155,10 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-       u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
-       u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
+       struct snd_soc_component *component = dai->component;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
+       u16 srate = snd_soc_component_read32(component, WM8753_SRATE1) & 0x01c0;
+       u16 hifi = snd_soc_component_read32(component, WM8753_HIFI) & 0x01f3;
        int coeff;
 
        /* is digital filter coefficient valid ? */
@@ -1167,7 +1167,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
                printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
                return coeff;
        }
-       snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+       snd_soc_component_write(component, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
                coeff_div[coeff].usb);
 
        /* bit size */
@@ -1185,70 +1185,70 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_write(codec, WM8753_HIFI, hifi);
+       snd_soc_component_write(component, WM8753_HIFI, hifi);
        return 0;
 }
 
-static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode1v_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
        u16 clock;
 
        /* set clk source as pcmclk */
-       clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
-       snd_soc_write(codec, WM8753_CLOCK, clock);
+       clock = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfffb;
+       snd_soc_component_write(component, WM8753_CLOCK, clock);
 
-       return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
+       return wm8753_vdac_adc_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode1h_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
-       return wm8753_hdac_set_dai_fmt(codec, fmt);
+       return wm8753_hdac_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode2_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
        u16 clock;
 
        /* set clk source as pcmclk */
-       clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
-       snd_soc_write(codec, WM8753_CLOCK, clock);
+       clock = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfffb;
+       snd_soc_component_write(component, WM8753_CLOCK, clock);
 
-       return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
+       return wm8753_vdac_adc_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
        u16 clock;
 
        /* set clk source as mclk */
-       clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
-       snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
+       clock = snd_soc_component_read32(component, WM8753_CLOCK) & 0xfffb;
+       snd_soc_component_write(component, WM8753_CLOCK, clock | 0x4);
 
-       if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
+       if (wm8753_hdac_set_dai_fmt(component, fmt) < 0)
                return -EINVAL;
-       return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
+       return wm8753_vdac_adc_set_dai_fmt(component, fmt);
 }
 
-static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_hifi_write_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        switch (wm8753->dai_func) {
        case 0:
-               ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
+               ret = wm8753_mode1h_set_dai_fmt(component, fmt);
                break;
        case 1:
-               ret = wm8753_mode2_set_dai_fmt(codec, fmt);
+               ret = wm8753_mode2_set_dai_fmt(component, fmt);
                break;
        case 2:
        case 3:
-               ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
+               ret = wm8753_mode3_4_set_dai_fmt(component, fmt);
                break;
        default:
                 break;
@@ -1256,33 +1256,33 @@ static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
        if (ret)
                return ret;
 
-       return wm8753_i2s_set_dai_fmt(codec, fmt);
+       return wm8753_i2s_set_dai_fmt(component, fmt);
 }
 
 static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
        wm8753->hifi_fmt = fmt;
 
-       return wm8753_hifi_write_dai_fmt(codec, fmt);
+       return wm8753_hifi_write_dai_fmt(component, fmt);
 };
 
-static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
+static int wm8753_voice_write_dai_fmt(struct snd_soc_component *component,
                unsigned int fmt)
 {
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if (wm8753->dai_func != 0)
                return 0;
 
-       ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
+       ret = wm8753_mode1v_set_dai_fmt(component, fmt);
        if (ret)
                return ret;
-       ret = wm8753_pcm_set_dai_fmt(codec, fmt);
+       ret = wm8753_pcm_set_dai_fmt(component, fmt);
        if (ret)
                return ret;
 
@@ -1292,30 +1292,30 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
 static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = codec_dai->component;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
        wm8753->voice_fmt = fmt;
 
-       return wm8753_voice_write_dai_fmt(codec, fmt);
+       return wm8753_voice_write_dai_fmt(component, fmt);
 };
 
 static int wm8753_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8753_DAC) & 0xfff7;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
        /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
         * make sure we check if they are not both active when we mute */
        if (mute && wm8753->dai_func == 1) {
-               if (!snd_soc_codec_is_active(codec))
-                       snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
+               if (!snd_soc_component_is_active(component))
+                       snd_soc_component_write(component, WM8753_DAC, mute_reg | 0x8);
        } else {
                if (mute)
-                       snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
+                       snd_soc_component_write(component, WM8753_DAC, mute_reg | 0x8);
                else
-                       snd_soc_write(codec, WM8753_DAC, mute_reg);
+                       snd_soc_component_write(component, WM8753_DAC, mute_reg);
        }
 
        return 0;
@@ -1330,35 +1330,35 @@ static void wm8753_charge_work(struct work_struct *work)
        regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
 }
 
-static int wm8753_set_bias_level(struct snd_soc_codec *codec,
+static int wm8753_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-       u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
+       u16 pwr_reg = snd_soc_component_read32(component, WM8753_PWR1) & 0xfe3e;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
                /* set vmid to 50k and unmute dac */
-               snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+               snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x00c0);
                break;
        case SND_SOC_BIAS_PREPARE:
                /* Wait until fully charged */
                flush_delayed_work(&wm8753->charge_work);
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        /* set vmid to 5k for quick power up */
-                       snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+                       snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x01c1);
                        schedule_delayed_work(&wm8753->charge_work,
                                msecs_to_jiffies(caps_charge));
                } else {
                        /* mute dac and set vmid to 500k, enable VREF */
-                       snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+                       snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x0141);
                }
                break;
        case SND_SOC_BIAS_OFF:
                cancel_delayed_work_sync(&wm8753->charge_work);
-               snd_soc_write(codec, WM8753_PWR1, 0x0001);
+               snd_soc_component_write(component, WM8753_PWR1, 0x0001);
                break;
        }
        return 0;
@@ -1440,59 +1440,60 @@ static struct snd_soc_dai_driver wm8753_dai[] = {
 },
 };
 
-static int wm8753_resume(struct snd_soc_codec *codec)
+static int wm8753_resume(struct snd_soc_component *component)
 {
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
 
        regcache_sync(wm8753->regmap);
 
        return 0;
 }
 
-static int wm8753_probe(struct snd_soc_codec *codec)
+static int wm8753_probe(struct snd_soc_component *component)
 {
-       struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+       struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
        int ret;
 
        INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
 
-       ret = wm8753_reset(codec);
+       ret = wm8753_reset(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+               dev_err(component->dev, "Failed to issue reset: %d\n", ret);
                return ret;
        }
 
        wm8753->dai_func = 0;
 
        /* set the update bits */
-       snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_LADC, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_RADC, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
-       snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_LDAC, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_RDAC, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_LADC, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_RADC, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_LOUT1V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_ROUT1V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_LOUT2V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_ROUT2V, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_LINVOL, 0x0100, 0x0100);
+       snd_soc_component_update_bits(component, WM8753_RINVOL, 0x0100, 0x0100);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
-       .probe =        wm8753_probe,
-       .resume =       wm8753_resume,
-       .set_bias_level = wm8753_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8753_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8753_snd_controls),
-               .dapm_widgets           = wm8753_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8753_dapm_widgets),
-               .dapm_routes            = wm8753_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8753_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8753 = {
+       .probe                  = wm8753_probe,
+       .resume                 = wm8753_resume,
+       .set_bias_level         = wm8753_set_bias_level,
+       .controls               = wm8753_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8753_snd_controls),
+       .dapm_widgets           = wm8753_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8753_dapm_widgets),
+       .dapm_routes            = wm8753_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8753_dapm_routes),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8753_of_match[] = {
@@ -1534,7 +1535,7 @@ static int wm8753_spi_probe(struct spi_device *spi)
                return ret;
        }
 
-       ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
+       ret = devm_snd_soc_register_component(&spi->dev, &soc_component_dev_wm8753,
                                     wm8753_dai, ARRAY_SIZE(wm8753_dai));
        if (ret != 0)
                dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
@@ -1542,19 +1543,12 @@ static int wm8753_spi_probe(struct spi_device *spi)
        return ret;
 }
 
-static int wm8753_spi_remove(struct spi_device *spi)
-{
-       snd_soc_unregister_codec(&spi->dev);
-       return 0;
-}
-
 static struct spi_driver wm8753_spi_driver = {
        .driver = {
                .name   = "wm8753",
                .of_match_table = wm8753_of_match,
        },
        .probe          = wm8753_spi_probe,
-       .remove         = wm8753_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
@@ -1580,7 +1574,7 @@ static int wm8753_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
+       ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_wm8753,
                                     wm8753_dai, ARRAY_SIZE(wm8753_dai));
        if (ret != 0)
                dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
@@ -1588,12 +1582,6 @@ static int wm8753_i2c_probe(struct i2c_client *i2c,
        return ret;
 }
 
-static int wm8753_i2c_remove(struct i2c_client *client)
-{
-       snd_soc_unregister_codec(&client->dev);
-       return 0;
-}
-
 static const struct i2c_device_id wm8753_i2c_id[] = {
        { "wm8753", 0 },
        { }
@@ -1606,7 +1594,6 @@ static struct i2c_driver wm8753_i2c_driver = {
                .of_match_table = wm8753_of_match,
        },
        .probe =    wm8753_i2c_probe,
-       .remove =   wm8753_i2c_remove,
        .id_table = wm8753_i2c_id,
 };
 #endif
index d6edcbbdec12e3839babe286fa16a0e28fbd551b..806245c70f8beb551af92f4ad556d4bb5da929d1 100644 (file)
@@ -84,7 +84,7 @@ struct wm8770_priv {
        struct regmap *regmap;
        struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
        struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        int sysclk;
 };
 
@@ -308,14 +308,14 @@ static const struct snd_soc_dapm_route wm8770_intercon[] = {
 static int vout12supply_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
+               snd_soc_component_update_bits(component, WM8770_OUTMUX1, 0x180, 0);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
+               snd_soc_component_update_bits(component, WM8770_OUTMUX1, 0x180, 0x180);
                break;
        }
 
@@ -325,31 +325,31 @@ static int vout12supply_event(struct snd_soc_dapm_widget *w,
 static int vout34supply_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
+               snd_soc_component_update_bits(component, WM8770_OUTMUX2, 0x180, 0);
                break;
        case SND_SOC_DAPM_POST_PMD:
-               snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
+               snd_soc_component_update_bits(component, WM8770_OUTMUX2, 0x180, 0x180);
                break;
        }
 
        return 0;
 }
 
-static int wm8770_reset(struct snd_soc_codec *codec)
+static int wm8770_reset(struct snd_soc_component *component)
 {
-       return snd_soc_write(codec, WM8770_RESET, 0);
+       return snd_soc_component_write(component, WM8770_RESET, 0);
 }
 
 static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        int iface, master;
 
-       codec = dai->codec;
+       component = dai->component;
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -392,8 +392,8 @@ static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
-       snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
-       snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
+       snd_soc_component_update_bits(component, WM8770_IFACECTRL, 0xf, iface);
+       snd_soc_component_update_bits(component, WM8770_MSTRCTRL, 0x100, master);
 
        return 0;
 }
@@ -411,15 +411,15 @@ static int wm8770_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct wm8770_priv *wm8770;
        int i;
        int iface;
        int shift;
        int ratio;
 
-       codec = dai->codec;
-       wm8770 = snd_soc_codec_get_drvdata(codec);
+       component = dai->component;
+       wm8770 = snd_soc_component_get_drvdata(component);
 
        iface = 0;
        switch (params_width(params)) {
@@ -450,7 +450,7 @@ static int wm8770_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* Only need to set MCLK/LRCLK ratio if we're master */
-       if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
+       if (snd_soc_component_read32(component, WM8770_MSTRCTRL) & 0x100) {
                for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
                        ratio = wm8770->sysclk / params_rate(params);
                        if (ratio == mclk_ratios[i])
@@ -458,51 +458,51 @@ static int wm8770_hw_params(struct snd_pcm_substream *substream,
                }
 
                if (i == ARRAY_SIZE(mclk_ratios)) {
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Unable to configure MCLK ratio %d/%d\n",
                                wm8770->sysclk, params_rate(params));
                        return -EINVAL;
                }
 
-               dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
+               dev_dbg(component->dev, "MCLK is %dfs\n", mclk_ratios[i]);
 
-               snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
+               snd_soc_component_update_bits(component, WM8770_MSTRCTRL, 0x7 << shift,
                                    i << shift);
        }
 
-       snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
+       snd_soc_component_update_bits(component, WM8770_IFACECTRL, 0x30, iface);
 
        return 0;
 }
 
 static int wm8770_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 
-       codec = dai->codec;
-       return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
+       component = dai->component;
+       return snd_soc_component_update_bits(component, WM8770_DACMUTE, 0x10,
                                   !!mute << 4);
 }
 
 static int wm8770_set_sysclk(struct snd_soc_dai *dai,
                             int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct wm8770_priv *wm8770;
 
-       codec = dai->codec;
-       wm8770 = snd_soc_codec_get_drvdata(codec);
+       component = dai->component;
+       wm8770 = snd_soc_component_get_drvdata(component);
        wm8770->sysclk = freq;
        return 0;
 }
 
-static int wm8770_set_bias_level(struct snd_soc_codec *codec,
+static int wm8770_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        int ret;
        struct wm8770_priv *wm8770;
 
-       wm8770 = snd_soc_codec_get_drvdata(codec);
+       wm8770 = snd_soc_component_get_drvdata(component);
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -510,11 +510,11 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
+               if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
                                                    wm8770->supplies);
                        if (ret) {
-                               dev_err(codec->dev,
+                               dev_err(component->dev,
                                        "Failed to enable supplies: %d\n",
                                        ret);
                                return ret;
@@ -523,12 +523,12 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec,
                        regcache_sync(wm8770->regmap);
 
                        /* global powerup */
-                       snd_soc_write(codec, WM8770_PWDNCTRL, 0);
+                       snd_soc_component_write(component, WM8770_PWDNCTRL, 0);
                }
                break;
        case SND_SOC_BIAS_OFF:
                /* global powerdown */
-               snd_soc_write(codec, WM8770_PWDNCTRL, 1);
+               snd_soc_component_write(component, WM8770_PWDNCTRL, 1);
                regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
                                       wm8770->supplies);
                break;
@@ -567,60 +567,59 @@ static struct snd_soc_dai_driver wm8770_dai = {
        .symmetric_rates = 1
 };
 
-static int wm8770_probe(struct snd_soc_codec *codec)
+static int wm8770_probe(struct snd_soc_component *component)
 {
        struct wm8770_priv *wm8770;
        int ret;
 
-       wm8770 = snd_soc_codec_get_drvdata(codec);
-       wm8770->codec = codec;
+       wm8770 = snd_soc_component_get_drvdata(component);
+       wm8770->component = component;
 
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
                                    wm8770->supplies);
        if (ret) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+               dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
                return ret;
        }
 
-       ret = wm8770_reset(codec);
+       ret = wm8770_reset(component);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+               dev_err(component->dev, "Failed to issue reset: %d\n", ret);
                goto err_reg_enable;
        }
 
        /* latch the volume update bits */
-       snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
-       snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_MSDIGVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_MSALGVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_VOUT1RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_VOUT2RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_VOUT3RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_VOUT4RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_DAC1RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_DAC2RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_DAC3RVOL, 0x100, 0x100);
+       snd_soc_component_update_bits(component, WM8770_DAC4RVOL, 0x100, 0x100);
 
        /* mute all DACs */
-       snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
+       snd_soc_component_update_bits(component, WM8770_DACMUTE, 0x10, 0x10);
 
 err_reg_enable:
        regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
        return ret;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
-       .probe = wm8770_probe,
-       .set_bias_level = wm8770_set_bias_level,
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm8770_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8770_snd_controls),
-               .dapm_widgets           = wm8770_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8770_dapm_widgets),
-               .dapm_routes            = wm8770_intercon,
-               .num_dapm_routes        = ARRAY_SIZE(wm8770_intercon),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8770 = {
+       .probe                  = wm8770_probe,
+       .set_bias_level         = wm8770_set_bias_level,
+       .controls               = wm8770_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8770_snd_controls),
+       .dapm_widgets           = wm8770_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8770_dapm_widgets),
+       .dapm_routes            = wm8770_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(wm8770_intercon),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct of_device_id wm8770_of_match[] = {
@@ -682,8 +681,8 @@ static int wm8770_spi_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, wm8770);
 
-       ret = snd_soc_register_codec(&spi->dev,
-                                    &soc_codec_dev_wm8770, &wm8770_dai, 1);
+       ret = devm_snd_soc_register_component(&spi->dev,
+                                    &soc_component_dev_wm8770, &wm8770_dai, 1);
 
        return ret;
 }
@@ -697,8 +696,6 @@ static int wm8770_spi_remove(struct spi_device *spi)
                regulator_unregister_notifier(wm8770->supplies[i].consumer,
                                              &wm8770->disable_nb[i]);
 
-       snd_soc_unregister_codec(&spi->dev);
-
        return 0;
 }
 
index bcda210185050a0ddc3901ba244f0bbdc70dfee8..7949703f3d0482427002c87a07fbde124e5fcb7e 100644 (file)
@@ -50,25 +50,21 @@ static struct snd_soc_dai_driver wm8782_dai = {
        },
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8782 = {
-       .component_driver = {
-               .dapm_widgets           = wm8782_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8782_dapm_widgets),
-               .dapm_routes            = wm8782_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8782_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8782 = {
+       .dapm_widgets           = wm8782_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8782_dapm_widgets),
+       .dapm_routes            = wm8782_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8782_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm8782_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_wm8782, &wm8782_dai, 1);
-}
-
-static int wm8782_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm8782, &wm8782_dai, 1);
 }
 
 static struct platform_driver wm8782_codec_driver = {
@@ -76,7 +72,6 @@ static struct platform_driver wm8782_codec_driver = {
                .name = "wm8782",
        },
        .probe = wm8782_probe,
-       .remove = wm8782_remove,
 };
 
 module_platform_driver(wm8782_codec_driver);
index fc69b87443d80489382b97332de6d5ad12a58ec8..89f13249966ea0274e2beb099de8e7e38e8824c0 100644 (file)
@@ -137,21 +137,21 @@ static const struct snd_soc_dapm_route wm8804_dapm_routes[] = {
 static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                /* power up the aif */
                if (!wm8804->aif_pwr)
-                       snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x0);
+                       snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x0);
                wm8804->aif_pwr++;
                break;
        case SND_SOC_DAPM_POST_PMD:
                /* power down only both paths are disabled */
                wm8804->aif_pwr--;
                if (!wm8804->aif_pwr)
-                       snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x10);
+                       snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x10);
                break;
        }
 
@@ -161,8 +161,8 @@ static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
 static int txsrc_put(struct snd_kcontrol *kcontrol,
                     struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l;
        unsigned int mask = 1 << e->shift_l;
@@ -173,18 +173,18 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
 
        snd_soc_dapm_mutex_lock(dapm);
 
-       if (snd_soc_test_bits(codec, e->reg, mask, val)) {
+       if (snd_soc_component_test_bits(component, e->reg, mask, val)) {
                /* save the current power state of the transmitter */
-               txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;
+               txpwr = snd_soc_component_read32(component, WM8804_PWRDN) & 0x4;
 
                /* power down the transmitter */
-               snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);
+               snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, 0x4);
 
                /* set the tx source */
-               snd_soc_update_bits(codec, e->reg, mask, val);
+               snd_soc_component_update_bits(component, e->reg, mask, val);
 
                /* restore the transmitter's configuration */
-               snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
+               snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, txpwr);
        }
 
        snd_soc_dapm_mutex_unlock(dapm);
@@ -218,10 +218,10 @@ static int wm8804_soft_reset(struct wm8804_priv *wm8804)
 
 static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        u16 format, master, bcp, lrp;
 
-       codec = dai->codec;
+       component = dai->component;
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
@@ -243,8 +243,8 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
 
        /* set data format */
-       snd_soc_update_bits(codec, WM8804_AIFTX, 0x3, format);
-       snd_soc_update_bits(codec, WM8804_AIFRX, 0x3, format);
+       snd_soc_component_update_bits(component, WM8804_AIFTX, 0x3, format);
+       snd_soc_component_update_bits(component, WM8804_AIFRX, 0x3, format);
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
@@ -259,7 +259,7 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
 
        /* set master/slave mode */
-       snd_soc_update_bits(codec, WM8804_AIFRX, 0x40, master << 6);
+       snd_soc_component_update_bits(component, WM8804_AIFRX, 0x40, master << 6);
 
        bcp = lrp = 0;
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -280,9 +280,9 @@ static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        }
 
        /* set frame inversion */
-       snd_soc_update_bits(codec, WM8804_AIFTX, 0x10 | 0x20,
+       snd_soc_component_update_bits(component, WM8804_AIFTX, 0x10 | 0x20,
                            (bcp << 4) | (lrp << 5));
-       snd_soc_update_bits(codec, WM8804_AIFRX, 0x10 | 0x20,
+       snd_soc_component_update_bits(component, WM8804_AIFRX, 0x10 | 0x20,
                            (bcp << 4) | (lrp << 5));
        return 0;
 }
@@ -291,10 +291,10 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream,
                            struct snd_pcm_hw_params *params,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        u16 blen;
 
-       codec = dai->codec;
+       component = dai->component;
 
        switch (params_width(params)) {
        case 16:
@@ -313,8 +313,8 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* set word length */
-       snd_soc_update_bits(codec, WM8804_AIFTX, 0xc, blen << 2);
-       snd_soc_update_bits(codec, WM8804_AIFRX, 0xc, blen << 2);
+       snd_soc_component_update_bits(component, WM8804_AIFTX, 0xc, blen << 2);
+       snd_soc_component_update_bits(component, WM8804_AIFRX, 0xc, blen << 2);
 
        return 0;
 }
@@ -405,8 +405,8 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
                          int source, unsigned int freq_in,
                          unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = dai->component;
+       struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);
        bool change;
 
        if (!freq_in || !freq_out) {
@@ -431,18 +431,18 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
                        pm_runtime_get_sync(wm8804->dev);
 
                /* set PLLN and PRESCALE */
-               snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
+               snd_soc_component_update_bits(component, WM8804_PLL4, 0xf | 0x10,
                                    pll_div.n | (pll_div.prescale << 4));
                /* set mclkdiv and freqmode */
-               snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8,
+               snd_soc_component_update_bits(component, WM8804_PLL5, 0x3 | 0x8,
                                    pll_div.freqmode | (pll_div.mclkdiv << 3));
                /* set PLLK */
-               snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff);
-               snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
-               snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16);
+               snd_soc_component_write(component, WM8804_PLL1, pll_div.k & 0xff);
+               snd_soc_component_write(component, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
+               snd_soc_component_write(component, WM8804_PLL3, pll_div.k >> 16);
 
                /* power up the PLL */
-               snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0);
+               snd_soc_component_update_bits(component, WM8804_PWRDN, 0x1, 0);
        }
 
        return 0;
@@ -451,15 +451,15 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
 static int wm8804_set_sysclk(struct snd_soc_dai *dai,
                             int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 
-       codec = dai->codec;
+       component = dai->component;
 
        switch (clk_id) {
        case WM8804_TX_CLKSRC_MCLK:
                if ((freq >= 10000000 && freq <= 14400000)
                                || (freq >= 16280000 && freq <= 27000000))
-                       snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0x80);
+                       snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0x80);
                else {
                        dev_err(dai->dev, "OSCCLOCK is not within the "
                                "recommended range: %uHz\n", freq);
@@ -467,13 +467,13 @@ static int wm8804_set_sysclk(struct snd_soc_dai *dai,
                }
                break;
        case WM8804_TX_CLKSRC_PLL:
-               snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0);
+               snd_soc_component_update_bits(component, WM8804_PLL6, 0x80, 0);
                break;
        case WM8804_CLKOUT_SRC_CLK1:
-               snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0);
+               snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0);
                break;
        case WM8804_CLKOUT_SRC_OSCCLK:
-               snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0x8);
+               snd_soc_component_update_bits(component, WM8804_PLL6, 0x8, 0x8);
                break;
        default:
                dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
@@ -486,17 +486,17 @@ static int wm8804_set_sysclk(struct snd_soc_dai *dai,
 static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
                             int div_id, int div)
 {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        struct wm8804_priv *wm8804;
 
-       codec = dai->codec;
+       component = dai->component;
        switch (div_id) {
        case WM8804_CLKOUT_DIV:
-               snd_soc_update_bits(codec, WM8804_PLL5, 0x30,
+               snd_soc_component_update_bits(component, WM8804_PLL5, 0x30,
                                    (div & 0x3) << 4);
                break;
        case WM8804_MCLK_DIV:
-               wm8804 = snd_soc_codec_get_drvdata(codec);
+               wm8804 = snd_soc_component_get_drvdata(component);
                wm8804->mclk_div = div;
                break;
        default:
@@ -542,15 +542,14 @@ static struct snd_soc_dai_driver wm8804_dai = {
        .symmetric_rates = 1
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
-       .idle_bias_off = true,
-
-       .component_driver = {
-               .dapm_widgets           = wm8804_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8804_dapm_widgets),
-               .dapm_routes            = wm8804_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8804_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8804 = {
+       .dapm_widgets           = wm8804_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8804_dapm_widgets),
+       .dapm_routes            = wm8804_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8804_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 const struct regmap_config wm8804_regmap_config = {
@@ -661,7 +660,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
                }
        }
 
-       ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804,
+       ret = devm_snd_soc_register_component(dev, &soc_component_dev_wm8804,
                                     &wm8804_dai, 1);
        if (ret < 0) {
                dev_err(dev, "Failed to register CODEC: %d\n", ret);
@@ -683,7 +682,6 @@ EXPORT_SYMBOL_GPL(wm8804_probe);
 void wm8804_remove(struct device *dev)
 {
        pm_runtime_disable(dev);
-       snd_soc_unregister_codec(dev);
 }
 EXPORT_SYMBOL_GPL(wm8804_remove);
 
index cac9b3e7e15d3ae982fd2f1ee6a0942cc8cd878d..df5b36b8fc5a69ab441137916053c0ad795457e9 100644 (file)
@@ -84,8 +84,8 @@ static const struct reg_default wm8997_sysclk_reva_patch[] = {
 static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(component->dev->parent);
        struct regmap *regmap = arizona->regmap;
        const struct reg_default *patch = NULL;
        int i, patch_size;
@@ -118,7 +118,7 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
        return arizona_dvfs_sysclk_ev(w, kcontrol, event);
 }
 
-static const char *wm8997_osr_text[] = {
+static const char * const wm8997_osr_text[] = {
        "Low power", "Normal", "High performance",
 };
 
@@ -609,8 +609,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
                    ARIZONA_SLIMRX8_ENA_SHIFT, 0),
 
 SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-                      &wm8997_aec_loopback_mux),
+                ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm8997_aec_loopback_mux),
 
 SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
                   ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
@@ -927,10 +926,10 @@ static const struct snd_soc_dapm_route wm8997_dapm_routes[] = {
        { "MICSUPP", NULL, "SYSCLK" },
 };
 
-static int wm8997_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-                         unsigned int Fref, unsigned int Fout)
+static int wm8997_set_fll(struct snd_soc_component *component, int fll_id,
+                         int source, unsigned int Fref, unsigned int Fout)
 {
-       struct wm8997_priv *wm8997 = snd_soc_codec_get_drvdata(codec);
+       struct wm8997_priv *wm8997 = snd_soc_component_get_drvdata(component);
 
        switch (fll_id) {
        case WM8997_FLL1:
@@ -1057,17 +1056,16 @@ static struct snd_soc_dai_driver wm8997_dai[] = {
        },
 };
 
-static int wm8997_codec_probe(struct snd_soc_codec *codec)
+static int wm8997_component_probe(struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
-       struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct wm8997_priv *priv = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = priv->core.arizona;
        int ret;
 
-       snd_soc_codec_init_regmap(codec, arizona->regmap);
+       snd_soc_component_init_regmap(component, arizona->regmap);
 
-       ret = arizona_init_spk(codec);
+       ret = arizona_init_spk(component);
        if (ret < 0)
                return ret;
 
@@ -1078,13 +1076,11 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int wm8997_codec_remove(struct snd_soc_codec *codec)
+static void wm8997_component_remove(struct snd_soc_component *component)
 {
-       struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm8997_priv *priv = snd_soc_component_get_drvdata(component);
 
        priv->core.arizona->dapm = NULL;
-
-       return 0;
 }
 
 #define WM8997_DIG_VU 0x0200
@@ -1098,23 +1094,20 @@ static unsigned int wm8997_digital_vu[] = {
        ARIZONA_DAC_DIGITAL_VOLUME_5R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
-       .probe = wm8997_codec_probe,
-       .remove = wm8997_codec_remove,
-
-       .idle_bias_off = true,
-
-       .set_sysclk = arizona_set_sysclk,
-       .set_pll = wm8997_set_fll,
-
-       .component_driver = {
-               .controls               = wm8997_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8997_snd_controls),
-               .dapm_widgets           = wm8997_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8997_dapm_widgets),
-               .dapm_routes            = wm8997_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8997_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8997 = {
+       .probe                  = wm8997_component_probe,
+       .remove                 = wm8997_component_remove,
+       .set_sysclk             = arizona_set_sysclk,
+       .set_pll                = wm8997_set_fll,
+       .controls               = wm8997_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8997_snd_controls),
+       .dapm_widgets           = wm8997_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8997_dapm_widgets),
+       .dapm_routes            = wm8997_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8997_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm8997_probe(struct platform_device *pdev)
@@ -1178,10 +1171,12 @@ static int wm8997_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8997,
-                                    wm8997_dai, ARRAY_SIZE(wm8997_dai));
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &soc_component_dev_wm8997,
+                                             wm8997_dai,
+                                             ARRAY_SIZE(wm8997_dai));
        if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
                goto err_spk_irqs;
        }
 
@@ -1196,7 +1191,6 @@ static int wm8997_remove(struct platform_device *pdev)
        struct wm8997_priv *wm8997 = platform_get_drvdata(pdev);
        struct arizona *arizona = wm8997->core.arizona;
 
-       snd_soc_unregister_codec(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        arizona_free_spk_irqs(arizona);
index 1288e1f67dcf15f1460b5ee90ff18fb7cc15a0f6..61294c787f27423a0aa083777f521971c27717b9 100644 (file)
@@ -41,12 +41,12 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
                          struct snd_kcontrol *kcontrol,
                          int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        unsigned int val;
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               val = snd_soc_read(codec, ARIZONA_ASRC_RATE1);
+               val = snd_soc_component_read32(component, ARIZONA_ASRC_RATE1);
                val &= ARIZONA_ASRC_RATE1_MASK;
                val >>= ARIZONA_ASRC_RATE1_SHIFT;
 
@@ -54,23 +54,23 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
                case 0:
                case 1:
                case 2:
-                       val = snd_soc_read(codec,
+                       val = snd_soc_component_read32(component,
                                           ARIZONA_SAMPLE_RATE_1 + val);
                        if (val >= 0x11) {
-                               dev_warn(codec->dev,
+                               dev_warn(component->dev,
                                         "Unsupported ASRC rate1 (%s)\n",
                                         arizona_sample_rate_val_to_name(val));
                        return -EINVAL;
                        }
                        break;
                default:
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Illegal ASRC rate1 selector (0x%x)\n",
                                val);
                        return -EINVAL;
                }
 
-               val = snd_soc_read(codec, ARIZONA_ASRC_RATE2);
+               val = snd_soc_component_read32(component, ARIZONA_ASRC_RATE2);
                val &= ARIZONA_ASRC_RATE2_MASK;
                val >>= ARIZONA_ASRC_RATE2_SHIFT;
 
@@ -78,17 +78,17 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
                case 8:
                case 9:
                        val -= 0x8;
-                       val = snd_soc_read(codec,
+                       val = snd_soc_component_read32(component,
                                           ARIZONA_ASYNC_SAMPLE_RATE_1 + val);
                        if (val >= 0x11) {
-                               dev_warn(codec->dev,
+                               dev_warn(component->dev,
                                         "Unsupported ASRC rate2 (%s)\n",
                                         arizona_sample_rate_val_to_name(val));
                                return -EINVAL;
                        }
                        break;
                default:
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Illegal ASRC rate2 selector (0x%x)\n",
                                val);
                        return -EINVAL;
@@ -104,9 +104,9 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
 static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
                            struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+       struct wm8998_priv *wm8998 = snd_soc_component_get_drvdata(component);
        struct arizona *arizona = wm8998->core.arizona;
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
        unsigned int mode_reg, mode_index;
@@ -137,11 +137,13 @@ static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
        if (inmode & ARIZONA_INMODE_SE)
                src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
 
-       snd_soc_update_bits(codec, mode_reg, ARIZONA_IN1_MODE_MASK, mode_val);
+       snd_soc_component_update_bits(component, mode_reg,
+                                     ARIZONA_IN1_MODE_MASK, mode_val);
 
-       snd_soc_update_bits(codec, e->reg,
-                           ARIZONA_IN1L_SRC_MASK | ARIZONA_IN1L_SRC_SE_MASK,
-                           src_val);
+       snd_soc_component_update_bits(component, e->reg,
+                                     ARIZONA_IN1L_SRC_MASK |
+                                     ARIZONA_IN1L_SRC_SE_MASK,
+                                     src_val);
 
        return snd_soc_dapm_mux_update_power(dapm, kcontrol,
                                             ucontrol->value.enumerated.item[0],
@@ -322,7 +324,7 @@ SOC_DOUBLE_R("HPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
 SOC_DOUBLE_R("LINEOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
             ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
 SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
-            ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
+          ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
             ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("SPKDAT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
@@ -335,7 +337,7 @@ SOC_DOUBLE_R_TLV("LINEOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
                 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
-                ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
+              ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
 SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
                 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
@@ -615,12 +617,12 @@ SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
                 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("AEC1 Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-                      &wm8998_aec_loopback_mux[0]),
+                ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
+                &wm8998_aec_loopback_mux[0]),
 
 SND_SOC_DAPM_MUX("AEC2 Loopback", ARIZONA_DAC_AEC_CONTROL_2,
-                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
-                      &wm8998_aec_loopback_mux[1]),
+                ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
+                &wm8998_aec_loopback_mux[1]),
 
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
                     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
@@ -739,9 +741,9 @@ SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
                   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 
 SND_SOC_DAPM_PGA("SPD1TX1", ARIZONA_SPD1_TX_CONTROL,
-                  ARIZONA_SPD1_VAL1_SHIFT, 0, NULL, 0),
+                ARIZONA_SPD1_VAL1_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_PGA("SPD1TX2", ARIZONA_SPD1_TX_CONTROL,
-                  ARIZONA_SPD1_VAL2_SHIFT, 0, NULL, 0),
+                ARIZONA_SPD1_VAL2_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_OUT_DRV("SPD1", ARIZONA_SPD1_TX_CONTROL,
                     ARIZONA_SPD1_ENA_SHIFT, 0, NULL, 0),
 
@@ -1249,10 +1251,10 @@ static struct snd_soc_dai_driver wm8998_dai[] = {
        },
 };
 
-static int wm8998_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
-                         unsigned int Fref, unsigned int Fout)
+static int wm8998_set_fll(struct snd_soc_component *component, int fll_id,
+                         int source, unsigned int Fref, unsigned int Fout)
 {
-       struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
+       struct wm8998_priv *wm8998 = snd_soc_component_get_drvdata(component);
 
        switch (fll_id) {
        case WM8998_FLL1:
@@ -1270,35 +1272,32 @@ static int wm8998_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        }
 }
 
-static int wm8998_codec_probe(struct snd_soc_codec *codec)
+static int wm8998_component_probe(struct snd_soc_component *component)
 {
-       struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
-       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+       struct wm8998_priv *priv = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        struct arizona *arizona = priv->core.arizona;
        int ret;
 
        arizona->dapm = dapm;
-       snd_soc_codec_init_regmap(codec, arizona->regmap);
+       snd_soc_component_init_regmap(component, arizona->regmap);
 
-       ret = arizona_init_spk(codec);
+       ret = arizona_init_spk(component);
        if (ret < 0)
                return ret;
 
-       arizona_init_gpio(codec);
+       arizona_init_gpio(component);
 
        snd_soc_component_disable_pin(component, "HAPTICS");
 
        return 0;
 }
 
-static int wm8998_codec_remove(struct snd_soc_codec *codec)
+static void wm8998_component_remove(struct snd_soc_component *component)
 {
-       struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct wm8998_priv *priv = snd_soc_component_get_drvdata(component);
 
        priv->core.arizona->dapm = NULL;
-
-       return 0;
 }
 
 #define WM8998_DIG_VU 0x0200
@@ -1315,23 +1314,20 @@ static unsigned int wm8998_digital_vu[] = {
        ARIZONA_DAC_DIGITAL_VOLUME_5R,
 };
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
-       .probe = wm8998_codec_probe,
-       .remove = wm8998_codec_remove,
-
-       .idle_bias_off = true,
-
-       .set_sysclk = arizona_set_sysclk,
-       .set_pll = wm8998_set_fll,
-
-       .component_driver = {
-               .controls               = wm8998_snd_controls,
-               .num_controls           = ARRAY_SIZE(wm8998_snd_controls),
-               .dapm_widgets           = wm8998_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm8998_dapm_widgets),
-               .dapm_routes            = wm8998_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(wm8998_dapm_routes),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm8998 = {
+       .probe                  = wm8998_component_probe,
+       .remove                 = wm8998_component_remove,
+       .set_sysclk             = arizona_set_sysclk,
+       .set_pll                = wm8998_set_fll,
+       .controls               = wm8998_snd_controls,
+       .num_controls           = ARRAY_SIZE(wm8998_snd_controls),
+       .dapm_widgets           = wm8998_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm8998_dapm_widgets),
+       .dapm_routes            = wm8998_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(wm8998_dapm_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm8998_probe(struct platform_device *pdev)
@@ -1384,10 +1380,12 @@ static int wm8998_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8998,
-                                    wm8998_dai, ARRAY_SIZE(wm8998_dai));
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &soc_component_dev_wm8998,
+                                             wm8998_dai,
+                                             ARRAY_SIZE(wm8998_dai));
        if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
                goto err_spk_irqs;
        }
 
@@ -1404,7 +1402,6 @@ static int wm8998_remove(struct platform_device *pdev)
        struct wm8998_priv *wm8998 = platform_get_drvdata(pdev);
        struct arizona *arizona = wm8998->core.arizona;
 
-       snd_soc_unregister_codec(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        arizona_free_spk_irqs(arizona);
index 2c09f71fe433bd77bede92fe199eebdca0604425..ccdf088461b7f078e1f10891e2ce0db3db4c7023 100644 (file)
@@ -235,17 +235,17 @@ static const struct snd_soc_dapm_route wm9705_audio_map[] = {
 static int ac97_prepare(struct snd_pcm_substream *substream,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int reg;
 
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                reg = AC97_PCM_FRONT_DAC_RATE;
        else
                reg = AC97_PCM_LR_ADC_RATE;
 
-       return snd_soc_write(codec, reg, substream->runtime->rate);
+       return snd_soc_component_write(component, reg, substream->runtime->rate);
 }
 
 #define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
@@ -289,18 +289,18 @@ static struct snd_soc_dai_driver wm9705_dai[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm9705_soc_suspend(struct snd_soc_codec *codec)
+static int wm9705_soc_suspend(struct snd_soc_component *component)
 {
-       regcache_cache_bypass(codec->component.regmap, true);
-       snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
-       regcache_cache_bypass(codec->component.regmap, false);
+       regcache_cache_bypass(component->regmap, true);
+       snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
+       regcache_cache_bypass(component->regmap, false);
 
        return 0;
 }
 
-static int wm9705_soc_resume(struct snd_soc_codec *codec)
+static int wm9705_soc_resume(struct snd_soc_component *component)
 {
-       struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
+       struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_ac97_reset(wm9705->ac97, true, WM9705_VENDOR_ID,
@@ -308,7 +308,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
        if (ret < 0)
                return ret;
 
-       regcache_sync(codec->component.regmap);
+       snd_soc_component_cache_sync(component);
 
        return 0;
 }
@@ -317,9 +317,9 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
 #define wm9705_soc_resume NULL
 #endif
 
-static int wm9705_soc_probe(struct snd_soc_codec *codec)
+static int wm9705_soc_probe(struct snd_soc_component *component)
 {
-       struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
+       struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
        struct regmap *regmap;
 
        if (wm9705->mfd_pdata) {
@@ -327,54 +327,54 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
                regmap = wm9705->mfd_pdata->regmap;
        } else {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-               wm9705->ac97 = snd_soc_new_ac97_codec(codec, WM9705_VENDOR_ID,
+               wm9705->ac97 = snd_soc_new_ac97_component(component, WM9705_VENDOR_ID,
                                                      WM9705_VENDOR_ID_MASK);
                if (IS_ERR(wm9705->ac97)) {
-                       dev_err(codec->dev, "Failed to register AC97 codec\n");
+                       dev_err(component->dev, "Failed to register AC97 codec\n");
                        return PTR_ERR(wm9705->ac97);
                }
 
                regmap = regmap_init_ac97(wm9705->ac97, &wm9705_regmap_config);
                if (IS_ERR(regmap)) {
-                       snd_soc_free_ac97_codec(wm9705->ac97);
+                       snd_soc_free_ac97_component(wm9705->ac97);
                        return PTR_ERR(regmap);
                }
 #endif
        }
 
-       snd_soc_codec_set_drvdata(codec, wm9705->ac97);
-       snd_soc_codec_init_regmap(codec, regmap);
+       snd_soc_component_set_drvdata(component, wm9705->ac97);
+       snd_soc_component_init_regmap(component, regmap);
 
        return 0;
 }
 
-static int wm9705_soc_remove(struct snd_soc_codec *codec)
+static void wm9705_soc_remove(struct snd_soc_component *component)
 {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-       struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
+       struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
 
        if (!wm9705->mfd_pdata) {
-               snd_soc_codec_exit_regmap(codec);
-               snd_soc_free_ac97_codec(wm9705->ac97);
+               snd_soc_component_exit_regmap(component);
+               snd_soc_free_ac97_component(wm9705->ac97);
        }
 #endif
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
-       .probe =        wm9705_soc_probe,
-       .remove =       wm9705_soc_remove,
-       .suspend =      wm9705_soc_suspend,
-       .resume =       wm9705_soc_resume,
-
-       .component_driver = {
-               .controls               = wm9705_snd_ac97_controls,
-               .num_controls           = ARRAY_SIZE(wm9705_snd_ac97_controls),
-               .dapm_widgets           = wm9705_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm9705_dapm_widgets),
-               .dapm_routes            = wm9705_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(wm9705_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm9705 = {
+       .probe                  = wm9705_soc_probe,
+       .remove                 = wm9705_soc_remove,
+       .suspend                = wm9705_soc_suspend,
+       .resume                 = wm9705_soc_resume,
+       .controls               = wm9705_snd_ac97_controls,
+       .num_controls           = ARRAY_SIZE(wm9705_snd_ac97_controls),
+       .dapm_widgets           = wm9705_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm9705_dapm_widgets),
+       .dapm_routes            = wm9705_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(wm9705_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm9705_probe(struct platform_device *pdev)
@@ -388,14 +388,8 @@ static int wm9705_probe(struct platform_device *pdev)
        wm9705->mfd_pdata = dev_get_platdata(&pdev->dev);
        platform_set_drvdata(pdev, wm9705);
 
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
-}
-
-static int wm9705_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
 }
 
 static struct platform_driver wm9705_codec_driver = {
@@ -404,7 +398,6 @@ static struct platform_driver wm9705_codec_driver = {
        },
 
        .probe = wm9705_probe,
-       .remove = wm9705_remove,
 };
 
 module_platform_driver(wm9705_codec_driver);
index 4f6d1a442bc448e35cf28e365e93071a9270bfc4..7aeeeec8adbd6b2f91bd80006f0277d977c55799 100644 (file)
@@ -220,8 +220,8 @@ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+       struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
        unsigned int val = ucontrol->value.integer.value[0];
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
@@ -264,8 +264,8 @@ static int wm9712_hp_mixer_get(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+       struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int shift, mixer;
@@ -527,33 +527,33 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = {
 static int ac97_prepare(struct snd_pcm_substream *substream,
                        struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        int reg;
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                reg = AC97_PCM_FRONT_DAC_RATE;
        else
                reg = AC97_PCM_LR_ADC_RATE;
 
-       return snd_soc_write(codec, reg, runtime->rate);
+       return snd_soc_component_write(component, reg, runtime->rate);
 }
 
 static int ac97_aux_prepare(struct snd_pcm_substream *substream,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x1, 0x1);
-       snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x1, 0x1);
+       snd_soc_component_update_bits(component, AC97_PCI_SID, 0x8000, 0x8000);
 
        if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
                return -ENODEV;
 
-       return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
+       return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate);
 }
 
 #define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -597,7 +597,7 @@ static struct snd_soc_dai_driver wm9712_dai[] = {
 }
 };
 
-static int wm9712_set_bias_level(struct snd_soc_codec *codec,
+static int wm9712_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
@@ -605,20 +605,20 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
-               snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
+               snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
                break;
        case SND_SOC_BIAS_OFF:
                /* disable everything including AC link */
-               snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
-               snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+               snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
+               snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
                break;
        }
        return 0;
 }
 
-static int wm9712_soc_resume(struct snd_soc_codec *codec)
+static int wm9712_soc_resume(struct snd_soc_component *component)
 {
-       struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+       struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_ac97_reset(wm9712->ac97, true, WM9712_VENDOR_ID,
@@ -626,17 +626,17 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
        if (ret < 0)
                return ret;
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        if (ret == 0)
-               regcache_sync(codec->component.regmap);
+               snd_soc_component_cache_sync(component);
 
        return ret;
 }
 
-static int wm9712_soc_probe(struct snd_soc_codec *codec)
+static int wm9712_soc_probe(struct snd_soc_component *component)
 {
-       struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+       struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
        struct regmap *regmap;
        int ret;
 
@@ -645,59 +645,59 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
                regmap = wm9712->mfd_pdata->regmap;
        } else {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-               wm9712->ac97 = snd_soc_new_ac97_codec(codec, WM9712_VENDOR_ID,
+               wm9712->ac97 = snd_soc_new_ac97_component(component, WM9712_VENDOR_ID,
                                                      WM9712_VENDOR_ID_MASK);
                if (IS_ERR(wm9712->ac97)) {
                        ret = PTR_ERR(wm9712->ac97);
-                       dev_err(codec->dev,
+                       dev_err(component->dev,
                                "Failed to register AC97 codec: %d\n", ret);
                        return ret;
                }
 
                regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config);
                if (IS_ERR(regmap)) {
-                       snd_soc_free_ac97_codec(wm9712->ac97);
+                       snd_soc_free_ac97_component(wm9712->ac97);
                        return PTR_ERR(regmap);
                }
 #endif
        }
 
-       snd_soc_codec_init_regmap(codec, regmap);
+       snd_soc_component_init_regmap(component, regmap);
 
        /* set alc mux to none */
-       snd_soc_update_bits(codec, AC97_VIDEO, 0x3000, 0x3000);
+       snd_soc_component_update_bits(component, AC97_VIDEO, 0x3000, 0x3000);
 
        return 0;
 }
 
-static int wm9712_soc_remove(struct snd_soc_codec *codec)
+static void wm9712_soc_remove(struct snd_soc_component *component)
 {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-       struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
+       struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
 
        if (!wm9712->mfd_pdata) {
-               snd_soc_codec_exit_regmap(codec);
-               snd_soc_free_ac97_codec(wm9712->ac97);
+               snd_soc_component_exit_regmap(component);
+               snd_soc_free_ac97_component(wm9712->ac97);
        }
 #endif
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
-       .probe =        wm9712_soc_probe,
-       .remove =       wm9712_soc_remove,
-       .resume =       wm9712_soc_resume,
-       .set_bias_level = wm9712_set_bias_level,
-       .suspend_bias_off = true,
-
-       .component_driver = {
-               .controls               = wm9712_snd_ac97_controls,
-               .num_controls           = ARRAY_SIZE(wm9712_snd_ac97_controls),
-               .dapm_widgets           = wm9712_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm9712_dapm_widgets),
-               .dapm_routes            = wm9712_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(wm9712_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm9712 = {
+       .probe                  = wm9712_soc_probe,
+       .remove                 = wm9712_soc_remove,
+       .resume                 = wm9712_soc_resume,
+       .set_bias_level         = wm9712_set_bias_level,
+       .controls               = wm9712_snd_ac97_controls,
+       .num_controls           = ARRAY_SIZE(wm9712_snd_ac97_controls),
+       .dapm_widgets           = wm9712_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm9712_dapm_widgets),
+       .dapm_routes            = wm9712_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(wm9712_audio_map),
+       .suspend_bias_off       = 1,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm9712_probe(struct platform_device *pdev)
@@ -713,26 +713,19 @@ static int wm9712_probe(struct platform_device *pdev)
        wm9712->mfd_pdata = dev_get_platdata(&pdev->dev);
        platform_set_drvdata(pdev, wm9712);
 
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
-}
-
-static int wm9712_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
 }
 
-static struct platform_driver wm9712_codec_driver = {
+static struct platform_driver wm9712_component_driver = {
        .driver = {
-               .name = "wm9712-codec",
+               .name = "wm9712-component",
        },
 
        .probe = wm9712_probe,
-       .remove = wm9712_remove,
 };
 
-module_platform_driver(wm9712_codec_driver);
+module_platform_driver(wm9712_component_driver);
 
 MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
 MODULE_AUTHOR("Liam Girdwood");
index df7220656d9855457a44f5378ec2c283eb06810c..3d6cf008500548adb93d00cc25f7b849c60582bb 100644 (file)
@@ -196,16 +196,16 @@ SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
 static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
                                 struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 
        if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
                return -EINVAL;
 
        /* Gracefully shut down the voice interface. */
-       snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0200);
+       snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, 0x0200);
        schedule_timeout_interruptible(msecs_to_jiffies(1));
-       snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
-       snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x1000, 0x1000);
+       snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x1000, 0x1000);
 
        return 0;
 }
@@ -229,8 +229,8 @@ static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+       struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
        unsigned int val = ucontrol->value.integer.value[0];
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
@@ -273,8 +273,8 @@ static int wm9713_hp_mixer_get(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
-       struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
+       struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        unsigned int mixer, shift;
@@ -753,7 +753,7 @@ struct _pll_div {
  * to allow rounding later */
 #define FIXED_PLL_SIZE ((1 << 22) * 10)
 
-static void pll_factors(struct snd_soc_codec *codec,
+static void pll_factors(struct snd_soc_component *component,
        struct _pll_div *pll_div, unsigned int source)
 {
        u64 Kpart;
@@ -789,7 +789,7 @@ static void pll_factors(struct snd_soc_codec *codec,
 
        Ndiv = target / source;
        if ((Ndiv < 5) || (Ndiv > 12))
-               dev_warn(codec->dev,
+               dev_warn(component->dev,
                        "WM9713 PLL N value %u out of recommended range!\n",
                        Ndiv);
 
@@ -815,28 +815,28 @@ static void pll_factors(struct snd_soc_codec *codec,
  * Please note that changing the PLL input frequency may require
  * resynchronisation with the AC97 controller.
  */
-static int wm9713_set_pll(struct snd_soc_codec *codec,
+static int wm9713_set_pll(struct snd_soc_component *component,
        int pll_id, unsigned int freq_in, unsigned int freq_out)
 {
-       struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+       struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
        u16 reg, reg2;
        struct _pll_div pll_div;
 
        /* turn PLL off ? */
        if (freq_in == 0) {
                /* disable PLL power and select ext source */
-               snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0080);
-               snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0200);
+               snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0080, 0x0080);
+               snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x0200, 0x0200);
                wm9713->pll_in = 0;
                return 0;
        }
 
-       pll_factors(codec, &pll_div, freq_in);
+       pll_factors(component, &pll_div, freq_in);
 
        if (pll_div.k == 0) {
                reg = (pll_div.n << 12) | (pll_div.lf << 11) |
                        (pll_div.divsel << 9) | (pll_div.divctl << 8);
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
        } else {
                /* write the fractional k to the reg 0x46 pages */
                reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) |
@@ -844,31 +844,31 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
 
                /* K [21:20] */
                reg = reg2 | (0x5 << 4) | (pll_div.k >> 20);
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
                /* K [19:16] */
                reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf);
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
                /* K [15:12] */
                reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf);
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
                /* K [11:8] */
                reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf);
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
                /* K [7:4] */
                reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf);
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
 
                reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */
-               snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
+               snd_soc_component_write(component, AC97_LINE1_LEVEL, reg);
        }
 
        /* turn PLL on and select as source */
-       snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0000);
-       snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0000);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x0200, 0x0000);
+       snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0080, 0x0000);
        wm9713->pll_in = freq_in;
 
        /* wait 10ms AC97 link frames for the link to stabilise */
@@ -879,8 +879,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
 static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
                int source, unsigned int freq_in, unsigned int freq_out)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
+       struct snd_soc_component *component = codec_dai->component;
+       return wm9713_set_pll(component, pll_id, freq_in, freq_out);
 }
 
 /*
@@ -890,10 +890,10 @@ static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
        int tristate)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        if (tristate)
-               snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+               snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
                                    0x6000, 0x0000);
 
        return 0;
@@ -906,30 +906,30 @@ static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
 static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                int div_id, int div)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
 
        switch (div_id) {
        case WM9713_PCMCLK_DIV:
-               snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, div);
+               snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0f00, div);
                break;
        case WM9713_CLKA_MULT:
-               snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0002, div);
+               snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0002, div);
                break;
        case WM9713_CLKB_MULT:
-               snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0004, div);
+               snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x0004, div);
                break;
        case WM9713_HIFI_DIV:
-               snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x7000, div);
+               snd_soc_component_update_bits(component, AC97_HANDSET_RATE, 0x7000, div);
                break;
        case WM9713_PCMBCLK_DIV:
-               snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER, 0x0e00, div);
+               snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER, 0x0e00, div);
                break;
        case WM9713_PCMCLK_PLL_DIV:
-               snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
+               snd_soc_component_update_bits(component, AC97_LINE1_LEVEL,
                                    0x007f, div | 0x60);
                break;
        case WM9713_HIFI_PLL_DIV:
-               snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
+               snd_soc_component_update_bits(component, AC97_LINE1_LEVEL,
                                    0x007f, div | 0x70);
                break;
        default:
@@ -942,8 +942,8 @@ static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 gpio = snd_soc_read(codec, AC97_GPIO_CFG) & 0xffc5;
+       struct snd_soc_component *component = codec_dai->component;
+       u16 gpio = snd_soc_component_read32(component, AC97_GPIO_CFG) & 0xffc5;
        u16 reg = 0x8000;
 
        /* clock masters */
@@ -996,8 +996,8 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
                break;
        }
 
-       snd_soc_write(codec, AC97_GPIO_CFG, gpio);
-       snd_soc_write(codec, AC97_CENTER_LFE_MASTER, reg);
+       snd_soc_component_write(component, AC97_GPIO_CFG, gpio);
+       snd_soc_component_write(component, AC97_CENTER_LFE_MASTER, reg);
        return 0;
 }
 
@@ -1005,22 +1005,22 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
 
        /* enable PCM interface in master mode */
        switch (params_width(params)) {
        case 16:
                break;
        case 20:
-               snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+               snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
                                    0x000c, 0x0004);
                break;
        case 24:
-               snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+               snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
                                    0x000c, 0x0008);
                break;
        case 32:
-               snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
+               snd_soc_component_update_bits(component, AC97_CENTER_LFE_MASTER,
                                    0x000c, 0x000c);
                break;
        }
@@ -1030,33 +1030,33 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
 static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct snd_pcm_runtime *runtime = substream->runtime;
        int reg;
 
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                reg = AC97_PCM_FRONT_DAC_RATE;
        else
                reg = AC97_PCM_LR_ADC_RATE;
 
-       return snd_soc_write(codec, reg, runtime->rate);
+       return snd_soc_component_write(component, reg, runtime->rate);
 }
 
 static int ac97_aux_prepare(struct snd_pcm_substream *substream,
                            struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
-       snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000);
+       snd_soc_component_update_bits(component, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
+       snd_soc_component_update_bits(component, AC97_PCI_SID, 0x8000, 0x8000);
 
        if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
                return -ENODEV;
 
-       return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
+       return snd_soc_component_write(component, AC97_PCM_SURR_DAC_RATE, runtime->rate);
 }
 
 #define WM9713_RATES (SNDRV_PCM_RATE_8000  |   \
@@ -1142,48 +1142,48 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
        },
 };
 
-static int wm9713_set_bias_level(struct snd_soc_codec *codec,
+static int wm9713_set_bias_level(struct snd_soc_component *component,
                                 enum snd_soc_bias_level level)
 {
        switch (level) {
        case SND_SOC_BIAS_ON:
                /* enable thermal shutdown */
-               snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xe400, 0x0000);
+               snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0xe400, 0x0000);
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
        case SND_SOC_BIAS_STANDBY:
                /* enable master bias and vmid */
-               snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xc400, 0x0000);
-               snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
+               snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0xc400, 0x0000);
+               snd_soc_component_write(component, AC97_POWERDOWN, 0x0000);
                break;
        case SND_SOC_BIAS_OFF:
                /* disable everything including AC link */
-               snd_soc_write(codec, AC97_EXTENDED_MID, 0xffff);
-               snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
-               snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+               snd_soc_component_write(component, AC97_EXTENDED_MID, 0xffff);
+               snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
+               snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
                break;
        }
        return 0;
 }
 
-static int wm9713_soc_suspend(struct snd_soc_codec *codec)
+static int wm9713_soc_suspend(struct snd_soc_component *component)
 {
        /* Disable everything except touchpanel - that will be handled
         * by the touch driver and left disabled if touch is not in
         * use. */
-       snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x7fff,
+       snd_soc_component_update_bits(component, AC97_EXTENDED_MID, 0x7fff,
                                 0x7fff);
-       snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
-       snd_soc_write(codec, AC97_POWERDOWN, 0x6f00);
-       snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
+       snd_soc_component_write(component, AC97_EXTENDED_MSTATUS, 0xffff);
+       snd_soc_component_write(component, AC97_POWERDOWN, 0x6f00);
+       snd_soc_component_write(component, AC97_POWERDOWN, 0xffff);
 
        return 0;
 }
 
-static int wm9713_soc_resume(struct snd_soc_codec *codec)
+static int wm9713_soc_resume(struct snd_soc_component *component)
 {
-       struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+       struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID,
@@ -1191,24 +1191,24 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
        if (ret < 0)
                return ret;
 
-       snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
 
        /* do we need to re-start the PLL ? */
        if (wm9713->pll_in)
-               wm9713_set_pll(codec, 0, wm9713->pll_in, 0);
+               wm9713_set_pll(component, 0, wm9713->pll_in, 0);
 
        /* only synchronise the codec if warm reset failed */
        if (ret == 0) {
-               regcache_mark_dirty(codec->component.regmap);
-               snd_soc_cache_sync(codec);
+               regcache_mark_dirty(component->regmap);
+               snd_soc_component_cache_sync(component);
        }
 
        return ret;
 }
 
-static int wm9713_soc_probe(struct snd_soc_codec *codec)
+static int wm9713_soc_probe(struct snd_soc_component *component)
 {
-       struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+       struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
        struct regmap *regmap = NULL;
 
        if (wm9713->mfd_pdata) {
@@ -1216,54 +1216,54 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
                regmap = wm9713->mfd_pdata->regmap;
        } else {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-               wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
+               wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID,
                                                      WM9713_VENDOR_ID_MASK);
                if (IS_ERR(wm9713->ac97))
                        return PTR_ERR(wm9713->ac97);
                regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
                if (IS_ERR(regmap)) {
-                       snd_soc_free_ac97_codec(wm9713->ac97);
+                       snd_soc_free_ac97_component(wm9713->ac97);
                        return PTR_ERR(regmap);
                }
 #endif
        }
 
-       snd_soc_codec_init_regmap(codec, regmap);
+       snd_soc_component_init_regmap(component, regmap);
 
        /* unmute the adc - move to kcontrol */
-       snd_soc_update_bits(codec, AC97_CD, 0x7fff, 0x0000);
+       snd_soc_component_update_bits(component, AC97_CD, 0x7fff, 0x0000);
 
        return 0;
 }
 
-static int wm9713_soc_remove(struct snd_soc_codec *codec)
+static void wm9713_soc_remove(struct snd_soc_component *component)
 {
 #ifdef CONFIG_SND_SOC_AC97_BUS
-       struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
+       struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
 
        if (!wm9713->mfd_pdata) {
-               snd_soc_codec_exit_regmap(codec);
-               snd_soc_free_ac97_codec(wm9713->ac97);
+               snd_soc_component_exit_regmap(component);
+               snd_soc_free_ac97_component(wm9713->ac97);
        }
 #endif
-       return 0;
 }
 
-static const struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
-       .probe =        wm9713_soc_probe,
-       .remove =       wm9713_soc_remove,
-       .suspend =      wm9713_soc_suspend,
-       .resume =       wm9713_soc_resume,
-       .set_bias_level = wm9713_set_bias_level,
-
-       .component_driver = {
-               .controls               = wm9713_snd_ac97_controls,
-               .num_controls           = ARRAY_SIZE(wm9713_snd_ac97_controls),
-               .dapm_widgets           = wm9713_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(wm9713_dapm_widgets),
-               .dapm_routes            = wm9713_audio_map,
-               .num_dapm_routes        = ARRAY_SIZE(wm9713_audio_map),
-       },
+static const struct snd_soc_component_driver soc_component_dev_wm9713 = {
+       .probe                  = wm9713_soc_probe,
+       .remove                 = wm9713_soc_remove,
+       .suspend                = wm9713_soc_suspend,
+       .resume                 = wm9713_soc_resume,
+       .set_bias_level         = wm9713_set_bias_level,
+       .controls               = wm9713_snd_ac97_controls,
+       .num_controls           = ARRAY_SIZE(wm9713_snd_ac97_controls),
+       .dapm_widgets           = wm9713_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(wm9713_dapm_widgets),
+       .dapm_routes            = wm9713_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(wm9713_audio_map),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int wm9713_probe(struct platform_device *pdev)
@@ -1279,14 +1279,8 @@ static int wm9713_probe(struct platform_device *pdev)
        wm9713->mfd_pdata = dev_get_platdata(&pdev->dev);
        platform_set_drvdata(pdev, wm9713);
 
-       return snd_soc_register_codec(&pdev->dev,
-                       &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
-}
-
-static int wm9713_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_codec(&pdev->dev);
-       return 0;
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &soc_component_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
 }
 
 static struct platform_driver wm9713_codec_driver = {
@@ -1295,7 +1289,6 @@ static struct platform_driver wm9713_codec_driver = {
        },
 
        .probe = wm9713_probe,
-       .remove = wm9713_remove,
 };
 
 module_platform_driver(wm9713_codec_driver);
index 66e32f5d2917f2f0b958c124b5f4a0eeca296c10..1d7ed1bef842158d34f66d2ff0d3763ebec0c75c 100644 (file)
@@ -605,13 +605,13 @@ static const struct {
 };
 
 static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
-                                 struct snd_soc_codec *codec)
+                                 struct snd_soc_component *component)
 {
        struct dentry *root = NULL;
        char *root_name;
        int i;
 
-       if (!codec->component.debugfs_root) {
+       if (!component->debugfs_root) {
                adsp_err(dsp, "No codec debugfs root\n");
                goto err;
        }
@@ -621,7 +621,7 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
                goto err;
 
        snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num);
-       root = debugfs_create_dir(root_name, codec->component.debugfs_root);
+       root = debugfs_create_dir(root_name, component->debugfs_root);
        kfree(root_name);
 
        if (!root)
@@ -662,7 +662,7 @@ static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
 }
 #else
 static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
-                                        struct snd_soc_codec *codec)
+                                        struct snd_soc_component *component)
 {
 }
 
@@ -688,9 +688,9 @@ static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+       struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw;
 
@@ -700,9 +700,9 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
 static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+       struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
        int ret = 0;
 
        if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
@@ -1204,16 +1204,18 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
                kcontrol->put = wm_coeff_put_acked;
                break;
        default:
-               kcontrol->get = wm_coeff_get;
-               kcontrol->put = wm_coeff_put;
-
-               ctl->bytes_ext.max = ctl->len;
-               ctl->bytes_ext.get = wm_coeff_tlv_get;
-               ctl->bytes_ext.put = wm_coeff_tlv_put;
+               if (kcontrol->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
+                       ctl->bytes_ext.max = ctl->len;
+                       ctl->bytes_ext.get = wm_coeff_tlv_get;
+                       ctl->bytes_ext.put = wm_coeff_tlv_put;
+               } else {
+                       kcontrol->get = wm_coeff_get;
+                       kcontrol->put = wm_coeff_put;
+               }
                break;
        }
 
-       ret = snd_soc_add_codec_controls(dsp->codec, kcontrol, 1);
+       ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1);
        if (ret < 0)
                goto err_kcontrol;
 
@@ -2396,14 +2398,14 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol,
                   int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
        struct wm_adsp *dsp = &dsps[w->shift];
        struct wm_coeff_ctl *ctl;
        int ret;
        unsigned int val;
 
-       dsp->codec = codec;
+       dsp->component = component;
 
        mutex_lock(&dsp->pwr_lock);
 
@@ -2633,8 +2635,8 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
 int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = dsp->preloaded;
 
@@ -2645,9 +2647,9 @@ EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get);
 int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        char preload[32];
@@ -2683,8 +2685,8 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
                         struct snd_kcontrol *kcontrol, int event,
                         unsigned int freq)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
        struct wm_adsp *dsp = &dsps[w->shift];
        struct wm_coeff_ctl *ctl;
 
@@ -2726,8 +2728,8 @@ EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
 int wm_adsp2_event(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-       struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
        struct wm_adsp *dsp = &dsps[w->shift];
        int ret;
 
@@ -2841,31 +2843,31 @@ err:
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_event);
 
-int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec)
+int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component)
 {
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        char preload[32];
 
        snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num);
        snd_soc_dapm_disable_pin(dapm, preload);
 
-       wm_adsp2_init_debugfs(dsp, codec);
+       wm_adsp2_init_debugfs(dsp, component);
 
-       dsp->codec = codec;
+       dsp->component = component;
 
-       return snd_soc_add_codec_controls(codec,
+       return snd_soc_add_component_controls(component,
                                          &wm_adsp_fw_controls[dsp->num - 1],
                                          1);
 }
-EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe);
+EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
 
-int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec)
+int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component)
 {
        wm_adsp2_cleanup_debugfs(dsp);
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove);
+EXPORT_SYMBOL_GPL(wm_adsp2_component_remove);
 
 int wm_adsp2_init(struct wm_adsp *dsp)
 {
index 41cc11c19b837cbcdd815c18794d025e2156abfd..82d651ff9d73db71785013930712c3c48a3efb2d 100644 (file)
@@ -62,7 +62,7 @@ struct wm_adsp {
        int type;
        struct device *dev;
        struct regmap *regmap;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 
        int base;
        int sysclk_reg;
@@ -126,8 +126,8 @@ extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
 int wm_adsp1_init(struct wm_adsp *dsp);
 int wm_adsp2_init(struct wm_adsp *dsp);
 void wm_adsp2_remove(struct wm_adsp *dsp);
-int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec);
-int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec);
+int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component);
+int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component);
 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol, int event);
 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
index 3849616519048401a44e691db64945050b7a8d68..807040bb39215a714626da890339966791c7ab38 100644 (file)
@@ -34,6 +34,7 @@
 #include "edma-pcm.h"
 #include "davinci-i2s.h"
 
+#define DRV_NAME "davinci-i2s"
 
 /*
  * NOTE:  terminology here is confusing.
@@ -190,7 +191,7 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
                struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_platform *platform = rtd->platform;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
        u32 spcr;
        u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
@@ -211,8 +212,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
        if (playback) {
                /* Stop the DMA to avoid data loss */
                /* while the transmitter is out of reset to handle XSYNCERR */
-               if (platform->driver->ops->trigger) {
-                       int ret = platform->driver->ops->trigger(substream,
+               if (component->driver->ops->trigger) {
+                       int ret = component->driver->ops->trigger(substream,
                                SNDRV_PCM_TRIGGER_STOP);
                        if (ret < 0)
                                printk(KERN_DEBUG "Playback DMA stop failed\n");
@@ -233,8 +234,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
                toggle_clock(dev, playback);
 
                /* Restart the DMA */
-               if (platform->driver->ops->trigger) {
-                       int ret = platform->driver->ops->trigger(substream,
+               if (component->driver->ops->trigger) {
+                       int ret = component->driver->ops->trigger(substream,
                                SNDRV_PCM_TRIGGER_START);
                        if (ret < 0)
                                printk(KERN_DEBUG "Playback DMA start failed\n");
@@ -651,7 +652,7 @@ static struct snd_soc_dai_driver davinci_i2s_dai = {
 };
 
 static const struct snd_soc_component_driver davinci_i2s_component = {
-       .name           = "davinci-i2s",
+       .name           = DRV_NAME,
 };
 
 static int davinci_i2s_probe(struct platform_device *pdev)
index e27e21f8569a0e9719c2c90a801189dd0507c8a3..65112b9d8588ae75995e618741e6c88ec87d0abf 100644 (file)
@@ -491,6 +491,10 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
                        dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
                comp1 = comp1 & ~BIT(5);
 
+       if (dev->capability & DWC_I2S_PLAY &&
+                       dev->quirks & DW_I2S_QUIRK_COMP_PARAM1)
+               comp1 = comp1 & ~BIT(6);
+
        if (COMP1_TX_ENABLED(comp1)) {
                dev_dbg(dev->dev, " designware: play supported\n");
                idx = COMP1_TX_WORDSIZE_0(comp1);
index 406fd867117b84dcdbefa4381b511338e6e12285..2cc9632024fc39575a05b18d3385b449546c0cdb 100644 (file)
@@ -269,7 +269,7 @@ static const struct snd_pcm_ops dw_pcm_ops = {
        .pointer = dw_pcm_pointer,
 };
 
-static const struct snd_soc_platform_driver dw_pcm_platform = {
+static const struct snd_soc_component_driver dw_pcm_component = {
        .pcm_new = dw_pcm_new,
        .pcm_free = dw_pcm_free,
        .ops = &dw_pcm_ops,
@@ -277,5 +277,6 @@ static const struct snd_soc_platform_driver dw_pcm_platform = {
 
 int dw_pcm_register(struct platform_device *pdev)
 {
-       return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
+       return devm_snd_soc_register_component(&pdev->dev, &dw_pcm_component,
+                                              NULL, 0);
 }
index 37f9b6201918348098194e6eb8da5460b7a09640..6ec19fb4a934d08084b4e75016689a658bddce76 100644 (file)
@@ -231,17 +231,6 @@ config SND_SOC_EUKREA_TLV320
          Enable I2S based access to the TLV320AIC23B codec attached
          to the SSI interface
 
-config SND_SOC_IMX_WM8962
-       tristate "SoC Audio support for i.MX boards with wm8962"
-       depends on OF && I2C && INPUT
-       select SND_SOC_WM8962
-       select SND_SOC_IMX_PCM_DMA
-       select SND_SOC_IMX_AUDMUX
-       select SND_SOC_FSL_SSI
-       help
-         Say Y if you want to add support for SoC audio on an i.MX board with
-         a wm8962 codec.
-
 config SND_SOC_IMX_ES8328
        tristate "SoC Audio support for i.MX boards with the ES8328 codec"
        depends on OF && (I2C || SPI)
index c67bf1139e1e83fb6268b55e4a6e82c7b8a47c67..de94fa057e24bf0f0820a3d6b143f1dfa656736b 100644 (file)
@@ -55,7 +55,6 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
-snd-soc-imx-wm8962-objs := imx-wm8962.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
 
@@ -65,6 +64,5 @@ obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
 obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
-obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
index 989be518c4ed6aad92df786663033516911c97f1..4a6750aa36379e30ff5480d7200b8c2a1e73b80f 100644 (file)
@@ -91,9 +91,9 @@ struct fsl_asoc_card_priv {
        struct cpu_priv cpu_priv;
        struct snd_soc_card card;
        u32 sample_rate;
-       u32 sample_format;
+       snd_pcm_format_t sample_format;
        u32 asrc_rate;
-       u32 asrc_format;
+       snd_pcm_format_t asrc_format;
        u32 dai_fmt;
        char name[32];
 };
@@ -199,7 +199,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 
        mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
        snd_mask_none(mask);
-       snd_mask_set(mask, priv->asrc_format);
+       snd_mask_set(mask, (__force int)priv->asrc_format);
 
        return 0;
 }
index 806d39927318f97d55baf39739f8b7e14467f438..adfb8135d73996949d4ac2fee2399ffc0354719e 100644 (file)
@@ -582,10 +582,6 @@ static struct snd_soc_dai_driver fsl_asrc_dai = {
        .ops = &fsl_asrc_dai_ops,
 };
 
-static const struct snd_soc_component_driver fsl_asrc_component = {
-       .name = "fsl-asrc-dai",
-};
-
 static bool fsl_asrc_readable_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
@@ -927,12 +923,6 @@ static int fsl_asrc_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret = devm_snd_soc_register_platform(&pdev->dev, &fsl_asrc_platform);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register ASoC platform\n");
-               return ret;
-       }
-
        return 0;
 }
 
index 2c5856ac5bc31f7760c8bf4bed2db91454875375..d558dd5499a595675a861d60f23cf121458ba337 100644 (file)
@@ -462,6 +462,7 @@ struct fsl_asrc {
        u32 regcache_cfg;
 };
 
-extern struct snd_soc_platform_driver fsl_asrc_platform;
+#define DRV_NAME "fsl-asrc-dai"
+extern struct snd_soc_component_driver fsl_asrc_component;
 struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir);
 #endif /* _FSL_ASRC_H */
index e1b97e59275a9ebdc31f85cc7e8aa883b0ad1700..565e16d8fe853e9ec0f044f3f1eb1b23afb35430 100644 (file)
@@ -64,7 +64,8 @@ static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct fsl_asrc_pair *pair = runtime->private_data;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
        unsigned long flags = DMA_CTRL_ACK;
 
        /* Prepare and submit Front-End DMA channel */
@@ -137,12 +138,13 @@ static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
        struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
        struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct fsl_asrc_pair *pair = runtime->private_data;
        struct fsl_asrc *asrc_priv = pair->asrc_priv;
        struct dma_slave_config config_fe, config_be;
        enum asrc_pair_index index = pair->index;
-       struct device *dev = rtd->platform->dev;
+       struct device *dev = component->dev;
        int stream = substream->stream;
        struct imx_dma_data *tmp_data;
        struct snd_soc_dpcm *dpcm;
@@ -274,7 +276,8 @@ static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
        struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
        struct fsl_asrc_pair *pair;
 
@@ -381,9 +384,10 @@ static void fsl_asrc_dma_pcm_free(struct snd_pcm *pcm)
        }
 }
 
-struct snd_soc_platform_driver fsl_asrc_platform = {
+struct snd_soc_component_driver fsl_asrc_component = {
+       .name           = DRV_NAME,
        .ops            = &fsl_asrc_dma_pcm_ops,
        .pcm_new        = fsl_asrc_dma_pcm_new,
        .pcm_free       = fsl_asrc_dma_pcm_free,
 };
-EXPORT_SYMBOL_GPL(fsl_asrc_platform);
+EXPORT_SYMBOL_GPL(fsl_asrc_component);
index 8c2981b70f6451c54fd5d65d07e0664bd0672d74..fce2010d3c53fd0a41c5e6f7346ab0473eed2e49 100644 (file)
@@ -37,6 +37,8 @@
 #include "fsl_dma.h"
 #include "fsl_ssi.h"   /* For the offset of stx0 and srx0 */
 
+#define DRV_NAME "fsl_dma"
+
 /*
  * The formats that the DMA controller supports, which is anything
  * that is 8, 16, or 32 bits.
@@ -56,7 +58,7 @@
                            SNDRV_PCM_FMTBIT_U32_LE     | \
                            SNDRV_PCM_FMTBIT_U32_BE)
 struct dma_object {
-       struct snd_soc_platform_driver dai;
+       struct snd_soc_component_driver dai;
        dma_addr_t ssi_stx_phys;
        dma_addr_t ssi_srx_phys;
        unsigned int ssi_fifo_depth;
@@ -203,7 +205,8 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
        struct fsl_dma_private *dma_private = dev_id;
        struct snd_pcm_substream *substream = dma_private->substream;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
        struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
        irqreturn_t ret = IRQ_NONE;
        u32 sr, sr2 = 0;
@@ -385,9 +388,10 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
        struct dma_object *dma =
-               container_of(rtd->platform->driver, struct dma_object, dai);
+               container_of(component->driver, struct dma_object, dai);
        struct fsl_dma_private *dma_private;
        struct ccsr_dma_channel __iomem *dma_channel;
        dma_addr_t ld_buf_phys;
@@ -539,7 +543,8 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct fsl_dma_private *dma_private = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
 
        /* Number of bits per sample */
        unsigned int sample_bits =
@@ -702,7 +707,8 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct fsl_dma_private *dma_private = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
        struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
        dma_addr_t position;
        snd_pcm_uframes_t frames;
@@ -799,9 +805,10 @@ static int fsl_dma_close(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct fsl_dma_private *dma_private = runtime->private_data;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct device *dev = rtd->platform->dev;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct device *dev = component->dev;
        struct dma_object *dma =
-               container_of(rtd->platform->driver, struct dma_object, dai);
+               container_of(component->driver, struct dma_object, dai);
 
        if (dma_private) {
                if (dma_private->irq)
@@ -908,6 +915,7 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       dma->dai.name = DRV_NAME;
        dma->dai.ops = &fsl_dma_ops;
        dma->dai.pcm_new = fsl_dma_new;
        dma->dai.pcm_free = fsl_dma_free_dma_buffers;
@@ -925,7 +933,7 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
 
        of_node_put(ssi_np);
 
-       ret = snd_soc_register_platform(&pdev->dev, &dma->dai);
+       ret = devm_snd_soc_register_component(&pdev->dev, &dma->dai, NULL, 0);
        if (ret) {
                dev_err(&pdev->dev, "could not register platform\n");
                kfree(dma);
@@ -944,7 +952,6 @@ static int fsl_soc_dma_remove(struct platform_device *pdev)
 {
        struct dma_object *dma = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_platform(&pdev->dev);
        iounmap(dma->channel);
        irq_dispose_mapping(dma->irq);
        kfree(dma);
index cef79a1a620b7dc3105572e6987c358da8db8a30..40a700493f4c8f0d3dec67956ee8afb8b20c37f3 100644 (file)
@@ -788,7 +788,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct fsl_esai *esai_priv;
        struct resource *res;
-       const uint32_t *iprop;
+       const __be32 *iprop;
        void __iomem *regs;
        int irq, ret;
 
index aecd00f7929d9ee67dd25be751fe6b4765792157..0823b08923b5ef5d0860c14807af75f899eed0ed 100644 (file)
 #include "fsl_ssi.h"
 #include "imx-pcm.h"
 
+/* Define RX and TX to index ssi->regvals array; Can be 0 or 1 only */
+#define RX 0
+#define TX 1
+
 /**
  * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
  *
         SNDRV_PCM_FMTBIT_S24_LE)
 #endif
 
+/*
+ * In AC97 mode, TXDIR bit is forced to 0 and TFDIR bit is forced to 1:
+ *  - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS
+ *  - Also have NB_NF to mark these two clocks will not be inverted
+ */
+#define FSLSSI_AC97_DAIFMT \
+       (SND_SOC_DAIFMT_AC97 | \
+        SND_SOC_DAIFMT_CBM_CFS | \
+        SND_SOC_DAIFMT_NB_NF)
+
 #define FSLSSI_SIER_DBG_RX_FLAGS \
        (SSI_SIER_RFF0_EN | \
         SSI_SIER_RLS_EN | \
@@ -201,7 +215,9 @@ struct fsl_ssi_soc_data {
  * @cpu_dai_drv: CPU DAI driver for this device
  *
  * @dai_fmt: DAI configuration this device is currently used with
+ * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
  * @i2s_net: I2S and Network mode configurations of SCR register
+ * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
  * @use_dma: DMA is used or FIQ with stream filter
  * @use_dual_fifo: DMA with support for dual FIFO mode
  * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree
@@ -223,8 +239,12 @@ struct fsl_ssi_soc_data {
  *
  * @fiq_params: FIQ stream filtering parameters
  *
- * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only)
- *        TODO: Should be replaced with simple-sound-card
+ * @card_pdev: Platform_device pointer to register a sound card for PowerPC or
+ *             to register a CODEC platform device for AC97
+ * @card_name: Platform_device name to register a sound card for PowerPC or
+ *             to register a CODEC platform device for AC97
+ * @card_idx: The index of SSI to register a sound card for PowerPC or
+ *            to register a CODEC platform device for AC97
  *
  * @dbg_stats: Debugging statistics
  *
@@ -245,7 +265,9 @@ struct fsl_ssi {
        struct snd_soc_dai_driver cpu_dai_drv;
 
        unsigned int dai_fmt;
+       u8 streams;
        u8 i2s_net;
+       bool synchronous;
        bool use_dma;
        bool use_dual_fifo;
        bool has_ipg_clk_name;
@@ -267,7 +289,9 @@ struct fsl_ssi {
 
        struct imx_pcm_fiq_params fiq_params;
 
-       struct platform_device *pdev;
+       struct platform_device *card_pdev;
+       char card_name[32];
+       u32 card_idx;
 
        struct fsl_ssi_dbg dbg_stats;
 
@@ -376,181 +400,172 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 }
 
 /**
- * Enable or disable all rx/tx config flags at once
+ * Set SCR, SIER, STCR and SRCR registers with cached values in regvals
+ *
+ * Notes:
+ * 1) For offline_config SoCs, enable all necessary bits of both streams
+ *    when 1st stream starts, even if the opposite stream will not start
+ * 2) It also clears FIFO before setting regvals; SOR is safe to set online
  */
-static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
+static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx)
 {
-       struct regmap *regs = ssi->regs;
        struct fsl_ssi_regvals *vals = ssi->regvals;
+       int dir = tx ? TX : RX;
+       u32 sier, srcr, stcr;
+
+       /* Clear dirty data in the FIFO; It also prevents channel slipping */
+       regmap_update_bits(ssi->regs, REG_SSI_SOR,
+                          SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
+
+       /*
+        * On offline_config SoCs, SxCR and SIER are already configured when
+        * the previous stream started. So skip all SxCR and SIER settings
+        * to prevent online reconfigurations, then jump to set SCR directly
+        */
+       if (ssi->soc->offline_config && ssi->streams)
+               goto enable_scr;
 
-       if (enable) {
-               regmap_update_bits(regs, REG_SSI_SIER,
-                                  vals[RX].sier | vals[TX].sier,
-                                  vals[RX].sier | vals[TX].sier);
-               regmap_update_bits(regs, REG_SSI_SRCR,
-                                  vals[RX].srcr | vals[TX].srcr,
-                                  vals[RX].srcr | vals[TX].srcr);
-               regmap_update_bits(regs, REG_SSI_STCR,
-                                  vals[RX].stcr | vals[TX].stcr,
-                                  vals[RX].stcr | vals[TX].stcr);
+       if (ssi->soc->offline_config) {
+               /*
+                * Online reconfiguration not supported, so enable all bits for
+                * both streams at once to avoid necessity of reconfigurations
+                */
+               srcr = vals[RX].srcr | vals[TX].srcr;
+               stcr = vals[RX].stcr | vals[TX].stcr;
+               sier = vals[RX].sier | vals[TX].sier;
        } else {
-               regmap_update_bits(regs, REG_SSI_SRCR,
-                                  vals[RX].srcr | vals[TX].srcr, 0);
-               regmap_update_bits(regs, REG_SSI_STCR,
-                                  vals[RX].stcr | vals[TX].stcr, 0);
-               regmap_update_bits(regs, REG_SSI_SIER,
-                                  vals[RX].sier | vals[TX].sier, 0);
+               /* Otherwise, only set bits for the current stream */
+               srcr = vals[dir].srcr;
+               stcr = vals[dir].stcr;
+               sier = vals[dir].sier;
        }
-}
 
-/**
- * Clear remaining data in the FIFO to avoid dirty data or channel slipping
- */
-static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
-{
-       bool tx = !is_rx;
+       /* Configure SRCR, STCR and SIER at once */
+       regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, srcr);
+       regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, stcr);
+       regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, sier);
 
-       regmap_update_bits(ssi->regs, REG_SSI_SOR,
-                          SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
+enable_scr:
+       /*
+        * Start DMA before setting TE to avoid FIFO underrun
+        * which may cause a channel slip or a channel swap
+        *
+        * TODO: FIQ cases might also need this upon testing
+        */
+       if (ssi->use_dma && tx) {
+               int try = 100;
+               u32 sfcsr;
+
+               /* Enable SSI first to send TX DMA request */
+               regmap_update_bits(ssi->regs, REG_SSI_SCR,
+                                  SSI_SCR_SSIEN, SSI_SCR_SSIEN);
+
+               /* Busy wait until TX FIFO not empty -- DMA working */
+               do {
+                       regmap_read(ssi->regs, REG_SSI_SFCSR, &sfcsr);
+                       if (SSI_SFCSR_TFCNT0(sfcsr))
+                               break;
+               } while (--try);
+
+               /* FIFO still empty -- something might be wrong */
+               if (!SSI_SFCSR_TFCNT0(sfcsr))
+                       dev_warn(ssi->dev, "Timeout waiting TX FIFO filling\n");
+       }
+       /* Enable all remaining bits in SCR */
+       regmap_update_bits(ssi->regs, REG_SSI_SCR,
+                          vals[dir].scr, vals[dir].scr);
+
+       /* Log the enabled stream to the mask */
+       ssi->streams |= BIT(dir);
 }
 
 /**
- * Calculate the bits that have to be disabled for the current stream that is
- * getting disabled. This keeps the bits enabled that are necessary for the
- * second stream to work if 'stream_active' is true.
+ * Exclude bits that are used by the opposite stream
  *
- * Detailed calculation:
- * These are the values that need to be active after disabling. For non-active
- * second stream, this is 0:
- *     vals_stream * !!stream_active
+ * When both streams are active, disabling some bits for the current stream
+ * might break the other stream if these bits are used by it.
  *
- * The following computes the overall differences between the setup for the
- * to-disable stream and the active stream, a simple XOR:
- *     vals_disable ^ (vals_stream * !!(stream_active))
+ * @vals : regvals of the current stream
+ * @avals: regvals of the opposite stream
+ * @aactive: active state of the opposite stream
  *
- * The full expression adds a mask on all values we care about
+ *  1) XOR vals and avals to get the differences if the other stream is active;
+ *     Otherwise, return current vals if the other stream is not active
+ *  2) AND the result of 1) with the current vals
  */
-#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \
-       ((vals_disable) & \
-        ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active))))
+#define _ssi_xor_shared_bits(vals, avals, aactive) \
+       ((vals) ^ ((avals) * (aactive)))
+
+#define ssi_excl_shared_bits(vals, avals, aactive) \
+       ((vals) & _ssi_xor_shared_bits(vals, avals, aactive))
 
 /**
- * Enable or disable SSI configuration.
+ * Unset SCR, SIER, STCR and SRCR registers with cached values in regvals
+ *
+ * Notes:
+ * 1) For offline_config SoCs, to avoid online reconfigurations, disable all
+ *    bits of both streams at once when the last stream is abort to end
+ * 2) It also clears FIFO after unsetting regvals; SOR is safe to set online
  */
-static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
-                          struct fsl_ssi_regvals *vals)
+static void fsl_ssi_config_disable(struct fsl_ssi *ssi, bool tx)
 {
-       struct regmap *regs = ssi->regs;
-       struct fsl_ssi_regvals *avals;
-       int nr_active_streams;
-       u32 scr;
-       int keep_active;
-
-       regmap_read(regs, REG_SSI_SCR, &scr);
+       struct fsl_ssi_regvals *vals, *avals;
+       u32 sier, srcr, stcr, scr;
+       int adir = tx ? RX : TX;
+       int dir = tx ? TX : RX;
+       bool aactive;
 
-       nr_active_streams = !!(scr & SSI_SCR_TE) + !!(scr & SSI_SCR_RE);
+       /* Check if the opposite stream is active */
+       aactive = ssi->streams & BIT(adir);
 
-       if (nr_active_streams - 1 > 0)
-               keep_active = 1;
-       else
-               keep_active = 0;
+       vals = &ssi->regvals[dir];
 
-       /* Get the opposite direction to keep its values untouched */
-       if (&ssi->regvals[RX] == vals)
-               avals = &ssi->regvals[TX];
-       else
-               avals = &ssi->regvals[RX];
-
-       if (!enable) {
-               /*
-                * To keep the other stream safe, exclude shared bits between
-                * both streams, and get safe bits to disable current stream
-                */
-               u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr,
-                                             keep_active);
-               /* Safely disable SCR register for the stream */
-               regmap_update_bits(regs, REG_SSI_SCR, scr, 0);
-       }
+       /* Get regvals of the opposite stream to keep opposite stream safe */
+       avals = &ssi->regvals[adir];
 
        /*
-        * For cases where online configuration is not supported,
-        * 1) Enable all necessary bits of both streams when 1st stream starts
-        *    even if the opposite stream will not start
-        * 2) Disable all remaining bits of both streams when last stream ends
+        * To keep the other stream safe, exclude shared bits between
+        * both streams, and get safe bits to disable current stream
         */
-       if (ssi->soc->offline_config) {
-               if ((enable && !nr_active_streams) || (!enable && !keep_active))
-                       fsl_ssi_rxtx_config(ssi, enable);
+       scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
 
-               goto config_done;
-       }
+       /* Disable safe bits of SCR register for the current stream */
+       regmap_update_bits(ssi->regs, REG_SSI_SCR, scr, 0);
 
-       /* Online configure single direction while SSI is running */
-       if (enable) {
-               fsl_ssi_fifo_clear(ssi, vals->scr & SSI_SCR_RE);
+       /* Log the disabled stream to the mask */
+       ssi->streams &= ~BIT(dir);
 
-               regmap_update_bits(regs, REG_SSI_SRCR, vals->srcr, vals->srcr);
-               regmap_update_bits(regs, REG_SSI_STCR, vals->stcr, vals->stcr);
-               regmap_update_bits(regs, REG_SSI_SIER, vals->sier, vals->sier);
-       } else {
-               u32 sier;
-               u32 srcr;
-               u32 stcr;
+       /*
+        * On offline_config SoCs, if the other stream is active, skip
+        * SxCR and SIER settings to prevent online reconfigurations
+        */
+       if (ssi->soc->offline_config && aactive)
+               goto fifo_clear;
 
+       if (ssi->soc->offline_config) {
+               /* Now there is only current stream active, disable all bits */
+               srcr = vals->srcr | avals->srcr;
+               stcr = vals->stcr | avals->stcr;
+               sier = vals->sier | avals->sier;
+       } else {
                /*
                 * To keep the other stream safe, exclude shared bits between
                 * both streams, and get safe bits to disable current stream
                 */
-               sier = fsl_ssi_disable_val(vals->sier, avals->sier,
-                                          keep_active);
-               srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr,
-                                          keep_active);
-               stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr,
-                                          keep_active);
-
-               /* Safely disable other control registers for the stream */
-               regmap_update_bits(regs, REG_SSI_SRCR, srcr, 0);
-               regmap_update_bits(regs, REG_SSI_STCR, stcr, 0);
-               regmap_update_bits(regs, REG_SSI_SIER, sier, 0);
+               sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive);
+               srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive);
+               stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive);
        }
 
-config_done:
-       /* Enabling of subunits is done after configuration */
-       if (enable) {
-               /*
-                * Start DMA before setting TE to avoid FIFO underrun
-                * which may cause a channel slip or a channel swap
-                *
-                * TODO: FIQ cases might also need this upon testing
-                */
-               if (ssi->use_dma && (vals->scr & SSI_SCR_TE)) {
-                       int i;
-                       int max_loop = 100;
-
-                       /* Enable SSI first to send TX DMA request */
-                       regmap_update_bits(regs, REG_SSI_SCR,
-                                          SSI_SCR_SSIEN, SSI_SCR_SSIEN);
-
-                       /* Busy wait until TX FIFO not empty -- DMA working */
-                       for (i = 0; i < max_loop; i++) {
-                               u32 sfcsr;
-                               regmap_read(regs, REG_SSI_SFCSR, &sfcsr);
-                               if (SSI_SFCSR_TFCNT0(sfcsr))
-                                       break;
-                       }
-                       if (i == max_loop) {
-                               dev_err(ssi->dev,
-                                       "Timeout waiting TX FIFO filling\n");
-                       }
-               }
-               /* Enable all remaining bits */
-               regmap_update_bits(regs, REG_SSI_SCR, vals->scr, vals->scr);
-       }
-}
+       /* Clear configurations of SRCR, STCR and SIER at once */
+       regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, 0);
+       regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, 0);
+       regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, 0);
 
-static void fsl_ssi_rx_config(struct fsl_ssi *ssi, bool enable)
-{
-       fsl_ssi_config(ssi, enable, &ssi->regvals[RX]);
+fifo_clear:
+       /* Clear remaining data in the FIFO */
+       regmap_update_bits(ssi->regs, REG_SSI_SOR,
+                          SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
 }
 
 static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
@@ -566,21 +581,6 @@ static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
        }
 }
 
-static void fsl_ssi_tx_config(struct fsl_ssi *ssi, bool enable)
-{
-       /*
-        * SACCST might be modified via AC Link by a CODEC if it sends
-        * extra bits in their SLOTREQ requests, which'll accidentally
-        * send valid data to slots other than normal playback slots.
-        *
-        * To be safe, configure SACCST right before TX starts.
-        */
-       if (enable && fsl_ssi_is_ac97(ssi))
-               fsl_ssi_tx_ac97_saccst_setup(ssi);
-
-       fsl_ssi_config(ssi, enable, &ssi->regvals[TX]);
-}
-
 /**
  * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely
  */
@@ -588,17 +588,20 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
 {
        struct fsl_ssi_regvals *vals = ssi->regvals;
 
-       vals[RX].sier = SSI_SIER_RFF0_EN;
+       vals[RX].sier = SSI_SIER_RFF0_EN | FSLSSI_SIER_DBG_RX_FLAGS;
        vals[RX].srcr = SSI_SRCR_RFEN0;
-       vals[RX].scr = 0;
-       vals[TX].sier = SSI_SIER_TFE0_EN;
+       vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
+       vals[TX].sier = SSI_SIER_TFE0_EN | FSLSSI_SIER_DBG_TX_FLAGS;
        vals[TX].stcr = SSI_STCR_TFEN0;
-       vals[TX].scr = 0;
+       vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
 
        /* AC97 has already enabled SSIEN, RE and TE, so ignore them */
-       if (!fsl_ssi_is_ac97(ssi)) {
-               vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
-               vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
+       if (fsl_ssi_is_ac97(ssi))
+               vals[RX].scr = vals[TX].scr = 0;
+
+       if (ssi->use_dual_fifo) {
+               vals[RX].srcr |= SSI_SRCR_RFEN1;
+               vals[TX].stcr |= SSI_STCR_TFEN1;
        }
 
        if (ssi->use_dma) {
@@ -608,9 +611,6 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
                vals[RX].sier |= SSI_SIER_RIE;
                vals[TX].sier |= SSI_SIER_TIE;
        }
-
-       vals[RX].sier |= FSLSSI_SIER_DBG_RX_FLAGS;
-       vals[TX].sier |= FSLSSI_SIER_DBG_TX_FLAGS;
 }
 
 static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi)
@@ -681,7 +681,6 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
        bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
        struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
        struct regmap *regs = ssi->regs;
-       int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret;
        u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
        unsigned long clkrate, baudrate, tmprate;
        unsigned int slots = params_channels(hw_params);
@@ -689,6 +688,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
        u64 sub, savesub = 100000;
        unsigned int freq;
        bool baudclk_is_used;
+       int ret;
 
        /* Override slots and slot_width if being specifically set... */
        if (ssi->slots)
@@ -767,7 +767,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
        mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR;
 
        /* STCCR is used for RX in synchronous mode */
-       tx2 = tx || synchronous;
+       tx2 = tx || ssi->synchronous;
        regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr);
 
        if (!baudclk_is_used) {
@@ -803,11 +803,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
        unsigned int sample_size = params_width(hw_params);
        u32 wl = SSI_SxCCR_WL(sample_size);
        int ret;
-       u32 scr;
-       int enabled;
-
-       regmap_read(regs, REG_SSI_SCR, &scr);
-       enabled = scr & SSI_SCR_SSIEN;
 
        /*
         * SSI is properly configured if it is enabled and running in
@@ -815,7 +810,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
         * that should set separate configurations for STCCR and SRCCR
         * despite running in the synchronous mode.
         */
-       if (enabled && ssi->cpu_dai_drv.symmetric_rates)
+       if (ssi->streams && ssi->synchronous)
                return 0;
 
        if (fsl_ssi_is_i2s_master(ssi)) {
@@ -834,20 +829,20 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (!fsl_ssi_is_ac97(ssi)) {
-               u8 i2s_net;
                /* Normal + Network mode to send 16-bit data in 32-bit frames */
                if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
-                       i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
-               else
-                       i2s_net = ssi->i2s_net;
+                       ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
+
+               /* Use Normal mode to send mono data at 1st slot of 2 slots */
+               if (channels == 1)
+                       ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL;
 
                regmap_update_bits(regs, REG_SSI_SCR,
-                                  SSI_SCR_I2S_NET_MASK,
-                                  channels == 1 ? 0 : i2s_net);
+                                  SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
        }
 
        /* In synchronous mode, the SSI uses STCCR for capture */
-       tx2 = tx || ssi->cpu_dai_drv.symmetric_rates;
+       tx2 = tx || ssi->synchronous;
        regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl);
 
        return 0;
@@ -868,45 +863,31 @@ static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int _fsl_ssi_set_dai_fmt(struct device *dev,
-                               struct fsl_ssi *ssi, unsigned int fmt)
+static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt)
 {
-       struct regmap *regs = ssi->regs;
-       u32 strcr = 0, stcr, srcr, scr, mask;
-       u8 wm;
+       u32 strcr = 0, scr = 0, stcr, srcr, mask;
 
        ssi->dai_fmt = fmt;
 
-       if (fsl_ssi_is_i2s_master(ssi) && IS_ERR(ssi->baudclk)) {
-               dev_err(dev, "missing baudclk for master mode\n");
-               return -EINVAL;
-       }
-
-       fsl_ssi_setup_regvals(ssi);
-
-       regmap_read(regs, REG_SSI_SCR, &scr);
-       scr &= ~(SSI_SCR_SYN | SSI_SCR_I2S_MODE_MASK);
        /* Synchronize frame sync clock for TE to avoid data slipping */
        scr |= SSI_SCR_SYNC_TX_FS;
 
-       mask = SSI_STCR_TXBIT0 | SSI_STCR_TFDIR | SSI_STCR_TXDIR |
-              SSI_STCR_TSCKP | SSI_STCR_TFSI | SSI_STCR_TFSL | SSI_STCR_TEFS;
-       regmap_read(regs, REG_SSI_STCR, &stcr);
-       regmap_read(regs, REG_SSI_SRCR, &srcr);
-       stcr &= ~mask;
-       srcr &= ~mask;
+       /* Set to default shifting settings: LSB_ALIGNED */
+       strcr |= SSI_STCR_TXBIT0;
 
        /* Use Network mode as default */
        ssi->i2s_net = SSI_SCR_NET;
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               regmap_update_bits(regs, REG_SSI_STCCR,
-                                  SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
-               regmap_update_bits(regs, REG_SSI_SRCCR,
-                                  SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-               case SND_SOC_DAIFMT_CBM_CFS:
                case SND_SOC_DAIFMT_CBS_CFS:
+                       if (IS_ERR(ssi->baudclk)) {
+                               dev_err(ssi->dev,
+                                       "missing baudclk for master mode\n");
+                               return -EINVAL;
+                       }
+                       /* fall through */
+               case SND_SOC_DAIFMT_CBM_CFS:
                        ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER;
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
@@ -916,30 +897,34 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
                        return -EINVAL;
                }
 
+               regmap_update_bits(ssi->regs, REG_SSI_STCCR,
+                                  SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
+               regmap_update_bits(ssi->regs, REG_SSI_SRCCR,
+                                  SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2));
+
                /* Data on rising edge of bclk, frame low, 1clk before data */
-               strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP |
-                        SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+               strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP | SSI_STCR_TEFS;
                break;
        case SND_SOC_DAIFMT_LEFT_J:
                /* Data on rising edge of bclk, frame high */
-               strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
+               strcr |= SSI_STCR_TSCKP;
                break;
        case SND_SOC_DAIFMT_DSP_A:
                /* Data on rising edge of bclk, frame high, 1clk before data */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP |
-                        SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
+               strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | SSI_STCR_TEFS;
                break;
        case SND_SOC_DAIFMT_DSP_B:
                /* Data on rising edge of bclk, frame high */
-               strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | SSI_STCR_TXBIT0;
+               strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP;
                break;
        case SND_SOC_DAIFMT_AC97:
                /* Data on falling edge of bclk, frame high, 1clk before data */
-               ssi->i2s_net |= SSI_SCR_I2S_MODE_NORMAL;
+               strcr |= SSI_STCR_TEFS;
                break;
        default:
                return -EINVAL;
        }
+
        scr |= ssi->i2s_net;
 
        /* DAI clock inversion */
@@ -973,49 +958,33 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
                break;
        case SND_SOC_DAIFMT_CBM_CFM:
                /* Input bit or frame sync clocks */
-               scr &= ~SSI_SCR_SYS_CLK_EN;
                break;
        case SND_SOC_DAIFMT_CBM_CFS:
                /* Input bit clock but output frame sync clock */
-               strcr &= ~SSI_STCR_TXDIR;
                strcr |= SSI_STCR_TFDIR;
-               scr &= ~SSI_SCR_SYS_CLK_EN;
                break;
        default:
-               if (!fsl_ssi_is_ac97(ssi))
-                       return -EINVAL;
+               return -EINVAL;
        }
 
-       stcr |= strcr;
-       srcr |= strcr;
+       stcr = strcr;
+       srcr = strcr;
 
        /* Set SYN mode and clear RXDIR bit when using SYN or AC97 mode */
-       if (ssi->cpu_dai_drv.symmetric_rates || fsl_ssi_is_ac97(ssi)) {
+       if (ssi->synchronous || fsl_ssi_is_ac97(ssi)) {
                srcr &= ~SSI_SRCR_RXDIR;
                scr |= SSI_SCR_SYN;
        }
 
-       regmap_write(regs, REG_SSI_STCR, stcr);
-       regmap_write(regs, REG_SSI_SRCR, srcr);
-       regmap_write(regs, REG_SSI_SCR, scr);
+       mask = SSI_STCR_TFDIR | SSI_STCR_TXDIR | SSI_STCR_TSCKP |
+              SSI_STCR_TFSL | SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
 
-       wm = ssi->fifo_watermark;
+       regmap_update_bits(ssi->regs, REG_SSI_STCR, mask, stcr);
+       regmap_update_bits(ssi->regs, REG_SSI_SRCR, mask, srcr);
 
-       regmap_write(regs, REG_SSI_SFCSR,
-                    SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
-                    SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));
-
-       if (ssi->use_dual_fifo) {
-               regmap_update_bits(regs, REG_SSI_SRCR,
-                                  SSI_SRCR_RFEN1, SSI_SRCR_RFEN1);
-               regmap_update_bits(regs, REG_SSI_STCR,
-                                  SSI_STCR_TFEN1, SSI_STCR_TFEN1);
-               regmap_update_bits(regs, REG_SSI_SCR,
-                                  SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);
-       }
-
-       if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
-               fsl_ssi_setup_ac97(ssi);
+       mask = SSI_SCR_SYNC_TX_FS | SSI_SCR_I2S_MODE_MASK |
+              SSI_SCR_SYS_CLK_EN | SSI_SCR_SYN;
+       regmap_update_bits(ssi->regs, REG_SSI_SCR, mask, scr);
 
        return 0;
 }
@@ -1031,7 +1000,7 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        if (fsl_ssi_is_ac97(ssi))
                return 0;
 
-       return _fsl_ssi_set_dai_fmt(dai->dev, ssi, fmt);
+       return _fsl_ssi_set_dai_fmt(ssi, fmt);
 }
 
 /**
@@ -1051,9 +1020,7 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
        }
 
        /* The slot number should be >= 2 if using Network mode or I2S mode */
-       regmap_read(regs, REG_SSI_SCR, &val);
-       val &= SSI_SCR_I2S_MODE_MASK | SSI_SCR_NET;
-       if (val && slots < 2) {
+       if (ssi->i2s_net && slots < 2) {
                dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n");
                return -EINVAL;
        }
@@ -1063,9 +1030,8 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
        regmap_update_bits(regs, REG_SSI_SRCCR,
                           SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots));
 
-       /* Save SSIEN bit of the SCR register */
+       /* Save the SCR register value */
        regmap_read(regs, REG_SSI_SCR, &val);
-       val &= SSI_SCR_SSIEN;
        /* Temporarily enable SSI to allow SxMSKs to be configurable */
        regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN);
 
@@ -1092,39 +1058,34 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
-       struct regmap *regs = ssi->regs;
+       bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       fsl_ssi_tx_config(ssi, true);
-               else
-                       fsl_ssi_rx_config(ssi, true);
+               /*
+                * SACCST might be modified via AC Link by a CODEC if it sends
+                * extra bits in their SLOTREQ requests, which'll accidentally
+                * send valid data to slots other than normal playback slots.
+                *
+                * To be safe, configure SACCST right before TX starts.
+                */
+               if (tx && fsl_ssi_is_ac97(ssi))
+                       fsl_ssi_tx_ac97_saccst_setup(ssi);
+               fsl_ssi_config_enable(ssi, tx);
                break;
 
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       fsl_ssi_tx_config(ssi, false);
-               else
-                       fsl_ssi_rx_config(ssi, false);
+               fsl_ssi_config_disable(ssi, tx);
                break;
 
        default:
                return -EINVAL;
        }
 
-       /* Clear corresponding FIFO */
-       if (fsl_ssi_is_ac97(ssi)) {
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       regmap_write(regs, REG_SSI_SOR, SSI_SOR_TX_CLR);
-               else
-                       regmap_write(regs, REG_SSI_SOR, SSI_SOR_RX_CLR);
-       }
-
        return 0;
 }
 
@@ -1132,10 +1093,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
 {
        struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
 
-       if (ssi->soc->imx && ssi->use_dma) {
-               dai->playback_dma_data = &ssi->dma_params_tx;
-               dai->capture_dma_data = &ssi->dma_params_rx;
-       }
+       if (ssi->soc->imx && ssi->use_dma)
+               snd_soc_dai_init_dma_data(dai, &ssi->dma_params_tx,
+                                         &ssi->dma_params_rx);
 
        return 0;
 }
@@ -1175,6 +1135,7 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
 
 static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
        .bus_control = true,
+       .symmetric_channels = 1,
        .probe = fsl_ssi_dai_probe,
        .playback = {
                .stream_name = "AC97 Playback",
@@ -1271,6 +1232,53 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
        .write = fsl_ssi_ac97_write,
 };
 
+/**
+ * Initialize SSI registers
+ */
+static int fsl_ssi_hw_init(struct fsl_ssi *ssi)
+{
+       u32 wm = ssi->fifo_watermark;
+
+       /* Initialize regvals */
+       fsl_ssi_setup_regvals(ssi);
+
+       /* Set watermarks */
+       regmap_write(ssi->regs, REG_SSI_SFCSR,
+                    SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
+                    SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));
+
+       /* Enable Dual FIFO mode */
+       if (ssi->use_dual_fifo)
+               regmap_update_bits(ssi->regs, REG_SSI_SCR,
+                                  SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);
+
+       /* AC97 should start earlier to communicate with CODECs */
+       if (fsl_ssi_is_ac97(ssi)) {
+               _fsl_ssi_set_dai_fmt(ssi, ssi->dai_fmt);
+               fsl_ssi_setup_ac97(ssi);
+       }
+
+       return 0;
+}
+
+/**
+ * Clear SSI registers
+ */
+static void fsl_ssi_hw_clean(struct fsl_ssi *ssi)
+{
+       /* Disable registers for AC97 */
+       if (fsl_ssi_is_ac97(ssi)) {
+               /* Disable TE and RE bits first */
+               regmap_update_bits(ssi->regs, REG_SSI_SCR,
+                                  SSI_SCR_TE | SSI_SCR_RE, 0);
+               /* Disable AC97 mode */
+               regmap_write(ssi->regs, REG_SSI_SACNT, 0);
+               /* Unset WAIT bits */
+               regmap_write(ssi->regs, REG_SSI_SOR, 0);
+               /* Disable SSI -- software reset */
+               regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0);
+       }
+}
 /**
  * Make every character in a string lower-case
  */
@@ -1285,9 +1293,7 @@ static void make_lowercase(char *s)
 static int fsl_ssi_imx_probe(struct platform_device *pdev,
                             struct fsl_ssi *ssi, void __iomem *iomem)
 {
-       struct device_node *np = pdev->dev.of_node;
        struct device *dev = &pdev->dev;
-       u32 dmas[4];
        int ret;
 
        /* Backward compatible for a DT without ipg clock name assigned */
@@ -1321,14 +1327,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
        ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0;
        ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0;
 
-       /* Set to dual FIFO mode according to the SDMA sciprt */
-       ret = of_property_read_u32_array(np, "dmas", dmas, 4);
-       if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
-               ssi->use_dual_fifo = true;
-               /*
-                * Use even numbers to avoid channel swap due to SDMA
-                * script design
-                */
+       /* Use even numbers to avoid channel swap due to SDMA script design */
+       if (ssi->use_dual_fifo) {
                ssi->dma_params_tx.maxburst &= ~0x1;
                ssi->dma_params_rx.maxburst &= ~0x1;
        }
@@ -1369,41 +1369,109 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi)
                clk_disable_unprepare(ssi->clk);
 }
 
-static int fsl_ssi_probe(struct platform_device *pdev)
+static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi)
 {
-       struct fsl_ssi *ssi;
-       int ret = 0;
-       struct device_node *np = pdev->dev.of_node;
-       struct device *dev = &pdev->dev;
+       struct device *dev = ssi->dev;
+       struct device_node *np = dev->of_node;
        const struct of_device_id *of_id;
        const char *p, *sprop;
-       const uint32_t *iprop;
-       struct resource *res;
-       void __iomem *iomem;
-       char name[64];
-       struct regmap_config regconfig = fsl_ssi_regconfig;
+       const __be32 *iprop;
+       u32 dmas[4];
+       int ret;
 
        of_id = of_match_device(fsl_ssi_ids, dev);
        if (!of_id || !of_id->data)
                return -EINVAL;
 
-       ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
-       if (!ssi)
-               return -ENOMEM;
-
        ssi->soc = of_id->data;
-       ssi->dev = dev;
+
+       ret = of_property_match_string(np, "clock-names", "ipg");
+       /* Get error code if not found */
+       ssi->has_ipg_clk_name = ret >= 0;
 
        /* Check if being used in AC97 mode */
        sprop = of_get_property(np, "fsl,mode", NULL);
-       if (sprop) {
-               if (!strcmp(sprop, "ac97-slave"))
-                       ssi->dai_fmt = SND_SOC_DAIFMT_AC97;
+       if (sprop && !strcmp(sprop, "ac97-slave")) {
+               ssi->dai_fmt = FSLSSI_AC97_DAIFMT;
+
+               ret = of_property_read_u32(np, "cell-index", &ssi->card_idx);
+               if (ret) {
+                       dev_err(dev, "failed to get SSI index property\n");
+                       return -EINVAL;
+               }
+               strcpy(ssi->card_name, "ac97-codec");
+       } else if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
+               /*
+                * In synchronous mode, STCK and STFS ports are used by RX
+                * as well. So the software should limit the sample rates,
+                * sample bits and channels to be symmetric.
+                *
+                * This is exclusive with FSLSSI_AC97_FORMATS as AC97 runs
+                * in the SSI synchronous mode however it does not have to
+                * limit symmetric sample rates and sample bits.
+                */
+               ssi->synchronous = true;
        }
 
        /* Select DMA or FIQ */
        ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter");
 
+       /* Fetch FIFO depth; Set to 8 for older DT without this property */
+       iprop = of_get_property(np, "fsl,fifo-depth", NULL);
+       if (iprop)
+               ssi->fifo_depth = be32_to_cpup(iprop);
+       else
+               ssi->fifo_depth = 8;
+
+       /* Use dual FIFO mode depending on the support from SDMA script */
+       ret = of_property_read_u32_array(np, "dmas", dmas, 4);
+       if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL)
+               ssi->use_dual_fifo = true;
+
+       /*
+        * Backward compatible for older bindings by manually triggering the
+        * machine driver's probe(). Use /compatible property, including the
+        * address of CPU DAI driver structure, as the name of machine driver
+        *
+        * If card_name is set by AC97 earlier, bypass here since it uses a
+        * different name to register the device.
+        */
+       if (!ssi->card_name[0] && of_get_property(np, "codec-handle", NULL)) {
+               sprop = of_get_property(of_find_node_by_path("/"),
+                                       "compatible", NULL);
+               /* Strip "fsl," in the compatible name if applicable */
+               p = strrchr(sprop, ',');
+               if (p)
+                       sprop = p + 1;
+               snprintf(ssi->card_name, sizeof(ssi->card_name),
+                        "snd-soc-%s", sprop);
+               make_lowercase(ssi->card_name);
+               ssi->card_idx = 0;
+       }
+
+       return 0;
+}
+
+static int fsl_ssi_probe(struct platform_device *pdev)
+{
+       struct regmap_config regconfig = fsl_ssi_regconfig;
+       struct device *dev = &pdev->dev;
+       struct fsl_ssi *ssi;
+       struct resource *res;
+       void __iomem *iomem;
+       int ret = 0;
+
+       ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
+       if (!ssi)
+               return -ENOMEM;
+
+       ssi->dev = dev;
+
+       /* Probe from DT */
+       ret = fsl_ssi_probe_from_dt(ssi);
+       if (ret)
+               return ret;
+
        if (fsl_ssi_is_ac97(ssi)) {
                memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai,
                       sizeof(fsl_ssi_ac97_dai));
@@ -1427,15 +1495,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
                        REG_SSI_SRMSK / sizeof(uint32_t) + 1;
        }
 
-       ret = of_property_match_string(np, "clock-names", "ipg");
-       if (ret < 0) {
-               ssi->has_ipg_clk_name = false;
-               ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig);
-       } else {
-               ssi->has_ipg_clk_name = true;
+       if (ssi->has_ipg_clk_name)
                ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem,
                                                      &regconfig);
-       }
+       else
+               ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig);
        if (IS_ERR(ssi->regs)) {
                dev_err(dev, "failed to init register map\n");
                return PTR_ERR(ssi->regs);
@@ -1447,23 +1511,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
                return ssi->irq;
        }
 
-       /* Set software limitations for synchronous mode */
-       if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
-               if (!fsl_ssi_is_ac97(ssi)) {
-                       ssi->cpu_dai_drv.symmetric_rates = 1;
-                       ssi->cpu_dai_drv.symmetric_samplebits = 1;
-               }
-
+       /* Set software limitations for synchronous mode except AC97 */
+       if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) {
+               ssi->cpu_dai_drv.symmetric_rates = 1;
                ssi->cpu_dai_drv.symmetric_channels = 1;
+               ssi->cpu_dai_drv.symmetric_samplebits = 1;
        }
 
-       /* Fetch FIFO depth; Set to 8 for older DT without this property */
-       iprop = of_get_property(np, "fsl,fifo-depth", NULL);
-       if (iprop)
-               ssi->fifo_depth = be32_to_cpup(iprop);
-       else
-               ssi->fifo_depth = 8;
-
        /*
         * Configure TX and RX DMA watermarks -- when to send a DMA request
         *
@@ -1528,50 +1582,27 @@ static int fsl_ssi_probe(struct platform_device *pdev)
        if (ret)
                goto error_asoc_register;
 
-       /* Bypass it if using newer DT bindings of ASoC machine drivers */
-       if (!of_get_property(np, "codec-handle", NULL))
-               goto done;
-
-       /*
-        * Backward compatible for older bindings by manually triggering the
-        * machine driver's probe(). Use /compatible property, including the
-        * address of CPU DAI driver structure, as the name of machine driver.
-        */
-       sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
-       /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
-       p = strrchr(sprop, ',');
-       if (p)
-               sprop = p + 1;
-       snprintf(name, sizeof(name), "snd-soc-%s", sprop);
-       make_lowercase(name);
-
-       ssi->pdev = platform_device_register_data(dev, name, 0, NULL, 0);
-       if (IS_ERR(ssi->pdev)) {
-               ret = PTR_ERR(ssi->pdev);
-               dev_err(dev, "failed to register platform: %d\n", ret);
-               goto error_sound_card;
-       }
-
-done:
-       if (ssi->dai_fmt)
-               _fsl_ssi_set_dai_fmt(dev, ssi, ssi->dai_fmt);
-
-       if (fsl_ssi_is_ac97(ssi)) {
-               u32 ssi_idx;
+       /* Initially configures SSI registers */
+       fsl_ssi_hw_init(ssi);
 
-               ret = of_property_read_u32(np, "cell-index", &ssi_idx);
-               if (ret) {
-                       dev_err(dev, "failed to get SSI index property\n");
-                       goto error_sound_card;
-               }
-
-               ssi->pdev = platform_device_register_data(NULL, "ac97-codec",
-                                                         ssi_idx, NULL, 0);
-               if (IS_ERR(ssi->pdev)) {
-                       ret = PTR_ERR(ssi->pdev);
-                       dev_err(dev,
-                               "failed to register AC97 codec platform: %d\n",
-                               ret);
+       /* Register a platform device for older bindings or AC97 */
+       if (ssi->card_name[0]) {
+               struct device *parent = dev;
+               /*
+                * Do not set SSI dev as the parent of AC97 CODEC device since
+                * it does not have a DT node. Otherwise ASoC core will assume
+                * CODEC has the same DT node as the SSI, so it may bypass the
+                * dai_probe() of SSI and then cause NULL DMA data pointers.
+                */
+               if (fsl_ssi_is_ac97(ssi))
+                       parent = NULL;
+
+               ssi->card_pdev = platform_device_register_data(parent,
+                               ssi->card_name, ssi->card_idx, NULL, 0);
+               if (IS_ERR(ssi->card_pdev)) {
+                       ret = PTR_ERR(ssi->card_pdev);
+                       dev_err(dev, "failed to register %s: %d\n",
+                               ssi->card_name, ret);
                        goto error_sound_card;
                }
        }
@@ -1599,8 +1630,11 @@ static int fsl_ssi_remove(struct platform_device *pdev)
 
        fsl_ssi_debugfs_remove(&ssi->dbg_stats);
 
-       if (ssi->pdev)
-               platform_device_unregister(ssi->pdev);
+       if (ssi->card_pdev)
+               platform_device_unregister(ssi->card_pdev);
+
+       /* Clean up SSI registers */
+       fsl_ssi_hw_clean(ssi);
 
        if (ssi->soc->imx)
                fsl_ssi_imx_clean(pdev, ssi);
index de2fdc5db72604f752b55a6d7f993bc0509f0036..18f8dd5209d58b280babb696617ef4479bb8036c 100644 (file)
@@ -12,9 +12,6 @@
 #ifndef _MPC8610_I2S_H
 #define _MPC8610_I2S_H
 
-#define RX 0
-#define TX 1
-
 /* -- SSI Register Map -- */
 
 /* SSI Transmit Data Register 0 */
index b9e42b503a37728b8a20a14a3979ada69ed82872..7592b0406370dffd2076f2b1d36d8b1b4440c0ad 100644 (file)
@@ -36,7 +36,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
 {
        struct resource res;
        struct device_node *dma_channel_np, *dma_np;
-       const u32 *iprop;
+       const __be32 *iprop;
        int ret;
 
        dma_channel_np = of_parse_phandle(ssi_np, name, 0);
index 4e5fefee111eb285c1005edcbf22dd9d1c47d6f2..0578f348684709d62c77412ff05fb9041d76188c 100644 (file)
@@ -341,7 +341,7 @@ static void imx_pcm_fiq_free(struct snd_pcm *pcm)
        imx_pcm_free(pcm);
 }
 
-static const struct snd_soc_platform_driver imx_soc_platform_fiq = {
+static const struct snd_soc_component_driver imx_soc_component_fiq = {
        .ops            = &imx_pcm_ops,
        .pcm_new        = imx_pcm_fiq_new,
        .pcm_free       = imx_pcm_fiq_free,
@@ -368,7 +368,8 @@ int imx_pcm_fiq_init(struct platform_device *pdev,
        params->dma_params_tx->maxburst = 4;
        params->dma_params_rx->maxburst = 6;
 
-       ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
+       ret = devm_snd_soc_register_component(&pdev->dev, &imx_soc_component_fiq,
+                                             NULL, 0);
        if (ret)
                goto failed_register;
 
@@ -384,7 +385,6 @@ EXPORT_SYMBOL_GPL(imx_pcm_fiq_init);
 
 void imx_pcm_fiq_exit(struct platform_device *pdev)
 {
-       snd_soc_unregister_platform(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(imx_pcm_fiq_exit);
 
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
deleted file mode 100644 (file)
index 206b898..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * Based on imx-sgtl5000.c
- * Copyright 2012 Freescale Semiconductor, Inc.
- * Copyright 2012 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/module.h>
-#include <linux/of_platform.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <sound/soc.h>
-#include <sound/pcm_params.h>
-#include <sound/soc-dapm.h>
-#include <linux/pinctrl/consumer.h>
-
-#include "../codecs/wm8962.h"
-#include "imx-audmux.h"
-
-#define DAI_NAME_SIZE  32
-
-struct imx_wm8962_data {
-       struct snd_soc_dai_link dai;
-       struct snd_soc_card card;
-       char codec_dai_name[DAI_NAME_SIZE];
-       char platform_name[DAI_NAME_SIZE];
-       unsigned int clk_frequency;
-};
-
-struct imx_priv {
-       struct platform_device *pdev;
-       int sample_rate;
-       snd_pcm_format_t sample_format;
-};
-
-static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
-       SND_SOC_DAPM_HP("Headphone Jack", NULL),
-       SND_SOC_DAPM_SPK("Ext Spk", NULL),
-       SND_SOC_DAPM_MIC("AMIC", NULL),
-       SND_SOC_DAPM_MIC("DMIC", NULL),
-};
-
-static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
-               struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-
-       priv->sample_rate = params_rate(params);
-       priv->sample_format = params_format(params);
-
-       return 0;
-}
-
-static const struct snd_soc_ops imx_hifi_ops = {
-       .hw_params = imx_hifi_hw_params,
-};
-
-static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
-                                       struct snd_soc_dapm_context *dapm,
-                                       enum snd_soc_bias_level level)
-{
-       struct snd_soc_pcm_runtime *rtd;
-       struct snd_soc_dai *codec_dai;
-       struct imx_priv *priv = snd_soc_card_get_drvdata(card);
-       struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
-       struct device *dev = &priv->pdev->dev;
-       unsigned int pll_out;
-       int ret;
-
-       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-       codec_dai = rtd->codec_dai;
-       if (dapm->dev != codec_dai->dev)
-               return 0;
-
-       switch (level) {
-       case SND_SOC_BIAS_PREPARE:
-               if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
-                       if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
-                               pll_out = priv->sample_rate * 384;
-                       else
-                               pll_out = priv->sample_rate * 256;
-
-                       ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
-                                       WM8962_FLL_MCLK, data->clk_frequency,
-                                       pll_out);
-                       if (ret < 0) {
-                               dev_err(dev, "failed to start FLL: %d\n", ret);
-                               return ret;
-                       }
-
-                       ret = snd_soc_dai_set_sysclk(codec_dai,
-                                       WM8962_SYSCLK_FLL, pll_out,
-                                       SND_SOC_CLOCK_IN);
-                       if (ret < 0) {
-                               dev_err(dev, "failed to set SYSCLK: %d\n", ret);
-                               return ret;
-                       }
-               }
-               break;
-
-       case SND_SOC_BIAS_STANDBY:
-               if (dapm->bias_level == SND_SOC_BIAS_PREPARE) {
-                       ret = snd_soc_dai_set_sysclk(codec_dai,
-                                       WM8962_SYSCLK_MCLK, data->clk_frequency,
-                                       SND_SOC_CLOCK_IN);
-                       if (ret < 0) {
-                               dev_err(dev,
-                                       "failed to switch away from FLL: %d\n",
-                                       ret);
-                               return ret;
-                       }
-
-                       ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
-                                       0, 0, 0);
-                       if (ret < 0) {
-                               dev_err(dev, "failed to stop FLL: %d\n", ret);
-                               return ret;
-                       }
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static int imx_wm8962_late_probe(struct snd_soc_card *card)
-{
-       struct snd_soc_pcm_runtime *rtd;
-       struct snd_soc_dai *codec_dai;
-       struct imx_priv *priv = snd_soc_card_get_drvdata(card);
-       struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
-       struct device *dev = &priv->pdev->dev;
-       int ret;
-
-       rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-       codec_dai = rtd->codec_dai;
-       ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
-                       data->clk_frequency, SND_SOC_CLOCK_IN);
-       if (ret < 0)
-               dev_err(dev, "failed to set sysclk in %s\n", __func__);
-
-       return ret;
-}
-
-static int imx_wm8962_probe(struct platform_device *pdev)
-{
-       struct device_node *np = pdev->dev.of_node;
-       struct device_node *ssi_np, *codec_np;
-       struct platform_device *ssi_pdev;
-       struct i2c_client *codec_dev;
-       struct imx_wm8962_data *data;
-       struct imx_priv *priv;
-       struct clk *codec_clk;
-       int int_port, ext_port;
-       int ret;
-
-       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->pdev = pdev;
-       priv->sample_rate = 44100;
-       priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;
-
-       ret = of_property_read_u32(np, "mux-int-port", &int_port);
-       if (ret) {
-               dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
-               return ret;
-       }
-       ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
-       if (ret) {
-               dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
-               return ret;
-       }
-
-       /*
-        * The port numbering in the hardware manual starts at 1, while
-        * the audmux API expects it starts at 0.
-        */
-       int_port--;
-       ext_port--;
-       ret = imx_audmux_v2_configure_port(int_port,
-                       IMX_AUDMUX_V2_PTCR_SYN |
-                       IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
-                       IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
-                       IMX_AUDMUX_V2_PTCR_TFSDIR |
-                       IMX_AUDMUX_V2_PTCR_TCLKDIR,
-                       IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
-       if (ret) {
-               dev_err(&pdev->dev, "audmux internal port setup failed\n");
-               return ret;
-       }
-       ret = imx_audmux_v2_configure_port(ext_port,
-                       IMX_AUDMUX_V2_PTCR_SYN,
-                       IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
-       if (ret) {
-               dev_err(&pdev->dev, "audmux external port setup failed\n");
-               return ret;
-       }
-
-       ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
-       codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
-       if (!ssi_np || !codec_np) {
-               dev_err(&pdev->dev, "phandle missing or invalid\n");
-               ret = -EINVAL;
-               goto fail;
-       }
-
-       ssi_pdev = of_find_device_by_node(ssi_np);
-       if (!ssi_pdev) {
-               dev_err(&pdev->dev, "failed to find SSI platform device\n");
-               ret = -EINVAL;
-               goto fail;
-       }
-       codec_dev = of_find_i2c_device_by_node(codec_np);
-       if (!codec_dev || !codec_dev->dev.driver) {
-               dev_err(&pdev->dev, "failed to find codec platform device\n");
-               ret = -EINVAL;
-               goto fail;
-       }
-
-       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       codec_clk = clk_get(&codec_dev->dev, NULL);
-       if (IS_ERR(codec_clk)) {
-               ret = PTR_ERR(codec_clk);
-               dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
-               goto fail;
-       }
-
-       data->clk_frequency = clk_get_rate(codec_clk);
-       clk_put(codec_clk);
-
-       data->dai.name = "HiFi";
-       data->dai.stream_name = "HiFi";
-       data->dai.codec_dai_name = "wm8962";
-       data->dai.codec_of_node = codec_np;
-       data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
-       data->dai.platform_of_node = ssi_np;
-       data->dai.ops = &imx_hifi_ops;
-       data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-                           SND_SOC_DAIFMT_CBM_CFM;
-
-       data->card.dev = &pdev->dev;
-       ret = snd_soc_of_parse_card_name(&data->card, "model");
-       if (ret)
-               goto fail;
-       ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
-       if (ret)
-               goto fail;
-       data->card.num_links = 1;
-       data->card.owner = THIS_MODULE;
-       data->card.dai_link = &data->dai;
-       data->card.dapm_widgets = imx_wm8962_dapm_widgets;
-       data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
-
-       data->card.late_probe = imx_wm8962_late_probe;
-       data->card.set_bias_level = imx_wm8962_set_bias_level;
-
-       platform_set_drvdata(pdev, &data->card);
-       snd_soc_card_set_drvdata(&data->card, data);
-
-       ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
-       if (ret) {
-               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
-               goto fail;
-       }
-
-fail:
-       of_node_put(ssi_np);
-       of_node_put(codec_np);
-
-       return ret;
-}
-
-static const struct of_device_id imx_wm8962_dt_ids[] = {
-       { .compatible = "fsl,imx-audio-wm8962", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_wm8962_dt_ids);
-
-static struct platform_driver imx_wm8962_driver = {
-       .driver = {
-               .name = "imx-wm8962",
-               .pm = &snd_soc_pm_ops,
-               .of_match_table = imx_wm8962_dt_ids,
-       },
-       .probe = imx_wm8962_probe,
-};
-module_platform_driver(imx_wm8962_driver);
-
-MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("Freescale i.MX WM8962 ASoC machine driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:imx-wm8962");
index e63029f1aabc0b499985226c9624950cb146737c..c1a4544eb16b81dfafaaa392fd4082080e04a80a 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "mpc5200_dma.h"
 
+#define DRV_NAME "mpc5200_dma"
+
 /*
  * Interrupt handlers
  */
@@ -300,12 +302,13 @@ static const struct snd_pcm_ops psc_dma_ops = {
 static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_card *card = rtd->card->snd_card;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct snd_soc_dai *dai = rtd->cpu_dai;
        struct snd_pcm *pcm = rtd->pcm;
        size_t size = psc_dma_hardware.buffer_bytes_max;
        int rc;
 
-       dev_dbg(rtd->platform->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
+       dev_dbg(component->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
                card, dai, pcm);
 
        rc = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
@@ -341,10 +344,11 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 static void psc_dma_free(struct snd_pcm *pcm)
 {
        struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct snd_pcm_substream *substream;
        int stream;
 
-       dev_dbg(rtd->platform->dev, "psc_dma_free(pcm=%p)\n", pcm);
+       dev_dbg(component->dev, "psc_dma_free(pcm=%p)\n", pcm);
 
        for (stream = 0; stream < 2; stream++) {
                substream = pcm->streams[stream].substream;
@@ -356,7 +360,8 @@ static void psc_dma_free(struct snd_pcm *pcm)
        }
 }
 
-static const struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
+static const struct snd_soc_component_driver mpc5200_audio_dma_component = {
+       .name           = DRV_NAME,
        .ops            = &psc_dma_ops,
        .pcm_new        = &psc_dma_new,
        .pcm_free       = &psc_dma_free,
@@ -468,7 +473,8 @@ int mpc5200_audio_dma_create(struct platform_device *op)
        dev_set_drvdata(&op->dev, psc_dma);
 
        /* Tell the ASoC OF helpers about it */
-       return snd_soc_register_platform(&op->dev, &mpc5200_audio_dma_platform);
+       return devm_snd_soc_register_component(&op->dev,
+                                       &mpc5200_audio_dma_component, NULL, 0);
 out_irq:
        free_irq(psc_dma->irq, psc_dma);
        free_irq(psc_dma->capture.irq, &psc_dma->capture);
@@ -487,8 +493,6 @@ int mpc5200_audio_dma_destroy(struct platform_device *op)
 
        dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
 
-       snd_soc_unregister_platform(&op->dev);
-
        bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
        bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
 
index cdaf16367b4714afa74e601ab80448cfaf947211..2f80b21b29211f94fedbdba7601770a6997501a4 100644 (file)
@@ -201,18 +201,18 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
 
 static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        /* Headphone jack detection */
        snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE,
                              &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins));
-       wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
+       wm8350_hp_jack_detect(component, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
 
        /* Microphone jack detection */
        snd_soc_card_jack_new(rtd->card, "Microphone",
                              SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack,
                              mic_jack_pins, ARRAY_SIZE(mic_jack_pins));
-       wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
+       wm8350_mic_jack_detect(component, &mic_jack, SND_JACK_MICROPHONE,
                               SND_JACK_BTN_0);
 
        snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
index 53e11c6d4e22cbabfdabcf1c01cc30ffd9c92b85..915b894f99ce72ad4164f57d4b6f5791c7013888 100644 (file)
@@ -122,26 +122,26 @@ static struct snd_soc_dai_driver pistachio_internal_dac_dais[] = {
        },
 };
 
-static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec)
+static int pistachio_internal_dac_codec_probe(struct snd_soc_component *component)
 {
-       struct pistachio_internal_dac *dac = snd_soc_codec_get_drvdata(codec);
+       struct pistachio_internal_dac *dac = snd_soc_component_get_drvdata(component);
 
-       snd_soc_codec_init_regmap(codec, dac->regmap);
+       snd_soc_component_init_regmap(component, dac->regmap);
 
        return 0;
 }
 
-static const struct snd_soc_codec_driver pistachio_internal_dac_driver = {
-       .probe = pistachio_internal_dac_codec_probe,
-       .idle_bias_off = true,
-       .component_driver = {
-               .controls               = pistachio_internal_dac_snd_controls,
-               .num_controls           = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
-               .dapm_widgets           = pistachio_internal_dac_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(pistachio_internal_dac_widgets),
-               .dapm_routes            = pistachio_internal_dac_routes,
-               .num_dapm_routes        = ARRAY_SIZE(pistachio_internal_dac_routes),
-       },
+static const struct snd_soc_component_driver pistachio_internal_dac_driver = {
+       .probe                  = pistachio_internal_dac_codec_probe,
+       .controls               = pistachio_internal_dac_snd_controls,
+       .num_controls           = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
+       .dapm_widgets           = pistachio_internal_dac_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(pistachio_internal_dac_widgets),
+       .dapm_routes            = pistachio_internal_dac_routes,
+       .num_dapm_routes        = ARRAY_SIZE(pistachio_internal_dac_routes),
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int pistachio_internal_dac_probe(struct platform_device *pdev)
@@ -202,11 +202,12 @@ static int pistachio_internal_dac_probe(struct platform_device *pdev)
        pm_runtime_enable(dev);
        pm_runtime_idle(dev);
 
-       ret = snd_soc_register_codec(dev, &pistachio_internal_dac_driver,
+       ret = devm_snd_soc_register_component(dev,
+                       &pistachio_internal_dac_driver,
                        pistachio_internal_dac_dais,
                        ARRAY_SIZE(pistachio_internal_dac_dais));
        if (ret) {
-               dev_err(dev, "failed to register codec: %d\n", ret);
+               dev_err(dev, "failed to register component: %d\n", ret);
                goto err_pwr;
        }
 
@@ -225,7 +226,6 @@ static int pistachio_internal_dac_remove(struct platform_device *pdev)
 {
        struct pistachio_internal_dac *dac = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_codec(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        pistachio_internal_dac_pwr_off(dac);
        regulator_disable(dac->supply);
index 0f3604b5594240ed74b6fb1d4661efe36665b147..3672d36b4b66f4fcd62ed863ef7a8b44ac9b0c4b 100644 (file)
@@ -1414,11 +1414,11 @@ static int sst_fill_module_list(struct snd_kcontrol *kctl,
  * name. First part of control name contains the pipe name (widget name).
  */
 static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w,
-       struct snd_soc_platform *platform)
+       struct snd_soc_component *component)
 {
        struct snd_kcontrol *kctl;
        int index, ret = 0;
-       struct snd_card *card = platform->component.card->snd_card;
+       struct snd_card *card = component->card->snd_card;
        char *idx;
 
        down_read(&card->controls_rwsem);
@@ -1468,13 +1468,13 @@ static int sst_fill_widget_module_info(struct snd_soc_dapm_widget *w,
 /**
  * sst_fill_linked_widgets - fill the parent pointer for the linked widget
  */
-static void sst_fill_linked_widgets(struct snd_soc_platform *platform,
+static void sst_fill_linked_widgets(struct snd_soc_component *component,
                                                struct sst_ids *ids)
 {
        struct snd_soc_dapm_widget *w;
        unsigned int len = strlen(ids->parent_wname);
 
-       list_for_each_entry(w, &platform->component.card->widgets, list) {
+       list_for_each_entry(w, &component->card->widgets, list) {
                if (!strncmp(ids->parent_wname, w->name, len)) {
                        ids->parent_w = w;
                        break;
@@ -1485,41 +1485,41 @@ static void sst_fill_linked_widgets(struct snd_soc_platform *platform,
 /**
  * sst_map_modules_to_pipe - fill algo/gains list for all pipes
  */
-static int sst_map_modules_to_pipe(struct snd_soc_platform *platform)
+static int sst_map_modules_to_pipe(struct snd_soc_component *component)
 {
        struct snd_soc_dapm_widget *w;
        int ret = 0;
 
-       list_for_each_entry(w, &platform->component.card->widgets, list) {
+       list_for_each_entry(w, &component->card->widgets, list) {
                if (is_sst_dapm_widget(w) && (w->priv)) {
                        struct sst_ids *ids = w->priv;
 
-                       dev_dbg(platform->dev, "widget type=%d name=%s\n",
+                       dev_dbg(component->dev, "widget type=%d name=%s\n",
                                        w->id, w->name);
                        INIT_LIST_HEAD(&ids->algo_list);
                        INIT_LIST_HEAD(&ids->gain_list);
-                       ret = sst_fill_widget_module_info(w, platform);
+                       ret = sst_fill_widget_module_info(w, component);
 
                        if (ret < 0)
                                return ret;
 
                        /* fill linked widgets */
                        if (ids->parent_wname !=  NULL)
-                               sst_fill_linked_widgets(platform, ids);
+                               sst_fill_linked_widgets(component, ids);
                }
        }
        return 0;
 }
 
-int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
+int sst_dsp_init_v2_dpcm(struct snd_soc_component *component)
 {
        int i, ret = 0;
        struct snd_soc_dapm_context *dapm =
-                       snd_soc_component_get_dapm(&platform->component);
-       struct sst_data *drv = snd_soc_platform_get_drvdata(platform);
+                       snd_soc_component_get_dapm(component);
+       struct sst_data *drv = snd_soc_component_get_drvdata(component);
        unsigned int gains = ARRAY_SIZE(sst_gain_controls)/3;
 
-       drv->byte_stream = devm_kzalloc(platform->dev,
+       drv->byte_stream = devm_kzalloc(component->dev,
                                        SST_MAX_BIN_BYTES, GFP_KERNEL);
        if (!drv->byte_stream)
                return -ENOMEM;
@@ -1537,26 +1537,26 @@ int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
                sst_gains[i].ramp_duration = SST_GAIN_RAMP_DURATION_DEFAULT;
        }
 
-       ret = snd_soc_add_platform_controls(platform, sst_gain_controls,
+       ret = snd_soc_add_component_controls(component, sst_gain_controls,
                        ARRAY_SIZE(sst_gain_controls));
        if (ret)
                return ret;
 
        /* Initialize algo control params */
-       ret = sst_algo_control_init(platform->dev);
+       ret = sst_algo_control_init(component->dev);
        if (ret)
                return ret;
-       ret = snd_soc_add_platform_controls(platform, sst_algo_controls,
+       ret = snd_soc_add_component_controls(component, sst_algo_controls,
                        ARRAY_SIZE(sst_algo_controls));
        if (ret)
                return ret;
 
-       ret = snd_soc_add_platform_controls(platform, sst_slot_controls,
+       ret = snd_soc_add_component_controls(component, sst_slot_controls,
                        ARRAY_SIZE(sst_slot_controls));
        if (ret)
                return ret;
 
-       ret = sst_map_modules_to_pipe(platform);
+       ret = sst_map_modules_to_pipe(component);
 
        return ret;
 }
index 1dbcab5a6ff0bf1fdf509a837f5e23125abc86bd..6a44b19423cfe0943c86ca670bfea6c8f7538e1e 100644 (file)
@@ -107,8 +107,8 @@ static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
        struct snd_sst_params str_params;
        struct sst_compress_cb cb;
        struct snd_soc_pcm_runtime *rtd = cstream->private_data;
-       struct snd_soc_platform *platform = rtd->platform;
-       struct sst_data *ctx = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_data *ctx = snd_soc_component_get_drvdata(component);
 
        stream = cstream->runtime->private_data;
        /* construct fw structure for this*/
index 43e7fdd19f291b0ade6a484117c99d28b44da22e..6c36da56087759ac11dcba4616a9a5f7f4c99d3b 100644 (file)
@@ -697,26 +697,22 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
        return retval;
 }
 
-static int sst_soc_probe(struct snd_soc_platform *platform)
+static int sst_soc_probe(struct snd_soc_component *component)
 {
-       struct sst_data *drv = dev_get_drvdata(platform->dev);
+       struct sst_data *drv = dev_get_drvdata(component->dev);
 
-       drv->soc_card = platform->component.card;
-       return sst_dsp_init_v2_dpcm(platform);
+       drv->soc_card = component->card;
+       return sst_dsp_init_v2_dpcm(component);
 }
 
-static const struct snd_soc_platform_driver sst_soc_platform_drv  = {
+static const struct snd_soc_component_driver sst_soc_platform_drv  = {
+       .name           = DRV_NAME,
        .probe          = sst_soc_probe,
        .ops            = &sst_platform_ops,
        .compr_ops      = &sst_platform_compr_ops,
        .pcm_new        = sst_pcm_new,
 };
 
-static const struct snd_soc_component_driver sst_component = {
-       .name           = "sst",
-};
-
-
 static int sst_platform_probe(struct platform_device *pdev)
 {
        struct sst_data *drv;
@@ -740,26 +736,16 @@ static int sst_platform_probe(struct platform_device *pdev)
        mutex_init(&drv->lock);
        dev_set_drvdata(&pdev->dev, drv);
 
-       ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
-       if (ret) {
-               dev_err(&pdev->dev, "registering soc platform failed\n");
-               return ret;
-       }
-
-       ret = snd_soc_register_component(&pdev->dev, &sst_component,
+       ret = devm_snd_soc_register_component(&pdev->dev, &sst_soc_platform_drv,
                                sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
-       if (ret) {
+       if (ret)
                dev_err(&pdev->dev, "registering cpu dais failed\n");
-               snd_soc_unregister_platform(&pdev->dev);
-       }
+
        return ret;
 }
 
 static int sst_platform_remove(struct platform_device *pdev)
 {
-
-       snd_soc_unregister_component(&pdev->dev);
-       snd_soc_unregister_platform(&pdev->dev);
        dev_dbg(&pdev->dev, "sst_platform_remove success\n");
        return 0;
 }
index 31a58c25472cb51be10c83143a0fac237fec9293..5f729df57bb5f41356f40e954ff4dd7f0a8fd42f 100644 (file)
@@ -27,6 +27,8 @@
 extern struct sst_device *sst;
 extern const struct snd_compr_ops sst_platform_compr_ops;
 
+#define DRV_NAME "sst"
+
 #define SST_MONO               1
 #define SST_STEREO             2
 #define SST_MAX_CAP            5
@@ -155,7 +157,7 @@ struct sst_device {
 
 struct sst_data;
 
-int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform);
+int sst_dsp_init_v2_dpcm(struct snd_soc_component *component);
 int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute);
 int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable);
 int sst_handle_vb_timer(struct snd_soc_dai *dai, bool enable);
index 8afdff457579fe9062089fcb6d364cd2185f45ee..0962bc9adc62e9fb5993485b2a98b84574b37b0d 100644 (file)
@@ -449,6 +449,13 @@ static int intel_sst_suspend(struct device *dev)
                        dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
                        return -EBUSY;
                }
+
+               if (ctx->pdata->streams_lost_on_suspend) {
+                       stream->resume_status = stream->status;
+                       stream->resume_prev = stream->prev;
+                       if (stream->status != STREAM_UN_INIT)
+                               sst_free_stream(ctx, i);
+               }
        }
        synchronize_irq(ctx->irq_num);
        flush_workqueue(ctx->post_msg_wq);
@@ -509,8 +516,8 @@ static int intel_sst_resume(struct device *dev)
 {
        struct intel_sst_drv *ctx = dev_get_drvdata(dev);
        struct sst_fw_save *fw_save = ctx->fw_save;
-       int ret = 0;
        struct sst_block *block;
+       int i, ret = 0;
 
        if (!fw_save)
                return 0;
@@ -550,6 +557,21 @@ static int intel_sst_resume(struct device *dev)
                sst_set_fw_state_locked(ctx, SST_FW_RUNNING);
        }
 
+       if (ctx->pdata->streams_lost_on_suspend) {
+               for (i = 1; i <= ctx->info.max_streams; i++) {
+                       struct stream_info *stream = &ctx->streams[i];
+
+                       if (stream->resume_status != STREAM_UN_INIT) {
+                               dev_dbg(ctx->dev, "Re-allocing stream %d status %d prev %d\n",
+                                       i, stream->resume_status,
+                                       stream->resume_prev);
+                               sst_realloc_stream(ctx, i);
+                               stream->status = stream->resume_status;
+                               stream->prev = stream->resume_prev;
+                       }
+               }
+       }
+
        sst_free_block(ctx, block);
        return ret;
 }
index e02e2b4cc08f0e657be5096fce99aa3d003db96d..b2a705dc930458e27d221e61b7bedfb54cdb37ca 100644 (file)
@@ -65,9 +65,7 @@ enum sst_stream_states {
        STREAM_UN_INIT  = 0,    /* Freed/Not used stream */
        STREAM_RUNNING  = 1,    /* Running */
        STREAM_PAUSED   = 2,    /* Paused stream */
-       STREAM_DECODE   = 3,    /* stream is in decoding only state */
-       STREAM_INIT     = 4,    /* stream init, waiting for data */
-       STREAM_RESET    = 5,    /* force reset on recovery */
+       STREAM_INIT     = 3,    /* stream init, waiting for data */
 };
 
 enum sst_ram_type {
@@ -181,22 +179,22 @@ struct sst_block {
  *
  * @status : stream current state
  * @prev : stream prev state
- * @ops : stream operation pb/cp/drm...
- * @bufs: stream buffer list
+ * @resume_status : stream current state to restore on resume
+ * @resume_prev : stream prev state to restore on resume
  * @lock : stream mutex for protecting state
+ * @alloc_param : parameters used for stream (re-)allocation
  * @pcm_substream : PCM substream
  * @period_elapsed : PCM period elapsed callback
  * @sfreq : stream sampling freq
- * @str_type : stream type
  * @cumm_bytes : cummulative bytes decoded
- * @str_type : stream type
- * @src : stream source
  */
 struct stream_info {
        unsigned int            status;
        unsigned int            prev;
-       unsigned int            ops;
+       unsigned int            resume_status;
+       unsigned int            resume_prev;
        struct mutex            lock;
+       struct snd_sst_alloc_mrfld alloc_param;
 
        void                    *pcm_substream;
        void (*period_elapsed)(void *pcm_substream);
@@ -212,7 +210,6 @@ struct stream_info {
 
        unsigned int            num_ch;
        unsigned int            pipe_id;
-       unsigned int            str_id;
        unsigned int            task_id;
 };
 
@@ -438,6 +435,7 @@ struct intel_sst_ops {
        void (*post_download)(struct intel_sst_drv *sst);
 };
 
+int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);
 int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int id);
 int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int id);
 int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int id);
@@ -501,8 +499,6 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
 
 void sst_process_pending_msg(struct work_struct *work);
 int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx);
-void sst_init_stream(struct stream_info *stream,
-               int codec, int sst_id, int ops, u8 slot);
 int sst_validate_strid(struct intel_sst_drv *sst_drv_ctx, int str_id);
 struct stream_info *get_stream_info(struct intel_sst_drv *sst_drv_ctx,
                int str_id);
index 6cd481bec27524c6e8bd395071ba066fd97871e2..c90b04cc071dc230391746628c40bc9541d07f95 100644 (file)
@@ -143,10 +143,11 @@ static struct sst_platform_info byt_rvp_platform_data = {
        .lib_info = &byt_lib_dnld_info,
        .res_info = &byt_rvp_res_info,
        .platform = "sst-mfld-platform",
+       .streams_lost_on_suspend = true,
 };
 
 /* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail,
- * so pdata is same as Baytrail.
+ * so pdata is same as Baytrail, minus the streams_lost_on_suspend quirk.
  */
 static struct sst_platform_info chv_platform_data = {
        .probe_data = &byt_fwparse_info,
index 71af5449be90235ddc04a8cc4fe33fe159334f10..6a8b253c58d254e9cdaf754747801dc3e1c4efb1 100644 (file)
@@ -238,16 +238,7 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id)
                return -EINVAL;
        }
 
-       if (stream->status == STREAM_RESET) {
-               dev_dbg(dev, "stream in reset state...\n");
-               stream->status = STREAM_UN_INIT;
-
-               retval = 0;
-               goto put;
-       }
-
        retval = sst_free_stream(ctx, str_id);
-put:
        stream->compr_cb_param = NULL;
        stream->compr_cb = NULL;
 
@@ -256,7 +247,6 @@ put:
 
        dev_dbg(dev, "End\n");
        return retval;
-
 }
 
 static int sst_cdev_ack(struct device *dev, unsigned int str_id,
@@ -486,16 +476,7 @@ static int sst_close_pcm_stream(struct device *dev, unsigned int str_id)
                return -EINVAL;
        }
 
-       if (stream->status == STREAM_RESET) {
-               /* silently fail here as we have cleaned the stream earlier */
-               dev_dbg(ctx->dev, "stream in reset state...\n");
-
-               retval = 0;
-               goto put;
-       }
-
        retval = free_stream_context(ctx, str_id);
-put:
        stream->pcm_substream = NULL;
        stream->status = STREAM_UN_INIT;
        stream->period_elapsed = NULL;
index b1e6b8f34a6a797d335e9630b4972842400977f2..af93244b48686f48ac08f8f8e55269911545b8ed 100644 (file)
@@ -360,14 +360,6 @@ int sst_assign_pvt_id(struct intel_sst_drv *drv)
        return local;
 }
 
-void sst_init_stream(struct stream_info *stream,
-               int codec, int sst_id, int ops, u8 slot)
-{
-       stream->status = STREAM_INIT;
-       stream->prev = STREAM_UN_INIT;
-       stream->ops = ops;
-}
-
 int sst_validate_strid(
                struct intel_sst_drv *sst_drv_ctx, int str_id)
 {
index 7ee6aeb7e0af5a63683a560bd65c2243927c67bd..107271f7dd634ec04fe7b74deaab40ab268b7d85 100644 (file)
 
 int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
 {
-       struct snd_sst_alloc_mrfld alloc_param;
+       struct snd_pcm_params *pcm_params;
        struct snd_sst_params *str_params;
        struct snd_sst_tstamp fw_tstamp;
        struct stream_info *str_info;
-       struct snd_sst_alloc_response *response;
-       unsigned int str_id, pipe_id, task_id;
-       int i, num_ch, ret = 0;
-       void *data = NULL;
+       int i, num_ch, str_id;
 
        dev_dbg(sst_drv_ctx->dev, "Enter\n");
 
        str_params = (struct snd_sst_params *)params;
-       memset(&alloc_param, 0, sizeof(alloc_param));
-       alloc_param.operation = str_params->ops;
-       alloc_param.codec_type = str_params->codec;
-       alloc_param.sg_count = str_params->aparams.sg_count;
-       alloc_param.ring_buf_info[0].addr =
+       str_id = str_params->stream_id;
+       str_info = get_stream_info(sst_drv_ctx, str_id);
+       if (!str_info)
+               return -EINVAL;
+
+       memset(&str_info->alloc_param, 0, sizeof(str_info->alloc_param));
+       str_info->alloc_param.operation = str_params->ops;
+       str_info->alloc_param.codec_type = str_params->codec;
+       str_info->alloc_param.sg_count = str_params->aparams.sg_count;
+       str_info->alloc_param.ring_buf_info[0].addr =
                str_params->aparams.ring_buf_info[0].addr;
-       alloc_param.ring_buf_info[0].size =
+       str_info->alloc_param.ring_buf_info[0].size =
                str_params->aparams.ring_buf_info[0].size;
-       alloc_param.frag_size = str_params->aparams.frag_size;
+       str_info->alloc_param.frag_size = str_params->aparams.frag_size;
 
-       memcpy(&alloc_param.codec_params, &str_params->sparams,
+       memcpy(&str_info->alloc_param.codec_params, &str_params->sparams,
                        sizeof(struct snd_sst_stream_params));
 
        /*
@@ -67,47 +69,62 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
         * Currently hardcoding as per FW reqm.
         */
        num_ch = sst_get_num_channel(str_params);
+       pcm_params = &str_info->alloc_param.codec_params.uc.pcm_params;
        for (i = 0; i < 8; i++) {
                if (i < num_ch)
-                       alloc_param.codec_params.uc.pcm_params.channel_map[i] = i;
+                       pcm_params->channel_map[i] = i;
                else
-                       alloc_param.codec_params.uc.pcm_params.channel_map[i] = 0xFF;
+                       pcm_params->channel_map[i] = 0xff;
        }
 
-       str_id = str_params->stream_id;
-       str_info = get_stream_info(sst_drv_ctx, str_id);
-       if (str_info == NULL) {
-               dev_err(sst_drv_ctx->dev, "get stream info returned null\n");
-               return -EINVAL;
-       }
-
-       pipe_id = str_params->device_type;
-       task_id = str_params->task;
-       sst_drv_ctx->streams[str_id].pipe_id = pipe_id;
-       sst_drv_ctx->streams[str_id].task_id = task_id;
+       sst_drv_ctx->streams[str_id].status = STREAM_INIT;
+       sst_drv_ctx->streams[str_id].prev = STREAM_UN_INIT;
+       sst_drv_ctx->streams[str_id].pipe_id = str_params->device_type;
+       sst_drv_ctx->streams[str_id].task_id = str_params->task;
        sst_drv_ctx->streams[str_id].num_ch = num_ch;
 
        if (sst_drv_ctx->info.lpe_viewpt_rqd)
-               alloc_param.ts = sst_drv_ctx->info.mailbox_start +
+               str_info->alloc_param.ts = sst_drv_ctx->info.mailbox_start +
                        sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
        else
-               alloc_param.ts = sst_drv_ctx->mailbox_add +
+               str_info->alloc_param.ts = sst_drv_ctx->mailbox_add +
                        sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
 
        dev_dbg(sst_drv_ctx->dev, "alloc tstamp location = 0x%x\n",
-                       alloc_param.ts);
+                       str_info->alloc_param.ts);
        dev_dbg(sst_drv_ctx->dev, "assigned pipe id 0x%x to task %d\n",
-                       pipe_id, task_id);
+                       str_info->pipe_id, str_info->task_id);
+
+       return sst_realloc_stream(sst_drv_ctx, str_id);
+}
+
+/**
+ * sst_realloc_stream - Send msg for (re-)allocating a stream using the
+ * @sst_drv_ctx  intel_sst_drv context pointer
+ * @str_id:     stream ID
+ *
+ * Send a msg for (re-)allocating a stream using the parameters previously
+ * passed to sst_alloc_stream_mrfld() for the same stream ID.
+ * Return: 0 or negative errno value.
+ */
+int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
+{
+       struct snd_sst_alloc_response *response;
+       struct stream_info *str_info;
+       void *data = NULL;
+       int ret;
 
-       /* allocate device type context */
-       sst_init_stream(&sst_drv_ctx->streams[str_id], alloc_param.codec_type,
-                       str_id, alloc_param.operation, 0);
+       str_info = get_stream_info(sst_drv_ctx, str_id);
+       if (!str_info)
+               return -EINVAL;
 
        dev_dbg(sst_drv_ctx->dev, "Alloc for str %d pipe %#x\n",
-                       str_id, pipe_id);
-       ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
-                       IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
-                       &alloc_param, &data, true, true, false, true);
+               str_id, str_info->pipe_id);
+
+       ret = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD,
+                       IPC_IA_ALLOC_STREAM_MRFLD, str_info->pipe_id,
+                       sizeof(str_info->alloc_param), &str_info->alloc_param,
+                       &data, true, true, false, true);
 
        if (ret < 0) {
                dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
@@ -253,7 +270,7 @@ int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
                if (retval == 0) {
                        str_info->prev = str_info->status;
                        str_info->status = STREAM_PAUSED;
-               } else if (retval == SST_ERR_INVALID_STREAM_ID) {
+               } else if (retval == -SST_ERR_INVALID_STREAM_ID) {
                        retval = -EINVAL;
                        mutex_lock(&sst_drv_ctx->sst_lock);
                        sst_clean_stream(str_info);
@@ -285,7 +302,29 @@ int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
                return -EINVAL;
        if (str_info->status == STREAM_RUNNING)
                return 0;
-       if (str_info->status == STREAM_PAUSED) {
+
+       if (str_info->resume_status == STREAM_PAUSED &&
+           str_info->resume_prev == STREAM_RUNNING) {
+               /*
+                * Stream was running before suspend and re-created on resume,
+                * start it to get back to running state.
+                */
+               dev_dbg(sst_drv_ctx->dev, "restart recreated stream after resume\n");
+               str_info->status = STREAM_RUNNING;
+               str_info->prev = STREAM_PAUSED;
+               retval = sst_start_stream(sst_drv_ctx, str_id);
+               str_info->resume_status = STREAM_UN_INIT;
+       } else if (str_info->resume_status == STREAM_PAUSED &&
+                  str_info->resume_prev == STREAM_INIT) {
+               /*
+                * Stream was idle before suspend and re-created on resume,
+                * keep it as is.
+                */
+               dev_dbg(sst_drv_ctx->dev, "leaving recreated stream idle after resume\n");
+               str_info->status = STREAM_INIT;
+               str_info->prev = STREAM_PAUSED;
+               str_info->resume_status = STREAM_UN_INIT;
+       } else if (str_info->status == STREAM_PAUSED) {
                retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id,
                                IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD,
                                str_info->pipe_id, 0, NULL, NULL,
index c54529320f0720560b7cc396a59b70f793fa11d8..aabb35bf6b963d86ab6f7e26d8f17f4c8460d37b 100644 (file)
@@ -23,6 +23,7 @@
 #include "../common/sst-dsp-priv.h"
 #include "../common/sst-dsp.h"
 
+#define DRV_NAME "byt-dai"
 #define BYT_PCM_COUNT          2
 
 static const struct snd_pcm_hardware sst_byt_pcm_hardware = {
@@ -69,8 +70,8 @@ static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
        struct sst_byt *byt = pdata->byt;
        u32 rate, bits;
@@ -141,8 +142,8 @@ static int sst_byt_pcm_hw_free(struct snd_pcm_substream *substream)
 static int sst_byt_pcm_restore_stream_context(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
        struct sst_byt *byt = pdata->byt;
        int ret;
@@ -174,8 +175,8 @@ static void sst_byt_pcm_work(struct work_struct *work)
 static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
        struct sst_byt *byt = pdata->byt;
 
@@ -216,8 +217,8 @@ static u32 byt_notify_pointer(struct sst_byt_stream *stream, void *data)
        struct snd_pcm_substream *substream = pcm_data->substream;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt *byt = pdata->byt;
        u32 pos, hw_pos;
 
@@ -238,8 +239,8 @@ static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
 
        dev_dbg(rtd->dev, "PCM: DMA pointer %u bytes\n", pcm_data->hw_ptr);
@@ -250,8 +251,8 @@ static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream
 static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
        struct sst_byt *byt = pdata->byt;
 
@@ -278,8 +279,8 @@ static int sst_byt_pcm_open(struct snd_pcm_substream *substream)
 static int sst_byt_pcm_close(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct sst_byt_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_byt_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream];
        struct sst_byt *byt = pdata->byt;
        int ret;
@@ -324,8 +325,8 @@ static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_pcm *pcm = rtd->pcm;
        size_t size;
-       struct snd_soc_platform *platform = rtd->platform;
-       struct sst_pdata *pdata = dev_get_platdata(platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_pdata *pdata = dev_get_platdata(component->dev);
        int ret = 0;
 
        if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
@@ -366,21 +367,21 @@ static struct snd_soc_dai_driver byt_dais[] = {
        },
 };
 
-static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
+static int sst_byt_pcm_probe(struct snd_soc_component *component)
 {
-       struct sst_pdata *plat_data = dev_get_platdata(platform->dev);
+       struct sst_pdata *plat_data = dev_get_platdata(component->dev);
        struct sst_byt_priv_data *priv_data;
        int i;
 
        if (!plat_data)
                return -ENODEV;
 
-       priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data),
+       priv_data = devm_kzalloc(component->dev, sizeof(*priv_data),
                                 GFP_KERNEL);
        if (!priv_data)
                return -ENOMEM;
        priv_data->byt = plat_data->dsp;
-       snd_soc_platform_set_drvdata(platform, priv_data);
+       snd_soc_component_set_drvdata(component, priv_data);
 
        for (i = 0; i < BYT_PCM_COUNT; i++) {
                mutex_init(&priv_data->pcm[i].mutex);
@@ -390,22 +391,13 @@ static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
        return 0;
 }
 
-static int sst_byt_pcm_remove(struct snd_soc_platform *platform)
-{
-       return 0;
-}
-
-static const struct snd_soc_platform_driver byt_soc_platform = {
+static const struct snd_soc_component_driver byt_dai_component = {
+       .name           = DRV_NAME,
        .probe          = sst_byt_pcm_probe,
-       .remove         = sst_byt_pcm_remove,
        .ops            = &sst_byt_pcm_ops,
        .pcm_new        = sst_byt_pcm_new,
 };
 
-static const struct snd_soc_component_driver byt_dai_component = {
-       .name           = "byt-dai",
-};
-
 #ifdef CONFIG_PM
 static int sst_byt_pcm_dev_suspend_late(struct device *dev)
 {
@@ -461,19 +453,13 @@ static int sst_byt_pcm_dev_probe(struct platform_device *pdev)
        if (ret < 0)
                return -ENODEV;
 
-       ret = snd_soc_register_platform(&pdev->dev, &byt_soc_platform);
-       if (ret < 0)
-               goto err_plat;
-
-       ret = snd_soc_register_component(&pdev->dev, &byt_dai_component,
+       ret = devm_snd_soc_register_component(&pdev->dev, &byt_dai_component,
                                         byt_dais, ARRAY_SIZE(byt_dais));
        if (ret < 0)
-               goto err_comp;
+               goto err_plat;
 
        return 0;
 
-err_comp:
-       snd_soc_unregister_platform(&pdev->dev);
 err_plat:
        sst_byt_dsp_free(&pdev->dev, sst_pdata);
        return ret;
@@ -483,8 +469,6 @@ static int sst_byt_pcm_dev_remove(struct platform_device *pdev)
 {
        struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
 
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_component(&pdev->dev);
        sst_byt_dsp_free(&pdev->dev, sst_pdata);
 
        return 0;
index fefb1ee9fec6fea0233ef16292a1fe307fbeec9e..24797482a3d22d231a73a6e9ba0ff8e4af53a622 100644 (file)
@@ -125,6 +125,17 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
          Say Y or m if you have such a device. This is a recommended option.
          If unsure select "N".
 
+config SND_SOC_INTEL_CHT_BSW_NAU8824_MACH
+       tristate "Cherrytrail & Braswell with NAU88L24 codec"
+       depends on X86_INTEL_LPSS && I2C && ACPI
+       select SND_SOC_ACPI
+       select SND_SOC_NAU8824
+       help
+         This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
+         platforms with NAU88L24 audio codec.
+         Say Y or m if you have such a device. This is a recommended option.
+         If unsure select "N".
+
 config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
        tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
        depends on X86_INTEL_LPSS && I2C && ACPI
@@ -256,6 +267,20 @@ config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
           create an alsa sound card for RT5663 + RT5514 + MAX98927.
           Say Y or m if you have such a device. This is a recommended option.
           If unsure select "N".
+
+config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
+       tristate "KBL with DA7219 and MAX98357A in I2S Mode"
+       depends on MFD_INTEL_LPSS && I2C && ACPI
+       select SND_SOC_DA7219
+       select SND_SOC_MAX98357A
+       select SND_SOC_DMIC
+       select SND_SOC_HDAC_HDMI
+       help
+         This adds support for ASoC Onboard Codec I2S machine driver. This will
+         create an alsa sound card for DA7219 + MAX98357A I2S audio codec.
+         Say Y if you have such a device.
+         If unsure select "N".
+
 endif ## SND_SOC_INTEL_SKYLAKE
 
 endif ## SND_SOC_INTEL_MACH
index 69d2dfaeb00c2ff3a19852884ee5b24e7c9d7d55..92b5507291af49ff7caf979248f77aa90ee141b6 100644 (file)
@@ -11,9 +11,11 @@ snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
 snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
 snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
 snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
+snd-soc-sst-cht-bsw-nau8824-objs := cht_bsw_nau8824.o
 snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
 snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
 snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
+snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o
 snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
 snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
 snd-soc-skl_rt286-objs := skl_rt286.o
@@ -32,9 +34,11 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
+obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH) += snd-soc-sst-cht-bsw-nau8824.o
 obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
 obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) += snd-soc-sst-byt-cht-es8316.o
 obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o
+obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH) += snd-soc-kbl_da7219_max98357a.o
 obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o
 obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH) += snd-soc-kbl_rt5663_rt5514_max98927.o
 obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
index 058b8ccedf02ed658305474531d5b2b32c3d0631..6ea360f33575ae8520a6cd4dccca6fbd309ae801 100644 (file)
@@ -34,7 +34,7 @@
 
 struct bdw_rt5677_priv {
        struct gpio_desc *gpio_hp_en;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 };
 
 static int bdw_rt5677_event_hp(struct snd_soc_dapm_widget *w,
@@ -183,7 +183,8 @@ static const struct snd_soc_ops bdw_rt5677_ops = {
 
 static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_pdata *pdata = dev_get_platdata(component->dev);
        struct sst_hsw *broadwell = pdata->dsp;
        int ret;
 
@@ -203,26 +204,26 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct bdw_rt5677_priv *bdw_rt5677 =
                        snd_soc_card_get_drvdata(rtd->card);
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = rtd->codec_dai->component;
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
        int ret;
 
-       ret = devm_acpi_dev_add_driver_gpios(codec->dev, bdw_rt5677_gpios);
+       ret = devm_acpi_dev_add_driver_gpios(component->dev, bdw_rt5677_gpios);
        if (ret)
-               dev_warn(codec->dev, "Failed to add driver gpios\n");
+               dev_warn(component->dev, "Failed to add driver gpios\n");
 
        /* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
         * The ASRC clock source is clk_i2s1_asrc.
         */
-       rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER |
+       rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER |
                        RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
                        RT5677_CLK_SEL_I2S1_ASRC);
 
        /* Request rt5677 GPIO for headphone amp control */
-       bdw_rt5677->gpio_hp_en = devm_gpiod_get(codec->dev, "headphone-enable",
+       bdw_rt5677->gpio_hp_en = devm_gpiod_get(component->dev, "headphone-enable",
                                                GPIOD_OUT_LOW);
        if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
-               dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
+               dev_err(component->dev, "Can't find HP_AMP_SHDN_L gpio\n");
                return PTR_ERR(bdw_rt5677->gpio_hp_en);
        }
 
@@ -230,25 +231,25 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
        if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack",
                        SND_JACK_HEADPHONE, &headphone_jack,
                        &headphone_jack_pin, 1)) {
-               headphone_jack_gpio.gpiod_dev = codec->dev;
+               headphone_jack_gpio.gpiod_dev = component->dev;
                if (snd_soc_jack_add_gpios(&headphone_jack, 1,
                                &headphone_jack_gpio))
-                       dev_err(codec->dev, "Can't add headphone jack gpio\n");
+                       dev_err(component->dev, "Can't add headphone jack gpio\n");
        } else {
-               dev_err(codec->dev, "Can't create headphone jack\n");
+               dev_err(component->dev, "Can't create headphone jack\n");
        }
 
        /* Create and initialize mic jack */
        if (!snd_soc_card_jack_new(rtd->card, "Mic Jack",
                        SND_JACK_MICROPHONE, &mic_jack,
                        &mic_jack_pin, 1)) {
-               mic_jack_gpio.gpiod_dev = codec->dev;
+               mic_jack_gpio.gpiod_dev = component->dev;
                if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
-                       dev_err(codec->dev, "Can't add mic jack gpio\n");
+                       dev_err(component->dev, "Can't add mic jack gpio\n");
        } else {
-               dev_err(codec->dev, "Can't create mic jack\n");
+               dev_err(component->dev, "Can't create mic jack\n");
        }
-       bdw_rt5677->codec = codec;
+       bdw_rt5677->component = component;
 
        snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
        return 0;
@@ -301,8 +302,8 @@ static int bdw_rt5677_suspend_pre(struct snd_soc_card *card)
        struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
        struct snd_soc_dapm_context *dapm;
 
-       if (bdw_rt5677->codec) {
-               dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
+       if (bdw_rt5677->component) {
+               dapm = snd_soc_component_get_dapm(bdw_rt5677->component);
                snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
        }
        return 0;
@@ -313,8 +314,8 @@ static int bdw_rt5677_resume_post(struct snd_soc_card *card)
        struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
        struct snd_soc_dapm_context *dapm;
 
-       if (bdw_rt5677->codec) {
-               dapm = snd_soc_codec_get_dapm(bdw_rt5677->codec);
+       if (bdw_rt5677->component) {
+               dapm = snd_soc_component_get_dapm(bdw_rt5677->component);
                snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
        }
        return 0;
index 6dcbbcefc25b446d5191362101f0bc206414cf56..7b0ee67b4fc8b04d26fd62a12c964353379a6494 100644 (file)
@@ -78,7 +78,7 @@ static const struct snd_soc_dapm_route broadwell_rt286_map[] = {
 
 static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        int ret = 0;
        ret = snd_soc_card_jack_new(rtd->card, "Headset",
                SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset,
@@ -86,7 +86,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
        if (ret)
                return ret;
 
-       rt286_mic_detect(codec, &broadwell_headset);
+       rt286_mic_detect(component, &broadwell_headset);
        return 0;
 }
 
@@ -132,7 +132,8 @@ static const struct snd_soc_ops broadwell_rt286_ops = {
 
 static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_pdata *pdata = dev_get_platdata(component->dev);
        struct sst_hsw *broadwell = pdata->dsp;
        int ret;
 
@@ -224,10 +225,9 @@ static int broadwell_suspend(struct snd_soc_card *card){
 
        list_for_each_entry(component, &card->component_dev_list, card_list) {
                if (!strcmp(component->name, "i2c-INT343A:00")) {
-                       struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-                       dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
-                       rt286_mic_detect(codec, NULL);
+                       dev_dbg(component->dev, "disabling jack detect before going to suspend.\n");
+                       rt286_mic_detect(component, NULL);
                        break;
                }
        }
@@ -239,10 +239,9 @@ static int broadwell_resume(struct snd_soc_card *card){
 
        list_for_each_entry(component, &card->component_dev_list, card_list) {
                if (!strcmp(component->name, "i2c-INT343A:00")) {
-                       struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-                       dev_dbg(codec->dev, "enabling jack detect for resume.\n");
-                       rt286_mic_detect(codec, &broadwell_headset);
+                       dev_dbg(component->dev, "enabling jack detect for resume.\n");
+                       rt286_mic_detect(component, &broadwell_headset);
                        break;
                }
        }
index f8a91a6f2a17af51c68e69ec88b907e718e72952..668c0934e942ba070a1908d905c452b9f6c0f165 100644 (file)
@@ -169,7 +169,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        /* Configure sysclk for codec */
        ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000,
@@ -192,7 +192,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
                return ret;
        }
 
-       da7219_aad_jack_det(codec, &broxton_headset);
+       da7219_aad_jack_det(component, &broxton_headset);
 
        snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -522,12 +522,12 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 {
        struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
        struct bxt_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -545,10 +545,10 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* broxton audio machine driver for SPT + da7219 */
index 7843104fadcbf2eff7915ffe3c903d5152ad86cf..c7e9024e65efa734dcd24e097e432fefe74bb43f 100644 (file)
@@ -146,6 +146,9 @@ static const struct snd_soc_dapm_route geminilake_rt298_map[] = {
        { "dmic01_hifi", NULL, "DMIC01 Rx" },
        { "DMIC01 Rx", NULL, "Capture" },
 
+       { "dmic_voice", NULL, "DMIC16k Rx" },
+       { "DMIC16k Rx", NULL, "Capture" },
+
        { "hifi3", NULL, "iDisp3 Tx"},
        { "iDisp3 Tx", NULL, "iDisp3_out"},
        { "hifi2", NULL, "iDisp2 Tx"},
@@ -167,7 +170,7 @@ static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd)
 
 static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        int ret = 0;
 
        ret = snd_soc_card_jack_new(rtd->card, "Headset",
@@ -178,7 +181,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
        if (ret)
                return ret;
 
-       rt298_mic_detect(codec, &broxton_headset);
+       rt298_mic_detect(component, &broxton_headset);
 
        snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -456,6 +459,18 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
                .dpcm_capture = 1,
                .no_pcm = 1,
        },
+       {
+               .name = "dmic16k",
+               .id = 2,
+               .cpu_dai_name = "DMIC16k Pin",
+               .codec_name = "dmic-codec",
+               .codec_dai_name = "dmic-hifi",
+               .platform_name = "0000:00:0e.0",
+               .be_hw_params_fixup = broxton_dmic_fixup,
+               .ignore_suspend = 1,
+               .dpcm_capture = 1,
+               .no_pcm = 1,
+       },
        {
                .name = "iDisp1",
                .id = 3,
@@ -496,12 +511,12 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 {
        struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
        struct bxt_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -519,10 +534,10 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 
index de9788a3fd06221dd7971d3c4967ad4c0bf22b81..df902d82145e300e0431116c494b90b8e1a37d8c 100644 (file)
@@ -131,7 +131,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
        int ret;
-       struct snd_soc_codec *codec = runtime->codec;
+       struct snd_soc_component *component = runtime->codec_dai->component;
        struct snd_soc_card *card = runtime->card;
        const struct snd_soc_dapm_route *custom_map;
        int num_routes;
@@ -165,7 +165,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
 
        if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
-               ret = rt5640_dmic_enable(codec, 0, 0);
+               ret = rt5640_dmic_enable(component, 0, 0);
                if (ret)
                        return ret;
        }
index b6a1cfeec83011deba6519ac2f532adabf5b44d1..a8d8bff788e70b3abeaca46fc67fd1fd079ae469 100644 (file)
@@ -444,14 +444,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_soc_card *card = runtime->card;
        struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
-       struct snd_soc_codec *codec = runtime->codec;
+       struct snd_soc_component *component = runtime->codec_dai->component;
        const struct snd_soc_dapm_route *custom_map;
        int num_routes;
        int ret;
 
        card->dapm.idle_bias_off = true;
 
-       rt5640_sel_asrc_clk_src(codec,
+       rt5640_sel_asrc_clk_src(component,
                                RT5640_DA_STEREO_FILTER |
                                RT5640_DA_MONO_L_FILTER |
                                RT5640_DA_MONO_R_FILTER |
@@ -522,12 +522,12 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
 
        if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
-               snd_soc_update_bits(codec,  RT5640_IN1_IN2, RT5640_IN_DF1,
+               snd_soc_component_update_bits(component,  RT5640_IN1_IN2, RT5640_IN_DF1,
                                    RT5640_IN_DF1);
        }
 
        if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
-               ret = rt5640_dmic_enable(codec, 0, 0);
+               ret = rt5640_dmic_enable(component, 0, 0);
                if (ret)
                        return ret;
        }
index 456526a93dd568b6b8bb89df752a2de6d7d86ea1..1b1997f1d60c843bb6b7abb7a86d6bdc09138ca1 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
 #include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -39,22 +42,55 @@ enum {
        BYT_RT5651_IN1_MAP,
        BYT_RT5651_IN2_MAP,
        BYT_RT5651_IN1_IN2_MAP,
-       BYT_RT5651_IN3_MAP,
+       BYT_RT5651_IN1_HS_IN3_MAP,
+       BYT_RT5651_IN2_HS_IN3_MAP,
 };
 
-#define BYT_RT5651_MAP(quirk)  ((quirk) & GENMASK(7, 0))
-#define BYT_RT5651_DMIC_EN     BIT(16)
-#define BYT_RT5651_MCLK_EN     BIT(17)
-#define BYT_RT5651_MCLK_25MHZ  BIT(18)
+enum {
+       BYT_RT5651_JD_NULL      = (RT5651_JD_NULL << 4),
+       BYT_RT5651_JD1_1        = (RT5651_JD1_1 << 4),
+       BYT_RT5651_JD1_2        = (RT5651_JD1_2 << 4),
+       BYT_RT5651_JD2          = (RT5651_JD2 << 4),
+};
+
+enum {
+       BYT_RT5651_OVCD_TH_600UA  = (6 << 8),
+       BYT_RT5651_OVCD_TH_1500UA = (15 << 8),
+       BYT_RT5651_OVCD_TH_2000UA = (20 << 8),
+};
+
+enum {
+       BYT_RT5651_OVCD_SF_0P5  = (RT5651_OVCD_SF_0P5 << 13),
+       BYT_RT5651_OVCD_SF_0P75 = (RT5651_OVCD_SF_0P75 << 13),
+       BYT_RT5651_OVCD_SF_1P0  = (RT5651_OVCD_SF_1P0 << 13),
+       BYT_RT5651_OVCD_SF_1P5  = (RT5651_OVCD_SF_1P5 << 13),
+};
+
+#define BYT_RT5651_MAP(quirk)          ((quirk) & GENMASK(3, 0))
+#define BYT_RT5651_JDSRC(quirk)                (((quirk) & GENMASK(7, 4)) >> 4)
+#define BYT_RT5651_OVCD_TH(quirk)      (((quirk) & GENMASK(12, 8)) >> 8)
+#define BYT_RT5651_OVCD_SF(quirk)      (((quirk) & GENMASK(14, 13)) >> 13)
+#define BYT_RT5651_DMIC_EN             BIT(16)
+#define BYT_RT5651_MCLK_EN             BIT(17)
+#define BYT_RT5651_MCLK_25MHZ          BIT(18)
+#define BYT_RT5651_SSP2_AIF2           BIT(19) /* default is using AIF1  */
+#define BYT_RT5651_SSP0_AIF1           BIT(20)
+#define BYT_RT5651_SSP0_AIF2           BIT(21)
+
+/* jack-detect-source + dmic-en + ovcd-th + -sf + terminating empty entry */
+#define MAX_NO_PROPS 5
 
 struct byt_rt5651_private {
        struct clk *mclk;
        struct snd_soc_jack jack;
 };
 
-static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP |
-                                       BYT_RT5651_DMIC_EN |
-                                       BYT_RT5651_MCLK_EN;
+/* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
+static unsigned long byt_rt5651_quirk = BYT_RT5651_MCLK_EN |
+                                       BYT_RT5651_JD1_1 |
+                                       BYT_RT5651_OVCD_TH_2000UA |
+                                       BYT_RT5651_OVCD_SF_0P75 |
+                                       BYT_RT5651_IN2_HS_IN3_MAP;
 
 static void log_quirks(struct device *dev)
 {
@@ -64,17 +100,66 @@ static void log_quirks(struct device *dev)
                dev_info(dev, "quirk IN1_MAP enabled");
        if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
                dev_info(dev, "quirk IN2_MAP enabled");
-       if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN3_MAP)
-               dev_info(dev, "quirk IN3_MAP enabled");
+       if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_HS_IN3_MAP)
+               dev_info(dev, "quirk IN1_HS_IN3_MAP enabled");
+       if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_HS_IN3_MAP)
+               dev_info(dev, "quirk IN2_HS_IN3_MAP enabled");
+       if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
+               dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
+                        BYT_RT5651_JDSRC(byt_rt5651_quirk));
+               dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
+                        BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
+               dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
+                        BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
+       }
        if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
                dev_info(dev, "quirk DMIC enabled");
        if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
                dev_info(dev, "quirk MCLK_EN enabled");
        if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
                dev_info(dev, "quirk MCLK_25MHZ enabled");
+       if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2)
+               dev_info(dev, "quirk SSP2_AIF2 enabled\n");
+       if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1)
+               dev_info(dev, "quirk SSP0_AIF1 enabled\n");
+       if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)
+               dev_info(dev, "quirk SSP0_AIF2 enabled\n");
 }
 
 #define BYT_CODEC_DAI1 "rt5651-aif1"
+#define BYT_CODEC_DAI2 "rt5651-aif2"
+
+static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
+                                             int rate, int bclk_ratio)
+{
+       int clk_id, clk_freq, ret;
+
+       /* Configure the PLL before selecting it */
+       if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
+               clk_id = RT5651_PLL1_S_BCLK1,
+               clk_freq = rate * bclk_ratio;
+       } else {
+               clk_id = RT5651_PLL1_S_MCLK;
+               if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
+                       clk_freq = 25000000;
+               else
+                       clk_freq = 19200000;
+       }
+       ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, rate * 512);
+       if (ret < 0) {
+               dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
+                                    rate * 512, SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
 
 static int platform_clock_control(struct snd_soc_dapm_widget *w,
                                  struct snd_kcontrol *k, int  event)
@@ -86,6 +171,8 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
        int ret;
 
        codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
+       if (!codec_dai)
+               codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
        if (!codec_dai) {
                dev_err(card->dev,
                        "Codec dai not found; Unable to set platform clock\n");
@@ -101,9 +188,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
                                return ret;
                        }
                }
-               ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
-                                            48000 * 512,
-                                            SND_SOC_CLOCK_IN);
+               ret = byt_rt5651_prepare_and_enable_pll1(codec_dai, 48000, 50);
        } else {
                /*
                 * Set codec clock source to internal clock before
@@ -145,13 +230,6 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
        {"Speaker", NULL, "Platform Clock"},
        {"Line In", NULL, "Platform Clock"},
 
-       {"AIF1 Playback", NULL, "ssp2 Tx"},
-       {"ssp2 Tx", NULL, "codec_out0"},
-       {"ssp2 Tx", NULL, "codec_out1"},
-       {"codec_in0", NULL, "ssp2 Rx"},
-       {"codec_in1", NULL, "ssp2 Rx"},
-       {"ssp2 Rx", NULL, "AIF1 Capture"},
-
        {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
        {"Headphone", NULL, "HPOL"},
        {"Headphone", NULL, "HPOR"},
@@ -170,8 +248,8 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
 
 static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
        {"Internal Mic", NULL, "micbias1"},
-       {"IN2P", NULL, "Headset Mic"},
        {"IN1P", NULL, "Internal Mic"},
+       {"IN2P", NULL, "Headset Mic"},
 };
 
 static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
@@ -187,10 +265,52 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map[] = {
        {"IN3P", NULL, "Headset Mic"},
 };
 
-static const struct snd_soc_dapm_route byt_rt5651_intmic_in3_map[] = {
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_hs_in3_map[] = {
        {"Internal Mic", NULL, "micbias1"},
-       {"IN3P", NULL, "Headset Mic"},
        {"IN1P", NULL, "Internal Mic"},
+       {"IN3P", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_hs_in3_map[] = {
+       {"Internal Mic", NULL, "micbias1"},
+       {"IN2P", NULL, "Internal Mic"},
+       {"IN3P", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif1_map[] = {
+       {"ssp0 Tx", NULL, "modem_out"},
+       {"modem_in", NULL, "ssp0 Rx"},
+
+       {"AIF1 Playback", NULL, "ssp0 Tx"},
+       {"ssp0 Rx", NULL, "AIF1 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif2_map[] = {
+       {"ssp0 Tx", NULL, "modem_out"},
+       {"modem_in", NULL, "ssp0 Rx"},
+
+       {"AIF2 Playback", NULL, "ssp0 Tx"},
+       {"ssp0 Rx", NULL, "AIF2 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif1_map[] = {
+       {"ssp2 Tx", NULL, "codec_out0"},
+       {"ssp2 Tx", NULL, "codec_out1"},
+       {"codec_in0", NULL, "ssp2 Rx"},
+       {"codec_in1", NULL, "ssp2 Rx"},
+
+       {"AIF1 Playback", NULL, "ssp2 Tx"},
+       {"ssp2 Rx", NULL, "AIF1 Capture"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif2_map[] = {
+       {"ssp2 Tx", NULL, "codec_out0"},
+       {"ssp2 Tx", NULL, "codec_out1"},
+       {"codec_in0", NULL, "ssp2 Rx"},
+       {"codec_in1", NULL, "ssp2 Rx"},
+
+       {"AIF2 Playback", NULL, "ssp2 Tx"},
+       {"ssp2 Rx", NULL, "AIF2 Capture"},
 };
 
 static const struct snd_kcontrol_new byt_rt5651_controls[] = {
@@ -217,44 +337,16 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int ret;
-
-       snd_soc_dai_set_bclk_ratio(codec_dai, 50);
+       snd_pcm_format_t format = params_format(params);
+       int rate = params_rate(params);
+       int bclk_ratio;
 
-       ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
-                                    params_rate(params) * 512,
-                                    SND_SOC_CLOCK_IN);
-       if (ret < 0) {
-               dev_err(rtd->dev, "can't set codec clock %d\n", ret);
-               return ret;
-       }
+       if (format == SNDRV_PCM_FORMAT_S16_LE)
+               bclk_ratio = 32;
+       else
+               bclk_ratio = 50;
 
-       if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
-               /* 2x25 bit slots on SSP2 */
-               ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                       RT5651_PLL1_S_BCLK1,
-                                       params_rate(params) * 50,
-                                       params_rate(params) * 512);
-       } else {
-               if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) {
-                       ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                               RT5651_PLL1_S_MCLK,
-                                               25000000,
-                                               params_rate(params) * 512);
-               } else {
-                       ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                               RT5651_PLL1_S_MCLK,
-                                               19200000,
-                                               params_rate(params) * 512);
-               }
-       }
-
-       if (ret < 0) {
-               dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
+       return byt_rt5651_prepare_and_enable_pll1(codec_dai, rate, bclk_ratio);
 }
 
 static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
@@ -270,7 +362,7 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
                },
-               .driver_data = (void *)(BYT_RT5651_IN3_MAP),
+               .driver_data = (void *)(BYT_RT5651_IN1_HS_IN3_MAP),
        },
        {
                .callback = byt_rt5651_quirk_cb,
@@ -279,7 +371,7 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"),
                },
                .driver_data = (void *)(BYT_RT5651_MCLK_EN |
-                                       BYT_RT5651_IN3_MAP),
+                                       BYT_RT5651_IN1_HS_IN3_MAP),
        },
        {
                .callback = byt_rt5651_quirk_cb,
@@ -288,15 +380,76 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
                },
                .driver_data = (void *)(BYT_RT5651_MCLK_EN |
+                                       BYT_RT5651_JD1_1 |
+                                       BYT_RT5651_OVCD_TH_2000UA |
+                                       BYT_RT5651_OVCD_SF_0P75 |
+                                       BYT_RT5651_IN1_IN2_MAP),
+       },
+       {
+               /* Chuwi Vi8 Plus (CWI519) */
+               .callback = byt_rt5651_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "D2D3_Vi8A1"),
+               },
+               .driver_data = (void *)(BYT_RT5651_MCLK_EN |
+                                       BYT_RT5651_JD1_1 |
+                                       BYT_RT5651_OVCD_TH_2000UA |
+                                       BYT_RT5651_OVCD_SF_0P75 |
+                                       BYT_RT5651_IN2_HS_IN3_MAP),
+       },
+       {
+               /* VIOS LTH17 */
+               .callback = byt_rt5651_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "VIOS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LTH17"),
+               },
+               .driver_data = (void *)(BYT_RT5651_MCLK_EN |
+                                       BYT_RT5651_JD1_1 |
+                                       BYT_RT5651_OVCD_TH_2000UA |
+                                       BYT_RT5651_OVCD_SF_1P0 |
                                        BYT_RT5651_IN1_IN2_MAP),
        },
        {}
 };
 
+/*
+ * Note this MUST be called before snd_soc_register_card(), so that the props
+ * are in place before the codec component driver's probe function parses them.
+ */
+static int byt_rt5651_add_codec_device_props(const char *i2c_dev_name)
+{
+       struct property_entry props[MAX_NO_PROPS] = {};
+       struct device *i2c_dev;
+       int ret, cnt = 0;
+
+       i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
+       if (!i2c_dev)
+               return -EPROBE_DEFER;
+
+       props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
+                               BYT_RT5651_JDSRC(byt_rt5651_quirk));
+
+       props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-threshold-microamp",
+                               BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
+
+       props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-scale-factor",
+                               BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
+
+       if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
+               props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en");
+
+       ret = device_add_properties(i2c_dev, props);
+       put_device(i2c_dev);
+
+       return ret;
+}
+
 static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_soc_card *card = runtime->card;
-       struct snd_soc_codec *codec = runtime->codec;
+       struct snd_soc_component *codec = runtime->codec_dai->component;
        struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
        const struct snd_soc_dapm_route *custom_map;
        int num_routes;
@@ -304,6 +457,11 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
 
        card->dapm.idle_bias_off = true;
 
+       /* Start with RC clk for jack-detect (we disable MCLK below) */
+       if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
+               snd_soc_component_update_bits(codec, RT5651_GLB_CLK,
+                       RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_RCCLK);
+
        switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
        case BYT_RT5651_IN1_MAP:
                custom_map = byt_rt5651_intmic_in1_map;
@@ -317,9 +475,13 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
                custom_map = byt_rt5651_intmic_in1_in2_map;
                num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
                break;
-       case BYT_RT5651_IN3_MAP:
-               custom_map = byt_rt5651_intmic_in3_map;
-               num_routes = ARRAY_SIZE(byt_rt5651_intmic_in3_map);
+       case BYT_RT5651_IN1_HS_IN3_MAP:
+               custom_map = byt_rt5651_intmic_in1_hs_in3_map;
+               num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_hs_in3_map);
+               break;
+       case BYT_RT5651_IN2_HS_IN3_MAP:
+               custom_map = byt_rt5651_intmic_in2_hs_in3_map;
+               num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_hs_in3_map);
                break;
        default:
                custom_map = byt_rt5651_intmic_dmic_map;
@@ -329,6 +491,26 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
        if (ret)
                return ret;
 
+       if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5651_ssp2_aif2_map,
+                                       ARRAY_SIZE(byt_rt5651_ssp2_aif2_map));
+       } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5651_ssp0_aif1_map,
+                                       ARRAY_SIZE(byt_rt5651_ssp0_aif1_map));
+       } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5651_ssp0_aif2_map,
+                                       ARRAY_SIZE(byt_rt5651_ssp0_aif2_map));
+       } else {
+               ret = snd_soc_dapm_add_routes(&card->dapm,
+                                       byt_rt5651_ssp2_aif1_map,
+                                       ARRAY_SIZE(byt_rt5651_ssp2_aif1_map));
+       }
+       if (ret)
+               return ret;
+
        ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
                                        ARRAY_SIZE(byt_rt5651_controls));
        if (ret) {
@@ -362,17 +544,21 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
                        dev_err(card->dev, "unable to set MCLK rate\n");
        }
 
-       ret = snd_soc_card_jack_new(runtime->card, "Headset",
+       if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
+               ret = snd_soc_card_jack_new(runtime->card, "Headset",
                                    SND_JACK_HEADSET, &priv->jack,
                                    bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
-       if (ret) {
-               dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
-               return ret;
-       }
+               if (ret) {
+                       dev_err(runtime->dev, "jack creation failed %d\n", ret);
+                       return ret;
+               }
 
-       rt5651_set_jack_detect(codec, &priv->jack);
+               ret = snd_soc_component_set_jack(codec, &priv->jack, NULL);
+               if (ret)
+                       return ret;
+       }
 
-       return ret;
+       return 0;
 }
 
 static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
@@ -390,18 +576,26 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
                        SNDRV_PCM_HW_PARAM_RATE);
        struct snd_interval *channels = hw_param_interval(params,
                                                SNDRV_PCM_HW_PARAM_CHANNELS);
-       int ret;
+       int ret, bits;
 
-       /* The DSP will covert the FE rate to 48k, stereo, 24bits */
+       /* The DSP will covert the FE rate to 48k, stereo */
        rate->min = rate->max = 48000;
        channels->min = channels->max = 2;
 
-       /* set SSP2 to 24-bit */
-       params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+       if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
+           (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
+               /* set SSP0 to 16-bit */
+               params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+               bits = 16;
+       } else {
+               /* set SSP2 to 24-bit */
+               params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+               bits = 24;
+       }
 
        /*
         * Default mode for SSP configuration is TDM 4 slot, override config
-        * with explicit setting to I2S 2ch 24-bit. The word length is set with
+        * with explicit setting to I2S 2ch. The word length is set with
         * dai_set_tdm_slot() since there is no other API exposed
         */
        ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
@@ -415,7 +609,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
                return ret;
        }
 
-       ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+       ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
        if (ret < 0) {
                dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
                return ret;
@@ -510,12 +704,32 @@ static struct snd_soc_card byt_rt5651_card = {
 };
 
 static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
+static char byt_rt5651_codec_aif_name[12]; /*  = "rt5651-aif[1|2]" */
+static char byt_rt5651_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+
+static bool is_valleyview(void)
+{
+       static const struct x86_cpu_id cpu_ids[] = {
+               { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
+               {}
+       };
+
+       if (!x86_match_cpu(cpu_ids))
+               return false;
+       return true;
+}
+
+struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
+       u64 aif_value;       /* 1: AIF1, 2: AIF2 */
+       u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
+};
 
 static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
 {
        struct byt_rt5651_private *priv;
        struct snd_soc_acpi_mach *mach;
        const char *i2c_name = NULL;
+       bool is_bytcr = false;
        int ret_val = 0;
        int dai_index = 0;
        int i;
@@ -540,17 +754,105 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
 
        /* fixup codec name based on HID */
        i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
-       if (i2c_name) {
-               snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
-                       "%s%s", "i2c-", i2c_name);
+       if (!i2c_name) {
+               dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
+               return -ENODEV;
+       }
+       snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
+               "%s%s", "i2c-", i2c_name);
+       byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
 
-               byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
+       /*
+        * swap SSP0 if bytcr is detected
+        * (will be overridden if DMI quirk is detected)
+        */
+       if (is_valleyview()) {
+               struct sst_platform_info *p_info = mach->pdata;
+               const struct sst_res_info *res_info = p_info->res_info;
+
+               if (res_info->acpi_ipc_irq_index == 0)
+                       is_bytcr = true;
+       }
+
+       if (is_bytcr) {
+               /*
+                * Baytrail CR platforms may have CHAN package in BIOS, try
+                * to find relevant routing quirk based as done on Windows
+                * platforms. We have to read the information directly from the
+                * BIOS, at this stage the card is not created and the links
+                * with the codec driver/pdata are non-existent
+                */
+
+               struct acpi_chan_package chan_package;
+
+               /* format specified: 2 64-bit integers */
+               struct acpi_buffer format = {sizeof("NN"), "NN"};
+               struct acpi_buffer state = {0, NULL};
+               struct snd_soc_acpi_package_context pkg_ctx;
+               bool pkg_found = false;
+
+               state.length = sizeof(chan_package);
+               state.pointer = &chan_package;
+
+               pkg_ctx.name = "CHAN";
+               pkg_ctx.length = 2;
+               pkg_ctx.format = &format;
+               pkg_ctx.state = &state;
+               pkg_ctx.data_valid = false;
+
+               pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
+                                                              &pkg_ctx);
+               if (pkg_found) {
+                       if (chan_package.aif_value == 1) {
+                               dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
+                               byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF1;
+                       } else  if (chan_package.aif_value == 2) {
+                               dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
+                               byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
+                       } else {
+                               dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
+                               pkg_found = false;
+                       }
+               }
+
+               if (!pkg_found) {
+                       /* no BIOS indications, assume SSP0-AIF2 connection */
+                       byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
+               }
        }
 
        /* check quirks before creating card */
        dmi_check_system(byt_rt5651_quirk_table);
+
+       /* Must be called before register_card, also see declaration comment. */
+       ret_val = byt_rt5651_add_codec_device_props(byt_rt5651_codec_name);
+       if (ret_val)
+               return ret_val;
+
        log_quirks(&pdev->dev);
 
+       if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
+           (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
+               /* fixup codec aif name */
+               snprintf(byt_rt5651_codec_aif_name,
+                       sizeof(byt_rt5651_codec_aif_name),
+                       "%s", "rt5651-aif2");
+
+               byt_rt5651_dais[dai_index].codec_dai_name =
+                       byt_rt5651_codec_aif_name;
+       }
+
+       if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
+           (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
+               /* fixup cpu dai name name */
+               snprintf(byt_rt5651_cpu_dai_name,
+                       sizeof(byt_rt5651_cpu_dai_name),
+                       "%s", "ssp0-port");
+
+               byt_rt5651_dais[dai_index].cpu_dai_name =
+                       byt_rt5651_cpu_dai_name;
+       }
+
        if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
                priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
                if (IS_ERR(priv->mclk)) {
diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c
new file mode 100644 (file)
index 0000000..680f2b3
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ *  cht-bsw-nau8824.c - ASoc Machine driver for Intel Cherryview-based
+ *          platforms Cherrytrail and Braswell, with nau8824 codec.
+ *
+ *  Copyright (C) 2018 Intel Corp
+ *  Copyright (C) 2018 Nuvoton Technology Corp
+ *
+ *  Author: Wang, Joseph C <joequant@gmail.com>
+ *  Co-author: John Hsu <KCHSU0@nuvoton.com>
+ *  This file is based on cht_bsw_rt5672.c and cht-bsw-max98090.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; 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <linux/input.h>
+#include "../atom/sst-atom-controls.h"
+#include "../../codecs/nau8824.h"
+
+struct cht_mc_private {
+       struct snd_soc_jack jack;
+};
+
+static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
+       {
+               .pin = "Headphone",
+               .mask = SND_JACK_HEADPHONE,
+       },
+       {
+               .pin = "Headset Mic",
+               .mask = SND_JACK_MICROPHONE,
+       },
+};
+
+static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+       SND_SOC_DAPM_MIC("Int Mic", NULL),
+       SND_SOC_DAPM_SPK("Ext Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route cht_audio_map[] = {
+       {"Ext Spk", NULL, "SPKOUTL"},
+       {"Ext Spk", NULL, "SPKOUTR"},
+       {"Headphone", NULL, "HPOL"},
+       {"Headphone", NULL, "HPOR"},
+       {"MIC1", NULL, "Int Mic"},
+       {"MIC2", NULL, "Int Mic"},
+       {"HSMIC1", NULL, "Headset Mic"},
+       {"HSMIC2", NULL, "Headset Mic"},
+       {"Playback", NULL, "ssp2 Tx"},
+       {"ssp2 Tx", NULL, "codec_out0"},
+       {"ssp2 Tx", NULL, "codec_out1"},
+       {"codec_in0", NULL, "ssp2 Rx" },
+       {"codec_in1", NULL, "ssp2 Rx" },
+       {"ssp2 Rx", NULL, "Capture"},
+};
+
+static const struct snd_kcontrol_new cht_mc_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Headphone"),
+       SOC_DAPM_PIN_SWITCH("Headset Mic"),
+       SOC_DAPM_PIN_SWITCH("Int Mic"),
+       SOC_DAPM_PIN_SWITCH("Ext Spk"),
+};
+
+static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       int ret;
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, NAU8824_CLK_FLL_FS, 0,
+               SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
+               return ret;
+       }
+       ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
+               params_rate(params) * 256);
+       if (ret < 0) {
+               dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
+{
+       struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
+       struct snd_soc_jack *jack = &ctx->jack;
+       struct snd_soc_dai *codec_dai = runtime->codec_dai;
+       struct snd_soc_component *component = codec_dai->component;
+       int ret, jack_type;
+
+       /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
+       ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xf, 0x1, 4, 24);
+       if (ret < 0) {
+               dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret);
+               return ret;
+       }
+
+       /* NAU88L24 supports 4 butons headset detection
+        * KEY_MEDIA
+        * KEY_VOICECOMMAND
+        * KEY_VOLUMEUP
+        * KEY_VOLUMEDOWN
+        */
+       jack_type = SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+               SND_JACK_BTN_2 | SND_JACK_BTN_3;
+       ret = snd_soc_card_jack_new(runtime->card, "Headset", jack_type, jack,
+               cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
+       if (ret) {
+               dev_err(runtime->dev,
+                       "Headset Jack creation failed %d\n", ret);
+               return ret;
+       }
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+       nau8824_enable_jack_detect(component, jack);
+
+       return ret;
+}
+
+static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_interval *rate = hw_param_interval(params,
+               SNDRV_PCM_HW_PARAM_RATE);
+       struct snd_interval *channels = hw_param_interval(params,
+               SNDRV_PCM_HW_PARAM_CHANNELS);
+       struct snd_mask *fmt =
+               hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+       /* The DSP will covert the FE rate to 48k, stereo, 24bits */
+       rate->min = rate->max = 48000;
+       channels->min = channels->max = 2;
+
+       /* set SSP2 to 24-bit */
+       snd_mask_none(fmt);
+       params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+       return 0;
+}
+
+static int cht_aif1_startup(struct snd_pcm_substream *substream)
+{
+       return snd_pcm_hw_constraint_single(substream->runtime,
+               SNDRV_PCM_HW_PARAM_RATE, 48000);
+}
+
+static const struct snd_soc_ops cht_aif1_ops = {
+       .startup = cht_aif1_startup,
+};
+
+static const struct snd_soc_ops cht_be_ssp2_ops = {
+       .hw_params = cht_aif1_hw_params,
+};
+
+static struct snd_soc_dai_link cht_dailink[] = {
+       /* Front End DAI links */
+       [MERR_DPCM_AUDIO] = {
+               .name = "Audio Port",
+               .stream_name = "Audio",
+               .cpu_dai_name = "media-cpu-dai",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .codec_name = "snd-soc-dummy",
+               .platform_name = "sst-mfld-platform",
+               .nonatomic = true,
+               .dynamic = 1,
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .ops = &cht_aif1_ops,
+       },
+       [MERR_DPCM_DEEP_BUFFER] = {
+               .name = "Deep-Buffer Audio Port",
+               .stream_name = "Deep-Buffer Audio",
+               .cpu_dai_name = "deepbuffer-cpu-dai",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .codec_name = "snd-soc-dummy",
+               .platform_name = "sst-mfld-platform",
+               .nonatomic = true,
+               .dynamic = 1,
+               .dpcm_playback = 1,
+               .ops = &cht_aif1_ops,
+       },
+       [MERR_DPCM_COMPR] = {
+               .name = "Compressed Port",
+               .stream_name = "Compress",
+               .cpu_dai_name = "compress-cpu-dai",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .codec_name = "snd-soc-dummy",
+               .platform_name = "sst-mfld-platform",
+       },
+       /* Back End DAI links */
+       {
+               /* SSP2 - Codec */
+               .name = "SSP2-Codec",
+               .id = 1,
+               .cpu_dai_name = "ssp2-port",
+               .platform_name = "sst-mfld-platform",
+               .no_pcm = 1,
+               .codec_dai_name = NAU8824_CODEC_DAI,
+               .codec_name = "i2c-10508824:00",
+               .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
+                       | SND_SOC_DAIFMT_CBS_CFS,
+               .init = cht_codec_init,
+               .be_hw_params_fixup = cht_codec_fixup,
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+               .ops = &cht_be_ssp2_ops,
+       },
+};
+
+/* SoC card */
+static struct snd_soc_card snd_soc_card_cht = {
+       .name = "chtnau8824",
+       .owner = THIS_MODULE,
+       .dai_link = cht_dailink,
+       .num_links = ARRAY_SIZE(cht_dailink),
+       .dapm_widgets = cht_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
+       .dapm_routes = cht_audio_map,
+       .num_dapm_routes = ARRAY_SIZE(cht_audio_map),
+       .controls = cht_mc_controls,
+       .num_controls = ARRAY_SIZE(cht_mc_controls),
+};
+
+static int snd_cht_mc_probe(struct platform_device *pdev)
+{
+       struct cht_mc_private *drv;
+       int ret_val;
+
+       drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
+       if (!drv)
+               return -ENOMEM;
+       snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
+
+       /* register the soc card */
+       snd_soc_card_cht.dev = &pdev->dev;
+       ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
+       if (ret_val) {
+               dev_err(&pdev->dev,
+                       "snd_soc_register_card failed %d\n", ret_val);
+               return ret_val;
+       }
+       platform_set_drvdata(pdev, &snd_soc_card_cht);
+
+       return ret_val;
+}
+
+static struct platform_driver snd_cht_mc_driver = {
+       .driver = {
+               .name = "cht-bsw-nau8824",
+       },
+       .probe = snd_cht_mc_probe,
+};
+
+module_platform_driver(snd_cht_mc_driver);
+
+MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
+MODULE_AUTHOR("Wang, Joseph C <joequant@gmail.com>");
+MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:cht-bsw-nau8824");
index 31641aab62cd17eef48c1ac85cb98726a532d807..49ba1a956a06a01c34e2a008c81629ae86ce85d3 100644 (file)
@@ -252,14 +252,14 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_soc_card *card = runtime->card;
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
-       struct snd_soc_codec *codec = runtime->codec;
+       struct snd_soc_component *component = runtime->codec_dai->component;
        int jack_type;
        int ret;
 
        if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
            (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
                /* Select clk_i2s2_asrc as ASRC clock source */
-               rt5645_sel_asrc_clk_src(codec,
+               rt5645_sel_asrc_clk_src(component,
                                        RT5645_DA_STEREO_FILTER |
                                        RT5645_DA_MONO_L_FILTER |
                                        RT5645_DA_MONO_R_FILTER |
@@ -267,7 +267,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
                                        RT5645_CLK_SEL_I2S2_ASRC);
        } else {
                /* Select clk_i2s1_asrc as ASRC clock source */
-               rt5645_sel_asrc_clk_src(codec,
+               rt5645_sel_asrc_clk_src(component,
                                        RT5645_DA_STEREO_FILTER |
                                        RT5645_DA_MONO_L_FILTER |
                                        RT5645_DA_MONO_R_FILTER |
@@ -310,7 +310,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
        }
 
-       rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack);
+       rt5645_set_jack_detect(component, &ctx->jack, &ctx->jack, &ctx->jack);
 
 
        /*
index c14a52d2f71440fd099d201e9ac2606b962e7b69..e68ec32720a4ad453718dfe936591d9c0ebd90df 100644 (file)
@@ -183,10 +183,10 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
 {
        int ret;
        struct snd_soc_dai *codec_dai = runtime->codec_dai;
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_component *component = codec_dai->component;
        struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
 
-       if (devm_acpi_dev_add_driver_gpios(codec->dev, cht_rt5672_gpios))
+       if (devm_acpi_dev_add_driver_gpios(component->dev, cht_rt5672_gpios))
                dev_warn(runtime->dev, "Unable to add GPIO mapping table\n");
 
        /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
@@ -201,7 +201,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
         * be supported by RT5672. Otherwise, ASRC will be disabled and cause
         * noise.
         */
-       rt5670_sel_asrc_clk_src(codec,
+       rt5670_sel_asrc_clk_src(component,
                                RT5670_DA_STEREO_FILTER
                                | RT5670_DA_MONO_L_FILTER
                                | RT5670_DA_MONO_R_FILTER
@@ -219,7 +219,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
         if (ret)
                 return ret;
 
-       rt5670_set_jack_detect(codec, &ctx->headset);
+       rt5670_set_jack_detect(component, &ctx->headset);
        if (ctx->mclk) {
                /*
                 * The firmware might enable the clock at
@@ -333,10 +333,9 @@ static int cht_suspend_pre(struct snd_soc_card *card)
        list_for_each_entry(component, &card->component_dev_list, card_list) {
                if (!strncmp(component->name,
                             ctx->codec_name, sizeof(ctx->codec_name))) {
-                       struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-                       dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
-                       rt5670_jack_suspend(codec);
+                       dev_dbg(component->dev, "disabling jack detect before going to suspend.\n");
+                       rt5670_jack_suspend(component);
                        break;
                }
        }
@@ -351,10 +350,9 @@ static int cht_resume_post(struct snd_soc_card *card)
        list_for_each_entry(component, &card->component_dev_list, card_list) {
                if (!strncmp(component->name,
                             ctx->codec_name, sizeof(ctx->codec_name))) {
-                       struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
 
-                       dev_dbg(codec->dev, "enabling jack detect for resume.\n");
-                       rt5670_jack_resume(codec);
+                       dev_dbg(component->dev, "enabling jack detect for resume.\n");
+                       rt5670_jack_resume(component);
                        break;
                }
        }
index 3c51607792044fe5200842a6a23be2d4f175fe3c..eab1f439dd3f1ad9a4553d03fa2190d673ec94a3 100644 (file)
@@ -87,7 +87,8 @@ static const struct snd_soc_ops haswell_rt5640_ops = {
 
 static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_pdata *pdata = dev_get_platdata(component->dev);
        struct sst_hsw *haswell = pdata->dsp;
        int ret;
 
diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c
new file mode 100644 (file)
index 0000000..e84baaf
--- /dev/null
@@ -0,0 +1,613 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2017-18 Intel Corporation.
+
+/*
+ * Intel Kabylake I2S Machine Driver with MAX98357A & DA7219 Codecs
+ *
+ * Modified from:
+ *   Intel Kabylake I2S Machine driver supporting MAXIM98927 and
+ *   RT5663 codecs
+ */
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include "../../codecs/da7219.h"
+#include "../../codecs/hdac_hdmi.h"
+#include "../skylake/skl.h"
+#include "../../codecs/da7219-aad.h"
+
+#define KBL_DIALOG_CODEC_DAI "da7219-hifi"
+#define KBL_MAXIM_CODEC_DAI "HiFi"
+#define MAXIM_DEV0_NAME "MX98357A:00"
+#define DUAL_CHANNEL 2
+#define QUAD_CHANNEL 4
+
+static struct snd_soc_card *kabylake_audio_card;
+static struct snd_soc_jack skylake_hdmi[3];
+
+struct kbl_hdmi_pcm {
+       struct list_head head;
+       struct snd_soc_dai *codec_dai;
+       int device;
+};
+
+struct kbl_codec_private {
+       struct snd_soc_jack kabylake_headset;
+       struct list_head hdmi_pcm_list;
+};
+
+enum {
+       KBL_DPCM_AUDIO_PB = 0,
+       KBL_DPCM_AUDIO_CP,
+       KBL_DPCM_AUDIO_DMIC_CP,
+       KBL_DPCM_AUDIO_HDMI1_PB,
+       KBL_DPCM_AUDIO_HDMI2_PB,
+       KBL_DPCM_AUDIO_HDMI3_PB,
+};
+
+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 snd_soc_dai *codec_dai;
+       int ret = 0;
+
+       codec_dai = snd_soc_card_get_codec_dai(card, KBL_DIALOG_CODEC_DAI);
+       if (!codec_dai) {
+               dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
+               return -EIO;
+       }
+
+       /* Configure sysclk for codec */
+       ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret) {
+               dev_err(card->dev, "can't set codec sysclk configuration\n");
+               return ret;
+       }
+
+       if (SND_SOC_DAPM_EVENT_OFF(event)) {
+               ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                    DA7219_SYSCLK_MCLK, 0, 0);
+               if (ret)
+                       dev_err(card->dev, "failed to stop PLL: %d\n", ret);
+       } else if (SND_SOC_DAPM_EVENT_ON(event)) {
+               ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM,
+                                    0, DA7219_PLL_FREQ_OUT_98304);
+               if (ret)
+                       dev_err(card->dev, "failed to start PLL: %d\n", ret);
+       }
+
+       return ret;
+}
+
+static const struct snd_kcontrol_new kabylake_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+       SOC_DAPM_PIN_SWITCH("Headset Mic"),
+       SOC_DAPM_PIN_SWITCH("Spk"),
+};
+
+static const struct snd_soc_dapm_widget kabylake_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+       SND_SOC_DAPM_SPK("Spk", NULL),
+       SND_SOC_DAPM_MIC("SoC DMIC", NULL),
+       SND_SOC_DAPM_SPK("DP", NULL),
+       SND_SOC_DAPM_SPK("HDMI", 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[] = {
+       { "Headphone Jack", NULL, "HPL" },
+       { "Headphone Jack", NULL, "HPR" },
+
+       /* speaker */
+       { "Spk", NULL, "Speaker" },
+
+       /* other jacks */
+       { "MIC", NULL, "Headset Mic" },
+       { "DMic", NULL, "SoC DMIC" },
+
+       { "HDMI", NULL, "hif5 Output" },
+       { "DP", NULL, "hif6 Output" },
+
+       /* CODEC BE connections */
+       { "HiFi Playback", NULL, "ssp0 Tx" },
+       { "ssp0 Tx", NULL, "codec0_out" },
+
+       { "Playback", NULL, "ssp1 Tx" },
+       { "ssp1 Tx", NULL, "codec1_out" },
+
+       { "codec0_in", NULL, "ssp1 Rx" },
+       { "ssp1 Rx", NULL, "Capture" },
+
+       /* DMIC */
+       { "dmic01_hifi", NULL, "DMIC01 Rx" },
+       { "DMIC01 Rx", NULL, "DMIC AIF" },
+
+       { "hifi1", NULL, "iDisp1 Tx" },
+       { "iDisp1 Tx", NULL, "iDisp1_out" },
+       { "hifi2", NULL, "iDisp2 Tx" },
+       { "iDisp2 Tx", NULL, "iDisp2_out" },
+       { "hifi3", NULL, "iDisp3 Tx"},
+       { "iDisp3 Tx", NULL, "iDisp3_out"},
+
+       { "Headphone Jack", NULL, "Platform Clock" },
+       { "Headset Mic", NULL, "Platform Clock" },
+};
+
+static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
+                       struct snd_pcm_hw_params *params)
+{
+       struct snd_interval *rate = hw_param_interval(params,
+                       SNDRV_PCM_HW_PARAM_RATE);
+       struct snd_interval *channels = hw_param_interval(params,
+                       SNDRV_PCM_HW_PARAM_CHANNELS);
+       struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+       /* The ADSP will convert the FE rate to 48k, stereo */
+       rate->min = rate->max = 48000;
+       channels->min = channels->max = DUAL_CHANNEL;
+
+       /* set SSP to 24 bit */
+       snd_mask_none(fmt);
+       snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
+
+       return 0;
+}
+
+static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_component *component = rtd->codec_dai->component;
+       struct snd_soc_jack *jack;
+       int ret;
+
+       /*
+        * Headset buttons map to the google Reference headset.
+        * These can be configured by userspace.
+        */
+       ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack",
+                       SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+                       SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
+                       &ctx->kabylake_headset, NULL, 0);
+       if (ret) {
+               dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+               return ret;
+       }
+
+       jack = &ctx->kabylake_headset;
+
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
+       snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+       da7219_aad_jack_det(component, &ctx->kabylake_headset);
+
+       ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
+       if (ret)
+               dev_err(rtd->dev, "SoC DMIC - Ignore suspend failed %d\n", ret);
+
+       return ret;
+}
+
+static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
+{
+       struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_dai *dai = rtd->codec_dai;
+       struct kbl_hdmi_pcm *pcm;
+
+       pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
+       if (!pcm)
+               return -ENOMEM;
+
+       pcm->device = device;
+       pcm->codec_dai = dai;
+
+       list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+       return 0;
+}
+
+static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
+{
+       return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB);
+}
+
+static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
+{
+       return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB);
+}
+
+static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
+{
+       return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB);
+}
+
+static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_dapm_context *dapm;
+       struct snd_soc_component *component = rtd->cpu_dai->component;
+
+       dapm = snd_soc_component_get_dapm(component);
+       snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
+
+       return 0;
+}
+
+static const unsigned int rates[] = {
+       48000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_rates = {
+       .count = ARRAY_SIZE(rates),
+       .list  = rates,
+       .mask = 0,
+};
+
+static const unsigned int channels[] = {
+       DUAL_CHANNEL,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+       .count = ARRAY_SIZE(channels),
+       .list = channels,
+       .mask = 0,
+};
+
+static unsigned int channels_quad[] = {
+       QUAD_CHANNEL,
+};
+
+static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
+       .count = ARRAY_SIZE(channels_quad),
+       .list = channels_quad,
+       .mask = 0,
+};
+
+static int kbl_fe_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       /*
+        * On this platform for PCM device we support,
+        * 48Khz
+        * stereo
+        * 16 bit audio
+        */
+
+       runtime->hw.channels_max = DUAL_CHANNEL;
+       snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                          &constraints_channels);
+
+       runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
+       snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
+
+       snd_pcm_hw_constraint_list(runtime, 0,
+                               SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
+
+       return 0;
+}
+
+static const struct snd_soc_ops kabylake_da7219_fe_ops = {
+       .startup = kbl_fe_startup,
+};
+
+static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
+               struct snd_pcm_hw_params *params)
+{
+       struct snd_interval *channels = hw_param_interval(params,
+                               SNDRV_PCM_HW_PARAM_CHANNELS);
+
+       /*
+        * set BE channel constraint as user FE channels
+        */
+
+       if (params_channels(params) == 2)
+               channels->min = channels->max = 2;
+       else
+               channels->min = channels->max = 4;
+
+       return 0;
+}
+
+static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
+       snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                       &constraints_channels_quad);
+
+       return snd_pcm_hw_constraint_list(substream->runtime, 0,
+                       SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
+}
+
+static struct snd_soc_ops kabylake_dmic_ops = {
+       .startup = kabylake_dmic_startup,
+};
+
+static const unsigned int rates_16000[] = {
+       16000,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_16000 = {
+       .count = ARRAY_SIZE(rates_16000),
+       .list  = rates_16000,
+};
+
+static const unsigned int ch_mono[] = {
+       1,
+};
+
+/* kabylake digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link kabylake_dais[] = {
+       /* Front End DAI links */
+       [KBL_DPCM_AUDIO_PB] = {
+               .name = "Kbl Audio Port",
+               .stream_name = "Audio",
+               .cpu_dai_name = "System Pin",
+               .platform_name = "0000:00:1f.3",
+               .dynamic = 1,
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .nonatomic = 1,
+               .init = kabylake_da7219_fe_init,
+               .trigger = {
+                       SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+               .dpcm_playback = 1,
+               .ops = &kabylake_da7219_fe_ops,
+       },
+       [KBL_DPCM_AUDIO_CP] = {
+               .name = "Kbl Audio Capture Port",
+               .stream_name = "Audio Record",
+               .cpu_dai_name = "System Pin",
+               .platform_name = "0000:00:1f.3",
+               .dynamic = 1,
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .nonatomic = 1,
+               .trigger = {
+                       SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+               .dpcm_capture = 1,
+       },
+       [KBL_DPCM_AUDIO_DMIC_CP] = {
+               .name = "Kbl Audio DMIC cap",
+               .stream_name = "dmiccap",
+               .cpu_dai_name = "DMIC Pin",
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .platform_name = "0000:00:1f.3",
+               .init = NULL,
+               .dpcm_capture = 1,
+               .nonatomic = 1,
+               .dynamic = 1,
+               .ops = &kabylake_dmic_ops,
+       },
+       [KBL_DPCM_AUDIO_HDMI1_PB] = {
+               .name = "Kbl HDMI Port1",
+               .stream_name = "Hdmi1",
+               .cpu_dai_name = "HDMI1 Pin",
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .platform_name = "0000:00:1f.3",
+               .dpcm_playback = 1,
+               .init = NULL,
+               .trigger = {
+                       SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+               .nonatomic = 1,
+               .dynamic = 1,
+       },
+       [KBL_DPCM_AUDIO_HDMI2_PB] = {
+               .name = "Kbl HDMI Port2",
+               .stream_name = "Hdmi2",
+               .cpu_dai_name = "HDMI2 Pin",
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .platform_name = "0000:00:1f.3",
+               .dpcm_playback = 1,
+               .init = NULL,
+               .trigger = {
+                       SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+               .nonatomic = 1,
+               .dynamic = 1,
+       },
+       [KBL_DPCM_AUDIO_HDMI3_PB] = {
+               .name = "Kbl HDMI Port3",
+               .stream_name = "Hdmi3",
+               .cpu_dai_name = "HDMI3 Pin",
+               .codec_name = "snd-soc-dummy",
+               .codec_dai_name = "snd-soc-dummy-dai",
+               .platform_name = "0000:00:1f.3",
+               .trigger = {
+                       SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
+               .dpcm_playback = 1,
+               .init = NULL,
+               .nonatomic = 1,
+               .dynamic = 1,
+       },
+
+       /* Back End DAI links */
+       {
+               /* SSP0 - Codec */
+               .name = "SSP0-Codec",
+               .id = 0,
+               .cpu_dai_name = "SSP0 Pin",
+               .platform_name = "0000:00:1f.3",
+               .no_pcm = 1,
+               .codec_name = MAXIM_DEV0_NAME,
+               .codec_dai_name = KBL_MAXIM_CODEC_DAI,
+               .dai_fmt = SND_SOC_DAIFMT_I2S |
+                       SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+               .ignore_pmdown_time = 1,
+               .be_hw_params_fixup = kabylake_ssp_fixup,
+               .dpcm_playback = 1,
+       },
+       {
+               /* SSP1 - Codec */
+               .name = "SSP1-Codec",
+               .id = 1,
+               .cpu_dai_name = "SSP1 Pin",
+               .platform_name = "0000:00:1f.3",
+               .no_pcm = 1,
+               .codec_name = "i2c-DLGS7219:00",
+               .codec_dai_name = KBL_DIALOG_CODEC_DAI,
+               .init = kabylake_da7219_codec_init,
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+               .ignore_pmdown_time = 1,
+               .be_hw_params_fixup = kabylake_ssp_fixup,
+               .dpcm_playback = 1,
+               .dpcm_capture = 1,
+       },
+       {
+               .name = "dmic01",
+               .id = 2,
+               .cpu_dai_name = "DMIC01 Pin",
+               .codec_name = "dmic-codec",
+               .codec_dai_name = "dmic-hifi",
+               .platform_name = "0000:00:1f.3",
+               .be_hw_params_fixup = kabylake_dmic_fixup,
+               .ignore_suspend = 1,
+               .dpcm_capture = 1,
+               .no_pcm = 1,
+       },
+       {
+               .name = "iDisp1",
+               .id = 3,
+               .cpu_dai_name = "iDisp1 Pin",
+               .codec_name = "ehdaudio0D2",
+               .codec_dai_name = "intel-hdmi-hifi1",
+               .platform_name = "0000:00:1f.3",
+               .dpcm_playback = 1,
+               .init = kabylake_hdmi1_init,
+               .no_pcm = 1,
+       },
+       {
+               .name = "iDisp2",
+               .id = 4,
+               .cpu_dai_name = "iDisp2 Pin",
+               .codec_name = "ehdaudio0D2",
+               .codec_dai_name = "intel-hdmi-hifi2",
+               .platform_name = "0000:00:1f.3",
+               .init = kabylake_hdmi2_init,
+               .dpcm_playback = 1,
+               .no_pcm = 1,
+       },
+       {
+               .name = "iDisp3",
+               .id = 5,
+               .cpu_dai_name = "iDisp3 Pin",
+               .codec_name = "ehdaudio0D2",
+               .codec_dai_name = "intel-hdmi-hifi3",
+               .platform_name = "0000:00:1f.3",
+               .init = kabylake_hdmi3_init,
+               .dpcm_playback = 1,
+               .no_pcm = 1,
+       },
+};
+
+#define NAME_SIZE      32
+static int kabylake_card_late_probe(struct snd_soc_card *card)
+{
+       struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
+       struct kbl_hdmi_pcm *pcm;
+       struct snd_soc_component *component = NULL;
+       int err, i = 0;
+       char jack_name[NAME_SIZE];
+
+       list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
+               component = pcm->codec_dai->component;
+               snprintf(jack_name, sizeof(jack_name),
+                       "HDMI/DP, pcm=%d Jack", pcm->device);
+               err = snd_soc_card_jack_new(card, jack_name,
+                                       SND_JACK_AVOUT, &skylake_hdmi[i],
+                                       NULL, 0);
+
+               if (err)
+                       return err;
+
+               err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
+                               &skylake_hdmi[i]);
+               if (err < 0)
+                       return err;
+
+               i++;
+
+       }
+
+       if (!component)
+               return -EINVAL;
+
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
+}
+
+/* kabylake audio machine driver for SPT + DA7219 */
+static struct snd_soc_card kabylake_audio_card_da7219_m98357a = {
+       .name = "kblda7219max",
+       .owner = THIS_MODULE,
+       .dai_link = kabylake_dais,
+       .num_links = ARRAY_SIZE(kabylake_dais),
+       .controls = kabylake_controls,
+       .num_controls = ARRAY_SIZE(kabylake_controls),
+       .dapm_widgets = kabylake_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(kabylake_widgets),
+       .dapm_routes = kabylake_map,
+       .num_dapm_routes = ARRAY_SIZE(kabylake_map),
+       .fully_routed = true,
+       .late_probe = kabylake_card_late_probe,
+};
+
+static int kabylake_audio_probe(struct platform_device *pdev)
+{
+       struct kbl_codec_private *ctx;
+
+       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
+       if (!ctx)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
+
+       kabylake_audio_card =
+               (struct snd_soc_card *)pdev->id_entry->driver_data;
+
+       kabylake_audio_card->dev = &pdev->dev;
+       snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
+       return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
+}
+
+static const struct platform_device_id kbl_board_ids[] = {
+       {
+               .name = "kbl_da7219_max98357a",
+               .driver_data =
+                       (kernel_ulong_t)&kabylake_audio_card_da7219_m98357a,
+       },
+       { }
+};
+
+static struct platform_driver kabylake_audio = {
+       .probe = kabylake_audio_probe,
+       .driver = {
+               .name = "kbl_da7219_max98357a",
+               .pm = &snd_soc_pm_ops,
+       },
+       .id_table = kbl_board_ids,
+};
+
+module_platform_driver(kabylake_audio)
+
+/* Module information */
+MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
+MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:kbl_da7219_max98357a");
index f5df6bca3156e8d3a42f21dcd36cf2e19c3682fc..0e6b7e79441ceee7f5392e6bab3058a79053d216 100644 (file)
@@ -204,13 +204,18 @@ static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = {
        SND_SOC_DAPM_MIC("Headset Mic", NULL),
        SND_SOC_DAPM_SPK("DP", NULL),
        SND_SOC_DAPM_SPK("HDMI", 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_5663_map[] = {
+       { "Headphone Jack", NULL, "Platform Clock" },
        { "Headphone Jack", NULL, "HPOL" },
        { "Headphone Jack", NULL, "HPOR" },
 
        /* other jacks */
+       { "Headset Mic", NULL, "Platform Clock" },
        { "IN1P", NULL, "Headset Mic" },
        { "IN1N", NULL, "Headset Mic" },
 
@@ -272,7 +277,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
        struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        struct snd_soc_jack *jack;
 
        /*
@@ -294,7 +299,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
        snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
        snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 
-       rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
+       rt5663_set_jack_detect(component, &ctx->kabylake_headset);
        return ret;
 }
 
@@ -448,7 +453,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
        int ret;
 
        /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
-       rt5663_sel_asrc_clk_src(codec_dai->codec,
+       rt5663_sel_asrc_clk_src(codec_dai->component,
                        RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
                        RT5663_CLK_SEL_I2S1_ASRC);
 
@@ -898,12 +903,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
        struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
        struct kbl_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -921,10 +926,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* kabylake audio machine driver for SPT + RT5663 */
index 90ea98f01c4cc03a91a96d6182773315191412da..69c3d8446f06244e8f7ed721d18b655f14763227 100644 (file)
@@ -178,7 +178,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
        struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        struct snd_soc_jack *jack;
 
        /*
@@ -200,7 +200,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
        snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
        snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 
-       rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
+       rt5663_set_jack_detect(component, &ctx->kabylake_headset);
 
        ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC");
        if (ret)
@@ -333,7 +333,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
        int ret;
 
        /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
-       rt5663_sel_asrc_clk_src(codec_dai->codec,
+       rt5663_sel_asrc_clk_src(codec_dai->component,
                        RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
                        RT5663_CLK_SEL_I2S1_ASRC);
 
@@ -599,12 +599,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
        struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
        struct kbl_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP,pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -620,10 +620,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /*
index 1b5a689dc99bb4810194a0bd068fea8f75c99426..9a7a0646bffe3545b9954002832e82b18f163173 100644 (file)
@@ -165,7 +165,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        /*
         * Headset buttons map to the google Reference headset.
@@ -180,7 +180,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
                return ret;
        }
 
-       nau8825_enable_jack_detect(codec, &skylake_headset);
+       nau8825_enable_jack_detect(component, &skylake_headset);
 
        snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -592,12 +592,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 {
        struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
        struct skl_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -616,10 +616,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* skylake audio machine driver for SPT + NAU88L25 */
index 7bea4bc774815a83e7d4f9490398fda08d4a48d8..212ac8971e55b41fc7377da88e771cfaa6b42f84 100644 (file)
@@ -195,7 +195,7 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd)
 static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
        int ret;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        /*
         * 4 buttons here map to the google Reference headset
@@ -210,7 +210,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
                return ret;
        }
 
-       nau8825_enable_jack_detect(codec, &skylake_headset);
+       nau8825_enable_jack_detect(component, &skylake_headset);
 
        snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -643,12 +643,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 {
        struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
        struct skl_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -667,10 +667,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* skylake audio machine driver for SPT + NAU88L25 */
index 2bc4cfca594e1b295a283f284bd26f6ad0fc6c5c..737d5615b0efeb180efbdc1e749ccec222cdca99 100644 (file)
@@ -130,7 +130,7 @@ static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
 
 static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        int ret;
 
        ret = snd_soc_card_jack_new(rtd->card, "Headset",
@@ -141,7 +141,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
        if (ret)
                return ret;
 
-       rt286_mic_detect(codec, &skylake_headset);
+       rt286_mic_detect(component, &skylake_headset);
 
        snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
 
@@ -478,12 +478,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
 {
        struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
        struct skl_hdmi_pcm *pcm;
-       struct snd_soc_codec *codec = NULL;
+       struct snd_soc_component *component = NULL;
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
-               codec = pcm->codec_dai->codec;
+               component = pcm->codec_dai->component;
                snprintf(jack_name, sizeof(jack_name),
                        "HDMI/DP, pcm=%d Jack", pcm->device);
                err = snd_soc_card_jack_new(card, jack_name,
@@ -501,10 +501,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!codec)
+       if (!component)
                return -EINVAL;
 
-       return hdac_hdmi_jack_port_init(codec, &card->dapm);
+       return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
 /* skylake audio machine driver for SPT + RT286S */
index b50a0d53846b9ccea566ec87e9be99d608828bd0..ad1eb2d644beab3333aa58b5415136ced1509544 100644 (file)
@@ -117,6 +117,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_cherrytrail_machines[] = {
                .sof_tplg_filename = "intel/reef-cht-max98090.tplg",
                .asoc_plat_name = "sst-mfld-platform",
        },
+       {
+               .id = "10508824",
+               .drv_name = "cht-bsw-nau8824",
+               .fw_filename = "intel/fw_sst_22a8.bin",
+               .board = "cht-bsw",
+               .sof_fw_filename = "intel/reef-cht.ri",
+               .sof_tplg_filename = "intel/reef-cht-nau8824.tplg",
+               .asoc_plat_name = "sst-mfld-platform",
+       },
        {
                .id = "DLGS7212",
                .drv_name = "bytcht_da7213",
index 06d71aefa1fe795e6354defa38b21789f2a40e39..fbc14df139e47138dea5d37f6206dd41533f78b9 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/platform_device.h>
 #include <sound/asound.h>
 
+#define DRV_NAME "haswell-dai"
+
 #define SST_HSW_NO_CHANNELS            4
 #define SST_HSW_MAX_DX_REGIONS         14
 #define SST_HSW_DX_CONTEXT_SIZE        (640 * 1024)
index c044400540ec837689f0c6e19634c77eb3e2135c..fe2c826e710c73bba7053900514504d3abd71d1f 100644 (file)
@@ -181,11 +181,11 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value)
 static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(platform);
+               snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw *hsw = pdata->hsw;
        u32 volume;
@@ -230,11 +230,11 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
 static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
        struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(platform);
+               snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw *hsw = pdata->hsw;
        u32 volume;
@@ -273,8 +273,8 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
 static int hsw_volume_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-       struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
        u32 volume;
 
@@ -302,8 +302,8 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol,
 static int hsw_volume_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-       struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
        unsigned int volume = 0;
 
@@ -322,8 +322,8 @@ static int hsw_volume_get(struct snd_kcontrol *kcontrol,
 static int hsw_waves_switch_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-       struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
        enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
 
@@ -336,8 +336,8 @@ static int hsw_waves_switch_get(struct snd_kcontrol *kcontrol,
 static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-       struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
        int ret = 0;
        enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
@@ -370,8 +370,8 @@ static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
 static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-       struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
 
        /* return a matching line from param buffer */
@@ -381,8 +381,8 @@ static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
 static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
-       struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
        int ret;
        enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
@@ -472,8 +472,8 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw *hsw = pdata->hsw;
        struct sst_module *module_data;
@@ -674,8 +674,8 @@ static int hsw_pcm_hw_free(struct snd_pcm_substream *substream)
 static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw_stream *sst_stream;
        struct sst_hsw *hsw = pdata->hsw;
@@ -718,8 +718,8 @@ static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
        struct snd_pcm_substream *substream = pcm_data->substream;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct sst_hsw *hsw = pdata->hsw;
        u32 pos;
        snd_pcm_uframes_t position = bytes_to_frames(runtime,
@@ -783,8 +783,8 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw *hsw = pdata->hsw;
        snd_pcm_uframes_t offset;
@@ -807,8 +807,8 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
 static int hsw_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw *hsw = pdata->hsw;
        int dai;
@@ -840,8 +840,8 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
 static int hsw_pcm_close(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct hsw_priv_data *pdata =
-               snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(component);
        struct hsw_pcm_data *pcm_data;
        struct sst_hsw *hsw = pdata->hsw;
        int ret, dai;
@@ -942,9 +942,9 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
 static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_pcm *pcm = rtd->pcm;
-       struct snd_soc_platform *platform = rtd->platform;
-       struct sst_pdata *pdata = dev_get_platdata(platform->dev);
-       struct hsw_priv_data *priv_data = dev_get_drvdata(platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct sst_pdata *pdata = dev_get_platdata(component->dev);
+       struct hsw_priv_data *priv_data = dev_get_drvdata(component->dev);
        struct device *dev = pdata->dma_dev;
        int ret = 0;
 
@@ -1052,23 +1052,23 @@ static const struct snd_soc_dapm_route graph[] = {
        {"Analog Capture", NULL, "SSP0 CODEC IN"},
 };
 
-static int hsw_pcm_probe(struct snd_soc_platform *platform)
+static int hsw_pcm_probe(struct snd_soc_component *component)
 {
-       struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform);
-       struct sst_pdata *pdata = dev_get_platdata(platform->dev);
+       struct hsw_priv_data *priv_data = snd_soc_component_get_drvdata(component);
+       struct sst_pdata *pdata = dev_get_platdata(component->dev);
        struct device *dma_dev, *dev;
        int i, ret = 0;
 
        if (!pdata)
                return -ENODEV;
 
-       dev = platform->dev;
+       dev = component->dev;
        dma_dev = pdata->dma_dev;
 
        priv_data->hsw = pdata->dsp;
-       priv_data->dev = platform->dev;
+       priv_data->dev = dev;
        priv_data->pm_state = HSW_PM_STATE_D0;
-       priv_data->soc_card = platform->component.card;
+       priv_data->soc_card = component->card;
 
        /* allocate DSP buffer page tables */
        for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
@@ -1098,11 +1098,10 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
                goto err;
 
        /* enable runtime PM with auto suspend */
-       pm_runtime_set_autosuspend_delay(platform->dev,
-               SST_RUNTIME_SUSPEND_DELAY);
-       pm_runtime_use_autosuspend(platform->dev);
-       pm_runtime_enable(platform->dev);
-       pm_runtime_idle(platform->dev);
+       pm_runtime_set_autosuspend_delay(dev, SST_RUNTIME_SUSPEND_DELAY);
+       pm_runtime_use_autosuspend(dev);
+       pm_runtime_enable(dev);
+       pm_runtime_idle(dev);
 
        return 0;
 
@@ -1116,13 +1115,13 @@ err:
        return ret;
 }
 
-static int hsw_pcm_remove(struct snd_soc_platform *platform)
+static void hsw_pcm_remove(struct snd_soc_component *component)
 {
        struct hsw_priv_data *priv_data =
-               snd_soc_platform_get_drvdata(platform);
+               snd_soc_component_get_drvdata(component);
        int i;
 
-       pm_runtime_disable(platform->dev);
+       pm_runtime_disable(component->dev);
        hsw_pcm_free_modules(priv_data);
 
        for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
@@ -1131,24 +1130,19 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform)
                if (hsw_dais[i].capture.channels_min)
                        snd_dma_free_pages(&priv_data->dmab[i][1]);
        }
-
-       return 0;
 }
 
-static const struct snd_soc_platform_driver hsw_soc_platform = {
+static const struct snd_soc_component_driver hsw_dai_component = {
+       .name           = DRV_NAME,
        .probe          = hsw_pcm_probe,
        .remove         = hsw_pcm_remove,
        .ops            = &hsw_pcm_ops,
        .pcm_new        = hsw_pcm_new,
-};
-
-static const struct snd_soc_component_driver hsw_dai_component = {
-       .name = "haswell-dai",
-       .controls = hsw_volume_controls,
-       .num_controls = ARRAY_SIZE(hsw_volume_controls),
-       .dapm_widgets = widgets,
+       .controls       = hsw_volume_controls,
+       .num_controls   = ARRAY_SIZE(hsw_volume_controls),
+       .dapm_widgets   = widgets,
        .num_dapm_widgets = ARRAY_SIZE(widgets),
-       .dapm_routes = graph,
+       .dapm_routes    = graph,
        .num_dapm_routes = ARRAY_SIZE(graph),
 };
 
@@ -1172,19 +1166,13 @@ static int hsw_pcm_dev_probe(struct platform_device *pdev)
        priv_data->hsw = sst_pdata->dsp;
        platform_set_drvdata(pdev, priv_data);
 
-       ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform);
-       if (ret < 0)
-               goto err_plat;
-
-       ret = snd_soc_register_component(&pdev->dev, &hsw_dai_component,
+       ret = devm_snd_soc_register_component(&pdev->dev, &hsw_dai_component,
                hsw_dais, ARRAY_SIZE(hsw_dais));
        if (ret < 0)
-               goto err_comp;
+               goto err_plat;
 
        return 0;
 
-err_comp:
-       snd_soc_unregister_platform(&pdev->dev);
 err_plat:
        sst_hsw_dsp_free(&pdev->dev, sst_pdata);
        return 0;
@@ -1194,8 +1182,6 @@ static int hsw_pcm_dev_remove(struct platform_device *pdev)
 {
        struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
 
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_component(&pdev->dev);
        sst_hsw_dsp_free(&pdev->dev, sst_pdata);
 
        return 0;
index dc20d91f62e6c45302b0bc5a8ead3d36b9c6ad1a..a016455a6ddb5daf7a07966a126bbd2ddaa6f223 100644 (file)
@@ -231,7 +231,7 @@ struct skl_debug *skl_debugfs_init(struct skl *skl)
 
        /* create the debugfs dir with platform component's debugfs as parent */
        d->fs = debugfs_create_dir("dsp",
-                                  skl->platform->component.debugfs_root);
+                                  skl->component->debugfs_root);
        if (IS_ERR(d->fs) || !d->fs) {
                dev_err(&skl->pci->dev, "debugfs root creation failed\n");
                return NULL;
index 60d76adade432c09db6133fd2a8796777f371318..57d4a58522a695c03928fae86374d1758b1b1544 100644 (file)
@@ -417,11 +417,16 @@ int skl_resume_dsp(struct skl *skl)
        if (skl->skl_sst->is_first_boot == true)
                return 0;
 
-       /* disable dynamic clock gating during fw and lib download */
+       /*
+        * Disable dynamic clock and power gating during firmware
+        * and library download
+        */
        ctx->enable_miscbdcge(ctx->dev, false);
+       ctx->clock_power_gating(ctx->dev, false);
 
        ret = skl_dsp_wake(ctx->dsp);
        ctx->enable_miscbdcge(ctx->dev, true);
+       ctx->clock_power_gating(ctx->dev, true);
        if (ret < 0)
                return ret;
 
@@ -1210,7 +1215,7 @@ out:
 static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
        enum skl_ipc_pipeline_state state)
 {
-       dev_dbg(ctx->dev, "%s: pipe_satate = %d\n", __func__, state);
+       dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state);
 
        return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state);
 }
index e4682853382614d83d73bf27a8e5a7ee3810bbca..15cb8ac3e374b856b542837f5dbe6aef2890d3b7 100644 (file)
@@ -958,6 +958,17 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
                .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
        },
 },
+{
+       .name = "DMIC16k Pin",
+       .ops = &skl_dmic_dai_ops,
+       .capture = {
+               .stream_name = "DMIC16k Rx",
+               .channels_min = HDA_MONO,
+               .channels_max = HDA_QUAD,
+               .rates = SNDRV_PCM_RATE_16000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+},
 {
        .name = "HD-Codec Pin",
        .ops = &skl_link_dai_ops,
@@ -1307,29 +1318,31 @@ static int skl_populate_modules(struct skl *skl)
                                        "query module info failed\n");
                                return ret;
                        }
+
+                       skl_tplg_add_moduleid_in_bind_params(skl, w);
                }
        }
 
        return ret;
 }
 
-static int skl_platform_soc_probe(struct snd_soc_platform *platform)
+static int skl_platform_soc_probe(struct snd_soc_component *component)
 {
-       struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
+       struct hdac_ext_bus *ebus = dev_get_drvdata(component->dev);
        struct skl *skl = ebus_to_skl(ebus);
        const struct skl_dsp_ops *ops;
        int ret;
 
-       pm_runtime_get_sync(platform->dev);
+       pm_runtime_get_sync(component->dev);
        if ((ebus_to_hbus(ebus))->ppcap) {
-               skl->platform = platform;
+               skl->component = component;
 
                /* init debugfs */
                skl->debugfs = skl_debugfs_init(skl);
 
-               ret = skl_tplg_init(platform, ebus);
+               ret = skl_tplg_init(component, ebus);
                if (ret < 0) {
-                       dev_err(platform->dev, "Failed to init topology!\n");
+                       dev_err(component->dev, "Failed to init topology!\n");
                        return ret;
                }
 
@@ -1339,17 +1352,22 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
                        return -EIO;
 
                if (skl->skl_sst->is_first_boot == false) {
-                       dev_err(platform->dev, "DSP reports first boot done!!!\n");
+                       dev_err(component->dev, "DSP reports first boot done!!!\n");
                        return -EIO;
                }
 
-               /* disable dynamic clock gating during fw and lib download */
-               skl->skl_sst->enable_miscbdcge(platform->dev, false);
+               /*
+                * Disable dynamic clock and power gating during firmware
+                * and library download
+                */
+               skl->skl_sst->enable_miscbdcge(component->dev, false);
+               skl->skl_sst->clock_power_gating(component->dev, false);
 
-               ret = ops->init_fw(platform->dev, skl->skl_sst);
-               skl->skl_sst->enable_miscbdcge(platform->dev, true);
+               ret = ops->init_fw(component->dev, skl->skl_sst);
+               skl->skl_sst->enable_miscbdcge(component->dev, true);
+               skl->skl_sst->clock_power_gating(component->dev, true);
                if (ret < 0) {
-                       dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
+                       dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
                        return ret;
                }
                skl_populate_modules(skl);
@@ -1362,22 +1380,20 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
                                        skl->cfg.astate_cfg);
                }
        }
-       pm_runtime_mark_last_busy(platform->dev);
-       pm_runtime_put_autosuspend(platform->dev);
+       pm_runtime_mark_last_busy(component->dev);
+       pm_runtime_put_autosuspend(component->dev);
 
        return 0;
 }
-static const struct snd_soc_platform_driver skl_platform_drv  = {
+
+static const struct snd_soc_component_driver skl_component  = {
+       .name           = "pcm",
        .probe          = skl_platform_soc_probe,
        .ops            = &skl_platform_ops,
        .pcm_new        = skl_pcm_new,
        .pcm_free       = skl_pcm_free,
 };
 
-static const struct snd_soc_component_driver skl_component = {
-       .name           = "pcm",
-};
-
 int skl_platform_register(struct device *dev)
 {
        int ret;
@@ -1389,12 +1405,6 @@ int skl_platform_register(struct device *dev)
        INIT_LIST_HEAD(&skl->ppl_list);
        INIT_LIST_HEAD(&skl->bind_list);
 
-       ret = snd_soc_register_platform(dev, &skl_platform_drv);
-       if (ret) {
-               dev_err(dev, "soc platform registration failed %d\n", ret);
-               return ret;
-       }
-
        skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
                            GFP_KERNEL);
        if (!skl->dais) {
@@ -1416,18 +1426,12 @@ int skl_platform_register(struct device *dev)
                num_dais += ARRAY_SIZE(skl_fe_dai);
        }
 
-       ret = snd_soc_register_component(dev, &skl_component,
+       ret = devm_snd_soc_register_component(dev, &skl_component,
                                         skl->dais, num_dais);
-       if (ret) {
+       if (ret)
                dev_err(dev, "soc component registration failed %d\n", ret);
-               goto err;
-       }
-
-       return 0;
 err:
-       snd_soc_unregister_platform(dev);
        return ret;
-
 }
 
 int skl_platform_unregister(struct device *dev)
@@ -1443,8 +1447,6 @@ int skl_platform_unregister(struct device *dev)
                }
        }
 
-       snd_soc_unregister_component(dev);
-       snd_soc_unregister_platform(dev);
        kfree(skl->dais);
 
        return 0;
index 7fbddf5e3b00576aeaec186b6883bb8c1e04a344..cda1b5fa7436e1fe875eb777d2aff4528cc7a973 100644 (file)
@@ -247,8 +247,8 @@ static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
 }
 
 /* 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)
+static long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long *parent_rate)
 {
        return rate;
 }
index 55f2d2ce09df4017fc0c27a8229e5696dc4834d4..f74f040dfd83d0231ece5f9a5f59b2043b31329c 100644 (file)
@@ -118,6 +118,9 @@ struct skl_sst {
        struct skl_d0i3_data d0i3;
 
        const struct skl_dsp_ops *dsp_ops;
+
+       /* Callback to update dynamic clock and power gating registers */
+       void (*clock_power_gating)(struct device *dev, bool enable);
 };
 
 struct skl_ipc_init_instance_msg {
index 73af6e19ebbde8d6eb997a96faaefb56a1f60b93..3b1dca419883b99bac94c6848f56d9ce138aa207 100644 (file)
@@ -94,8 +94,12 @@ void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps)
  * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
  * ignore. This helpers checks if the SKL driver handles this widget type
  */
-static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
+static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
+                                 struct device *dev)
 {
+       if (w->dapm->dev != dev)
+               return false;
+
        switch (w->id) {
        case snd_soc_dapm_dai_link:
        case snd_soc_dapm_dai_in:
@@ -826,7 +830,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
        if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
                struct skl_kpb_params *kpb_params =
                                (struct skl_kpb_params *)params;
-               struct skl_mod_inst_map *inst = kpb_params->map;
+               struct skl_mod_inst_map *inst = kpb_params->u.map;
 
                for (i = 0; i < kpb_params->num_modules; i++) {
                        pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
@@ -911,6 +915,87 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static int skl_get_module_id(struct skl_sst *ctx, uuid_le *uuid)
+{
+       struct uuid_module *module;
+
+       list_for_each_entry(module, &ctx->uuid_list, list) {
+               if (uuid_le_cmp(*uuid, module->uuid) == 0)
+                       return module->id;
+       }
+
+       return -EINVAL;
+}
+
+static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
+                                       const struct snd_kcontrol_new *k)
+{
+       struct soc_bytes_ext *sb = (void *) k->private_value;
+       struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
+       struct skl_kpb_params *uuid_params, *params;
+       struct hdac_bus *bus = ebus_to_hbus(skl_to_ebus(skl));
+       int i, size, module_id;
+
+       if (bc->set_params == SKL_PARAM_BIND && bc->max) {
+               uuid_params = (struct skl_kpb_params *)bc->params;
+               size = uuid_params->num_modules *
+                       sizeof(struct skl_mod_inst_map) +
+                       sizeof(uuid_params->num_modules);
+
+               params = devm_kzalloc(bus->dev, size, GFP_KERNEL);
+               if (!params)
+                       return -ENOMEM;
+
+               params->num_modules = uuid_params->num_modules;
+
+               for (i = 0; i < uuid_params->num_modules; i++) {
+                       module_id = skl_get_module_id(skl->skl_sst,
+                               &uuid_params->u.map_uuid[i].mod_uuid);
+                       if (module_id < 0) {
+                               devm_kfree(bus->dev, params);
+                               return -EINVAL;
+                       }
+
+                       params->u.map[i].mod_id = module_id;
+                       params->u.map[i].inst_id =
+                               uuid_params->u.map_uuid[i].inst_id;
+               }
+
+               devm_kfree(bus->dev, bc->params);
+               bc->params = (char *)params;
+               bc->max = size;
+       }
+
+       return 0;
+}
+
+/*
+ * Retrieve the module id from UUID mentioned in the
+ * post bind params
+ */
+void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+                               struct snd_soc_dapm_widget *w)
+{
+       struct skl_module_cfg *mconfig = w->priv;
+       int i;
+
+       /*
+        * Post bind params are used for only for KPB
+        * to set copier instances to drain the data
+        * in fast mode
+        */
+       if (mconfig->m_type != SKL_MODULE_TYPE_KPB)
+               return;
+
+       for (i = 0; i < w->num_kcontrols; i++)
+               if ((w->kcontrol_news[i].access &
+                       SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
+                       (skl_tplg_find_moduleid_from_uuid(skl,
+                       &w->kcontrol_news[i]) < 0))
+                       dev_err(skl->skl_sst->dev,
+                               "%s: invalid kpb post bind params\n",
+                               __func__);
+}
 
 static int skl_tplg_module_add_deferred_bind(struct skl *skl,
        struct skl_module_cfg *src, struct skl_module_cfg *dst)
@@ -969,7 +1054,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
 
                next_sink = p->sink;
 
-               if (!is_skl_dsp_widget_type(p->sink))
+               if (!is_skl_dsp_widget_type(p->sink, ctx->dev))
                        return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
 
                /*
@@ -978,7 +1063,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
                 * they are ones used for SKL so check that first
                 */
                if ((p->sink->priv != NULL) &&
-                                       is_skl_dsp_widget_type(p->sink)) {
+                               is_skl_dsp_widget_type(p->sink, ctx->dev)) {
 
                        sink = p->sink;
                        sink_mconfig = sink->priv;
@@ -1092,7 +1177,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
                 * ones used for SKL so check that first
                 */
                if ((p->source->priv != NULL) &&
-                                       is_skl_dsp_widget_type(p->source)) {
+                               is_skl_dsp_widget_type(p->source, ctx->dev)) {
                        return p->source;
                }
        }
@@ -1654,7 +1739,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
                w = dai->playback_widget;
                snd_soc_dapm_widget_for_each_sink_path(w, p) {
                        if (p->connect && p->sink->power &&
-                                       !is_skl_dsp_widget_type(p->sink))
+                               !is_skl_dsp_widget_type(p->sink, dai->dev))
                                continue;
 
                        if (p->sink->priv) {
@@ -1667,7 +1752,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
                w = dai->capture_widget;
                snd_soc_dapm_widget_for_each_source_path(w, p) {
                        if (p->connect && p->source->power &&
-                                       !is_skl_dsp_widget_type(p->source))
+                               !is_skl_dsp_widget_type(p->source, dai->dev))
                                continue;
 
                        if (p->source->priv) {
@@ -1819,7 +1904,7 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
        int ret = -EIO;
 
        snd_soc_dapm_widget_for_each_source_path(w, p) {
-               if (p->connect && is_skl_dsp_widget_type(p->source) &&
+               if (p->connect && is_skl_dsp_widget_type(p->source, dai->dev) &&
                                                p->source->priv) {
 
                        ret = skl_tplg_be_fill_pipe_params(dai,
@@ -1844,7 +1929,7 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
        int ret = -EIO;
 
        snd_soc_dapm_widget_for_each_sink_path(w, p) {
-               if (p->connect && is_skl_dsp_widget_type(p->sink) &&
+               if (p->connect && is_skl_dsp_widget_type(p->sink, dai->dev) &&
                                                p->sink->priv) {
 
                        ret = skl_tplg_be_fill_pipe_params(dai,
@@ -2710,15 +2795,15 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
        return 0;
 }
 
-static void skl_clear_pin_config(struct snd_soc_platform *platform,
+static void skl_clear_pin_config(struct snd_soc_component *component,
                                struct snd_soc_dapm_widget *w)
 {
        int i;
        struct skl_module_cfg *mconfig;
        struct skl_pipe *pipe;
 
-       if (!strncmp(w->dapm->component->name, platform->component.name,
-                                       strlen(platform->component.name))) {
+       if (!strncmp(w->dapm->component->name, component->name,
+                                       strlen(component->name))) {
                mconfig = w->priv;
                pipe = mconfig->pipe;
                for (i = 0; i < mconfig->module->max_input_pins; i++) {
@@ -2737,14 +2822,14 @@ static void skl_clear_pin_config(struct snd_soc_platform *platform,
 void skl_cleanup_resources(struct skl *skl)
 {
        struct skl_sst *ctx = skl->skl_sst;
-       struct snd_soc_platform *soc_platform = skl->platform;
+       struct snd_soc_component *soc_component = skl->component;
        struct snd_soc_dapm_widget *w;
        struct snd_soc_card *card;
 
-       if (soc_platform == NULL)
+       if (soc_component == NULL)
                return;
 
-       card = soc_platform->component.card;
+       card = soc_component->card;
        if (!card || !card->instantiated)
                return;
 
@@ -2752,8 +2837,8 @@ void skl_cleanup_resources(struct skl *skl)
        skl->resource.mcps = 0;
 
        list_for_each_entry(w, &card->widgets, list) {
-               if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
-                       skl_clear_pin_config(soc_platform, w);
+               if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL)
+                       skl_clear_pin_config(soc_component, w);
        }
 
        skl_clear_module_cnt(ctx->dsp);
@@ -3400,19 +3485,19 @@ static struct snd_soc_tplg_ops skl_tplg_ops  = {
  * widgets in a pipelines, so this helper - skl_tplg_create_pipe_widget_list()
  * helps to get the SKL type widgets in that pipeline
  */
-static int skl_tplg_create_pipe_widget_list(struct snd_soc_platform *platform)
+static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
 {
        struct snd_soc_dapm_widget *w;
        struct skl_module_cfg *mcfg = NULL;
        struct skl_pipe_module *p_module = NULL;
        struct skl_pipe *pipe;
 
-       list_for_each_entry(w, &platform->component.card->widgets, list) {
-               if (is_skl_dsp_widget_type(w) && w->priv != NULL) {
+       list_for_each_entry(w, &component->card->widgets, list) {
+               if (is_skl_dsp_widget_type(w, component->dev) && w->priv) {
                        mcfg = w->priv;
                        pipe = mcfg->pipe;
 
-                       p_module = devm_kzalloc(platform->dev,
+                       p_module = devm_kzalloc(component->dev,
                                                sizeof(*p_module), GFP_KERNEL);
                        if (!p_module)
                                return -ENOMEM;
@@ -3455,7 +3540,7 @@ static void skl_tplg_set_pipe_type(struct skl *skl, struct skl_pipe *pipe)
 /*
  * SKL topology init routine
  */
-int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
+int skl_tplg_init(struct snd_soc_component *component, struct hdac_ext_bus *ebus)
 {
        int ret;
        const struct firmware *fw;
@@ -3479,7 +3564,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
         * The complete tplg for SKL is loaded as index 0, we don't use
         * any other index
         */
-       ret = snd_soc_tplg_component_load(&platform->component,
+       ret = snd_soc_tplg_component_load(component,
                                        &skl_tplg_ops, fw, 0);
        if (ret < 0) {
                dev_err(bus->dev, "tplg component load failed%d\n", ret);
@@ -3491,7 +3576,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
        skl->resource.max_mem = SKL_FW_MAX_MEM;
 
        skl->tplg = fw;
-       ret = skl_tplg_create_pipe_widget_list(platform);
+       ret = skl_tplg_create_pipe_widget_list(component);
        if (ret < 0)
                return ret;
 
index b6496513fe555d476c6796f9cc5e40f2e29f4caf..b1e0667c0ae0a7ba7b6ac88cd574410c305206ca 100644 (file)
@@ -221,9 +221,18 @@ struct skl_mod_inst_map {
        u16 inst_id;
 };
 
+struct skl_uuid_inst_map {
+       u16 inst_id;
+       u16 reserved;
+       uuid_le mod_uuid;
+} __packed;
+
 struct skl_kpb_params {
        u32 num_modules;
-       struct skl_mod_inst_map map[0];
+       union {
+               struct skl_mod_inst_map map[0];
+               struct skl_uuid_inst_map map_uuid[0];
+       } u;
 };
 
 struct skl_module_inst_id {
@@ -460,7 +469,7 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
                        u32 caps_size, u32 node_id);
 void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
        struct skl_pipe_params *params, int stream);
-int skl_tplg_init(struct snd_soc_platform *platform,
+int skl_tplg_init(struct snd_soc_component *component,
                                struct hdac_ext_bus *ebus);
 struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
                struct snd_soc_dai *dai, int stream);
@@ -505,4 +514,6 @@ int skl_pcm_link_dma_prepare(struct device *dev,
 
 int skl_dai_load(struct snd_soc_component *cmp,
                 struct snd_soc_dai_driver *pcm_dai);
+void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
+                               struct snd_soc_dapm_widget *w);
 #endif
index 32ce64c6b2dced88c562bea3aef2dfdb9d1fa687..abf324747b2901d2b6622a9984e312ffdb597b16 100644 (file)
@@ -94,6 +94,32 @@ static void skl_enable_miscbdcge(struct device *dev, bool enable)
        update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
 }
 
+/**
+ * skl_clock_power_gating: Enable/Disable clock and power gating
+ *
+ * @dev: Device pointer
+ * @enable: Enable/Disable flag
+ */
+static void skl_clock_power_gating(struct device *dev, bool enable)
+{
+       struct pci_dev *pci = to_pci_dev(dev);
+       struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
+       struct hdac_bus *bus = ebus_to_hbus(ebus);
+       u32 val;
+
+       /* Update PDCGE bit of CGCTL register */
+       val = enable ? AZX_CGCTL_ADSPDCGE : 0;
+       update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_ADSPDCGE, val);
+
+       /* Update L1SEN bit of EM2 register */
+       val = enable ? AZX_REG_VS_EM2_L1SEN : 0;
+       snd_hdac_chip_updatel(bus, VS_EM2, AZX_REG_VS_EM2_L1SEN, val);
+
+       /* Update ADSPPGD bit of PGCTL register */
+       val = enable ? 0 : AZX_PGCTL_ADSPPGD;
+       update_pci_dword(pci, AZX_PCIREG_PGCTL, AZX_PGCTL_ADSPPGD, val);
+}
+
 /*
  * While performing reset, controller may not come back properly causing
  * issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
@@ -916,6 +942,7 @@ static int skl_probe(struct pci_dev *pci,
                        goto out_nhlt_free;
                }
                skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
+               skl->skl_sst->clock_power_gating = skl_clock_power_gating;
        }
        if (bus->mlcap)
                snd_hdac_ext_bus_get_ml_capabilities(ebus);
@@ -1017,6 +1044,11 @@ static struct snd_soc_acpi_codecs kbl_5663_5514_codecs = {
        .codecs = {"10EC5663", "10EC5514"}
 };
 
+static struct snd_soc_acpi_codecs kbl_7219_98357_codecs = {
+       .num_codecs = 1,
+       .codecs = {"MX98357A"}
+};
+
 static struct skl_machine_pdata cnl_pdata = {
        .use_tplg_pcm = true,
 };
@@ -1105,6 +1137,14 @@ static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
                .drv_name = "kbl_rt5663",
                .fw_filename = "intel/dsp_fw_kbl.bin",
        },
+       {
+               .id = "DLGS7219",
+               .drv_name = "kbl_da7219_max98357a",
+               .fw_filename = "intel/dsp_fw_kbl.bin",
+               .machine_quirk = snd_soc_acpi_codec_list,
+               .quirk_data = &kbl_7219_98357_codecs,
+               .pdata = &skl_dmic_data
+       },
 
        {}
 };
index 2d13f3fd988ad3881261257d162c9c5166f1bdbc..0d5375cbcf6ec3cff3fdc044e87493e6c46b3765 100644 (file)
 
 #define AZX_PCIREG_PGCTL               0x44
 #define AZX_PGCTL_LSRMD_MASK           (1 << 4)
+#define AZX_PGCTL_ADSPPGD              BIT(2)
 #define AZX_PCIREG_CGCTL               0x48
 #define AZX_CGCTL_MISCBDCGE_MASK       (1 << 6)
+#define AZX_CGCTL_ADSPDCGE             BIT(1)
 /* D0I3C Register fields */
 #define AZX_REG_VS_D0I3C_CIP      0x1 /* Command in progress */
 #define AZX_REG_VS_D0I3C_I3       0x4 /* D0i3 enable */
@@ -43,6 +45,8 @@
 #define DMA_TRANSMITION_START  2
 #define DMA_TRANSMITION_STOP   3
 
+#define AZX_REG_VS_EM2_L1SEN           BIT(13)
+
 struct skl_dsp_resource {
        u32 max_mcps;
        u32 max_mem;
@@ -74,7 +78,7 @@ struct skl {
        struct platform_device *dmic_dev;
        struct platform_device *i2s_dev;
        struct platform_device *clk_dev;
-       struct snd_soc_platform *platform;
+       struct snd_soc_component *component;
        struct snd_soc_dai_driver *dais;
 
        struct nhlt_acpi_table *nhlt; /* nhlt ptr */
index 505b0ff03c3b30dc68306f12bf885da331dd9e68..c6a58520d377aca17ef7538282362c69c370d4c2 100644 (file)
@@ -318,7 +318,8 @@ static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)
        }
 }
 
-const struct snd_soc_platform_driver kirkwood_soc_platform = {
+const struct snd_soc_component_driver kirkwood_soc_component = {
+       .name           = DRV_NAME,
        .ops            = &kirkwood_dma_ops,
        .pcm_new        = kirkwood_dma_new,
        .pcm_free       = kirkwood_dma_free_dma_buffers,
index 105a73cc5158519da5f62e256c4a72c1e5d40c49..9a2777b72dcd0b23ceb490069000fc6ec6bb82af 100644 (file)
@@ -26,8 +26,6 @@
 
 #include "kirkwood.h"
 
-#define DRV_NAME       "mvebu-audio"
-
 #define KIRKWOOD_I2S_FORMATS \
        (SNDRV_PCM_FMTBIT_S16_LE | \
         SNDRV_PCM_FMTBIT_S24_LE | \
@@ -524,10 +522,6 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
     },
 };
 
-static const struct snd_soc_component_driver kirkwood_i2s_component = {
-       .name           = DRV_NAME,
-};
-
 static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 {
        struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
@@ -601,24 +595,17 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
                priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
        }
 
-       err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
+       err = devm_snd_soc_register_component(&pdev->dev, &kirkwood_soc_component,
                                         soc_dai, 2);
        if (err) {
                dev_err(&pdev->dev, "snd_soc_register_component failed\n");
                goto err_component;
        }
 
-       err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
-       if (err) {
-               dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
-               goto err_platform;
-       }
-
        kirkwood_i2s_init(priv);
 
        return 0;
- err_platform:
-       snd_soc_unregister_component(&pdev->dev);
+
  err_component:
        if (!IS_ERR(priv->extclk))
                clk_disable_unprepare(priv->extclk);
@@ -631,9 +618,6 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
 {
        struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_component(&pdev->dev);
-
        if (!IS_ERR(priv->extclk))
                clk_disable_unprepare(priv->extclk);
        clk_disable_unprepare(priv->clk);
index 783cb1a4f30e3662a6e237a2b09db39e680c1f86..c13ee5f69446df3bd1cd46cf58a5c3d487e5c0a6 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef _KIRKWOOD_AUDIO_H
 #define _KIRKWOOD_AUDIO_H
 
+#define DRV_NAME       "mvebu-audio"
+
 #define KIRKWOOD_RECORD_WIN                    0
 #define KIRKWOOD_PLAYBACK_WIN                  1
 #define KIRKWOOD_MAX_AUDIO_WIN                 2
@@ -143,6 +145,6 @@ struct kirkwood_dma_data {
        int burst;
 };
 
-extern const struct snd_soc_platform_driver kirkwood_soc_platform;
+extern const struct snd_soc_component_driver kirkwood_soc_component;
 
 #endif
index ac231d33d8fe845b48efc7037f9e1f460526fd7d..c91e5f4cd902a931635f592dd75633a7118de862 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <sound/soc.h>
+#include "mtk-afe-platform-driver.h"
 #include "mtk-afe-fe-dai.h"
 #include "mtk-base-afe.h"
 
@@ -43,7 +44,8 @@ int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
                       struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *runtime = substream->runtime;
        int memif_num = rtd->cpu_dai->id;
        struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
@@ -105,7 +107,8 @@ void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
                         struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
        int irq_id;
 
@@ -128,7 +131,8 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
                         struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
        int msb_at_bit33 = 0;
        int ret, fs = 0;
@@ -192,7 +196,8 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime * const runtime = substream->runtime;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
        struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage];
        const struct mtk_base_irq_data *irq_data = irqs->irq_data;
@@ -255,7 +260,8 @@ int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
                       struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd  = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
        int hd_audio = 0;
 
index 82d439c15f4e3f366a5e3a6c032d3651f721e92b..53215b52e4f24111a9a9458686f1efd9e31adc43 100644 (file)
@@ -25,7 +25,8 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer
                         (struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
        const struct mtk_base_memif_data *memif_data = memif->data;
        struct regmap *regmap = afe->regmap;
@@ -65,7 +66,8 @@ static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
        size_t size;
        struct snd_card *card = rtd->card->snd_card;
        struct snd_pcm *pcm = rtd->pcm;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
        size = afe->mtk_afe_hardware->buffer_bytes_max;
        return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
@@ -77,7 +79,8 @@ static void mtk_afe_pcm_free(struct snd_pcm *pcm)
        snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
-const struct snd_soc_platform_driver mtk_afe_pcm_platform = {
+const struct snd_soc_component_driver mtk_afe_pcm_platform = {
+       .name = AFE_PCM_NAME,
        .ops = &mtk_afe_pcm_ops,
        .pcm_new = mtk_afe_pcm_new,
        .pcm_free = mtk_afe_pcm_free,
index a973fc9253b4b63572478bd8d92af11207245d8d..8dcdbed959ea5a21af1576d79a59d0432cffc170 100644 (file)
@@ -17,7 +17,8 @@
 #ifndef _MTK_AFE_PLATFORM_DRIVER_H_
 #define _MTK_AFE_PLATFORM_DRIVER_H_
 
-extern const struct snd_soc_platform_driver mtk_afe_pcm_platform;
+#define AFE_PCM_NAME "mtk-afe-pcm"
+extern const struct snd_soc_component_driver mtk_afe_pcm_platform;
 
 #endif
 
index d68b53f7cefe9334220a04183dbaa2bb997cdda5..73cce33fa439ab773914abad8505c06d366417b2 100644 (file)
@@ -93,7 +93,8 @@ static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
                                  struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
 
        if (i2s_num < 0)
@@ -108,7 +109,8 @@ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
                                        int dir_invert)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt2701_afe_private *afe_priv = afe->platform_priv;
        struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
        const struct mt2701_i2s_data *i2s_data;
@@ -144,7 +146,8 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
                                    struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt2701_afe_private *afe_priv = afe->platform_priv;
        int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
        struct mt2701_i2s_path *i2s_path;
@@ -176,7 +179,8 @@ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
                                          int dir_invert)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt2701_afe_private *afe_priv = afe->platform_priv;
        struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
        const struct mt2701_i2s_data *i2s_data;
@@ -247,7 +251,8 @@ static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
 {
        int clk_domain;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt2701_afe_private *afe_priv = afe->platform_priv;
        int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
        struct mt2701_i2s_path *i2s_path;
@@ -312,7 +317,8 @@ static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt2701_afe_private *afe_priv = afe->platform_priv;
        int ret;
 
@@ -329,14 +335,15 @@ static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        int stream_fs;
        u32 val, msk;
 
        stream_fs = params_rate(params);
 
        if ((stream_fs != 8000) && (stream_fs != 16000)) {
-               dev_err(afe->dev, "%s() btmgr not supprt this stream_fs %d\n",
+               dev_err(afe->dev, "%s() btmgr not support this stream_fs %d\n",
                        __func__, stream_fs);
                return -EINVAL;
        }
@@ -372,7 +379,8 @@ static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
                                  struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 
        /* if the other direction stream is not occupied */
@@ -392,7 +400,8 @@ static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
                                    struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        int stream_dir = substream->stream;
        int memif_num = rtd->cpu_dai->id;
        struct mtk_base_afe_memif *memif_tmp;
@@ -414,7 +423,8 @@ static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
                                      struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        int stream_dir = substream->stream;
 
        /* single DL use PAIR_INTERLEAVE */
@@ -431,7 +441,8 @@ static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif_tmp;
        const struct mtk_base_memif_data *memif_data;
        int i;
@@ -458,7 +469,8 @@ static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        const struct mtk_base_memif_data *memif_data;
        int i;
 
@@ -477,7 +489,8 @@ static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        int channels = params_channels(params);
 
        regmap_update_bits(afe->regmap,
@@ -500,7 +513,8 @@ static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
                                 int cmd, struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
 
        switch (cmd) {
@@ -1517,7 +1531,8 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
        }
        pm_runtime_get_sync(dev);
 
-       ret = snd_soc_register_platform(dev, &mtk_afe_pcm_platform);
+       ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform,
+                                             NULL, 0);
        if (ret) {
                dev_warn(dev, "err_platform\n");
                goto err_platform;
@@ -1526,13 +1541,11 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
        ret = mt2701_afe_add_component(afe);
        if (ret) {
                dev_warn(dev, "err_dai_component\n");
-               goto err_dai_component;
+               goto err_platform;
        }
 
        return 0;
 
-err_dai_component:
-       snd_soc_unregister_platform(dev);
 err_platform:
        pm_runtime_put_sync(dev);
 err_pm_disable:
@@ -1548,9 +1561,6 @@ static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
        if (!pm_runtime_status_suspended(&pdev->dev))
                mt2701_afe_runtime_suspend(&pdev->dev);
 
-       snd_soc_unregister_component(&pdev->dev);
-       snd_soc_unregister_platform(&pdev->dev);
-
        return 0;
 }
 
index c7f7f8add5d9dcd5d6437e245d7ba7516ccbfbf2..65d1433a09443e3c7c49602afa6e25ea5dd87827 100644 (file)
@@ -304,7 +304,8 @@ static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream,
                                  struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
        if (dai->active)
                return 0;
@@ -318,7 +319,8 @@ static void mt8173_afe_i2s_shutdown(struct snd_pcm_substream *substream,
                                    struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
        if (dai->active)
                return;
@@ -334,7 +336,8 @@ static int mt8173_afe_i2s_prepare(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime * const runtime = substream->runtime;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt8173_afe_private *afe_priv = afe->platform_priv;
        int ret;
 
@@ -356,7 +359,8 @@ static int mt8173_afe_hdmi_startup(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt8173_afe_private *afe_priv = afe->platform_priv;
 
        if (dai->active)
@@ -371,7 +375,8 @@ static void mt8173_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
                                     struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt8173_afe_private *afe_priv = afe->platform_priv;
 
        if (dai->active)
@@ -386,7 +391,8 @@ static int mt8173_afe_hdmi_prepare(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_pcm_runtime * const runtime = substream->runtime;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mt8173_afe_private *afe_priv = afe->platform_priv;
 
        unsigned int val;
@@ -449,7 +455,8 @@ static int mt8173_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
 
        dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name);
 
@@ -498,7 +505,8 @@ static int mt8173_memif_fs(struct snd_pcm_substream *substream,
                           unsigned int rate)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+       struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
        struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
        int fs;
 
@@ -1172,31 +1180,29 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
        afe->runtime_resume = mt8173_afe_runtime_resume;
        afe->runtime_suspend = mt8173_afe_runtime_suspend;
 
-       ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                        &mtk_afe_pcm_platform,
+                                        NULL, 0);
        if (ret)
                goto err_pm_disable;
 
-       ret = snd_soc_register_component(&pdev->dev,
+       ret = devm_snd_soc_register_component(&pdev->dev,
                                         &mt8173_afe_pcm_dai_component,
                                         mt8173_afe_pcm_dais,
                                         ARRAY_SIZE(mt8173_afe_pcm_dais));
        if (ret)
-               goto err_platform;
+               goto err_pm_disable;
 
-       ret = snd_soc_register_component(&pdev->dev,
+       ret = devm_snd_soc_register_component(&pdev->dev,
                                         &mt8173_afe_hdmi_dai_component,
                                         mt8173_afe_hdmi_dais,
                                         ARRAY_SIZE(mt8173_afe_hdmi_dais));
        if (ret)
-               goto err_comp;
+               goto err_pm_disable;
 
        dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
        return 0;
 
-err_comp:
-       snd_soc_unregister_component(&pdev->dev);
-err_platform:
-       snd_soc_unregister_platform(&pdev->dev);
 err_pm_disable:
        pm_runtime_disable(&pdev->dev);
        return ret;
@@ -1207,8 +1213,6 @@ static int mt8173_afe_pcm_dev_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
        if (!pm_runtime_status_suspended(&pdev->dev))
                mt8173_afe_runtime_suspend(&pdev->dev);
-       snd_soc_unregister_component(&pdev->dev);
-       snd_soc_unregister_platform(&pdev->dev);
        return 0;
 }
 
index e0c2b23ec711840bedaac375489dabcc1a50b2f5..b49b527a7cf95ae0c385da82f6f144afc08804c7 100644 (file)
@@ -75,7 +75,7 @@ static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime)
 {
        int ret;
        struct snd_soc_card *card = runtime->card;
-       struct snd_soc_codec *codec = runtime->codec;
+       struct snd_soc_component *component = runtime->codec_dai->component;
 
        /* enable jack detection */
        ret = snd_soc_card_jack_new(card, "Headphone", SND_JACK_HEADPHONE,
@@ -87,7 +87,7 @@ static int mt8173_max98090_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
        }
 
-       return max98090_mic_detect(codec, &mt8173_max98090_jack);
+       return max98090_mic_detect(component, &mt8173_max98090_jack);
 }
 
 /* Digital audio interface glue - connects codec <---> CPU */
index 5a9a5482976ec88b152843b8af9d9625470dc191..904f3ee6b0eb16d5b2c707bf785a3ecf91767f21 100644 (file)
@@ -82,10 +82,10 @@ static struct snd_soc_jack mt8173_rt5650_rt5514_jack;
 static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_soc_card *card = runtime->card;
-       struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
+       struct snd_soc_component *component = runtime->codec_dais[0]->component;
        int ret;
 
-       rt5645_sel_asrc_clk_src(codec,
+       rt5645_sel_asrc_clk_src(component,
                                RT5645_DA_STEREO_FILTER |
                                RT5645_AD_STEREO_FILTER,
                                RT5645_CLK_SEL_I2S1_ASRC);
@@ -101,7 +101,7 @@ static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
        }
 
-       return rt5645_set_jack_detect(codec,
+       return rt5645_set_jack_detect(component,
                                      &mt8173_rt5650_rt5514_jack,
                                      &mt8173_rt5650_rt5514_jack,
                                      &mt8173_rt5650_rt5514_jack);
index b7248085ca042387a86fc215eee7d0df8b6a8945..9c61b8c099c573d85fb25e22c2c5e45e8f27f567 100644 (file)
@@ -86,19 +86,19 @@ static struct snd_soc_jack mt8173_rt5650_rt5676_jack;
 static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_soc_card *card = runtime->card;
-       struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
-       struct snd_soc_codec *codec_sub = runtime->codec_dais[1]->codec;
+       struct snd_soc_component *component = runtime->codec_dais[0]->component;
+       struct snd_soc_component *component_sub = runtime->codec_dais[1]->component;
        int ret;
 
-       rt5645_sel_asrc_clk_src(codec,
+       rt5645_sel_asrc_clk_src(component,
                                RT5645_DA_STEREO_FILTER |
                                RT5645_AD_STEREO_FILTER,
                                RT5645_CLK_SEL_I2S1_ASRC);
-       rt5677_sel_asrc_clk_src(codec_sub,
+       rt5677_sel_asrc_clk_src(component_sub,
                                RT5677_DA_STEREO_FILTER |
                                RT5677_AD_STEREO1_FILTER,
                                RT5677_CLK_SEL_I2S1_ASRC);
-       rt5677_sel_asrc_clk_src(codec_sub,
+       rt5677_sel_asrc_clk_src(component_sub,
                                RT5677_AD_STEREO2_FILTER |
                                RT5677_I2S2_SOURCE,
                                RT5677_CLK_SEL_I2S2_ASRC);
@@ -114,7 +114,7 @@ static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
        }
 
-       return rt5645_set_jack_detect(codec,
+       return rt5645_set_jack_detect(component,
                                      &mt8173_rt5650_rt5676_jack,
                                      &mt8173_rt5650_rt5676_jack,
                                      &mt8173_rt5650_rt5676_jack);
index 679fc8bea0a32fdff72dcef61673f42d401d3dd6..84aa09d3dd98fe242ec919e5b8979214f90d5066 100644 (file)
@@ -112,26 +112,26 @@ static struct snd_soc_jack mt8173_rt5650_jack;
 static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime)
 {
        struct snd_soc_card *card = runtime->card;
-       struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
+       struct snd_soc_component *component = runtime->codec_dais[0]->component;
        const char *codec_capture_dai = runtime->codec_dais[1]->name;
        int ret;
 
-       rt5645_sel_asrc_clk_src(codec,
+       rt5645_sel_asrc_clk_src(component,
                                RT5645_DA_STEREO_FILTER,
                                RT5645_CLK_SEL_I2S1_ASRC);
 
        if (!strcmp(codec_capture_dai, "rt5645-aif1")) {
-               rt5645_sel_asrc_clk_src(codec,
+               rt5645_sel_asrc_clk_src(component,
                                        RT5645_AD_STEREO_FILTER,
                                        RT5645_CLK_SEL_I2S1_ASRC);
        } else if (!strcmp(codec_capture_dai, "rt5645-aif2")) {
-               rt5645_sel_asrc_clk_src(codec,
+               rt5645_sel_asrc_clk_src(component,
                                        RT5645_AD_STEREO_FILTER,
                                        RT5645_CLK_SEL_I2S2_ASRC);
        } else {
                dev_warn(card->dev,
                         "Only one dai codec found in DTS, enabled rt5645 AD filter\n");
-               rt5645_sel_asrc_clk_src(codec,
+               rt5645_sel_asrc_clk_src(component,
                                        RT5645_AD_STEREO_FILTER,
                                        RT5645_CLK_SEL_I2S1_ASRC);
        }
@@ -147,7 +147,7 @@ static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
        }
 
-       return rt5645_set_jack_detect(codec,
+       return rt5645_set_jack_detect(component,
                                      &mt8173_rt5650_jack,
                                      &mt8173_rt5650_jack,
                                      &mt8173_rt5650_jack);
index bd6dfa218d59844eaec9ff37a0f74652997d0f43..ad8392a87df99bfa79616950d5caf81b159b4b6c 100644 (file)
@@ -299,14 +299,15 @@ static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
-static const struct snd_soc_platform_driver nuc900_soc_platform = {
+static const struct snd_soc_component_driver nuc900_soc_component = {
        .ops            = &nuc900_dma_ops,
        .pcm_new        = nuc900_dma_new,
 };
 
 static int nuc900_soc_platform_probe(struct platform_device *pdev)
 {
-       return devm_snd_soc_register_platform(&pdev->dev, &nuc900_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev, &nuc900_soc_component,
+                                              NULL, 0);
 }
 
 static struct platform_driver nuc900_pcm_driver = {
index cb72c1e57da044941198a83e78aa1c2435cae508..77a30f0f0c960fd89b7bb4fedb70607bbb40bd41 100644 (file)
@@ -93,7 +93,7 @@ static unsigned short ams_delta_audio_agc;
  * Used for passing a codec structure pointer
  * from the board initialization code to the tty line discipline.
  */
-static struct snd_soc_codec *cx20442_codec;
+static struct snd_soc_component *cx20442_codec;
 
 static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
                                        struct snd_ctl_elem_value *ucontrol)
@@ -105,7 +105,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
        int pin, changed = 0;
 
        /* Refuse any mode changes if we are not able to control the codec. */
-       if (!cx20442_codec->component.card->pop_time)
+       if (!cx20442_codec->card->pop_time)
                return -EUNATCH;
 
        if (ucontrol->value.enumerated.item[0] >= control->items)
@@ -300,15 +300,15 @@ static int cx81801_open(struct tty_struct *tty)
 /* Line discipline .close() */
 static void cx81801_close(struct tty_struct *tty)
 {
-       struct snd_soc_codec *codec = tty->disc_data;
-       struct snd_soc_dapm_context *dapm = &codec->component.card->dapm;
+       struct snd_soc_component *component = tty->disc_data;
+       struct snd_soc_dapm_context *dapm = &component->card->dapm;
 
        del_timer_sync(&cx81801_timer);
 
        /* Prevent the hook switch from further changing the DAPM pins */
        INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
 
-       if (!codec)
+       if (!component)
                return;
 
        v253_ops.close(tty);
@@ -338,14 +338,14 @@ static int cx81801_hangup(struct tty_struct *tty)
 static void cx81801_receive(struct tty_struct *tty,
                                const unsigned char *cp, char *fp, int count)
 {
-       struct snd_soc_codec *codec = tty->disc_data;
+       struct snd_soc_component *component = tty->disc_data;
        const unsigned char *c;
        int apply, ret;
 
-       if (!codec)
+       if (!component)
                return;
 
-       if (!codec->component.card->pop_time) {
+       if (!component->card->pop_time) {
                /* First modem response, complete setup procedure */
 
                /* Initialize timer used for config pulse generation */
@@ -358,7 +358,7 @@ static void cx81801_receive(struct tty_struct *tty,
                                        ARRAY_SIZE(ams_delta_hook_switch_pins),
                                        ams_delta_hook_switch_pins);
                if (ret)
-                       dev_warn(codec->dev,
+                       dev_warn(component->dev,
                                "Failed to link hook switch to DAPM pins, "
                                "will continue with hook switch unlinked.\n");
 
@@ -467,7 +467,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
        /* Codec is ready, now add/activate board specific controls */
 
        /* Store a pointer to the codec structure for tty ldisc use */
-       cx20442_codec = rtd->codec;
+       cx20442_codec = rtd->codec_dai->component;
 
        /* Set up digital mute if not provided by the codec */
        if (!codec_dai->driver->ops) {
index 614b18d2f631b80c61e32eaca0b139c816fcb5d5..15ccbf479c9664019159b215cbb5f97e2f37cd62 100644 (file)
@@ -52,7 +52,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
        int clk_id, freq;
        int ret;
 
-       clk_id = twl6040_get_clk_id(rtd->codec);
+       clk_id = twl6040_get_clk_id(codec_dai->component);
        if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
                freq = priv->mclk_freq;
        else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
@@ -166,7 +166,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
 
 static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        struct snd_soc_card *card = rtd->card;
        struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
        int hs_trim;
@@ -176,7 +176,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
         * Configure McPDM offset cancellation based on the HSOTRIM value from
         * twl6040.
         */
-       hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
+       hs_trim = twl6040_get_trim_value(component, TWL6040_TRIM_HSOTRIM);
        omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
                                        TWL6040_HSF_TRIM_RIGHT(hs_trim));
 
@@ -189,7 +189,7 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
                if (ret)
                        return ret;
 
-               twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
+               twl6040_hs_jack_detect(component, &hs_jack, SND_JACK_HEADSET);
        }
 
        return 0;
index aca2c43d0f03ee69421416d4d1e55c12de4a46f0..778cc8f75b6ab7cb51c8c1ebaf94c26293b4b0b6 100644 (file)
@@ -243,7 +243,7 @@ out:
        return ret;
 }
 
-static const struct snd_soc_platform_driver omap_soc_platform = {
+static const struct snd_soc_component_driver omap_soc_component = {
        .ops            = &omap_pcm_ops,
        .pcm_new        = omap_pcm_new,
        .pcm_free       = omap_pcm_free_dma_buffers,
@@ -252,7 +252,8 @@ static const struct snd_soc_platform_driver omap_soc_platform = {
 int omap_pcm_platform_register(struct device *dev)
 {
        omap_pcm_limit_supported_formats();
-       return devm_snd_soc_register_platform(dev, &omap_soc_platform);
+       return devm_snd_soc_register_component(dev, &omap_soc_component,
+                                              NULL, 0);
 }
 EXPORT_SYMBOL_GPL(omap_pcm_platform_register);
 
index c4c6fbedc723ad78220d990756539e656f1d3329..47052fe3f5f4fce7498f9d04a351ae991f4558df 100644 (file)
 #define AC97_GPIO_PULL         0x58
 
 /* Use GPIO8 for rear speaker amplifier */
-static int rear_amp_power(struct snd_soc_codec *codec, int power)
+static int rear_amp_power(struct snd_soc_component *component, int power)
 {
        unsigned short reg;
 
        if (power) {
-               reg = snd_soc_read(codec, AC97_GPIO_CFG);
-               snd_soc_write(codec, AC97_GPIO_CFG, reg | 0x0100);
-               reg = snd_soc_read(codec, AC97_GPIO_PULL);
-               snd_soc_write(codec, AC97_GPIO_PULL, reg | (1<<15));
+               reg = snd_soc_component_read32(component, AC97_GPIO_CFG);
+               snd_soc_component_write(component, AC97_GPIO_CFG, reg | 0x0100);
+               reg = snd_soc_component_read32(component, AC97_GPIO_PULL);
+               snd_soc_component_write(component, AC97_GPIO_PULL, reg | (1<<15));
        } else {
-               reg = snd_soc_read(codec, AC97_GPIO_CFG);
-               snd_soc_write(codec, AC97_GPIO_CFG, reg & ~0x0100);
-               reg = snd_soc_read(codec, AC97_GPIO_PULL);
-               snd_soc_write(codec, AC97_GPIO_PULL, reg & ~(1<<15));
+               reg = snd_soc_component_read32(component, AC97_GPIO_CFG);
+               snd_soc_component_write(component, AC97_GPIO_CFG, reg & ~0x0100);
+               reg = snd_soc_component_read32(component, AC97_GPIO_PULL);
+               snd_soc_component_write(component, AC97_GPIO_PULL, reg & ~(1<<15));
        }
 
        return 0;
@@ -82,11 +82,11 @@ static int rear_amp_event(struct snd_soc_dapm_widget *widget,
 {
        struct snd_soc_card *card = widget->dapm->card;
        struct snd_soc_pcm_runtime *rtd;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 
        rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-       codec = rtd->codec;
-       return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
+       component = rtd->codec_dai->component;
+       return rear_amp_power(component, SND_SOC_DAPM_EVENT_ON(event));
 }
 
 /* mioa701 machine dapm widgets */
@@ -129,13 +129,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
 
 static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        /* Prepare GPIO8 for rear speaker amplifier */
-       snd_soc_update_bits(codec, AC97_GPIO_CFG, 0x100, 0x100);
+       snd_soc_component_update_bits(component, AC97_GPIO_CFG, 0x100, 0x100);
 
        /* Prepare MIC input */
-       snd_soc_update_bits(codec, AC97_3D_CONTROL, 0xc000, 0xc000);
+       snd_soc_component_update_bits(component, AC97_3D_CONTROL, 0xc000, 0xc000);
 
        return 0;
 }
index 624d9bd5dadd2701c02f5103a71b12b00cd85cd9..d2d4652de32cc8e6813d82dbb6ada0a74820649a 100644 (file)
@@ -25,6 +25,8 @@
 #include <sound/soc.h>
 #include <sound/dmaengine_pcm.h>
 
+#define DRV_NAME "mmp-pcm"
+
 struct mmp_dma_data {
        int ssp_id;
        struct resource *dma_res;
@@ -100,7 +102,8 @@ static bool filter(struct dma_chan *chan, void *param)
 static int mmp_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct platform_device *pdev = to_platform_device(rtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct platform_device *pdev = to_platform_device(component->dev);
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct mmp_dma_data dma_data;
        struct resource *r;
@@ -211,7 +214,8 @@ err:
        return ret;
 }
 
-static const struct snd_soc_platform_driver mmp_soc_platform = {
+static const struct snd_soc_component_driver mmp_soc_component = {
+       .name           = DRV_NAME,
        .ops            = &mmp_pcm_ops,
        .pcm_new        = mmp_pcm_new,
        .pcm_free       = mmp_pcm_free_dma_buffers,
@@ -231,7 +235,8 @@ static int mmp_pcm_probe(struct platform_device *pdev)
                mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max =
                                                pdata->period_max_capture;
        }
-       return devm_snd_soc_register_platform(&pdev->dev, &mmp_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev, &mmp_soc_component,
+                                              NULL, 0);
 }
 
 static struct platform_driver mmp_pcm_driver = {
index 64b85e30c1f87205e981b0a4ef119d40d2197758..7c998ea4ebee02bdd27354d034f90b22d596c035 100644 (file)
@@ -377,7 +377,6 @@ static int mmp_sspa_probe(struct snd_soc_dai *dai)
 #define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
                SNDRV_PCM_FMTBIT_S16_LE | \
                SNDRV_PCM_FMTBIT_S24_LE | \
-               SNDRV_PCM_FMTBIT_S24_LE | \
                SNDRV_PCM_FMTBIT_S32_LE)
 
 static const struct snd_soc_dai_ops mmp_sspa_dai_ops = {
index e64958d8bff0d727ca0712a495c28297f53a5940..8b6a70e94c01da6d1a7179eefe48a3da8f7b3837 100644 (file)
@@ -84,7 +84,7 @@ static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
        return ret;
 }
 
-static const struct snd_soc_platform_driver pxa2xx_soc_platform = {
+static const struct snd_soc_component_driver pxa2xx_soc_platform = {
        .ops            = &pxa2xx_pcm_ops,
        .pcm_new        = pxa2xx_soc_pcm_new,
        .pcm_free       = pxa2xx_pcm_free_dma_buffers,
@@ -92,7 +92,8 @@ static const struct snd_soc_platform_driver pxa2xx_soc_platform = {
 
 static int pxa2xx_soc_platform_probe(struct platform_device *pdev)
 {
-       return devm_snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev, &pxa2xx_soc_platform,
+                                              NULL, 0);
 }
 
 #ifdef CONFIG_OF
index 65c20f779177589bcb7eb0ce8d61a2196806eb69..5d6e61a4bb7e3d42d1095fb01db64e8feec272c1 100644 (file)
@@ -75,7 +75,7 @@ static const struct snd_soc_dapm_route ttc_audio_map[] = {
 
 static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        /* Headset jack detection */
        snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE |
@@ -86,9 +86,9 @@ static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
                              ARRAY_SIZE(mic_jack_pins));
 
        /* headphone, microphone detection & headset short detection */
-       pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
+       pm860x_hs_jack_detect(component, &hs_jack, SND_JACK_HEADPHONE,
                              SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
-       pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
+       pm860x_mic_jack_detect(component, &hs_jack, SND_JACK_MICROPHONE);
 
        return 0;
 }
index caf71aab8196bd0179114b70cf653bfcb56b4f8f..31fe78aa207fc175bf36bff01b3138757b0d2e14 100644 (file)
@@ -24,6 +24,8 @@
 #include "lpass-lpaif-reg.h"
 #include "lpass.h"
 
+#define DRV_NAME "lpass-platform"
+
 struct lpass_pcm_data {
        int dma_ch;
        int i2s_port;
@@ -61,8 +63,8 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
        struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
-       struct lpass_data *drvdata =
-               snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct lpass_variant *v = drvdata->variant;
        int ret, dma_ch, dir = substream->stream;
        struct lpass_pcm_data *data;
@@ -115,8 +117,8 @@ static int lpass_platform_pcmops_close(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_data *drvdata =
-               snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct lpass_variant *v = drvdata->variant;
        struct lpass_pcm_data *data;
 
@@ -132,8 +134,8 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_data *drvdata =
-               snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *rt = substream->runtime;
        struct lpass_pcm_data *pcm_data = rt->private_data;
        struct lpass_variant *v = drvdata->variant;
@@ -225,8 +227,8 @@ static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
 static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_data *drvdata =
-               snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *rt = substream->runtime;
        struct lpass_pcm_data *pcm_data = rt->private_data;
        struct lpass_variant *v = drvdata->variant;
@@ -246,8 +248,8 @@ static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_data *drvdata =
-               snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *rt = substream->runtime;
        struct lpass_pcm_data *pcm_data = rt->private_data;
        struct lpass_variant *v = drvdata->variant;
@@ -298,8 +300,8 @@ static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
                int cmd)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_data *drvdata =
-               snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *rt = substream->runtime;
        struct lpass_pcm_data *pcm_data = rt->private_data;
        struct lpass_variant *v = drvdata->variant;
@@ -372,8 +374,8 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
                struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
-       struct lpass_data *drvdata =
-                       snd_soc_platform_get_drvdata(soc_runtime->platform);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
+       struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
        struct snd_pcm_runtime *rt = substream->runtime;
        struct lpass_pcm_data *pcm_data = rt->private_data;
        struct lpass_variant *v = drvdata->variant;
@@ -509,13 +511,14 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
 {
        struct snd_pcm *pcm = soc_runtime->pcm;
        struct snd_pcm_substream *psubstream, *csubstream;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(soc_runtime, DRV_NAME);
        int ret = -EINVAL;
        size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
 
        psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
        if (psubstream) {
                ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
-                                       soc_runtime->platform->dev,
+                                       component->dev,
                                        size, &psubstream->dma_buffer);
                if (ret) {
                        dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
@@ -526,7 +529,7 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
        csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
        if (csubstream) {
                ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
-                                       soc_runtime->platform->dev,
+                                       component->dev,
                                        size, &csubstream->dma_buffer);
                if (ret) {
                        dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
@@ -555,7 +558,8 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm)
        }
 }
 
-static const struct snd_soc_platform_driver lpass_platform_driver = {
+static const struct snd_soc_component_driver lpass_component_driver = {
+       .name           = DRV_NAME,
        .pcm_new        = lpass_platform_pcm_new,
        .pcm_free       = lpass_platform_pcm_free,
        .ops            = &lpass_platform_pcm_ops,
@@ -591,8 +595,8 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
        }
 
 
-       return devm_snd_soc_register_platform(&pdev->dev,
-                       &lpass_platform_driver);
+       return devm_snd_soc_register_component(&pdev->dev,
+                       &lpass_component_driver, NULL, 0);
 }
 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
 
index b0825370d262f43730a9e96afd8a6d8239579797..957046ac6c8ca1438dde183a0382489f5ccd8ef8 100644 (file)
@@ -56,6 +56,9 @@ config SND_SOC_RK3288_HDMI_ANALOG
        depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
        select SND_SOC_ROCKCHIP_I2S
        select SND_SOC_HDMI_CODEC
+       select SND_SOC_ES8328_I2C
+       select SND_SOC_ES8328_SPI if SPI_MASTER
+       select DRM_DW_HDMI_I2S_AUDIO if DRM_DW_HDMI
        help
          Say Y or M here if you want to add support for SoC audio on Rockchip
          RK3288 boards using an analog output and the built-in HDMI audio.
index fa44e3901336d97342a1e158a2c1c066f9d0bc41..929b3fe289b0b9ca7298463ba03da0b36f49a7b1 100644 (file)
@@ -155,7 +155,7 @@ static struct snd_soc_dai_link_component rk_codecs[] = {
        { },
        {
                .name = "hdmi-audio-codec.2.auto",
-               .dai_name = "hdmi-hifi.0",
+               .dai_name = "i2s-hifi",
        },
 };
 
index 214bfc78cf5cd466659980db19caaa6d45922a7b..9a10181a081143f28d97f77db8f7fe58cb170029 100644 (file)
@@ -176,7 +176,7 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
 
 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec_dais[0]->codec;
+       struct snd_soc_component *component = rtd->codec_dais[0]->component;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
        int ret;
 
@@ -215,7 +215,7 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
        snd_jack_set_key(
                rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
 
-       da7219_aad_jack_det(codec, &rockchip_sound_jack);
+       da7219_aad_jack_det(component, &rockchip_sound_jack);
 
        return 0;
 }
index 9e0c178058074e5102b73978c9c15082e2be9f72..4db4fd56db358f4549f434a3e3712ed450f5776c 100644 (file)
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "rockchip_i2s.h"
+#include "../codecs/rt5645.h"
 
 #define DRV_NAME "rockchip-snd-rt5645"
 
 static struct snd_soc_jack headset_jack;
 
-/* Jack detect via rt5645 driver. */
-extern int rt5645_set_jack_detect(struct snd_soc_codec *codec,
-       struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
-       struct snd_soc_jack *btn_jack);
-
 static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
        SND_SOC_DAPM_HP("Headphones", NULL),
        SND_SOC_DAPM_SPK("Speakers", NULL),
@@ -129,7 +125,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime)
                return ret;
        }
 
-       return rt5645_set_jack_detect(runtime->codec,
+       return rt5645_set_jack_detect(runtime->codec_dai->component,
                                     &headset_jack,
                                     &headset_jack,
                                     &headset_jack);
index 030949e1e434229430eb66bfc132a3446bd73688..c3b76035f69c8d3f3ada82902bb25a9cfb0425ba 100644 (file)
@@ -21,8 +21,6 @@ obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-idma.o
 # S3C24XX Machine Support
 snd-soc-jive-wm8750-objs := jive_wm8750.o
 snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
-snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
-snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
 snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
 snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
 snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
@@ -32,7 +30,6 @@ snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
 snd-soc-smdk-wm8580-objs := smdk_wm8580.o
 snd-soc-smdk-wm8994-objs := smdk_wm8994.o
 snd-soc-snow-objs := snow.o
-snd-soc-smdk-wm9713-objs := smdk_wm9713.o
 snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
 snd-soc-smdk-spdif-objs := smdk_spdif.o
 snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
index fe69140054944c230c0b5197dc3d18b4c02dab58..964985ea2e80cdb72a543431adf6122ca1958b59 100644 (file)
 #define CON_RXDMA_ACTIVE       (1 << 1)
 #define CON_ACTIVE             (1 << 0)
 
-#define MOD_OPCLK_CDCLK_OUT    (0 << 30)
-#define MOD_OPCLK_CDCLK_IN     (1 << 30)
-#define MOD_OPCLK_BCLK_OUT     (2 << 30)
-#define MOD_OPCLK_PCLK         (3 << 30)
-#define MOD_OPCLK_MASK         (3 << 30)
+#define MOD_OPCLK_SHIFT                30
+#define MOD_OPCLK_CDCLK_OUT    (0 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_CDCLK_IN     (1 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_BCLK_OUT     (2 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_PCLK         (3 << MOD_OPCLK_SHIFT)
+#define MOD_OPCLK_MASK         (3 << MOD_OPCLK_SHIFT)
 #define MOD_TXS_IDMA           (1 << 28) /* Sec_TXFIFO use I-DMA */
 
 #define MOD_BLCS_SHIFT         26
index 233f1c9a4b6cc0c99200a70c411a8d8df0c29741..f914ed45db7d6b72c97af5b4822fc1f9144044b3 100644 (file)
@@ -489,7 +489,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
        switch (clk_id) {
        case SAMSUNG_I2S_OPCLK:
                mask = MOD_OPCLK_MASK;
-               val = dir;
+               val = (dir << MOD_OPCLK_SHIFT) & MOD_OPCLK_MASK;
                break;
        case SAMSUNG_I2S_CDCLK:
                mask = 1 << i2s_regs->cdclkcon_off;
@@ -656,8 +656,12 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
                tmp |= mod_slave;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               /* Set default source clock in Master mode */
-               if (i2s->rclk_srcrate == 0)
+               /*
+                * Set default source clock in Master mode, only when the
+                * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any
+                * clock configuration assigned in DT is not overwritten.
+                */
+               if (i2s->rclk_srcrate == 0 && i2s->clk_data.clks == NULL)
                        i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
                                                        0, SND_SOC_CLOCK_IN);
                break;
@@ -881,6 +885,11 @@ static int config_setup(struct i2s_dai *i2s)
                return 0;
 
        if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
+               struct clk *rclksrc = i2s->clk_table[CLK_I2S_RCLK_SRC];
+
+               if (rclksrc && !IS_ERR(rclksrc))
+                       i2s->rclk_srcrate = clk_get_rate(rclksrc);
+
                psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
                writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
                dev_dbg(&i2s->pdev->dev,
@@ -1184,11 +1193,13 @@ static void i2s_unregister_clock_provider(struct platform_device *pdev)
 
 static int i2s_register_clock_provider(struct platform_device *pdev)
 {
-       struct device *dev = &pdev->dev;
-       struct i2s_dai *i2s = dev_get_drvdata(dev);
+       const char * const i2s_clk_desc[] = { "cdclk", "rclk_src", "prescaler" };
        const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" };
        const char *p_names[2] = { NULL };
+       struct device *dev = &pdev->dev;
+       struct i2s_dai *i2s = dev_get_drvdata(dev);
        const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs;
+       const char *i2s_clk_name[ARRAY_SIZE(i2s_clk_desc)];
        struct clk *rclksrc;
        int ret, i;
 
@@ -1205,30 +1216,38 @@ static int i2s_register_clock_provider(struct platform_device *pdev)
                clk_put(rclksrc);
        }
 
+       for (i = 0; i < ARRAY_SIZE(i2s_clk_desc); i++) {
+               i2s_clk_name[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%s",
+                                               dev_name(dev), i2s_clk_desc[i]);
+               if (!i2s_clk_name[i])
+                       return -ENOMEM;
+       }
+
        if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
                /* Activate the prescaler */
                u32 val = readl(i2s->addr + I2SPSR);
                writel(val | PSR_PSREN, i2s->addr + I2SPSR);
 
                i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
-                               "i2s_rclksrc", p_names, ARRAY_SIZE(p_names),
+                               i2s_clk_name[CLK_I2S_RCLK_SRC], p_names,
+                               ARRAY_SIZE(p_names),
                                CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
                                i2s->addr + I2SMOD, reg_info->rclksrc_off,
                                1, 0, i2s->lock);
 
                i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
-                               "i2s_presc", "i2s_rclksrc",
+                               i2s_clk_name[CLK_I2S_RCLK_PSR],
+                               i2s_clk_name[CLK_I2S_RCLK_SRC],
                                CLK_SET_RATE_PARENT,
                                i2s->addr + I2SPSR, 8, 6, 0, i2s->lock);
 
-               p_names[0] = "i2s_presc";
+               p_names[0] = i2s_clk_name[CLK_I2S_RCLK_PSR];
                i2s->clk_data.clk_num = 2;
        }
-       of_property_read_string_index(dev->of_node,
-                               "clock-output-names", 0, &clk_name[0]);
 
-       i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev, clk_name[0],
-                               p_names[0], CLK_SET_RATE_PARENT,
+       i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
+                               i2s_clk_name[CLK_I2S_CDCLK], p_names[0],
+                               CLK_SET_RATE_PARENT,
                                i2s->addr + I2SMOD, reg_info->cdclkcon_off,
                                CLK_GATE_SET_TO_DISABLE, i2s->lock);
 
@@ -1385,9 +1404,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
 
        ret = i2s_register_clock_provider(pdev);
-       if (!ret)
-               return 0;
+       if (ret < 0)
+               goto err_disable_pm;
+
+       pri_dai->op_clk = clk_get_parent(pri_dai->clk_table[CLK_I2S_RCLK_SRC]);
+
+       return 0;
 
+err_disable_pm:
        pm_runtime_disable(&pdev->dev);
 err_disable_clk:
        clk_disable_unprepare(pri_dai->clk);
index 79781de2f24713ebee04545a07619b653f4f551d..a9832a9555cbc3f43ceb931f2332419cca6f28f9 100644 (file)
 #define SAMSUNG_I2S_DAI        "samsung-i2s"
 #define SAMSUNG_I2S_DAI_SEC    "samsung-i2s-sec"
 
-#define SAMSUNG_I2S_DIV_BCLK   1
+#define SAMSUNG_I2S_DIV_BCLK           1
 
-#define SAMSUNG_I2S_RCLKSRC_0  0
-#define SAMSUNG_I2S_RCLKSRC_1  1
+#define SAMSUNG_I2S_RCLKSRC_0          0
+#define SAMSUNG_I2S_RCLKSRC_1          1
 #define SAMSUNG_I2S_CDCLK              2
+/* Operation clock for IIS logic */
 #define SAMSUNG_I2S_OPCLK              3
+#define  SAMSUNG_I2S_OPCLK_CDCLK_OUT   0       /* CODEC clock out */
+#define  SAMSUNG_I2S_OPCLK_CDCLK_IN    1       /* CODEC clock in */
+#define  SAMSUNG_I2S_OPCLK_BCLK_OUT    2       /* Bit clock out */
+#define  SAMSUNG_I2S_OPCLK_PCLK                3       /* Audio bus clock */
 
 #endif /* __SND_SOC_SAMSUNG_I2S_H */
index a635df61f928c7f1164206754a937fa79010dc60..b1f09b942410d849a7c80e8cb24d54c6412d2818 100644 (file)
@@ -399,7 +399,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr)
 }
 EXPORT_SYMBOL_GPL(idma_reg_addr_init);
 
-static const struct snd_soc_platform_driver asoc_idma_platform = {
+static const struct snd_soc_component_driver asoc_idma_platform = {
        .ops = &idma_ops,
        .pcm_new = idma_new,
        .pcm_free = idma_free,
@@ -411,7 +411,8 @@ static int asoc_idma_platform_probe(struct platform_device *pdev)
        if (idma_irq < 0)
                return idma_irq;
 
-       return devm_snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
+       return devm_snd_soc_register_component(&pdev->dev, &asoc_idma_platform,
+                                              NULL, 0);
 }
 
 static struct platform_driver asoc_idma_driver = {
index 0d0f58208b756f0e89c9f3cdcd6179760c244209..c9081f42f37339a824827712463c7b43b34b6467 100644 (file)
@@ -37,10 +37,10 @@ static struct snd_soc_jack_pin lowland_headset_pins[] = {
 
 static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        int ret;
 
-       ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_SYSCLK,
+       ret = snd_soc_component_set_sysclk(component, WM5100_CLK_SYSCLK,
                                       WM5100_CLKSRC_MCLK1, MCLK1_RATE,
                                       SND_SOC_CLOCK_IN);
        if (ret < 0) {
@@ -49,7 +49,7 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
        }
 
        /* Clock OPCLK, used by the other audio components. */
-       ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_OPCLK, 0,
+       ret = snd_soc_component_set_sysclk(component, WM5100_CLK_OPCLK, 0,
                                       CLKOUT_RATE, 0);
        if (ret < 0) {
                pr_err("Failed to set OPCLK rate: %d\n", ret);
@@ -63,19 +63,19 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
        if (ret)
                return ret;
 
-       wm5100_detect(codec, &lowland_headset);
+       wm5100_detect(component, &lowland_headset);
 
        return 0;
 }
 
 static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
 
        snd_soc_dapm_nc_pin(&rtd->card->dapm, "LINEOUT");
 
        /* At any time the WM9081 is active it will have this clock */
-       return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
+       return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0,
                                        CLKOUT_RATE, 0);
 }
 
index 44b6de5a331aeb0e9b21b4c67697baff3b0f31d7..e7b371b0723048cf87c82ab8e18328a98e6c932e 100644 (file)
@@ -36,23 +36,24 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-       unsigned int pll_freq, rclk_freq;
+       unsigned int pll_freq, rclk_freq, rfs;
        int ret;
 
        switch (params_rate(params)) {
-       case 32000:
        case 64000:
-               pll_freq = 131072006U;
+               pll_freq = 196608001U;
+               rfs = 384;
                break;
        case 44100:
        case 88200:
-       case 176400:
                pll_freq = 180633609U;
+               rfs = 512;
                break;
+       case 32000:
        case 48000:
        case 96000:
-       case 192000:
                pll_freq = 196608001U;
+               rfs = 512;
                break;
        default:
                return -EINVAL;
@@ -67,7 +68,7 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
         *  frequency values due to the EPLL output frequency not being exact
         *  multiple of the audio sampling rate.
         */
-       rclk_freq = params_rate(params) * 256 + 1;
+       rclk_freq = params_rate(params) * rfs + 1;
 
        ret = clk_set_rate(priv->sclk_i2s, rclk_freq);
        if (ret < 0)
@@ -90,18 +91,6 @@ static const struct snd_soc_ops odroid_card_ops = {
        .hw_params = odroid_card_hw_params,
 };
 
-static void odroid_put_codec_of_nodes(struct snd_soc_dai_link *link)
-{
-       struct snd_soc_dai_link_component *component = link->codecs;
-       int i;
-
-       for (i = 0; i < link->num_codecs; i++, component++) {
-               if (!component->of_node)
-                       break;
-               of_node_put(component->of_node);
-       }
-}
-
 static int odroid_audio_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -196,7 +185,7 @@ err_put_sclk:
 err_put_i2s_n:
        of_node_put(link->cpu_of_node);
 err_put_codec_n:
-       odroid_put_codec_of_nodes(link);
+       snd_soc_of_put_dai_link_codecs(link);
        return ret;
 }
 
@@ -205,7 +194,7 @@ static int odroid_audio_remove(struct platform_device *pdev)
        struct odroid_priv *priv = platform_get_drvdata(pdev);
 
        of_node_put(priv->dai_link.cpu_of_node);
-       odroid_put_codec_of_nodes(&priv->dai_link);
+       snd_soc_of_put_dai_link_codecs(&priv->dai_link);
        clk_put(priv->sclk_i2s);
        clk_put(priv->clk_i2s_bus);
 
@@ -213,8 +202,10 @@ static int odroid_audio_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id odroid_audio_of_match[] = {
+       { .compatible   = "hardkernel,odroid-xu3-audio" },
+       { .compatible   = "hardkernel,odroid-xu4-audio" },
        { .compatible   = "samsung,odroid-xu3-audio" },
-       { .compatible   = "samsung,odroid-xu4-audio"},
+       { .compatible   = "samsung,odroid-xu4-audio" },
        { },
 };
 MODULE_DEVICE_TABLE(of, odroid_audio_of_match);
index d8ac907bbb0d76c2df3ca9900b1ae05b1140faa2..5d8efc2d5c38175fc1fdb8018bc69837894dd420 100644 (file)
  * General Public License for more details.
  */
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-
+#include <sound/pcm_params.h>
 #include <sound/soc.h>
 
 #include "i2s.h"
 
 #define FIN_PLL_RATE           24000000
 
-static struct snd_soc_dai_link snow_dai[] = {
-       {
-               .name = "Primary",
-               .stream_name = "Primary",
-               .codec_dai_name = "HiFi",
-               .dai_fmt = SND_SOC_DAIFMT_I2S |
-                               SND_SOC_DAIFMT_NB_NF |
-                               SND_SOC_DAIFMT_CBS_CFS,
-       },
+struct snow_priv {
+       struct snd_soc_dai_link dai_link;
+       struct clk *clk_i2s_bus;
+};
+
+static int snow_card_hw_params(struct snd_pcm_substream *substream,
+                                     struct snd_pcm_hw_params *params)
+{
+       static const unsigned int pll_rate[] = {
+               73728000U, 67737602U, 49152000U, 45158401U, 32768001U
+       };
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snow_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+       int bfs, psr, rfs, bitwidth;
+       unsigned long int rclk;
+       long int freq = -EINVAL;
+       int ret, i;
+
+       bitwidth = snd_pcm_format_width(params_format(params));
+       if (bitwidth < 0) {
+               dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
+               return bitwidth;
+       }
+
+       if (bitwidth != 16 && bitwidth != 24) {
+               dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", bitwidth);
+               return -EINVAL;
+       }
+
+       bfs = 2 * bitwidth;
+
+       switch (params_rate(params)) {
+       case 16000:
+       case 22050:
+       case 24000:
+       case 32000:
+       case 44100:
+       case 48000:
+       case 88200:
+       case 96000:
+               rfs = 8 * bfs;
+               break;
+       case 64000:
+               rfs = 384;
+               break;
+       case 8000:
+       case 11025:
+       case 12000:
+               rfs = 16 * bfs;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       rclk = params_rate(params) * rfs;
+
+       for (psr = 8; psr > 0; psr /= 2) {
+               for (i = 0; i < ARRAY_SIZE(pll_rate); i++) {
+                       if ((pll_rate[i] - rclk * psr) <= 2) {
+                               freq = pll_rate[i];
+                               break;
+                       }
+               }
+       }
+       if (freq < 0) {
+               dev_err(rtd->card->dev, "Unsupported RCLK rate: %lu\n", rclk);
+               return -EINVAL;
+       }
+
+       ret = clk_set_rate(priv->clk_i2s_bus, freq);
+       if (ret < 0) {
+               dev_err(rtd->card->dev, "I2S bus clock rate set failed\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static const struct snd_soc_ops snow_card_ops = {
+       .hw_params = snow_card_hw_params,
 };
 
 static int snow_late_probe(struct snd_soc_card *card)
 {
        struct snd_soc_pcm_runtime *rtd;
        struct snd_soc_dai *codec_dai;
-       struct snd_soc_dai *cpu_dai;
-       int ret;
 
        rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
-       codec_dai = rtd->codec_dai;
-       cpu_dai = rtd->cpu_dai;
 
-       /* Set the MCLK rate for the codec */
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0,
-                                       FIN_PLL_RATE, SND_SOC_CLOCK_IN);
-       if (ret < 0)
-               return ret;
+       /* In the multi-codec case codec_dais 0 is MAX98095 and 1 is HDMI. */
+       if (rtd->num_codecs > 1)
+               codec_dai = rtd->codec_dais[0];
+       else
+               codec_dai = rtd->codec_dai;
 
-       /* Select I2S Bus clock to set RCLK and BCLK */
-       ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
-                                       0, SND_SOC_CLOCK_IN);
-       if (ret < 0)
-               return ret;
-
-       return 0;
+       /* Set the MCLK rate for the codec */
+       return snd_soc_dai_set_sysclk(codec_dai, 0,
+                               FIN_PLL_RATE, SND_SOC_CLOCK_IN);
 }
 
 static struct snd_soc_card snow_snd = {
        .name = "Snow-I2S",
        .owner = THIS_MODULE,
-       .dai_link = snow_dai,
-       .num_links = ARRAY_SIZE(snow_dai),
-
        .late_probe = snow_late_probe,
 };
 
 static int snow_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct snd_soc_card *card = &snow_snd;
-       struct device_node *i2s_node, *codec_node;
-       int i, ret;
-
-       i2s_node = of_parse_phandle(pdev->dev.of_node,
-                                   "samsung,i2s-controller", 0);
-       if (!i2s_node) {
-               dev_err(&pdev->dev,
-                       "Property 'i2s-controller' missing or invalid\n");
-               return -EINVAL;
-       }
+       struct device_node *cpu, *codec;
+       struct snd_soc_dai_link *link;
+       struct snow_priv *priv;
+       int ret;
 
-       codec_node = of_parse_phandle(pdev->dev.of_node,
-                                     "samsung,audio-codec", 0);
-       if (!codec_node) {
-               dev_err(&pdev->dev,
-                       "Property 'audio-codec' missing or invalid\n");
-               return -EINVAL;
-       }
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       link = &priv->dai_link;
+
+       link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS;
+
+       link->name = "Primary";
+       link->stream_name = link->name;
+
+       card->dai_link = link;
+       card->num_links = 1;
+       card->dev = dev;
+
+       /* Try new DT bindings with HDMI support first. */
+       cpu = of_get_child_by_name(dev->of_node, "cpu");
+
+       if (cpu) {
+               link->ops = &snow_card_ops;
 
-       for (i = 0; i < ARRAY_SIZE(snow_dai); i++) {
-               snow_dai[i].codec_of_node = codec_node;
-               snow_dai[i].cpu_of_node = i2s_node;
-               snow_dai[i].platform_of_node = i2s_node;
+               link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
+               of_node_put(cpu);
+
+               if (!link->cpu_of_node) {
+                       dev_err(dev, "Failed parsing cpu/sound-dai property\n");
+                       return -EINVAL;
+               }
+
+               codec = of_get_child_by_name(dev->of_node, "codec");
+               ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
+               of_node_put(codec);
+
+               if (ret < 0) {
+                       of_node_put(link->cpu_of_node);
+                       dev_err(dev, "Failed parsing codec node\n");
+                       return ret;
+               }
+
+               priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node,
+                                                      "i2s_opclk0");
+               if (IS_ERR(priv->clk_i2s_bus)) {
+                       snd_soc_of_put_dai_link_codecs(link);
+                       of_node_put(link->cpu_of_node);
+                       return PTR_ERR(priv->clk_i2s_bus);
+               }
+       } else {
+               link->codec_dai_name = "HiFi",
+
+               link->cpu_of_node = of_parse_phandle(dev->of_node,
+                                               "samsung,i2s-controller", 0);
+               if (!link->cpu_of_node) {
+                       dev_err(dev, "i2s-controller property parse error\n");
+                       return -EINVAL;
+               }
+
+               link->codec_of_node = of_parse_phandle(dev->of_node,
+                                               "samsung,audio-codec", 0);
+               if (!link->codec_of_node) {
+                       of_node_put(link->cpu_of_node);
+                       dev_err(dev, "audio-codec property parse error\n");
+                       return -EINVAL;
+               }
        }
 
-       card->dev = &pdev->dev;
+       link->platform_of_node = link->cpu_of_node;
 
        /* Update card-name if provided through DT, else use default name */
        snd_soc_of_parse_card_name(card, "samsung,model");
 
-       ret = devm_snd_soc_register_card(&pdev->dev, card);
+       snd_soc_card_set_drvdata(card, priv);
+
+       ret = devm_snd_soc_register_card(dev, card);
        if (ret) {
                dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
                return ret;
@@ -110,6 +220,20 @@ static int snow_probe(struct platform_device *pdev)
        return ret;
 }
 
+static int snow_remove(struct platform_device *pdev)
+{
+       struct snow_priv *priv = platform_get_drvdata(pdev);
+       struct snd_soc_dai_link *link = &priv->dai_link;
+
+       of_node_put(link->cpu_of_node);
+       of_node_put(link->codec_of_node);
+       snd_soc_of_put_dai_link_codecs(link);
+
+       clk_put(priv->clk_i2s_bus);
+
+       return 0;
+}
+
 static const struct of_device_id snow_of_match[] = {
        { .compatible = "google,snow-audio-max98090", },
        { .compatible = "google,snow-audio-max98091", },
@@ -125,6 +249,7 @@ static struct platform_driver snow_driver = {
                .of_match_table = snow_of_match,
        },
        .probe = snow_probe,
+       .remove = snow_remove,
 };
 
 module_platform_driver(snow_driver);
index a55d18703fe7319df96608f0f4ce671104d6cd1c..43332c32d7e9b482e2e83be34cbd27e0d74a70e2 100644 (file)
@@ -31,7 +31,7 @@
 #define TM2_DAI_AIF2   1
 
 struct tm2_machine_priv {
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
        unsigned int sysclk_rate;
        struct gpio_desc *gpio_mic_bias;
 };
@@ -39,33 +39,33 @@ struct tm2_machine_priv {
 static int tm2_start_sysclk(struct snd_soc_card *card)
 {
        struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
-       struct snd_soc_codec *codec = priv->codec;
+       struct snd_soc_component *component = priv->component;
        int ret;
 
-       ret = snd_soc_codec_set_pll(codec, WM5110_FLL1_REFCLK,
+       ret = snd_soc_component_set_pll(component, WM5110_FLL1_REFCLK,
                                    ARIZONA_FLL_SRC_MCLK1,
                                    MCLK_RATE,
                                    priv->sysclk_rate);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set FLL1 source: %d\n", ret);
+               dev_err(component->dev, "Failed to set FLL1 source: %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_codec_set_pll(codec, WM5110_FLL1,
+       ret = snd_soc_component_set_pll(component, WM5110_FLL1,
                                    ARIZONA_FLL_SRC_MCLK1,
                                    MCLK_RATE,
                                    priv->sysclk_rate);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to start FLL1: %d\n", ret);
+               dev_err(component->dev, "Failed to start FLL1: %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+       ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK,
                                       ARIZONA_CLK_SRC_FLL1,
                                       priv->sysclk_rate,
                                       SND_SOC_CLOCK_IN);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set SYSCLK source: %d\n", ret);
+               dev_err(component->dev, "Failed to set SYSCLK source: %d\n", ret);
                return ret;
        }
 
@@ -75,19 +75,19 @@ static int tm2_start_sysclk(struct snd_soc_card *card)
 static int tm2_stop_sysclk(struct snd_soc_card *card)
 {
        struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
-       struct snd_soc_codec *codec = priv->codec;
+       struct snd_soc_component *component = priv->component;
        int ret;
 
-       ret = snd_soc_codec_set_pll(codec, WM5110_FLL1, 0, 0, 0);
+       ret = snd_soc_component_set_pll(component, WM5110_FLL1, 0, 0, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to stop FLL1: %d\n", ret);
+               dev_err(component->dev, "Failed to stop FLL1: %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+       ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK,
                                       ARIZONA_CLK_SRC_FLL1, 0, 0);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to stop SYSCLK: %d\n", ret);
+               dev_err(component->dev, "Failed to stop SYSCLK: %d\n", ret);
                return ret;
        }
 
@@ -98,7 +98,7 @@ static int tm2_aif1_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 
        switch (params_rate(params)) {
@@ -123,7 +123,7 @@ static int tm2_aif1_hw_params(struct snd_pcm_substream *substream,
                priv->sysclk_rate = 135475200U;
                break;
        default:
-               dev_err(codec->dev, "Not supported sample rate: %d\n",
+               dev_err(component->dev, "Not supported sample rate: %d\n",
                        params_rate(params));
                return -EINVAL;
        }
@@ -139,7 +139,7 @@ static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        unsigned int asyncclk_rate;
        int ret;
 
@@ -155,35 +155,35 @@ static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
                asyncclk_rate = 45158400U;
                break;
        default:
-               dev_err(codec->dev, "Not supported sample rate: %d\n",
+               dev_err(component->dev, "Not supported sample rate: %d\n",
                        params_rate(params));
                return -EINVAL;
        }
 
-       ret = snd_soc_codec_set_pll(codec, WM5110_FLL2_REFCLK,
+       ret = snd_soc_component_set_pll(component, WM5110_FLL2_REFCLK,
                                    ARIZONA_FLL_SRC_MCLK1,
                                    MCLK_RATE,
                                    asyncclk_rate);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set FLL2 source: %d\n", ret);
+               dev_err(component->dev, "Failed to set FLL2 source: %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_codec_set_pll(codec, WM5110_FLL2,
+       ret = snd_soc_component_set_pll(component, WM5110_FLL2,
                                    ARIZONA_FLL_SRC_MCLK1,
                                    MCLK_RATE,
                                    asyncclk_rate);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to start FLL2: %d\n", ret);
+               dev_err(component->dev, "Failed to start FLL2: %d\n", ret);
                return ret;
        }
 
-       ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
+       ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_ASYNCCLK,
                                       ARIZONA_CLK_SRC_FLL2,
                                       asyncclk_rate,
                                       SND_SOC_CLOCK_IN);
        if (ret < 0) {
-               dev_err(codec->dev, "Failed to set ASYNCCLK source: %d\n", ret);
+               dev_err(component->dev, "Failed to set ASYNCCLK source: %d\n", ret);
                return ret;
        }
 
@@ -193,14 +193,14 @@ static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
 static int tm2_aif2_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_component *component = rtd->codec_dai->component;
        int ret;
 
        /* disable FLL2 */
-       ret = snd_soc_codec_set_pll(codec, WM5110_FLL2, ARIZONA_FLL_SRC_MCLK1,
+       ret = snd_soc_component_set_pll(component, WM5110_FLL2, ARIZONA_FLL_SRC_MCLK1,
                                    0, 0);
        if (ret < 0)
-               dev_err(codec->dev, "Failed to stop FLL2: %d\n", ret);
+               dev_err(component->dev, "Failed to stop FLL2: %d\n", ret);
 
        return ret;
 }
@@ -210,6 +210,59 @@ static struct snd_soc_ops tm2_aif2_ops = {
        .hw_free = tm2_aif2_hw_free,
 };
 
+static int tm2_hdmi_hw_params(struct snd_pcm_substream *substream,
+                             struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       unsigned int bfs;
+       int bitwidth, ret;
+
+       bitwidth = snd_pcm_format_width(params_format(params));
+       if (bitwidth < 0) {
+               dev_err(rtd->card->dev, "Invalid bit-width: %d\n", bitwidth);
+               return bitwidth;
+       }
+
+       switch (bitwidth) {
+       case 48:
+               bfs = 64;
+               break;
+       case 16:
+               bfs = 32;
+               break;
+       default:
+               dev_err(rtd->card->dev, "Unsupported bit-width: %d\n", bitwidth);
+               return -EINVAL;
+       }
+
+       switch (params_rate(params)) {
+       case 48000:
+       case 96000:
+       case 192000:
+               break;
+       default:
+               dev_err(rtd->card->dev, "Unsupported sample rate: %d\n",
+                       params_rate(params));
+               return -EINVAL;
+       }
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK,
+                                       0, SAMSUNG_I2S_OPCLK_PCLK);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_ops tm2_hdmi_ops = {
+       .hw_params = tm2_hdmi_hw_params,
+};
+
 static int tm2_mic_bias(struct snd_soc_dapm_widget *w,
                                struct snd_kcontrol *kcontrol, int event)
 {
@@ -269,7 +322,7 @@ static int tm2_late_probe(struct snd_soc_card *card)
 
        rtd = snd_soc_get_pcm_runtime(card, card->dai_link[TM2_DAI_AIF1].name);
        aif1_dai = rtd->codec_dai;
-       priv->codec = rtd->codec;
+       priv->component = rtd->codec_dai->component;
 
        ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
        if (ret < 0) {
@@ -405,6 +458,12 @@ static struct snd_soc_dai_link tm2_dai_links[] = {
                .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
                                  SND_SOC_DAIFMT_CBM_CFM,
                .ignore_suspend = 1,
+       }, {
+               .name           = "HDMI",
+               .stream_name    = "i2s1",
+               .ops            = &tm2_hdmi_ops,
+               .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBS_CFS,
        }
 };
 
@@ -412,7 +471,6 @@ static struct snd_soc_card tm2_card = {
        .owner                  = THIS_MODULE,
 
        .dai_link               = tm2_dai_links,
-       .num_links              = ARRAY_SIZE(tm2_dai_links),
        .controls               = tm2_controls,
        .num_controls           = ARRAY_SIZE(tm2_controls),
        .dapm_widgets           = tm2_dapm_widgets,
@@ -426,11 +484,14 @@ static struct snd_soc_card tm2_card = {
 
 static int tm2_probe(struct platform_device *pdev)
 {
+       struct device_node *cpu_dai_node[2] = {};
+       struct device_node *codec_dai_node[2] = {};
+       const char *cells_name = NULL;
        struct device *dev = &pdev->dev;
        struct snd_soc_card *card = &tm2_card;
        struct tm2_machine_priv *priv;
-       struct device_node *cpu_dai_node, *codec_dai_node;
-       int ret, i;
+       struct of_phandle_args args;
+       int num_codecs, ret, i;
 
        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -464,47 +525,92 @@ static int tm2_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       cpu_dai_node = of_parse_phandle(dev->of_node, "i2s-controller", 0);
-       if (!cpu_dai_node) {
-               dev_err(dev, "i2s-controllers property invalid or missing\n");
-               ret = -EINVAL;
-               goto amp_node_put;
+       num_codecs = of_count_phandle_with_args(dev->of_node, "audio-codec",
+                                                NULL);
+
+       /* Skip the HDMI link if not specified in DT */
+       if (num_codecs > 1) {
+               card->num_links = ARRAY_SIZE(tm2_dai_links);
+               cells_name = "#sound-dai-cells";
+       } else {
+               card->num_links = ARRAY_SIZE(tm2_dai_links) - 1;
        }
 
-       codec_dai_node = of_parse_phandle(dev->of_node, "audio-codec", 0);
-       if (!codec_dai_node) {
-               dev_err(dev, "audio-codec property invalid or missing\n");
-               ret = -EINVAL;
-               goto cpu_dai_node_put;
+       for (i = 0; i < num_codecs; i++) {
+               struct of_phandle_args args;
+
+               ret = of_parse_phandle_with_args(dev->of_node, "i2s-controller",
+                                                cells_name, i, &args);
+               if (!args.np) {
+                       dev_err(dev, "i2s-controller property parse error: %d\n", i);
+                       ret = -EINVAL;
+                       goto dai_node_put;
+               }
+               cpu_dai_node[i] = args.np;
+
+               codec_dai_node[i] = of_parse_phandle(dev->of_node,
+                                                    "audio-codec", i);
+               if (!codec_dai_node[i]) {
+                       dev_err(dev, "audio-codec property parse error\n");
+                       ret = -EINVAL;
+                       goto dai_node_put;
+               }
        }
 
+       /* Initialize WM5110 - I2S and HDMI - I2S1 DAI links */
        for (i = 0; i < card->num_links; i++) {
+               unsigned int dai_index = 0; /* WM5110 */
+
                card->dai_link[i].cpu_name = NULL;
                card->dai_link[i].platform_name = NULL;
-               card->dai_link[i].codec_of_node = codec_dai_node;
-               card->dai_link[i].cpu_of_node = cpu_dai_node;
-               card->dai_link[i].platform_of_node = cpu_dai_node;
+
+               if (num_codecs > 1 && i == card->num_links - 1)
+                       dai_index = 1; /* HDMI */
+
+               card->dai_link[i].codec_of_node = codec_dai_node[dai_index];
+               card->dai_link[i].cpu_of_node = cpu_dai_node[dai_index];
+               card->dai_link[i].platform_of_node = cpu_dai_node[dai_index];
+       }
+
+       if (num_codecs > 1) {
+               /* HDMI DAI link (I2S1) */
+               i = card->num_links - 1;
+
+               ret = of_parse_phandle_with_fixed_args(dev->of_node,
+                                               "audio-codec", 0, 1, &args);
+               if (ret) {
+                       dev_err(dev, "audio-codec property parse error\n");
+                       goto dai_node_put;
+               }
+
+               ret = snd_soc_get_dai_name(&args, &card->dai_link[i].codec_dai_name);
+               if (ret) {
+                       dev_err(dev, "Unable to get codec_dai_name\n");
+                       goto dai_node_put;
+               }
        }
 
        ret = devm_snd_soc_register_component(dev, &tm2_component,
                                tm2_ext_dai, ARRAY_SIZE(tm2_ext_dai));
        if (ret < 0) {
                dev_err(dev, "Failed to register component: %d\n", ret);
-               goto codec_dai_node_put;
+               goto dai_node_put;
        }
 
        ret = devm_snd_soc_register_card(dev, card);
        if (ret < 0) {
                dev_err(dev, "Failed to register card: %d\n", ret);
-               goto codec_dai_node_put;
+               goto dai_node_put;
+       }
+
+dai_node_put:
+       for (i = 0; i < num_codecs; i++) {
+               of_node_put(codec_dai_node[i]);
+               of_node_put(cpu_dai_node[i]);
        }
 
-codec_dai_node_put:
-       of_node_put(codec_dai_node);
-cpu_dai_node_put:
-       of_node_put(cpu_dai_node);
-amp_node_put:
        of_node_put(card->aux_dev[0].codec_of_node);
+
        return ret;
 }
 
index 1e7d417b53ef22a199c6c0d78f9bcad281e8eb19..2dc3b762fdd9cab938ececae2088a187031543cc 100644 (file)
@@ -320,14 +320,15 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
-static const struct snd_soc_platform_driver sh7760_soc_platform = {
+static const struct snd_soc_component_driver sh7760_soc_component = {
        .ops            = &camelot_pcm_ops,
        .pcm_new        = camelot_pcm_new,
 };
 
 static int sh7760_soc_platform_probe(struct platform_device *pdev)
 {
-       return devm_snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev, &sh7760_soc_component,
+                                              NULL, 0);
 }
 
 static struct platform_driver sh7760_pcm_driver = {
index c3aaf4788557c4e14503d70f7b80ffe7d9a5c859..3bae06dd121f6c78cc61bd6c3cf2cf1ebdf2189d 100644 (file)
@@ -1764,7 +1764,7 @@ static const struct snd_pcm_ops fsi_pcm_ops = {
 };
 
 /*
- *             snd_soc_platform
+ *             snd_soc_component
  */
 
 #define PREALLOC_BUFFER                (32 * 1024)
@@ -1818,13 +1818,10 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = {
        },
 };
 
-static const struct snd_soc_platform_driver fsi_soc_platform = {
-       .ops            = &fsi_pcm_ops,
-       .pcm_new        = fsi_pcm_new,
-};
-
 static const struct snd_soc_component_driver fsi_soc_component = {
        .name           = "fsi",
+       .ops            = &fsi_pcm_ops,
+       .pcm_new        = fsi_pcm_new,
 };
 
 /*
@@ -2007,23 +2004,15 @@ static int fsi_probe(struct platform_device *pdev)
                goto exit_fsib;
        }
 
-       ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "cannot snd soc register\n");
-               goto exit_fsib;
-       }
-
-       ret = snd_soc_register_component(&pdev->dev, &fsi_soc_component,
+       ret = devm_snd_soc_register_component(&pdev->dev, &fsi_soc_component,
                                    fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
        if (ret < 0) {
                dev_err(&pdev->dev, "cannot snd component register\n");
-               goto exit_snd_soc;
+               goto exit_fsib;
        }
 
        return ret;
 
-exit_snd_soc:
-       snd_soc_unregister_platform(&pdev->dev);
 exit_fsib:
        pm_runtime_disable(&pdev->dev);
        fsi_stream_remove(&master->fsib);
@@ -2041,9 +2030,6 @@ static int fsi_remove(struct platform_device *pdev)
 
        pm_runtime_disable(&pdev->dev);
 
-       snd_soc_unregister_component(&pdev->dev);
-       snd_soc_unregister_platform(&pdev->dev);
-
        fsi_stream_remove(&master->fsia);
        fsi_stream_remove(&master->fsib);
 
index 64d5ecb865283f73c344494d0595abd25d200d1c..6a76688a8ba953d5b8f373e6a382c8437ec7bfa6 100644 (file)
  *  [mod]->fn() -> [mod]->fn() -> [mod]->fn()...
  *
  */
+
+/*
+ * you can enable below define if you don't need
+ * DAI status debug message when debugging
+ * see rsnd_dbg_dai_call()
+ *
+ * #define RSND_DEBUG_NO_DAI_CALL 1
+ */
+
 #include <linux/pm_runtime.h>
 #include "rsnd.h"
 
@@ -468,7 +477,7 @@ static int rsnd_status_update(u32 *status,
                                                __rsnd_mod_shift_##fn,  \
                                                __rsnd_mod_add_##fn,    \
                                                __rsnd_mod_call_##fn);  \
-               dev_dbg(dev, "%s[%d]\t0x%08x %s\n",                     \
+               rsnd_dbg_dai_call(dev, "%s[%d]\t0x%08x %s\n",           \
                        rsnd_mod_name(mod), rsnd_mod_id(mod), *status,  \
                        (func_call && (mod)->ops->fn) ? #fn : "");      \
                if (func_call && (mod)->ops->fn)                        \
@@ -1337,7 +1346,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
 }
 
 /*
- *             snd_soc_platform
+ *             snd_soc_component
  */
 
 #define PREALLOC_BUFFER                (32 * 1024)
@@ -1364,12 +1373,9 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
                PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
 }
 
-static const struct snd_soc_platform_driver rsnd_soc_platform = {
+static const struct snd_soc_component_driver rsnd_soc_component = {
        .ops            = &rsnd_pcm_ops,
        .pcm_new        = rsnd_pcm_new,
-};
-
-static const struct snd_soc_component_driver rsnd_soc_component = {
        .name           = "rsnd",
 };
 
@@ -1478,17 +1484,11 @@ static int rsnd_probe(struct platform_device *pdev)
        /*
         *      asoc register
         */
-       ret = snd_soc_register_platform(dev, &rsnd_soc_platform);
-       if (ret < 0) {
-               dev_err(dev, "cannot snd soc register\n");
-               return ret;
-       }
-
-       ret = snd_soc_register_component(dev, &rsnd_soc_component,
+       ret = devm_snd_soc_register_component(dev, &rsnd_soc_component,
                                         priv->daidrv, rsnd_rdai_nr(priv));
        if (ret < 0) {
                dev_err(dev, "cannot snd dai register\n");
-               goto exit_snd_soc;
+               goto exit_snd_probe;
        }
 
        pm_runtime_enable(dev);
@@ -1496,8 +1496,6 @@ static int rsnd_probe(struct platform_device *pdev)
        dev_info(dev, "probed\n");
        return ret;
 
-exit_snd_soc:
-       snd_soc_unregister_platform(dev);
 exit_snd_probe:
        for_each_rsnd_dai(rdai, priv, i) {
                rsnd_dai_call(remove, &rdai->playback, priv);
@@ -1535,9 +1533,6 @@ static int rsnd_remove(struct platform_device *pdev)
        for (i = 0; i < ARRAY_SIZE(remove_func); i++)
                remove_func[i](priv);
 
-       snd_soc_unregister_component(&pdev->dev);
-       snd_soc_unregister_platform(&pdev->dev);
-
        return ret;
 }
 
@@ -1560,8 +1555,7 @@ static int rsnd_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops rsnd_pm_ops = {
-       .suspend                = rsnd_suspend,
-       .resume                 = rsnd_resume,
+       SET_SYSTEM_SLEEP_PM_OPS(rsnd_suspend, rsnd_resume)
 };
 
 static struct platform_driver rsnd_driver = {
index ad6523595b0acdd0f3c3a7932b5ae535e9eb4cab..172c8d612890e28237942e8c13f4f8ab0d58c59f 100644 (file)
@@ -788,4 +788,24 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
 #define rsnd_mod_confirm_dvc(mdvc)
 #endif
 
+/*
+ * If you don't need interrupt status debug message,
+ * define RSND_DEBUG_NO_IRQ_STATUS as 1 on top of src.c/ssi.c
+ *
+ * #define RSND_DEBUG_NO_IRQ_STATUS 1
+ */
+#define rsnd_dbg_irq_status(dev, param...)             \
+       if (!IS_BUILTIN(RSND_DEBUG_NO_IRQ_STATUS))      \
+               dev_dbg(dev, param)
+
+/*
+ * If you don't need rsnd_dai_call debug message,
+ * define RSND_DEBUG_NO_DAI_CALL as 1 on top of core.c
+ *
+ * #define RSND_DEBUG_NO_DAI_CALL 1
+ */
+#define rsnd_dbg_dai_call(dev, param...)               \
+       if (!IS_BUILTIN(RSND_DEBUG_NO_DAI_CALL))        \
+               dev_dbg(dev, param)
+
 #endif
index 510b68a483b4056ec9e211d651b3638e1dac9c84..a727e71587b6e305ff89011b1bce8dc2f5789bc8 100644 (file)
@@ -8,6 +8,15 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+/*
+ * you can enable below define if you don't need
+ * SSI interrupt status debug message when debugging
+ * see rsnd_dbg_irq_status()
+ *
+ * #define RSND_DEBUG_NO_IRQ_STATUS 1
+ */
+
 #include "rsnd.h"
 
 #define SRC_NAME "src"
@@ -325,7 +334,10 @@ static void rsnd_src_status_clear(struct rsnd_mod *mod)
 
 static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
 {
+       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+       struct device *dev = rsnd_priv_to_dev(priv);
        u32 val0, val1;
+       u32 status0, status1;
        bool ret = false;
 
        val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
@@ -338,9 +350,15 @@ static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
        if (rsnd_src_sync_is_enabled(mod))
                val0 = val0 & 0xffff;
 
-       if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) ||
-           (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1))
+       status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0);
+       status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1);
+       if ((status0 & val0) || (status1 & val1)) {
+               rsnd_dbg_irq_status(dev, "%s[%d] err status : 0x%08x, 0x%08x\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod),
+                       status0, status1);
+
                ret = true;
+       }
 
        return ret;
 }
index 97a9db892a8f06461be29eacceae01e8c40f8da9..333b802681ad7be5818754588bbc5011925e4391 100644 (file)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+/*
+ * you can enable below define if you don't need
+ * SSI interrupt status debug message when debugging
+ * see rsnd_dbg_irq_status()
+ *
+ * #define RSND_DEBUG_NO_IRQ_STATUS 1
+ */
+
 #include <sound/simple_card_utils.h>
 #include <linux/delay.h>
 #include "rsnd.h"
@@ -603,6 +612,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
                                 struct rsnd_dai_stream *io)
 {
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
+       struct device *dev = rsnd_priv_to_dev(priv);
        int is_dma = rsnd_ssi_is_dma_mode(mod);
        u32 status;
        bool elapsed = false;
@@ -621,8 +631,12 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
                elapsed = rsnd_ssi_pio_interrupt(mod, io);
 
        /* DMA only */
-       if (is_dma && (status & (UIRQ | OIRQ)))
+       if (is_dma && (status & (UIRQ | OIRQ))) {
+               rsnd_dbg_irq_status(dev, "%s[%d] err status : 0x%08x\n",
+                       rsnd_mod_name(mod), rsnd_mod_id(mod), status);
+
                stop = true;
+       }
 
        rsnd_ssi_status_clear(mod);
 rsnd_ssi_interrupt_out:
index 83c3430ad79706d9c4c68e4836902abc4ea389df..6088d627c0e4b3d000539ed4e4549b5a98292ed3 100644 (file)
@@ -183,7 +183,7 @@ static inline u32 siu_read32(u32 __iomem *addr)
 #define SIU_BRGBSEL    (0x108 / sizeof(u32))
 #define SIU_BRRB       (0x10c / sizeof(u32))
 
-extern struct snd_soc_platform_driver siu_platform;
+extern struct snd_soc_component_driver siu_component;
 extern struct siu_info *siu_i2s_data;
 
 int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
index 160502947da20b238364745e620a6bd5e2baf1f4..ee2211635e92199e2e280d8be516d7dee80af8dc 100644 (file)
@@ -727,10 +727,6 @@ static struct snd_soc_dai_driver siu_i2s_dai = {
        .ops = &siu_dai_ops,
 };
 
-static const struct snd_soc_component_driver siu_i2s_component = {
-       .name           = "siu-i2s",
-};
-
 static int siu_probe(struct platform_device *pdev)
 {
        const struct firmware *fw_entry;
@@ -786,15 +782,11 @@ static int siu_probe(struct platform_device *pdev)
        dev_set_drvdata(&pdev->dev, info);
 
        /* register using ARRAY version so we can keep dai name */
-       ret = devm_snd_soc_register_component(&pdev->dev, &siu_i2s_component,
+       ret = devm_snd_soc_register_component(&pdev->dev, &siu_component,
                                              &siu_i2s_dai, 1);
        if (ret < 0)
                return ret;
 
-       ret = devm_snd_soc_register_platform(&pdev->dev, &siu_platform);
-       if (ret < 0)
-               return ret;
-
        pm_runtime_enable(&pdev->dev);
 
        return 0;
index 3118cb0ee3f2ccfbeb3184546e9d16953ea04bf5..172909570ed518ff6d89f1ff4ec5148689180cae 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "siu.h"
 
+#define DRV_NAME "siu-i2s"
 #define GET_MAX_PERIODS(buf_bytes, period_bytes) \
                                ((buf_bytes) / (period_bytes))
 #define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \
@@ -340,7 +341,8 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
 {
        /* Playback / Capture */
        struct snd_soc_pcm_runtime *rtd = ss->private_data;
-       struct siu_platform *pdata = rtd->platform->dev->platform_data;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct siu_platform *pdata = component->dev->platform_data;
        struct siu_info *info = siu_i2s_data;
        struct siu_port *port_info = siu_port_info(ss);
        struct siu_stream *siu_stream;
@@ -604,9 +606,10 @@ static const struct snd_pcm_ops siu_pcm_ops = {
        .pointer        = siu_pcm_pointer_dma,
 };
 
-struct snd_soc_platform_driver siu_platform = {
+struct snd_soc_component_driver siu_component = {
+       .name           = DRV_NAME,
        .ops                    = &siu_pcm_ops,
        .pcm_new        = siu_pcm_new,
        .pcm_free       = siu_pcm_free,
 };
-EXPORT_SYMBOL_GPL(siu_platform);
+EXPORT_SYMBOL_GPL(siu_component);
index bf0201cb15bc88b80f2c1584bec117c59a8cc25f..e22e13a619e85956861127fb658ebcf2042c1248 100644 (file)
                                        USP_RX_IO_DMA_INT|\
                                        USP_RXFIFO_FULL_INT|\
                                        USP_RXFIFO_THD_INT|\
-                                       USP_RXFIFO_THD_INT|USP_RX_TIMEOUT_INT)
+                                       USP_RX_TIMEOUT_INT)
 
 #define USP_INT_ALL        0x1FFF
 
index 36dae41f65fc7669a4de5b5dcb332abfddb285fd..3f424f214bcaec9d9dcf752dc5c72155765a4132 100644 (file)
@@ -44,7 +44,7 @@ struct snd_ac97_gpio_priv {
        struct gpio_chip gpio_chip;
 #endif
        unsigned int gpios_set;
-       struct snd_soc_codec *codec;
+       struct snd_soc_component *component;
 };
 
 static struct snd_ac97_bus soc_ac97_bus = {
@@ -57,11 +57,11 @@ static void soc_ac97_device_release(struct device *dev)
 }
 
 #ifdef CONFIG_GPIOLIB
-static inline struct snd_soc_codec *gpio_to_codec(struct gpio_chip *chip)
+static inline struct snd_soc_component *gpio_to_component(struct gpio_chip *chip)
 {
        struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
 
-       return gpio_priv->codec;
+       return gpio_priv->component;
 }
 
 static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
@@ -75,20 +75,22 @@ static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
 static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip,
                                          unsigned offset)
 {
-       struct snd_soc_codec *codec = gpio_to_codec(chip);
+       struct snd_soc_component *component = gpio_to_component(chip);
 
-       dev_dbg(codec->dev, "set gpio %d to output\n", offset);
-       return snd_soc_update_bits(codec, AC97_GPIO_CFG,
+       dev_dbg(component->dev, "set gpio %d to output\n", offset);
+       return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
                                   1 << offset, 1 << offset);
 }
 
 static int snd_soc_ac97_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-       struct snd_soc_codec *codec = gpio_to_codec(chip);
+       struct snd_soc_component *component = gpio_to_component(chip);
        int ret;
 
-       ret = snd_soc_read(codec, AC97_GPIO_STATUS);
-       dev_dbg(codec->dev, "get gpio %d : %d\n", offset,
+       if (snd_soc_component_read(component, AC97_GPIO_STATUS, &ret) < 0)
+               ret = -1;
+
+       dev_dbg(component->dev, "get gpio %d : %d\n", offset,
                ret < 0 ? ret : ret & (1 << offset));
 
        return ret < 0 ? ret : !!(ret & (1 << offset));
@@ -98,22 +100,24 @@ static void snd_soc_ac97_gpio_set(struct gpio_chip *chip, unsigned offset,
                                  int value)
 {
        struct snd_ac97_gpio_priv *gpio_priv = gpiochip_get_data(chip);
-       struct snd_soc_codec *codec = gpio_to_codec(chip);
+       struct snd_soc_component *component = gpio_to_component(chip);
 
        gpio_priv->gpios_set &= ~(1 << offset);
        gpio_priv->gpios_set |= (!!value) << offset;
-       snd_soc_write(codec, AC97_GPIO_STATUS, gpio_priv->gpios_set);
-       dev_dbg(codec->dev, "set gpio %d to %d\n", offset, !!value);
+       snd_soc_component_write(component, AC97_GPIO_STATUS,
+                               gpio_priv->gpios_set);
+       dev_dbg(component->dev, "set gpio %d to %d\n", offset, !!value);
 }
 
 static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
                                     unsigned offset, int value)
 {
-       struct snd_soc_codec *codec = gpio_to_codec(chip);
+       struct snd_soc_component *component = gpio_to_component(chip);
 
-       dev_dbg(codec->dev, "set gpio %d to output\n", offset);
+       dev_dbg(component->dev, "set gpio %d to output\n", offset);
        snd_soc_ac97_gpio_set(chip, offset, value);
-       return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0);
+       return snd_soc_component_update_bits(component, AC97_GPIO_CFG,
+                                            1 << offset, 0);
 }
 
 static const struct gpio_chip snd_soc_ac97_gpio_chip = {
@@ -128,24 +132,24 @@ static const struct gpio_chip snd_soc_ac97_gpio_chip = {
 };
 
 static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
-                                 struct snd_soc_codec *codec)
+                                 struct snd_soc_component *component)
 {
        struct snd_ac97_gpio_priv *gpio_priv;
        int ret;
 
-       gpio_priv = devm_kzalloc(codec->dev, sizeof(*gpio_priv), GFP_KERNEL);
+       gpio_priv = devm_kzalloc(component->dev, sizeof(*gpio_priv), GFP_KERNEL);
        if (!gpio_priv)
                return -ENOMEM;
        ac97->gpio_priv = gpio_priv;
-       gpio_priv->codec = codec;
+       gpio_priv->component = component;
        gpio_priv->gpio_chip = snd_soc_ac97_gpio_chip;
        gpio_priv->gpio_chip.ngpio = AC97_NUM_GPIOS;
-       gpio_priv->gpio_chip.parent = codec->dev;
+       gpio_priv->gpio_chip.parent = component->dev;
        gpio_priv->gpio_chip.base = -1;
 
        ret = gpiochip_add_data(&gpio_priv->gpio_chip, gpio_priv);
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+               dev_err(component->dev, "Failed to add GPIOs: %d\n", ret);
        return ret;
 }
 
@@ -155,7 +159,7 @@ static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
 }
 #else
 static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
-                                 struct snd_soc_codec *codec)
+                                 struct snd_soc_component *component)
 {
        return 0;
 }
@@ -166,8 +170,8 @@ static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
 #endif
 
 /**
- * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
- * @codec: The CODEC for which to create the AC'97 device
+ * snd_soc_alloc_ac97_component() - Allocate new a AC'97 device
+ * @component: The COMPONENT for which to create the AC'97 device
  *
  * Allocated a new snd_ac97 device and intializes it, but does not yet register
  * it. The caller is responsible to either call device_add(&ac97->dev) to
@@ -175,7 +179,7 @@ static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
  *
  * Returns: A snd_ac97 device or a PTR_ERR in case of an error.
  */
-struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
+struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component)
 {
        struct snd_ac97 *ac97;
 
@@ -187,26 +191,26 @@ struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec)
        ac97->num = 0;
 
        ac97->dev.bus = &ac97_bus_type;
-       ac97->dev.parent = codec->component.card->dev;
+       ac97->dev.parent = component->card->dev;
        ac97->dev.release = soc_ac97_device_release;
 
        dev_set_name(&ac97->dev, "%d-%d:%s",
-                    codec->component.card->snd_card->number, 0,
-                    codec->component.name);
+                    component->card->snd_card->number, 0,
+                    component->name);
 
        device_initialize(&ac97->dev);
 
        return ac97;
 }
-EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
+EXPORT_SYMBOL(snd_soc_alloc_ac97_component);
 
 /**
- * snd_soc_new_ac97_codec - initailise AC97 device
- * @codec: audio codec
+ * snd_soc_new_ac97_component - initailise AC97 device
+ * @component: audio component
  * @id: The expected device ID
  * @id_mask: Mask that is applied to the device ID before comparing with @id
  *
- * Initialises AC97 codec resources for use by ad-hoc devices only.
+ * Initialises AC97 component resources for use by ad-hoc devices only.
  *
  * If @id is not 0 this function will reset the device, then read the ID from
  * the device and check if it matches the expected ID. If it doesn't match an
@@ -214,20 +218,20 @@ EXPORT_SYMBOL(snd_soc_alloc_ac97_codec);
  *
  * Returns: A PTR_ERR() on failure or a valid snd_ac97 struct on success.
  */
-struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
        unsigned int id, unsigned int id_mask)
 {
        struct snd_ac97 *ac97;
        int ret;
 
-       ac97 = snd_soc_alloc_ac97_codec(codec);
+       ac97 = snd_soc_alloc_ac97_component(component);
        if (IS_ERR(ac97))
                return ac97;
 
        if (id) {
                ret = snd_ac97_reset(ac97, false, id, id_mask);
                if (ret < 0) {
-                       dev_err(codec->dev, "Failed to reset AC97 device: %d\n",
+                       dev_err(component->dev, "Failed to reset AC97 device: %d\n",
                                ret);
                        goto err_put_device;
                }
@@ -237,7 +241,7 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
        if (ret)
                goto err_put_device;
 
-       ret = snd_soc_ac97_init_gpio(ac97, codec);
+       ret = snd_soc_ac97_init_gpio(ac97, component);
        if (ret)
                goto err_put_device;
 
@@ -247,22 +251,22 @@ err_put_device:
        put_device(&ac97->dev);
        return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
+EXPORT_SYMBOL_GPL(snd_soc_new_ac97_component);
 
 /**
- * snd_soc_free_ac97_codec - free AC97 codec device
+ * snd_soc_free_ac97_component - free AC97 component device
  * @ac97: snd_ac97 device to be freed
  *
- * Frees AC97 codec device resources.
+ * Frees AC97 component device resources.
  */
-void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
+void snd_soc_free_ac97_component(struct snd_ac97 *ac97)
 {
        snd_soc_ac97_free_gpio(ac97);
        device_del(&ac97->dev);
        ac97->bus = NULL;
        put_device(&ac97->dev);
 }
-EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
+EXPORT_SYMBOL_GPL(snd_soc_free_ac97_component);
 
 static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
 
index 96c44f6576c95f4dfae19547414040e2d2153235..bf7ca32ab31fca97758ac25e2607fa57619c1976 100644 (file)
@@ -221,14 +221,14 @@ static const struct attribute_group soc_dapm_dev_group = {
        .is_visible = soc_dev_attr_is_visible,
 };
 
-static const struct attribute_group soc_dev_roup = {
+static const struct attribute_group soc_dev_group = {
        .attrs = soc_dev_attrs,
        .is_visible = soc_dev_attr_is_visible,
 };
 
 static const struct attribute_group *soc_dev_attr_groups[] = {
        &soc_dapm_dev_group,
-       &soc_dev_roup,
+       &soc_dev_group,
        NULL
 };
 
@@ -349,7 +349,7 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component)
                        "ASoC: Failed to create codec register debugfs file\n");
 }
 
-static int codec_list_seq_show(struct seq_file *m, void *v)
+static int codec_list_show(struct seq_file *m, void *v)
 {
        struct snd_soc_codec *codec;
 
@@ -362,20 +362,9 @@ static int codec_list_seq_show(struct seq_file *m, void *v)
 
        return 0;
 }
+DEFINE_SHOW_ATTRIBUTE(codec_list);
 
-static int codec_list_seq_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, codec_list_seq_show, NULL);
-}
-
-static const struct file_operations codec_list_fops = {
-       .open = codec_list_seq_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-static int dai_list_seq_show(struct seq_file *m, void *v)
+static int dai_list_show(struct seq_file *m, void *v)
 {
        struct snd_soc_component *component;
        struct snd_soc_dai *dai;
@@ -390,20 +379,9 @@ static int dai_list_seq_show(struct seq_file *m, void *v)
 
        return 0;
 }
+DEFINE_SHOW_ATTRIBUTE(dai_list);
 
-static int dai_list_seq_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, dai_list_seq_show, NULL);
-}
-
-static const struct file_operations dai_list_fops = {
-       .open = dai_list_seq_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-static int platform_list_seq_show(struct seq_file *m, void *v)
+static int platform_list_show(struct seq_file *m, void *v)
 {
        struct snd_soc_platform *platform;
 
@@ -416,18 +394,7 @@ static int platform_list_seq_show(struct seq_file *m, void *v)
 
        return 0;
 }
-
-static int platform_list_seq_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, platform_list_seq_show, NULL);
-}
-
-static const struct file_operations platform_list_fops = {
-       .open = platform_list_seq_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(platform_list);
 
 static void soc_init_card_debugfs(struct snd_soc_card *card)
 {
@@ -1100,8 +1067,8 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
        cpu_dai_component.dai_name = dai_link->cpu_dai_name;
        rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
        if (!rtd->cpu_dai) {
-               dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
-                       dai_link->cpu_dai_name);
+               dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",
+                        dai_link->cpu_dai_name);
                goto _err_defer;
        }
        snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component);
@@ -1162,11 +1129,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 
                rtd->platform = platform;
        }
-       if (!rtd->platform) {
-               dev_err(card->dev, "ASoC: platform %s not registered\n",
-                       dai_link->platform_name);
-               goto _err_defer;
-       }
 
        soc_add_pcm_runtime(card, rtd);
        return 0;
@@ -1624,22 +1586,21 @@ static int soc_probe_link_components(struct snd_soc_card *card,
 
 static int soc_probe_dai(struct snd_soc_dai *dai, int order)
 {
-       int ret;
+       if (dai->probed ||
+           dai->driver->probe_order != order)
+               return 0;
 
-       if (!dai->probed && dai->driver->probe_order == order) {
-               if (dai->driver->probe) {
-                       ret = dai->driver->probe(dai);
-                       if (ret < 0) {
-                               dev_err(dai->dev,
-                                       "ASoC: failed to probe DAI %s: %d\n",
-                                       dai->name, ret);
-                               return ret;
-                       }
+       if (dai->driver->probe) {
+               int ret = dai->driver->probe(dai);
+               if (ret < 0) {
+                       dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
+                               dai->name, ret);
+                       return ret;
                }
-
-               dai->probed = 1;
        }
 
+       dai->probed = 1;
+
        return 0;
 }
 
@@ -3459,7 +3420,6 @@ int snd_soc_add_component(struct device *dev,
 err_cleanup:
        snd_soc_component_cleanup(component);
 err_free:
-       kfree(component);
        return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_add_component);
@@ -3471,7 +3431,7 @@ int snd_soc_register_component(struct device *dev,
 {
        struct snd_soc_component *component;
 
-       component = kzalloc(sizeof(*component), GFP_KERNEL);
+       component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
        if (!component)
                return -ENOMEM;
 
@@ -3506,7 +3466,6 @@ static int __snd_soc_unregister_component(struct device *dev)
 
        if (found) {
                snd_soc_component_cleanup(component);
-               kfree(component);
        }
 
        return found;
@@ -4397,6 +4356,26 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
 
+/*
+ * snd_soc_of_put_dai_link_codecs - Dereference device nodes in the codecs array
+ * @dai_link: DAI link
+ *
+ * Dereference device nodes acquired by snd_soc_of_get_dai_link_codecs().
+ */
+void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link)
+{
+       struct snd_soc_dai_link_component *component = dai_link->codecs;
+       int index;
+
+       for (index = 0; index < dai_link->num_codecs; index++, component++) {
+               if (!component->of_node)
+                       break;
+               of_node_put(component->of_node);
+               component->of_node = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_codecs);
+
 /*
  * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree
  * @dev: Card device
@@ -4406,7 +4385,8 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
  * Builds an array of CODEC DAI components from the DAI link property
  * 'sound-dai'.
  * The array is set in the DAI link and the number of DAIs is set accordingly.
- * The device nodes in the array (of_node) must be dereferenced by the caller.
+ * The device nodes in the array (of_node) must be dereferenced by calling
+ * snd_soc_of_put_dai_link_codecs() on @dai_link.
  *
  * Returns 0 for success
  */
@@ -4454,14 +4434,7 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
        }
        return 0;
 err:
-       for (index = 0, component = dai_link->codecs;
-            index < dai_link->num_codecs;
-            index++, component++) {
-               if (!component->of_node)
-                       break;
-               of_node_put(component->of_node);
-               component->of_node = NULL;
-       }
+       snd_soc_of_put_dai_link_codecs(dai_link);
        dai_link->codecs = NULL;
        dai_link->num_codecs = 0;
        return ret;
index 92894d9cac19d54d835b6611c013b0ea527403a8..2d9709104ec55e026322f50d58d52b41a0bba4be 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -72,6 +73,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
 static int dapm_up_seq[] = {
        [snd_soc_dapm_pre] = 0,
        [snd_soc_dapm_regulator_supply] = 1,
+       [snd_soc_dapm_pinctrl] = 1,
        [snd_soc_dapm_clock_supply] = 1,
        [snd_soc_dapm_supply] = 2,
        [snd_soc_dapm_micbias] = 3,
@@ -121,6 +123,7 @@ static int dapm_down_seq[] = {
        [snd_soc_dapm_dai_link] = 11,
        [snd_soc_dapm_supply] = 12,
        [snd_soc_dapm_clock_supply] = 13,
+       [snd_soc_dapm_pinctrl] = 13,
        [snd_soc_dapm_regulator_supply] = 13,
        [snd_soc_dapm_post] = 14,
 };
@@ -1289,6 +1292,31 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(dapm_regulator_event);
 
+/*
+ * Handler for pinctrl widget.
+ */
+int dapm_pinctrl_event(struct snd_soc_dapm_widget *w,
+                      struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_dapm_pinctrl_priv *priv = w->priv;
+       struct pinctrl *p = w->pinctrl;
+       struct pinctrl_state *s;
+
+       if (!p || !priv)
+               return -EIO;
+
+       if (SND_SOC_DAPM_EVENT_ON(event))
+               s = pinctrl_lookup_state(p, priv->active_state);
+       else
+               s = pinctrl_lookup_state(p, priv->sleep_state);
+
+       if (IS_ERR(s))
+               return PTR_ERR(s);
+
+       return pinctrl_select_state(p, s);
+}
+EXPORT_SYMBOL_GPL(dapm_pinctrl_event);
+
 /*
  * Handler for clock supply widget.
  */
@@ -1902,6 +1930,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
                                break;
                        case snd_soc_dapm_supply:
                        case snd_soc_dapm_regulator_supply:
+                       case snd_soc_dapm_pinctrl:
                        case snd_soc_dapm_clock_supply:
                        case snd_soc_dapm_micbias:
                                if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
@@ -2315,6 +2344,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt,
                case snd_soc_dapm_mixer_named_ctl:
                case snd_soc_dapm_supply:
                case snd_soc_dapm_regulator_supply:
+               case snd_soc_dapm_pinctrl:
                case snd_soc_dapm_clock_supply:
                        if (w->name)
                                count += sprintf(buf + count, "%s: %s\n",
@@ -3165,7 +3195,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
        unsigned int invert = mc->invert;
        unsigned int val, rval = 0;
        int connect, rconnect = -1, change, reg_change = 0;
-       struct snd_soc_dapm_update update = { NULL };
+       struct snd_soc_dapm_update update = {};
        int ret = 0;
 
        val = (ucontrol->value.integer.value[0] & mask);
@@ -3292,7 +3322,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
        unsigned int *item = ucontrol->value.enumerated.item;
        unsigned int val, change, reg_change = 0;
        unsigned int mask;
-       struct snd_soc_dapm_update update = { NULL };
+       struct snd_soc_dapm_update update = {};
        int ret = 0;
 
        if (item[0] >= e->items)
@@ -3464,6 +3494,17 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
                                         w->name, ret);
                }
                break;
+       case snd_soc_dapm_pinctrl:
+               w->pinctrl = devm_pinctrl_get(dapm->dev);
+               if (IS_ERR_OR_NULL(w->pinctrl)) {
+                       ret = PTR_ERR(w->pinctrl);
+                       if (ret == -EPROBE_DEFER)
+                               return ERR_PTR(ret);
+                       dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
+                               w->name, ret);
+                       return NULL;
+               }
+               break;
        case snd_soc_dapm_clock_supply:
 #ifdef CONFIG_CLKDEV_LOOKUP
                w->clk = devm_clk_get(dapm->dev, w->name);
@@ -3543,6 +3584,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
                break;
        case snd_soc_dapm_supply:
        case snd_soc_dapm_regulator_supply:
+       case snd_soc_dapm_pinctrl:
        case snd_soc_dapm_clock_supply:
        case snd_soc_dapm_kcontrol:
                w->is_supply = 1;
index d53786498b61238cd8a6ade0481df8f65a9626bd..56a541b9ff9e2340eabc996c803a9b3a7427853c 100644 (file)
 struct dmaengine_pcm {
        struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
        const struct snd_dmaengine_pcm_config *config;
-       struct snd_soc_platform platform;
+       struct snd_soc_component component;
        unsigned int flags;
 };
 
-static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p)
+static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
 {
-       return container_of(p, struct dmaengine_pcm, platform);
+       return container_of(p, struct dmaengine_pcm, component);
 }
 
 static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm,
@@ -88,7 +88,9 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
        struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
        int (*prepare_slave_config)(struct snd_pcm_substream *substream,
                        struct snd_pcm_hw_params *params,
@@ -119,7 +121,9 @@ static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream,
 static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
        struct device *dma_dev = dmaengine_dma_dev(pcm, substream);
        struct dma_chan *chan = pcm->chan[substream->stream];
        struct snd_dmaengine_dai_dma_data *dma_data;
@@ -128,7 +132,8 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
        u32 addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
                          BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
                          BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
-       int i, ret;
+       snd_pcm_format_t i;
+       int ret;
 
        if (pcm->config && pcm->config->pcm_hardware)
                return snd_soc_set_runtime_hwparams(substream,
@@ -178,7 +183,7 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
                 * default assumption is that it supports 1, 2 and 4 bytes
                 * widths.
                 */
-               for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+               for (i = SNDRV_PCM_FORMAT_FIRST; i <= SNDRV_PCM_FORMAT_LAST; i++) {
                        int bits = snd_pcm_format_physical_width(i);
 
                        /*
@@ -206,7 +211,9 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
 static int dmaengine_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
        struct dma_chan *chan = pcm->chan[substream->stream];
        int ret;
 
@@ -221,7 +228,9 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel(
        struct snd_soc_pcm_runtime *rtd,
        struct snd_pcm_substream *substream)
 {
-       struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
        struct snd_dmaengine_dai_dma_data *dma_data;
        dma_filter_fn fn = NULL;
 
@@ -260,9 +269,11 @@ static bool dmaengine_pcm_can_report_residue(struct device *dev,
 
 static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
-       struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
        const struct snd_dmaengine_pcm_config *config = pcm->config;
-       struct device *dev = rtd->platform->dev;
+       struct device *dev = component->dev;
        struct snd_dmaengine_dai_dma_data *dma_data;
        struct snd_pcm_substream *substream;
        size_t prealloc_buffer_size;
@@ -296,7 +307,7 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
                }
 
                if (!pcm->chan[i]) {
-                       dev_err(rtd->platform->dev,
+                       dev_err(component->dev,
                                "Missing dma channel for stream: %d\n", i);
                        return -EINVAL;
                }
@@ -320,7 +331,9 @@ static snd_pcm_uframes_t dmaengine_pcm_pointer(
        struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
 
        if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
                return snd_dmaengine_pcm_pointer_no_residue(substream);
@@ -328,6 +341,41 @@ static snd_pcm_uframes_t dmaengine_pcm_pointer(
                return snd_dmaengine_pcm_pointer(substream);
 }
 
+static int dmaengine_copy_user(struct snd_pcm_substream *substream,
+                              int channel, unsigned long hwoff,
+                              void *buf, unsigned long bytes)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_component *component =
+               snd_soc_rtdcom_lookup(rtd, SND_DMAENGINE_PCM_DRV_NAME);
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
+       int (*process)(struct snd_pcm_substream *substream,
+                      int channel, unsigned long hwoff,
+                      void *buf, unsigned long bytes) = pcm->config->process;
+       bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+       void *dma_ptr = runtime->dma_area + hwoff +
+                       channel * (runtime->dma_bytes / runtime->channels);
+       int ret;
+
+       if (is_playback)
+               if (copy_from_user(dma_ptr, (void __user *)buf, bytes))
+                       return -EFAULT;
+
+       if (process) {
+               ret = process(substream, channel, hwoff,
+                             (void __user *)buf, bytes);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (!is_playback)
+               if (copy_to_user((void __user *)buf, dma_ptr, bytes))
+                       return -EFAULT;
+
+       return 0;
+}
+
 static const struct snd_pcm_ops dmaengine_pcm_ops = {
        .open           = dmaengine_pcm_open,
        .close          = snd_dmaengine_pcm_close,
@@ -338,14 +386,31 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
        .pointer        = dmaengine_pcm_pointer,
 };
 
-static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
-       .component_driver = {
-               .probe_order = SND_SOC_COMP_ORDER_LATE,
-       },
+static const struct snd_pcm_ops dmaengine_pcm_process_ops = {
+       .open           = dmaengine_pcm_open,
+       .close          = snd_dmaengine_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = dmaengine_pcm_hw_params,
+       .hw_free        = snd_pcm_lib_free_pages,
+       .trigger        = snd_dmaengine_pcm_trigger,
+       .pointer        = dmaengine_pcm_pointer,
+       .copy_user      = dmaengine_copy_user,
+};
+
+static const struct snd_soc_component_driver dmaengine_pcm_component = {
+       .name           = SND_DMAENGINE_PCM_DRV_NAME,
+       .probe_order    = SND_SOC_COMP_ORDER_LATE,
        .ops            = &dmaengine_pcm_ops,
        .pcm_new        = dmaengine_pcm_new,
 };
 
+static const struct snd_soc_component_driver dmaengine_pcm_component_process = {
+       .name           = SND_DMAENGINE_PCM_DRV_NAME,
+       .probe_order    = SND_SOC_COMP_ORDER_LATE,
+       .ops            = &dmaengine_pcm_process_ops,
+       .pcm_new        = dmaengine_pcm_new,
+};
+
 static const char * const dmaengine_pcm_dma_channel_names[] = {
        [SNDRV_PCM_STREAM_PLAYBACK] = "tx",
        [SNDRV_PCM_STREAM_CAPTURE] = "rx",
@@ -431,6 +496,9 @@ int snd_dmaengine_pcm_register(struct device *dev,
        if (!pcm)
                return -ENOMEM;
 
+#ifdef CONFIG_DEBUG_FS
+       pcm->component.debugfs_prefix = "dma";
+#endif
        pcm->config = config;
        pcm->flags = flags;
 
@@ -438,8 +506,13 @@ int snd_dmaengine_pcm_register(struct device *dev,
        if (ret)
                goto err_free_dma;
 
-       ret = snd_soc_add_platform(dev, &pcm->platform,
-               &dmaengine_pcm_platform);
+       if (config && config->process)
+               ret = snd_soc_add_component(dev, &pcm->component,
+                                           &dmaengine_pcm_component_process,
+                                           NULL, 0);
+       else
+               ret = snd_soc_add_component(dev, &pcm->component,
+                                           &dmaengine_pcm_component, NULL, 0);
        if (ret)
                goto err_free_dma;
 
@@ -461,16 +534,16 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
  */
 void snd_dmaengine_pcm_unregister(struct device *dev)
 {
-       struct snd_soc_platform *platform;
+       struct snd_soc_component *component;
        struct dmaengine_pcm *pcm;
 
-       platform = snd_soc_lookup_platform(dev);
-       if (!platform)
+       component = snd_soc_lookup_component(dev, SND_DMAENGINE_PCM_DRV_NAME);
+       if (!component)
                return;
 
-       pcm = soc_platform_to_pcm(platform);
+       pcm = soc_component_to_pcm(component);
 
-       snd_soc_remove_platform(platform);
+       snd_soc_unregister_component(dev);
        dmaengine_pcm_release_chan(pcm);
        kfree(pcm);
 }
index 2bc1c4c17896d6c946baf584656f4fdca2bc25e8..d36a192fbece4f8be1124fcb256355149eeef94e 100644 (file)
@@ -88,19 +88,16 @@ static int snd_soc_component_update_bits_legacy(
        unsigned int old, new;
        int ret;
 
-       if (!component->read || !component->write)
-               return -EIO;
-
        mutex_lock(&component->io_mutex);
 
-       ret = component->read(component, reg, &old);
+       ret = snd_soc_component_read(component, reg, &old);
        if (ret < 0)
                goto out_unlock;
 
        new = (old & ~mask) | (val & mask);
        *change = old != new;
        if (*change)
-               ret = component->write(component, reg, new);
+               ret = snd_soc_component_write(component, reg, new);
 out_unlock:
        mutex_unlock(&component->io_mutex);
 
index 084125463d101e96ab0aa119a964ac5609e6ab06..68d9dc930096365bc1d0c81d4bda93af2dd3ad29 100644 (file)
@@ -1392,12 +1392,18 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
        struct snd_soc_pcm_runtime *be;
        int i;
 
+       dev_dbg(card->dev, "ASoC: find BE for widget %s\n", widget->name);
+
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
                list_for_each_entry(be, &card->rtd_list, list) {
 
                        if (!be->dai_link->no_pcm)
                                continue;
 
+                       dev_dbg(card->dev, "ASoC: try BE : %s\n",
+                               be->cpu_dai->playback_widget ?
+                               be->cpu_dai->playback_widget->name : "(not set)");
+
                        if (be->cpu_dai->playback_widget == widget)
                                return be;
 
@@ -1414,6 +1420,10 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
                        if (!be->dai_link->no_pcm)
                                continue;
 
+                       dev_dbg(card->dev, "ASoC: try BE %s\n",
+                               be->cpu_dai->capture_widget ?
+                               be->cpu_dai->capture_widget->name : "(not set)");
+
                        if (be->cpu_dai->capture_widget == widget)
                                return be;
 
@@ -1425,6 +1435,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
                }
        }
 
+       /* dai link name and stream name set correctly ? */
        dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
                stream ? "capture" : "playback", widget->name);
        return NULL;
index 01a50413c66f6612762791b2d1d905b077eb87a2..fa27d0fca6dce10ed8befc8df9cdf7406dbcac75 100644 (file)
@@ -504,6 +504,9 @@ static void remove_widget(struct snd_soc_component *comp,
        if (dobj->ops && dobj->ops->widget_unload)
                dobj->ops->widget_unload(comp, dobj);
 
+       if (!w->kcontrols)
+               goto free_news;
+
        /*
         * Dynamic Widgets either have 1..N enum kcontrols or mixers.
         * The enum may either have an array of values or strings.
@@ -523,8 +526,8 @@ static void remove_widget(struct snd_soc_component *comp,
                                kfree(se->dobj.control.dtexts[j]);
 
                        kfree(se);
+                       kfree(w->kcontrol_news[i].name);
                }
-               kfree(w->kcontrol_news);
        } else {
                /* volume mixer or bytes controls */
                for (i = 0; i < w->num_kcontrols; i++) {
@@ -540,9 +543,13 @@ static void remove_widget(struct snd_soc_component *comp,
                         */
                        kfree((void *)kcontrol->private_value);
                        snd_ctl_remove(card, kcontrol);
+                       kfree(w->kcontrol_news[i].name);
                }
-               kfree(w->kcontrol_news);
        }
+
+free_news:
+       kfree(w->kcontrol_news);
+
        /* widget w is freed by soc-dapm.c */
 }
 
@@ -1233,7 +1240,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
                dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n",
                        mc->hdr.name, i);
 
-               kc[i].name = mc->hdr.name;
+               kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL);
+               if (kc[i].name == NULL)
+                       goto err_str;
                kc[i].private_value = (long)sm;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = mc->hdr.access;
@@ -1272,14 +1281,19 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
                        kfree(sm);
                        continue;
                }
+
+               /* create any TLV data */
+               soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr);
        }
        return kc;
 
 err_str:
        kfree(sm);
 err:
-       for (--i; i >= 0; i--)
+       for (--i; i >= 0; i--) {
                kfree((void *)kc[i].private_value);
+               kfree(kc[i].name);
+       }
        kfree(kc);
        return NULL;
 }
@@ -1310,7 +1324,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
                dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n",
                        ec->hdr.name);
 
-               kc[i].name = ec->hdr.name;
+               kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
+               if (kc[i].name == NULL)
+                       goto err_se;
                kc[i].private_value = (long)se;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = ec->hdr.access;
@@ -1386,6 +1402,7 @@ err_se:
                        kfree(se->dobj.control.dtexts[j]);
 
                kfree(se);
+               kfree(kc[i].name);
        }
 err:
        kfree(kc);
@@ -1424,7 +1441,9 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
                        "ASoC: adding bytes kcontrol %s with access 0x%x\n",
                        be->hdr.name, be->hdr.access);
 
-               kc[i].name = be->hdr.name;
+               kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
+               if (kc[i].name == NULL)
+                       goto err;
                kc[i].private_value = (long)sbe;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = be->hdr.access;
@@ -1454,8 +1473,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
        return kc;
 
 err:
-       for (--i; i >= 0; i--)
+       for (--i; i >= 0; i--) {
                kfree((void *)kc[i].private_value);
+               kfree(kc[i].name);
+       }
 
        kfree(kc);
        return NULL;
index bcd3da2739e20d5db3b9a52d185b357150369de0..2d9e98bd15301b30676d6c804f319aabe5e9f910 100644 (file)
@@ -284,11 +284,16 @@ static const struct snd_pcm_ops dummy_dma_ops = {
        .ioctl          = snd_pcm_lib_ioctl,
 };
 
-static const struct snd_soc_platform_driver dummy_platform = {
+static const struct snd_soc_component_driver dummy_platform = {
        .ops = &dummy_dma_ops,
 };
 
-static const struct snd_soc_codec_driver dummy_codec;
+static const struct snd_soc_component_driver dummy_codec = {
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
+};
 
 #define STUB_RATES     SNDRV_PCM_RATE_8000_192000
 #define STUB_FORMATS   (SNDRV_PCM_FMTBIT_S8 | \
@@ -338,33 +343,22 @@ static int snd_soc_dummy_probe(struct platform_device *pdev)
 {
        int ret;
 
-       ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &dummy_codec, &dummy_dai, 1);
        if (ret < 0)
                return ret;
 
-       ret = snd_soc_register_platform(&pdev->dev, &dummy_platform);
-       if (ret < 0) {
-               snd_soc_unregister_codec(&pdev->dev);
-               return ret;
-       }
+       ret = devm_snd_soc_register_component(&pdev->dev, &dummy_platform,
+                                             NULL, 0);
 
        return ret;
 }
 
-static int snd_soc_dummy_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_platform(&pdev->dev);
-       snd_soc_unregister_codec(&pdev->dev);
-
-       return 0;
-}
-
 static struct platform_driver soc_dummy_driver = {
        .driver = {
                .name = "snd-soc-dummy",
        },
        .probe = snd_soc_dummy_probe,
-       .remove = snd_soc_dummy_remove,
 };
 
 static struct platform_device *soc_dummy_dev;
index 7306e3eca9e16016b6a76ac22415fa3041720750..db73fef3e500715d4eae353f3dab31e69c69389a 100644 (file)
@@ -281,7 +281,7 @@ static void stm32_adfsdm_pcm_free(struct snd_pcm *pcm)
        }
 }
 
-static struct snd_soc_platform_driver stm32_adfsdm_soc_platform = {
+static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
        .ops            = &stm32_adfsdm_pcm_ops,
        .pcm_new        = stm32_adfsdm_pcm_new,
        .pcm_free       = stm32_adfsdm_pcm_free,
@@ -322,8 +322,9 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
        if (IS_ERR(priv->iio_cb))
                return PTR_ERR(priv->iio_cb);
 
-       ret = devm_snd_soc_register_platform(&pdev->dev,
-                                            &stm32_adfsdm_soc_platform);
+       ret = devm_snd_soc_register_component(&pdev->dev,
+                                             &stm32_adfsdm_soc_platform,
+                                             NULL, 0);
        if (ret < 0)
                dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
                        __func__);
index d743b7dd52fb9e1fc508ceca54c9d25a67182609..f22654253c43865116c8caff684f3b9013f20e01 100644 (file)
 
 static const struct stm32_sai_conf stm32_sai_conf_f4 = {
        .version = SAI_STM32F4,
+       .has_spdif = false,
 };
 
 static const struct stm32_sai_conf stm32_sai_conf_h7 = {
        .version = SAI_STM32H7,
+       .has_spdif = true,
 };
 
 static const struct of_device_id stm32_sai_ids[] = {
index bb062e70de63e538c49a052d90d73da6ff5f8149..f25422174909eef7684da0021bd22deffe17b30e 100644 (file)
@@ -248,9 +248,11 @@ enum stm32_sai_version {
 /**
  * struct stm32_sai_conf - SAI configuration
  * @version: SAI version
+ * @has_spdif: SAI S/PDIF support flag
  */
 struct stm32_sai_conf {
        int version;
+       bool has_spdif;
 };
 
 /**
index 08583b9584303851cd8530aa2a6fd39481ae0278..cfeb219e1d78b6d351b239c8533d3f838006eb0e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/of_platform.h>
 #include <linux/regmap.h>
 
+#include <sound/asoundef.h>
 #include <sound/core.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
@@ -30,6 +31,7 @@
 #include "stm32_sai.h"
 
 #define SAI_FREE_PROTOCOL      0x0
+#define SAI_SPDIF_PROTOCOL     0x1
 
 #define SAI_SLOT_SIZE_AUTO     0x0
 #define SAI_SLOT_SIZE_16       0x1
 #define SAI_SYNC_INTERNAL      0x1
 #define SAI_SYNC_EXTERNAL      0x2
 
+#define STM_SAI_PROTOCOL_IS_SPDIF(ip)  ((ip)->spdif)
+#define STM_SAI_HAS_SPDIF(x)   ((x)->pdata->conf->has_spdif)
 #define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
 
+#define SAI_IEC60958_BLOCK_FRAMES      192
+#define SAI_IEC60958_STATUS_BYTES      24
+
 /**
  * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
  * @pdev: device data pointer
@@ -78,6 +85,7 @@
  * @id: SAI sub block id corresponding to sub-block A or B
  * @dir: SAI block direction (playback or capture). set at init
  * @master: SAI block mode flag. (true=master, false=slave) set at init
+ * @spdif: SAI S/PDIF iec60958 mode flag. set at init
  * @fmt: SAI block format. relevant only for custom protocols. set at init
  * @sync: SAI block synchronization mode. (none, internal or external)
  * @synco: SAI block ext sync source (provider setting). (none, sub-block A/B)
@@ -87,6 +95,8 @@
  * @slot_width: rx or tx slot width in bits
  * @slot_mask: rx or tx active slots mask. set at init or at runtime
  * @data_size: PCM data width. corresponds to PCM substream width.
+ * @spdif_frm_cnt: S/PDIF playback frame counter
+ * @spdif_status_bits: S/PDIF status bits
  */
 struct stm32_sai_sub_data {
        struct platform_device *pdev;
@@ -104,6 +114,7 @@ struct stm32_sai_sub_data {
        unsigned int id;
        int dir;
        bool master;
+       bool spdif;
        int fmt;
        int sync;
        int synco;
@@ -113,6 +124,8 @@ struct stm32_sai_sub_data {
        int slot_width;
        int slot_mask;
        int data_size;
+       unsigned int spdif_frm_cnt;
+       unsigned char spdif_status_bits[SAI_IEC60958_STATUS_BYTES];
 };
 
 enum stm32_sai_fifo_th {
@@ -171,6 +184,10 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg)
        }
 }
 
+static const unsigned char default_status_bits[SAI_IEC60958_STATUS_BYTES] = {
+       0, 0, 0, IEC958_AES3_CON_FS_48000,
+};
+
 static const struct regmap_config stm32_sai_sub_regmap_config_f4 = {
        .reg_bits = 32,
        .reg_stride = 4,
@@ -277,6 +294,11 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
        struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
        int slotr, slotr_mask, slot_size;
 
+       if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+               dev_warn(cpu_dai->dev, "Slot setting relevant only for TDM\n");
+               return 0;
+       }
+
        dev_dbg(cpu_dai->dev, "Masks tx/rx:%#x/%#x, slots:%d, width:%d\n",
                tx_mask, rx_mask, slots, slot_width);
 
@@ -326,8 +348,17 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 
        dev_dbg(cpu_dai->dev, "fmt %x\n", fmt);
 
-       cr1_mask = SAI_XCR1_PRTCFG_MASK;
-       cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
+       /* Do not generate master by default */
+       cr1 = SAI_XCR1_NODIV;
+       cr1_mask = SAI_XCR1_NODIV;
+
+       cr1_mask |= SAI_XCR1_PRTCFG_MASK;
+       if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+               cr1 |= SAI_XCR1_PRTCFG_SET(SAI_SPDIF_PROTOCOL);
+               goto conf_update;
+       }
+
+       cr1 |= SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        /* SCK active high for all protocols */
@@ -409,10 +440,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 
        cr1_mask |= SAI_XCR1_SLAVE;
 
-       /* do not generate master by default */
-       cr1 |= SAI_XCR1_NODIV;
-       cr1_mask |= SAI_XCR1_NODIV;
-
+conf_update:
        ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
        if (ret < 0) {
                dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
@@ -478,6 +506,12 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
                           SAI_XCR2_FFLUSH |
                           SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
 
+       /* DS bits in CR1 not set for SPDIF (size forced to 24 bits).*/
+       if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+               sai->spdif_frm_cnt = 0;
+               return 0;
+       }
+
        /* Mode, data format and channel config */
        cr1_mask = SAI_XCR1_DS_MASK;
        switch (params_format(params)) {
@@ -592,13 +626,14 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
        int cr1, mask, div = 0;
        int sai_clk_rate, mclk_ratio, den, ret;
        int version = sai->pdata->conf->version;
+       unsigned int rate = params_rate(params);
 
        if (!sai->mclk_rate) {
                dev_err(cpu_dai->dev, "Mclk rate is null\n");
                return -EINVAL;
        }
 
-       if (!(params_rate(params) % 11025))
+       if (!(rate % 11025))
                clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
        else
                clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
@@ -623,24 +658,28 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
                 *      MCKDIV = sai_ck / (frl x ws)    (NOMCK=1)
                 * Note: NOMCK/NODIV correspond to same bit.
                 */
-               if (sai->mclk_rate) {
-                       mclk_ratio = sai->mclk_rate / params_rate(params);
-                       if (mclk_ratio != 256) {
+               if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+                       div = DIV_ROUND_CLOSEST(sai_clk_rate,
+                                               (params_rate(params) * 128));
+               } else {
+                       if (sai->mclk_rate) {
+                               mclk_ratio = sai->mclk_rate / rate;
                                if (mclk_ratio == 512) {
                                        mask = SAI_XCR1_OSR;
                                        cr1 = SAI_XCR1_OSR;
-                               } else {
+                               } else if (mclk_ratio != 256) {
                                        dev_err(cpu_dai->dev,
                                                "Wrong mclk ratio %d\n",
                                                mclk_ratio);
                                        return -EINVAL;
                                }
+                               div = DIV_ROUND_CLOSEST(sai_clk_rate,
+                                                       sai->mclk_rate);
+                       } else {
+                               /* mclk-fs not set, master clock not active */
+                               den = sai->fs_length * params_rate(params);
+                               div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
                        }
-                       div = DIV_ROUND_CLOSEST(sai_clk_rate, sai->mclk_rate);
-               } else {
-                       /* mclk-fs not set, master clock not active. NOMCK=1 */
-                       den = sai->fs_length * params_rate(params);
-                       div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
                }
        }
 
@@ -670,10 +709,12 @@ static int stm32_sai_hw_params(struct snd_pcm_substream *substream,
 
        sai->data_size = params_width(params);
 
-       ret = stm32_sai_set_slots(cpu_dai);
-       if (ret < 0)
-               return ret;
-       stm32_sai_set_frame(cpu_dai);
+       if (!STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
+               ret = stm32_sai_set_slots(cpu_dai);
+               if (ret < 0)
+                       return ret;
+               stm32_sai_set_frame(cpu_dai);
+       }
 
        ret = stm32_sai_set_config(cpu_dai, substream, params);
        if (ret)
@@ -723,6 +764,9 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
                                         (unsigned int)~SAI_XCR1_DMAEN);
                if (ret < 0)
                        dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
+
+               if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+                       sai->spdif_frm_cnt = 0;
                break;
        default:
                return -EINVAL;
@@ -776,6 +820,10 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
                                     sai->synco, sai->synci);
        }
 
+       if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+               memcpy(sai->spdif_status_bits, default_status_bits,
+                      sizeof(default_status_bits));
+
        cr1_mask |= SAI_XCR1_SYNCEN_MASK;
        cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
 
@@ -792,6 +840,42 @@ static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
        .shutdown       = stm32_sai_shutdown,
 };
 
+static int stm32_sai_pcm_process_spdif(struct snd_pcm_substream *substream,
+                                      int channel, unsigned long hwoff,
+                                      void *buf, unsigned long bytes)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
+       int *ptr = (int *)(runtime->dma_area + hwoff +
+                          channel * (runtime->dma_bytes / runtime->channels));
+       ssize_t cnt = bytes_to_samples(runtime, bytes);
+       unsigned int frm_cnt = sai->spdif_frm_cnt;
+       unsigned int byte;
+       unsigned int mask;
+
+       do {
+               *ptr = ((*ptr >> 8) & 0x00ffffff);
+
+               /* Set channel status bit */
+               byte = frm_cnt >> 3;
+               mask = 1 << (frm_cnt - (byte << 3));
+               if (sai->spdif_status_bits[byte] & mask)
+                       *ptr |= 0x04000000;
+               ptr++;
+
+               if (!(cnt % 2))
+                       frm_cnt++;
+
+               if (frm_cnt == SAI_IEC60958_BLOCK_FRAMES)
+                       frm_cnt = 0;
+       } while (--cnt);
+       sai->spdif_frm_cnt = frm_cnt;
+
+       return 0;
+}
+
 static const struct snd_pcm_hardware stm32_sai_pcm_hw = {
        .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
        .buffer_bytes_max = 8 * PAGE_SIZE,
@@ -842,8 +926,14 @@ static struct snd_soc_dai_driver stm32_sai_capture_dai[] = {
 };
 
 static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
-       .pcm_hardware   = &stm32_sai_pcm_hw,
-       .prepare_slave_config   = snd_dmaengine_pcm_prepare_slave_config,
+       .pcm_hardware = &stm32_sai_pcm_hw,
+       .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+};
+
+static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config_spdif = {
+       .pcm_hardware = &stm32_sai_pcm_hw,
+       .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+       .process = stm32_sai_pcm_process_spdif,
 };
 
 static const struct snd_soc_component_driver stm32_component = {
@@ -900,6 +990,18 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
                return -EINVAL;
        }
 
+       /* Get spdif iec60958 property */
+       sai->spdif = false;
+       if (of_get_property(np, "st,iec60958", NULL)) {
+               if (!STM_SAI_HAS_SPDIF(sai) ||
+                   sai->dir == SNDRV_PCM_STREAM_CAPTURE) {
+                       dev_err(&pdev->dev, "S/PDIF IEC60958 not supported\n");
+                       return -EINVAL;
+               }
+               sai->spdif = true;
+               sai->master = true;
+       }
+
        /* Get synchronization property */
        args.np = NULL;
        ret = of_parse_phandle_with_fixed_args(np, "st,sync", 1, 0, &args);
@@ -999,6 +1101,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
 {
        struct stm32_sai_sub_data *sai;
        const struct of_device_id *of_id;
+       const struct snd_dmaengine_pcm_config *conf = &stm32_sai_pcm_config;
        int ret;
 
        sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
@@ -1039,8 +1142,10 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
-                                             &stm32_sai_pcm_config, 0);
+       if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+               conf = &stm32_sai_pcm_config_spdif;
+
+       ret = devm_snd_dmaengine_pcm_register(&pdev->dev, conf, 0);
        if (ret) {
                dev_err(&pdev->dev, "Could not register pcm dma\n");
                return ret;
index b9bdefcd3e104a7f138803200be77b51648c1802..373df4f24be1a9a5e298e772cba1d6161b5e6fff 100644 (file)
@@ -819,7 +819,6 @@ static const struct snd_soc_dai_ops stm32_spdifrx_pcm_dai_ops = {
 
 static struct snd_soc_dai_driver stm32_spdifrx_dai[] = {
        {
-               .name = "spdifrx-capture-cpu-dai",
                .probe = stm32_spdifrx_dai_probe,
                .capture = {
                        .stream_name = "CPU-Capture",
@@ -858,8 +857,8 @@ static const struct of_device_id stm32_spdifrx_ids[] = {
        {}
 };
 
-static int stm_spdifrx_parse_of(struct platform_device *pdev,
-                               struct stm32_spdifrx_data *spdifrx)
+static int stm32_spdifrx_parse_of(struct platform_device *pdev,
+                                 struct stm32_spdifrx_data *spdifrx)
 {
        struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *of_id;
@@ -914,7 +913,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, spdifrx);
 
-       ret = stm_spdifrx_parse_of(pdev, spdifrx);
+       ret = stm32_spdifrx_parse_of(pdev, spdifrx);
        if (ret)
                return ret;
 
index 886281673972898cee7950d32ca0ce9c2804039a..9a3cb77048105fbc71c075906187fa43e060c9b0 100644 (file)
@@ -792,15 +792,17 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
        { "Mic1", NULL, "VMIC" },
 };
 
-static const struct snd_soc_codec_driver sun4i_codec_codec = {
-       .component_driver = {
-               .controls               = sun4i_codec_controls,
-               .num_controls           = ARRAY_SIZE(sun4i_codec_controls),
-               .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
-               .dapm_routes            = sun4i_codec_codec_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
-       },
+static const struct snd_soc_component_driver sun4i_codec_codec = {
+       .controls               = sun4i_codec_controls,
+       .num_controls           = ARRAY_SIZE(sun4i_codec_controls),
+       .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
+       .dapm_routes            = sun4i_codec_codec_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /*** sun6i Codec ***/
@@ -1098,15 +1100,17 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
        { "Right ADC", NULL, "Right ADC Mixer" },
 };
 
-static const struct snd_soc_codec_driver sun6i_codec_codec = {
-       .component_driver = {
-               .controls               = sun6i_codec_codec_widgets,
-               .num_controls           = ARRAY_SIZE(sun6i_codec_codec_widgets),
-               .dapm_widgets           = sun6i_codec_codec_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
-               .dapm_routes            = sun6i_codec_codec_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
-       },
+static const struct snd_soc_component_driver sun6i_codec_codec = {
+       .controls               = sun6i_codec_codec_widgets,
+       .num_controls           = ARRAY_SIZE(sun6i_codec_codec_widgets),
+       .dapm_widgets           = sun6i_codec_codec_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
+       .dapm_routes            = sun6i_codec_codec_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 /* sun8i A23 codec */
@@ -1126,13 +1130,15 @@ static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = {
 
 };
 
-static const struct snd_soc_codec_driver sun8i_a23_codec_codec = {
-       .component_driver = {
-               .controls               = sun8i_a23_codec_codec_controls,
-               .num_controls           = ARRAY_SIZE(sun8i_a23_codec_codec_controls),
-               .dapm_widgets           = sun8i_a23_codec_codec_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
-       },
+static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
+       .controls               = sun8i_a23_codec_codec_controls,
+       .num_controls           = ARRAY_SIZE(sun8i_a23_codec_codec_controls),
+       .dapm_widgets           = sun8i_a23_codec_codec_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct snd_soc_component_driver sun4i_codec_component = {
@@ -1450,7 +1456,7 @@ static const struct regmap_config sun8i_v3s_codec_regmap_config = {
 
 struct sun4i_codec_quirks {
        const struct regmap_config *regmap_config;
-       const struct snd_soc_codec_driver *codec;
+       const struct snd_soc_component_driver *codec;
        struct snd_soc_card * (*create_card)(struct device *dev);
        struct reg_field reg_adc_fifoc; /* used for regmap_field */
        unsigned int reg_dac_txdata;    /* TX FIFO offset for DMA config */
@@ -1657,7 +1663,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
        scodec->capture_dma_data.maxburst = 8;
        scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 
-       ret = snd_soc_register_codec(&pdev->dev, quirks->codec,
+       ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
                                     &sun4i_codec_dai, 1);
        if (ret) {
                dev_err(&pdev->dev, "Failed to register our codec\n");
@@ -1669,20 +1675,20 @@ static int sun4i_codec_probe(struct platform_device *pdev)
                                              &dummy_cpu_dai, 1);
        if (ret) {
                dev_err(&pdev->dev, "Failed to register our DAI\n");
-               goto err_unregister_codec;
+               goto err_assert_reset;
        }
 
        ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
        if (ret) {
                dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
-               goto err_unregister_codec;
+               goto err_assert_reset;
        }
 
        card = quirks->create_card(&pdev->dev);
        if (IS_ERR(card)) {
                ret = PTR_ERR(card);
                dev_err(&pdev->dev, "Failed to create our card\n");
-               goto err_unregister_codec;
+               goto err_assert_reset;
        }
 
        snd_soc_card_set_drvdata(card, scodec);
@@ -1690,13 +1696,11 @@ static int sun4i_codec_probe(struct platform_device *pdev)
        ret = snd_soc_register_card(card);
        if (ret) {
                dev_err(&pdev->dev, "Failed to register our card\n");
-               goto err_unregister_codec;
+               goto err_assert_reset;
        }
 
        return 0;
 
-err_unregister_codec:
-       snd_soc_unregister_codec(&pdev->dev);
 err_assert_reset:
        if (scodec->rst)
                reset_control_assert(scodec->rst);
@@ -1711,7 +1715,6 @@ static int sun4i_codec_remove(struct platform_device *pdev)
        struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
 
        snd_soc_unregister_card(card);
-       snd_soc_unregister_codec(&pdev->dev);
        if (scodec->rst)
                reset_control_assert(scodec->rst);
        clk_disable_unprepare(scodec->clk_apb);
index dca1143c1150ac58aa148a49db54c33226e366c8..a4aa931ebfaef4c081dc5594c4ffe06fba6aeb38 100644 (file)
 
 #define SUN8I_I2S_CHAN_CFG_REG         0x30
 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK    GENMASK(6, 4)
-#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)   (chan - 1)
+#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)   ((chan - 1) << 4)
 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK    GENMASK(2, 0)
 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)   (chan - 1)
 
index 7a15df92431655831f89670125192d3670165f46..fb37dd927e3385b1e7ac807866bcaf6577df9731 100644 (file)
@@ -184,7 +184,7 @@ static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
 
 static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+       struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
        u32 value;
 
        /* clock masters */
@@ -304,7 +304,7 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+       struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
        int sample_rate;
        u8 bclk_div;
 
@@ -500,13 +500,15 @@ static struct snd_soc_dai_driver sun8i_codec_dai = {
        .ops = &sun8i_codec_dai_ops,
 };
 
-static const struct snd_soc_codec_driver sun8i_soc_codec = {
-       .component_driver = {
-               .dapm_widgets           = sun8i_codec_dapm_widgets,
-               .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_dapm_widgets),
-               .dapm_routes            = sun8i_codec_dapm_routes,
-               .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_dapm_routes),
-       },
+static const struct snd_soc_component_driver sun8i_soc_component = {
+       .dapm_widgets           = sun8i_codec_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_dapm_widgets),
+       .dapm_routes            = sun8i_codec_dapm_routes,
+       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_dapm_routes),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static const struct regmap_config sun8i_codec_regmap_config = {
@@ -566,7 +568,7 @@ static int sun8i_codec_probe(struct platform_device *pdev)
                        goto err_pm_disable;
        }
 
-       ret = snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec,
+       ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
                                     &sun8i_codec_dai, 1);
        if (ret) {
                dev_err(&pdev->dev, "Failed to register codec\n");
@@ -594,7 +596,6 @@ static int sun8i_codec_remove(struct platform_device *pdev)
        if (!pm_runtime_status_suspended(&pdev->dev))
                sun8i_codec_runtime_suspend(&pdev->dev);
 
-       snd_soc_unregister_codec(&pdev->dev);
        clk_disable_unprepare(scodec->clk_module);
        clk_disable_unprepare(scodec->clk_bus);
 
index a2bb68fea5a32ae0ccb76f235d6c7ef4df399052..8d31fe628e2f5fdc9a18fc2b4e6ba8dcde316c4c 100644 (file)
@@ -23,6 +23,8 @@
 #include <sound/soc.h>
 #include "txx9aclc.h"
 
+#define DRV_NAME "txx9aclc"
+
 static struct txx9aclc_soc_device {
        struct txx9aclc_dmadata dmadata[2];
 } txx9aclc_soc_device;
@@ -53,6 +55,7 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
        struct txx9aclc_dmadata *dmadata = runtime->private_data;
        int ret;
 
@@ -60,13 +63,13 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       dev_dbg(rtd->platform->dev,
+       dev_dbg(component->dev,
                "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
                "runtime->min_align %ld\n",
                (unsigned long)runtime->dma_area,
                (unsigned long)runtime->dma_addr, runtime->dma_bytes,
                runtime->min_align);
-       dev_dbg(rtd->platform->dev,
+       dev_dbg(component->dev,
                "periods %d period_bytes %d stream %d\n",
                params_periods(params), params_period_bytes(params),
                substream->stream);
@@ -287,7 +290,8 @@ static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd)
        struct snd_card *card = rtd->card->snd_card;
        struct snd_soc_dai *dai = rtd->cpu_dai;
        struct snd_pcm *pcm = rtd->pcm;
-       struct platform_device *pdev = to_platform_device(rtd->platform->dev);
+       struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
+       struct platform_device *pdev = to_platform_device(component->dev);
        struct txx9aclc_soc_device *dev;
        struct resource *r;
        int i;
@@ -371,15 +375,15 @@ static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
        return 0;
 }
 
-static int txx9aclc_pcm_probe(struct snd_soc_platform *platform)
+static int txx9aclc_pcm_probe(struct snd_soc_component *component)
 {
-       snd_soc_platform_set_drvdata(platform, &txx9aclc_soc_device);
+       snd_soc_component_set_drvdata(component, &txx9aclc_soc_device);
        return 0;
 }
 
-static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
+static void txx9aclc_pcm_remove(struct snd_soc_component *component)
 {
-       struct txx9aclc_soc_device *dev = snd_soc_platform_get_drvdata(platform);
+       struct txx9aclc_soc_device *dev = snd_soc_component_get_drvdata(component);
        struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
        void __iomem *base = drvdata->base;
        int i;
@@ -400,10 +404,10 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
                }
                dev->dmadata[i].dma_chan = NULL;
        }
-       return 0;
 }
 
-static const struct snd_soc_platform_driver txx9aclc_soc_platform = {
+static const struct snd_soc_component_driver txx9aclc_soc_component = {
+       .name           = DRV_NAME,
        .probe          = txx9aclc_pcm_probe,
        .remove         = txx9aclc_pcm_remove,
        .ops            = &txx9aclc_pcm_ops,
@@ -412,8 +416,8 @@ static const struct snd_soc_platform_driver txx9aclc_soc_platform = {
 
 static int txx9aclc_soc_platform_probe(struct platform_device *pdev)
 {
-       return devm_snd_soc_register_platform(&pdev->dev,
-                                             &txx9aclc_soc_platform);
+       return devm_snd_soc_register_component(&pdev->dev,
+                                       &txx9aclc_soc_component, NULL, 0);
 }
 
 static struct platform_driver txx9aclc_pcm_driver = {
index 02886a457eafa3638fdd30805dfc518929170637..aa3592ee1358b06466dd9a05017142681b9669cc 100644 (file)
@@ -8,6 +8,39 @@ config SND_SOC_UNIPHIER
          audio interfaces to support below.
          If unsure select "N".
 
+config SND_SOC_UNIPHIER_AIO
+       tristate "UniPhier AIO DAI Driver"
+       select REGMAP_MMIO
+       select SND_SOC_COMPRESS
+       depends on SND_SOC_UNIPHIER
+       help
+         This adds ASoC driver support for Socionext UniPhier
+         'AIO' Audio Input/Output subsystem.
+         Select Y if you use such device.
+         If unsure select "N".
+
+config SND_SOC_UNIPHIER_LD11
+       tristate "UniPhier LD11/LD20 Device Driver"
+       depends on SND_SOC_UNIPHIER
+       select SND_SOC_UNIPHIER_AIO
+       select SND_SOC_UNIPHIER_AIO_DMA
+       help
+         This adds ASoC driver for Socionext UniPhier LD11/LD20
+         input and output that can be used with other codecs.
+         Select Y if you use such device.
+         If unsure select "N".
+
+config SND_SOC_UNIPHIER_PXS2
+       tristate "UniPhier PXs2 Device Driver"
+       depends on SND_SOC_UNIPHIER
+       select SND_SOC_UNIPHIER_AIO
+       select SND_SOC_UNIPHIER_AIO_DMA
+       help
+         This adds ASoC driver for Socionext UniPhier PXs2
+         input and output that can be used with other codecs.
+         Select Y if you use such device.
+         If unsure select "N".
+
 config SND_SOC_UNIPHIER_EVEA_CODEC
        tristate "UniPhier SoC internal audio codec"
        depends on SND_SOC_UNIPHIER
index 3be00d72f5e562556770377640e98ba43dbd06bd..88169395f68a32ac7fa75627ba9f3b7aefd9bf1b 100644 (file)
@@ -1,3 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
+snd-soc-uniphier-aio-cpu-objs := aio-core.o aio-dma.o aio-cpu.o aio-compress.o
+snd-soc-uniphier-aio-ld11-objs := aio-ld11.o
+snd-soc-uniphier-aio-pxs2-objs := aio-pxs2.o
+
+obj-$(CONFIG_SND_SOC_UNIPHIER_AIO) += snd-soc-uniphier-aio-cpu.o
+obj-$(CONFIG_SND_SOC_UNIPHIER_LD11) += snd-soc-uniphier-aio-ld11.o
+obj-$(CONFIG_SND_SOC_UNIPHIER_PXS2) += snd-soc-uniphier-aio-pxs2.o
+
 snd-soc-uniphier-evea-objs := evea.o
 obj-$(CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC) += snd-soc-uniphier-evea.o
diff --git a/sound/soc/uniphier/aio-compress.c b/sound/soc/uniphier/aio-compress.c
new file mode 100644 (file)
index 0000000..4c1027a
--- /dev/null
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO Compress Audio driver.
+//
+// Copyright (c) 2017-2018 Socionext Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// 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/bitfield.h>
+#include <linux/circ_buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+
+static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream);
+static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream);
+
+static int uniphier_aio_comprdma_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_compr *compr = rtd->compr;
+       struct device *dev = compr->card->dev;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
+       size_t size = AUD_RING_SIZE;
+       int dma_dir = DMA_FROM_DEVICE, ret;
+
+       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
+       if (ret)
+               return ret;
+
+       sub->compr_area = kzalloc(size, GFP_KERNEL);
+       if (!sub->compr_area)
+               return -ENOMEM;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT)
+               dma_dir = DMA_TO_DEVICE;
+
+       sub->compr_addr = dma_map_single(dev, sub->compr_area, size, dma_dir);
+       if (dma_mapping_error(dev, sub->compr_addr)) {
+               kfree(sub->compr_area);
+               sub->compr_area = NULL;
+
+               return -ENOMEM;
+       }
+
+       sub->compr_bytes = size;
+
+       return 0;
+}
+
+static int uniphier_aio_comprdma_free(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_compr *compr = rtd->compr;
+       struct device *dev = compr->card->dev;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
+       int dma_dir = DMA_FROM_DEVICE;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT)
+               dma_dir = DMA_TO_DEVICE;
+
+       dma_unmap_single(dev, sub->compr_addr, sub->compr_bytes, dma_dir);
+       kfree(sub->compr_area);
+       sub->compr_area = NULL;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_open(struct snd_compr_stream *cstream)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       int ret;
+
+       if (sub->cstream)
+               return -EBUSY;
+
+       sub->cstream = cstream;
+       sub->pass_through = 1;
+       sub->use_mmap = false;
+
+       ret = uniphier_aio_comprdma_new(rtd);
+       if (ret)
+               return ret;
+
+       ret = aio_init(sub);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_free(struct snd_compr_stream *cstream)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       int ret;
+
+       ret = uniphier_aio_compr_hw_free(cstream);
+       if (ret)
+               return ret;
+       ret = uniphier_aio_comprdma_free(rtd);
+       if (ret)
+               return ret;
+
+       sub->cstream = NULL;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_get_params(struct snd_compr_stream *cstream,
+                                        struct snd_codec *params)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+
+       *params = sub->cparams.codec;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_set_params(struct snd_compr_stream *cstream,
+                                        struct snd_compr_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       struct device *dev = &aio->chip->pdev->dev;
+       int ret;
+
+       if (params->codec.id != SND_AUDIOCODEC_IEC61937) {
+               dev_err(dev, "Codec ID is not supported(%d)\n",
+                       params->codec.id);
+               return -EINVAL;
+       }
+       if (params->codec.profile != SND_AUDIOPROFILE_IEC61937_SPDIF) {
+               dev_err(dev, "Codec profile is not supported(%d)\n",
+                       params->codec.profile);
+               return -EINVAL;
+       }
+
+       /* IEC frame type will be changed after received valid data */
+       sub->iec_pc = IEC61937_PC_AAC;
+
+       sub->cparams = *params;
+       sub->setting = 1;
+
+       aio_port_reset(sub);
+       aio_src_reset(sub);
+
+       ret = uniphier_aio_compr_prepare(cstream);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+
+       sub->setting = 0;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct snd_compr_runtime *runtime = cstream->runtime;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       int bytes = runtime->fragment_size;
+       unsigned long flags;
+       int ret;
+
+       ret = aiodma_ch_set_param(sub);
+       if (ret)
+               return ret;
+
+       spin_lock_irqsave(&sub->lock, flags);
+       ret = aiodma_rb_set_buffer(sub, sub->compr_addr,
+                                  sub->compr_addr + sub->compr_bytes,
+                                  bytes);
+       spin_unlock_irqrestore(&sub->lock, flags);
+       if (ret)
+               return ret;
+
+       ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
+       if (ret)
+               return ret;
+       ret = aio_oport_set_stream_type(sub, sub->iec_pc);
+       if (ret)
+               return ret;
+       aio_port_set_enable(sub, 1);
+
+       ret = aio_if_set_param(sub, sub->pass_through);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int uniphier_aio_compr_trigger(struct snd_compr_stream *cstream,
+                                     int cmd)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct snd_compr_runtime *runtime = cstream->runtime;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       struct device *dev = &aio->chip->pdev->dev;
+       int bytes = runtime->fragment_size, ret = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sub->lock, flags);
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+               aiodma_ch_set_enable(sub, 1);
+               sub->running = 1;
+
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               sub->running = 0;
+               aiodma_ch_set_enable(sub, 0);
+
+               break;
+       default:
+               dev_warn(dev, "Unknown trigger(%d)\n", cmd);
+               ret = -EINVAL;
+       }
+       spin_unlock_irqrestore(&sub->lock, flags);
+
+       return ret;
+}
+
+static int uniphier_aio_compr_pointer(struct snd_compr_stream *cstream,
+                                     struct snd_compr_tstamp *tstamp)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct snd_compr_runtime *runtime = cstream->runtime;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       int bytes = runtime->fragment_size;
+       unsigned long flags;
+       u32 pos;
+
+       spin_lock_irqsave(&sub->lock, flags);
+
+       aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               pos = sub->rd_offs;
+               /* Size of AIO output format is double of IEC61937 */
+               tstamp->copied_total = sub->rd_total / 2;
+       } else {
+               pos = sub->wr_offs;
+               tstamp->copied_total = sub->rd_total;
+       }
+       tstamp->byte_offset = pos;
+
+       spin_unlock_irqrestore(&sub->lock, flags);
+
+       return 0;
+}
+
+static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub,
+                               char __user *buf, size_t dstsize)
+{
+       u32 __user *srcbuf = (u32 __user *)buf;
+       u32 *dstbuf = (u32 *)(sub->compr_area + sub->wr_offs);
+       int src = 0, dst = 0, ret;
+       u32 frm, frm_a, frm_b;
+
+       while (dstsize > 0) {
+               ret = get_user(frm, srcbuf + src);
+               if (ret)
+                       return ret;
+               src++;
+
+               frm_a = frm & 0xffff;
+               frm_b = (frm >> 16) & 0xffff;
+
+               if (frm == IEC61937_HEADER_SIGN) {
+                       frm_a |= 0x01000000;
+
+                       /* Next data is Pc and Pd */
+                       sub->iec_header = true;
+               } else {
+                       u16 pc = be16_to_cpu((__be16)frm_a);
+
+                       if (sub->iec_header && sub->iec_pc != pc) {
+                               /* Force overwrite IEC frame type */
+                               sub->iec_pc = pc;
+                               ret = aio_oport_set_stream_type(sub, pc);
+                               if (ret)
+                                       return ret;
+                       }
+                       sub->iec_header = false;
+               }
+               dstbuf[dst++] = frm_a;
+               dstbuf[dst++] = frm_b;
+
+               dstsize -= sizeof(u32) * 2;
+       }
+
+       return 0;
+}
+
+static int uniphier_aio_compr_copy(struct snd_compr_stream *cstream,
+                                  char __user *buf, size_t count)
+{
+       struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+       struct snd_compr_runtime *runtime = cstream->runtime;
+       struct device *carddev = rtd->compr->card->dev;
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
+       size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2);
+       int bytes = runtime->fragment_size;
+       unsigned long flags;
+       size_t s;
+       int ret;
+
+       if (cnt < sizeof(u32))
+               return 0;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               dma_addr_t dmapos = sub->compr_addr + sub->wr_offs;
+
+               /* Size of AIO output format is double of IEC61937 */
+               s = cnt * 2;
+
+               dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE);
+               ret = aio_compr_send_to_hw(sub, buf, s);
+               dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE);
+       } else {
+               dma_addr_t dmapos = sub->compr_addr + sub->rd_offs;
+
+               s = cnt;
+
+               dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE);
+               ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s);
+               dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE);
+       }
+       if (ret)
+               return -EFAULT;
+
+       spin_lock_irqsave(&sub->lock, flags);
+
+       sub->threshold = 2 * bytes;
+       aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes);
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               sub->wr_offs += s;
+               if (sub->wr_offs >= sub->compr_bytes)
+                       sub->wr_offs -= sub->compr_bytes;
+       } else {
+               sub->rd_offs += s;
+               if (sub->rd_offs >= sub->compr_bytes)
+                       sub->rd_offs -= sub->compr_bytes;
+       }
+       aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+
+       spin_unlock_irqrestore(&sub->lock, flags);
+
+       return cnt;
+}
+
+static int uniphier_aio_compr_get_caps(struct snd_compr_stream *cstream,
+                                      struct snd_compr_caps *caps)
+{
+       caps->num_codecs = 1;
+       caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE;
+       caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE;
+       caps->min_fragments = AUD_MIN_FRAGMENT;
+       caps->max_fragments = AUD_MAX_FRAGMENT;
+       caps->codecs[0] = SND_AUDIOCODEC_IEC61937;
+
+       return 0;
+}
+
+static const struct snd_compr_codec_caps caps_iec = {
+       .num_descriptors = 1,
+       .descriptor[0].max_ch = 8,
+       .descriptor[0].num_sample_rates = 0,
+       .descriptor[0].num_bitrates = 0,
+       .descriptor[0].profiles = SND_AUDIOPROFILE_IEC61937_SPDIF,
+       .descriptor[0].modes = SND_AUDIOMODE_IEC_AC3 |
+                               SND_AUDIOMODE_IEC_MPEG1 |
+                               SND_AUDIOMODE_IEC_MP3 |
+                               SND_AUDIOMODE_IEC_DTS,
+       .descriptor[0].formats = 0,
+};
+
+static int uniphier_aio_compr_get_codec_caps(struct snd_compr_stream *stream,
+                                            struct snd_compr_codec_caps *codec)
+{
+       if (codec->codec == SND_AUDIOCODEC_IEC61937)
+               *codec = caps_iec;
+       else
+               return -EINVAL;
+
+       return 0;
+}
+
+const struct snd_compr_ops uniphier_aio_compr_ops = {
+       .open           = uniphier_aio_compr_open,
+       .free           = uniphier_aio_compr_free,
+       .get_params     = uniphier_aio_compr_get_params,
+       .set_params     = uniphier_aio_compr_set_params,
+       .trigger        = uniphier_aio_compr_trigger,
+       .pointer        = uniphier_aio_compr_pointer,
+       .copy           = uniphier_aio_compr_copy,
+       .get_caps       = uniphier_aio_compr_get_caps,
+       .get_codec_caps = uniphier_aio_compr_get_codec_caps,
+};
diff --git a/sound/soc/uniphier/aio-core.c b/sound/soc/uniphier/aio-core.c
new file mode 100644 (file)
index 0000000..6d50042
--- /dev/null
@@ -0,0 +1,1138 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA common driver.
+//
+// Copyright (c) 2016-2018 Socionext Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// 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/bitfield.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+#include "aio-reg.h"
+
+static u64 rb_cnt(u64 wr, u64 rd, u64 len)
+{
+       if (rd <= wr)
+               return wr - rd;
+       else
+               return len - (rd - wr);
+}
+
+static u64 rb_cnt_to_end(u64 wr, u64 rd, u64 len)
+{
+       if (rd <= wr)
+               return wr - rd;
+       else
+               return len - rd;
+}
+
+static u64 rb_space(u64 wr, u64 rd, u64 len)
+{
+       if (rd <= wr)
+               return len - (wr - rd) - 8;
+       else
+               return rd - wr - 8;
+}
+
+static u64 rb_space_to_end(u64 wr, u64 rd, u64 len)
+{
+       if (rd > wr)
+               return rd - wr - 8;
+       else if (rd > 0)
+               return len - wr;
+       else
+               return len - wr - 8;
+}
+
+u64 aio_rb_cnt(struct uniphier_aio_sub *sub)
+{
+       return rb_cnt(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub)
+{
+       return rb_cnt_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+u64 aio_rb_space(struct uniphier_aio_sub *sub)
+{
+       return rb_space(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub)
+{
+       return rb_space_to_end(sub->wr_offs, sub->rd_offs, sub->compr_bytes);
+}
+
+/**
+ * aio_iecout_set_enable - setup IEC output via SoC glue
+ * @chip: the AIO chip pointer
+ * @enable: false to stop the output, true to start
+ *
+ * Set enabled or disabled S/PDIF signal output to out of SoC via AOnIEC pins.
+ * This function need to call at driver startup.
+ *
+ * The regmap of SoC glue is specified by 'socionext,syscon' optional property
+ * of DT. This function has no effect if no property.
+ */
+void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable)
+{
+       struct regmap *r = chip->regmap_sg;
+
+       if (!r)
+               return;
+
+       regmap_write(r, SG_AOUTEN, (enable) ? ~0 : 0);
+}
+
+/**
+ * aio_chip_set_pll - set frequency to audio PLL
+ * @chip  : the AIO chip pointer
+ * @source: PLL
+ * @freq  : frequency in Hz, 0 is ignored
+ *
+ * Sets frequency of audio PLL. This function can be called anytime,
+ * but it takes time till PLL is locked.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
+                    unsigned int freq)
+{
+       struct device *dev = &chip->pdev->dev;
+       struct regmap *r = chip->regmap;
+       int shift;
+       u32 v;
+
+       /* Not change */
+       if (freq == 0)
+               return 0;
+
+       switch (pll_id) {
+       case AUD_PLL_A1:
+               shift = 0;
+               break;
+       case AUD_PLL_F1:
+               shift = 1;
+               break;
+       case AUD_PLL_A2:
+               shift = 2;
+               break;
+       case AUD_PLL_F2:
+               shift = 3;
+               break;
+       default:
+               dev_err(dev, "PLL(%d) not supported\n", pll_id);
+               return -EINVAL;
+       }
+
+       switch (freq) {
+       case 36864000:
+               v = A2APLLCTR1_APLLX_36MHZ;
+               break;
+       case 33868800:
+               v = A2APLLCTR1_APLLX_33MHZ;
+               break;
+       default:
+               dev_err(dev, "PLL frequency not supported(%d)\n", freq);
+               return -EINVAL;
+       }
+       chip->plls[pll_id].freq = freq;
+
+       regmap_update_bits(r, A2APLLCTR1, A2APLLCTR1_APLLX_MASK << shift,
+                          v << shift);
+
+       return 0;
+}
+
+/**
+ * aio_chip_init - initialize AIO whole settings
+ * @chip: the AIO chip pointer
+ *
+ * Sets AIO fixed and whole device settings to AIO.
+ * This function need to call once at driver startup.
+ *
+ * The register area that is changed by this function is shared by all
+ * modules of AIO. But there is not race condition since this function
+ * has always set the same initialize values.
+ */
+void aio_chip_init(struct uniphier_aio_chip *chip)
+{
+       struct regmap *r = chip->regmap;
+
+       regmap_update_bits(r, A2APLLCTR0,
+                          A2APLLCTR0_APLLXPOW_MASK,
+                          A2APLLCTR0_APLLXPOW_PWON);
+
+       regmap_update_bits(r, A2EXMCLKSEL0,
+                          A2EXMCLKSEL0_EXMCLK_MASK,
+                          A2EXMCLKSEL0_EXMCLK_OUTPUT);
+
+       regmap_update_bits(r, A2AIOINPUTSEL, A2AIOINPUTSEL_RXSEL_MASK,
+                          A2AIOINPUTSEL_RXSEL_PCMI1_HDMIRX1 |
+                          A2AIOINPUTSEL_RXSEL_PCMI2_SIF |
+                          A2AIOINPUTSEL_RXSEL_PCMI3_EVEA |
+                          A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1);
+
+       if (chip->chip_spec->addr_ext)
+               regmap_update_bits(r, CDA2D_TEST, CDA2D_TEST_DDR_MODE_MASK,
+                                  CDA2D_TEST_DDR_MODE_EXTON0);
+       else
+               regmap_update_bits(r, CDA2D_TEST, CDA2D_TEST_DDR_MODE_MASK,
+                                  CDA2D_TEST_DDR_MODE_EXTOFF1);
+}
+
+/**
+ * aio_init - initialize AIO substream
+ * @sub: the AIO substream pointer
+ *
+ * Sets fixed settings of each AIO substreams.
+ * This function need to call once at substream startup.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_init(struct uniphier_aio_sub *sub)
+{
+       struct device *dev = &sub->aio->chip->pdev->dev;
+       struct regmap *r = sub->aio->chip->regmap;
+
+       regmap_write(r, A2RBNMAPCTR0(sub->swm->rb.hw),
+                    MAPCTR0_EN | sub->swm->rb.map);
+       regmap_write(r, A2CHNMAPCTR0(sub->swm->ch.hw),
+                    MAPCTR0_EN | sub->swm->ch.map);
+
+       switch (sub->swm->type) {
+       case PORT_TYPE_I2S:
+       case PORT_TYPE_SPDIF:
+       case PORT_TYPE_EVE:
+               if (sub->swm->dir == PORT_DIR_INPUT) {
+                       regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
+                                    MAPCTR0_EN | sub->swm->iif.map);
+                       regmap_write(r, A2IPORTNMAPCTR0(sub->swm->iport.hw),
+                                    MAPCTR0_EN | sub->swm->iport.map);
+               } else {
+                       regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
+                                    MAPCTR0_EN | sub->swm->oif.map);
+                       regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
+                                    MAPCTR0_EN | sub->swm->oport.map);
+               }
+               break;
+       case PORT_TYPE_CONV:
+               regmap_write(r, A2OIFNMAPCTR0(sub->swm->oif.hw),
+                            MAPCTR0_EN | sub->swm->oif.map);
+               regmap_write(r, A2OPORTNMAPCTR0(sub->swm->oport.hw),
+                            MAPCTR0_EN | sub->swm->oport.map);
+               regmap_write(r, A2CHNMAPCTR0(sub->swm->och.hw),
+                            MAPCTR0_EN | sub->swm->och.map);
+               regmap_write(r, A2IIFNMAPCTR0(sub->swm->iif.hw),
+                            MAPCTR0_EN | sub->swm->iif.map);
+               break;
+       default:
+               dev_err(dev, "Unknown port type %d.\n", sub->swm->type);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * aio_port_reset - reset AIO port block
+ * @sub: the AIO substream pointer
+ *
+ * Resets the digital signal input/output port block of AIO.
+ */
+void aio_port_reset(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               regmap_write(r, AOUTRSTCTR0, BIT(sub->swm->oport.map));
+               regmap_write(r, AOUTRSTCTR1, BIT(sub->swm->oport.map));
+       } else {
+               regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
+                                  IPORTMXRSTCTR_RSTPI_MASK,
+                                  IPORTMXRSTCTR_RSTPI_RESET);
+               regmap_update_bits(r, IPORTMXRSTCTR(sub->swm->iport.map),
+                                  IPORTMXRSTCTR_RSTPI_MASK,
+                                  IPORTMXRSTCTR_RSTPI_RELEASE);
+       }
+}
+
+/**
+ * aio_port_set_rate - set sampling rate of LPCM
+ * @sub: the AIO substream pointer, PCM substream only
+ * @rate: Sampling rate in Hz.
+ *
+ * Set suitable I2S format settings to input/output port block of AIO.
+ * Parameter is specified by hw_params().
+ *
+ * This function may return error if non-PCM substream.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       struct device *dev = &sub->aio->chip->pdev->dev;
+       u32 v;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               switch (rate) {
+               case 8000:
+                       v = OPORTMXCTR1_FSSEL_8;
+                       break;
+               case 11025:
+                       v = OPORTMXCTR1_FSSEL_11_025;
+                       break;
+               case 12000:
+                       v = OPORTMXCTR1_FSSEL_12;
+                       break;
+               case 16000:
+                       v = OPORTMXCTR1_FSSEL_16;
+                       break;
+               case 22050:
+                       v = OPORTMXCTR1_FSSEL_22_05;
+                       break;
+               case 24000:
+                       v = OPORTMXCTR1_FSSEL_24;
+                       break;
+               case 32000:
+                       v = OPORTMXCTR1_FSSEL_32;
+                       break;
+               case 44100:
+                       v = OPORTMXCTR1_FSSEL_44_1;
+                       break;
+               case 48000:
+                       v = OPORTMXCTR1_FSSEL_48;
+                       break;
+               case 88200:
+                       v = OPORTMXCTR1_FSSEL_88_2;
+                       break;
+               case 96000:
+                       v = OPORTMXCTR1_FSSEL_96;
+                       break;
+               case 176400:
+                       v = OPORTMXCTR1_FSSEL_176_4;
+                       break;
+               case 192000:
+                       v = OPORTMXCTR1_FSSEL_192;
+                       break;
+               default:
+                       dev_err(dev, "Rate not supported(%d)\n", rate);
+                       return -EINVAL;
+               }
+
+               regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map),
+                                  OPORTMXCTR1_FSSEL_MASK, v);
+       } else {
+               switch (rate) {
+               case 8000:
+                       v = IPORTMXCTR1_FSSEL_8;
+                       break;
+               case 11025:
+                       v = IPORTMXCTR1_FSSEL_11_025;
+                       break;
+               case 12000:
+                       v = IPORTMXCTR1_FSSEL_12;
+                       break;
+               case 16000:
+                       v = IPORTMXCTR1_FSSEL_16;
+                       break;
+               case 22050:
+                       v = IPORTMXCTR1_FSSEL_22_05;
+                       break;
+               case 24000:
+                       v = IPORTMXCTR1_FSSEL_24;
+                       break;
+               case 32000:
+                       v = IPORTMXCTR1_FSSEL_32;
+                       break;
+               case 44100:
+                       v = IPORTMXCTR1_FSSEL_44_1;
+                       break;
+               case 48000:
+                       v = IPORTMXCTR1_FSSEL_48;
+                       break;
+               case 88200:
+                       v = IPORTMXCTR1_FSSEL_88_2;
+                       break;
+               case 96000:
+                       v = IPORTMXCTR1_FSSEL_96;
+                       break;
+               case 176400:
+                       v = IPORTMXCTR1_FSSEL_176_4;
+                       break;
+               case 192000:
+                       v = IPORTMXCTR1_FSSEL_192;
+                       break;
+               default:
+                       dev_err(dev, "Rate not supported(%d)\n", rate);
+                       return -EINVAL;
+               }
+
+               regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map),
+                                  IPORTMXCTR1_FSSEL_MASK, v);
+       }
+
+       return 0;
+}
+
+/**
+ * aio_port_set_fmt - set format of I2S data
+ * @sub: the AIO substream pointer, PCM substream only
+ * This parameter has no effect if substream is I2S or PCM.
+ *
+ * Set suitable I2S format settings to input/output port block of AIO.
+ * Parameter is specified by set_fmt().
+ *
+ * This function may return error if non-PCM substream.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_fmt(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       struct device *dev = &sub->aio->chip->pdev->dev;
+       u32 v;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               switch (sub->aio->fmt) {
+               case SND_SOC_DAIFMT_LEFT_J:
+                       v = OPORTMXCTR1_I2SLRSEL_LEFT;
+                       break;
+               case SND_SOC_DAIFMT_RIGHT_J:
+                       v = OPORTMXCTR1_I2SLRSEL_RIGHT;
+                       break;
+               case SND_SOC_DAIFMT_I2S:
+                       v = OPORTMXCTR1_I2SLRSEL_I2S;
+                       break;
+               default:
+                       dev_err(dev, "Format is not supported(%d)\n",
+                               sub->aio->fmt);
+                       return -EINVAL;
+               }
+
+               v |= OPORTMXCTR1_OUTBITSEL_24;
+               regmap_update_bits(r, OPORTMXCTR1(sub->swm->oport.map),
+                                  OPORTMXCTR1_I2SLRSEL_MASK |
+                                  OPORTMXCTR1_OUTBITSEL_MASK, v);
+       } else {
+               switch (sub->aio->fmt) {
+               case SND_SOC_DAIFMT_LEFT_J:
+                       v = IPORTMXCTR1_LRSEL_LEFT;
+                       break;
+               case SND_SOC_DAIFMT_RIGHT_J:
+                       v = IPORTMXCTR1_LRSEL_RIGHT;
+                       break;
+               case SND_SOC_DAIFMT_I2S:
+                       v = IPORTMXCTR1_LRSEL_I2S;
+                       break;
+               default:
+                       dev_err(dev, "Format is not supported(%d)\n",
+                               sub->aio->fmt);
+                       return -EINVAL;
+               }
+
+               v |= IPORTMXCTR1_OUTBITSEL_24 |
+                       IPORTMXCTR1_CHSEL_ALL;
+               regmap_update_bits(r, IPORTMXCTR1(sub->swm->iport.map),
+                                  IPORTMXCTR1_LRSEL_MASK |
+                                  IPORTMXCTR1_OUTBITSEL_MASK |
+                                  IPORTMXCTR1_CHSEL_MASK, v);
+       }
+
+       return 0;
+}
+
+/**
+ * aio_port_set_clk - set clock and divider of AIO port block
+ * @sub: the AIO substream pointer
+ *
+ * Set suitable PLL clock divider and relational settings to
+ * input/output port block of AIO. Parameters are specified by
+ * set_sysclk() and set_pll().
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_clk(struct uniphier_aio_sub *sub)
+{
+       struct uniphier_aio_chip *chip = sub->aio->chip;
+       struct device *dev = &sub->aio->chip->pdev->dev;
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 v_pll[] = {
+               OPORTMXCTR2_ACLKSEL_A1, OPORTMXCTR2_ACLKSEL_F1,
+               OPORTMXCTR2_ACLKSEL_A2, OPORTMXCTR2_ACLKSEL_F2,
+               OPORTMXCTR2_ACLKSEL_A2PLL,
+               OPORTMXCTR2_ACLKSEL_RX1,
+       };
+       u32 v_div[] = {
+               OPORTMXCTR2_DACCKSEL_1_2, OPORTMXCTR2_DACCKSEL_1_3,
+               OPORTMXCTR2_DACCKSEL_1_1, OPORTMXCTR2_DACCKSEL_2_3,
+       };
+       u32 v;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               if (sub->swm->type == PORT_TYPE_I2S) {
+                       if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) {
+                               dev_err(dev, "PLL(%d) is invalid\n",
+                                       sub->aio->pll_out);
+                               return -EINVAL;
+                       }
+                       if (sub->aio->plldiv >= ARRAY_SIZE(v_div)) {
+                               dev_err(dev, "PLL divider(%d) is invalid\n",
+                                       sub->aio->plldiv);
+                               return -EINVAL;
+                       }
+
+                       v = v_pll[sub->aio->pll_out] |
+                               OPORTMXCTR2_MSSEL_MASTER |
+                               v_div[sub->aio->plldiv];
+
+                       switch (chip->plls[sub->aio->pll_out].freq) {
+                       case 0:
+                       case 36864000:
+                       case 33868800:
+                               v |= OPORTMXCTR2_EXTLSIFSSEL_36;
+                               break;
+                       default:
+                               v |= OPORTMXCTR2_EXTLSIFSSEL_24;
+                               break;
+                       }
+               } else if (sub->swm->type == PORT_TYPE_EVE) {
+                       v = OPORTMXCTR2_ACLKSEL_A2PLL |
+                               OPORTMXCTR2_MSSEL_MASTER |
+                               OPORTMXCTR2_EXTLSIFSSEL_36 |
+                               OPORTMXCTR2_DACCKSEL_1_2;
+               } else if (sub->swm->type == PORT_TYPE_SPDIF) {
+                       if (sub->aio->pll_out >= ARRAY_SIZE(v_pll)) {
+                               dev_err(dev, "PLL(%d) is invalid\n",
+                                       sub->aio->pll_out);
+                               return -EINVAL;
+                       }
+                       v = v_pll[sub->aio->pll_out] |
+                               OPORTMXCTR2_MSSEL_MASTER |
+                               OPORTMXCTR2_DACCKSEL_1_2;
+
+                       switch (chip->plls[sub->aio->pll_out].freq) {
+                       case 0:
+                       case 36864000:
+                       case 33868800:
+                               v |= OPORTMXCTR2_EXTLSIFSSEL_36;
+                               break;
+                       default:
+                               v |= OPORTMXCTR2_EXTLSIFSSEL_24;
+                               break;
+                       }
+               } else {
+                       v = OPORTMXCTR2_ACLKSEL_A1 |
+                               OPORTMXCTR2_MSSEL_MASTER |
+                               OPORTMXCTR2_EXTLSIFSSEL_36 |
+                               OPORTMXCTR2_DACCKSEL_1_2;
+               }
+               regmap_write(r, OPORTMXCTR2(sub->swm->oport.map), v);
+       } else {
+               v = IPORTMXCTR2_ACLKSEL_A1 |
+                       IPORTMXCTR2_MSSEL_SLAVE |
+                       IPORTMXCTR2_EXTLSIFSSEL_36 |
+                       IPORTMXCTR2_DACCKSEL_1_2;
+               regmap_write(r, IPORTMXCTR2(sub->swm->iport.map), v);
+       }
+
+       return 0;
+}
+
+/**
+ * aio_port_set_param - set parameters of AIO port block
+ * @sub: the AIO substream pointer
+ * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
+ * This parameter has no effect if substream is I2S or PCM.
+ * @params: hardware parameters of ALSA
+ *
+ * Set suitable setting to input/output port block of AIO to process the
+ * specified in params.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
+                      const struct snd_pcm_hw_params *params)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       unsigned int rate;
+       u32 v;
+       int ret;
+
+       if (!pass_through) {
+               if (sub->swm->type == PORT_TYPE_EVE ||
+                   sub->swm->type == PORT_TYPE_CONV) {
+                       rate = 48000;
+               } else {
+                       rate = params_rate(params);
+               }
+
+               ret = aio_port_set_rate(sub, rate);
+               if (ret)
+                       return ret;
+
+               ret = aio_port_set_fmt(sub);
+               if (ret)
+                       return ret;
+       }
+
+       ret = aio_port_set_clk(sub);
+       if (ret)
+               return ret;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               if (pass_through)
+                       v = OPORTMXCTR3_SRCSEL_STREAM |
+                               OPORTMXCTR3_VALID_STREAM;
+               else
+                       v = OPORTMXCTR3_SRCSEL_PCM |
+                               OPORTMXCTR3_VALID_PCM;
+
+               v |= OPORTMXCTR3_IECTHUR_IECOUT |
+                       OPORTMXCTR3_PMSEL_PAUSE |
+                       OPORTMXCTR3_PMSW_MUTE_OFF;
+               regmap_write(r, OPORTMXCTR3(sub->swm->oport.map), v);
+       } else {
+               regmap_write(r, IPORTMXACLKSEL0EX(sub->swm->iport.map),
+                            IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL);
+               regmap_write(r, IPORTMXEXNOE(sub->swm->iport.map),
+                            IPORTMXEXNOE_PCMINOE_INPUT);
+       }
+
+       return 0;
+}
+
+/**
+ * aio_port_set_enable - start or stop of AIO port block
+ * @sub: the AIO substream pointer
+ * @enable: zero to stop the block, otherwise to start
+ *
+ * Start or stop the signal input/output port block of AIO.
+ */
+void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               regmap_write(r, OPORTMXPATH(sub->swm->oport.map),
+                            sub->swm->oif.map);
+
+               regmap_update_bits(r, OPORTMXMASK(sub->swm->oport.map),
+                                  OPORTMXMASK_IUDXMSK_MASK |
+                                  OPORTMXMASK_IUXCKMSK_MASK |
+                                  OPORTMXMASK_DXMSK_MASK |
+                                  OPORTMXMASK_XCKMSK_MASK,
+                                  OPORTMXMASK_IUDXMSK_OFF |
+                                  OPORTMXMASK_IUXCKMSK_OFF |
+                                  OPORTMXMASK_DXMSK_OFF |
+                                  OPORTMXMASK_XCKMSK_OFF);
+
+               if (enable)
+                       regmap_write(r, AOUTENCTR0, BIT(sub->swm->oport.map));
+               else
+                       regmap_write(r, AOUTENCTR1, BIT(sub->swm->oport.map));
+       } else {
+               regmap_update_bits(r, IPORTMXMASK(sub->swm->iport.map),
+                                  IPORTMXMASK_IUXCKMSK_MASK |
+                                  IPORTMXMASK_XCKMSK_MASK,
+                                  IPORTMXMASK_IUXCKMSK_OFF |
+                                  IPORTMXMASK_XCKMSK_OFF);
+
+               if (enable)
+                       regmap_update_bits(r,
+                                          IPORTMXCTR2(sub->swm->iport.map),
+                                          IPORTMXCTR2_REQEN_MASK,
+                                          IPORTMXCTR2_REQEN_ENABLE);
+               else
+                       regmap_update_bits(r,
+                                          IPORTMXCTR2(sub->swm->iport.map),
+                                          IPORTMXCTR2_REQEN_MASK,
+                                          IPORTMXCTR2_REQEN_DISABLE);
+       }
+}
+
+/**
+ * aio_if_set_param - set parameters of AIO DMA I/F block
+ * @sub: the AIO substream pointer
+ * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
+ * This parameter has no effect if substream is I2S or PCM.
+ *
+ * Set suitable setting to DMA interface block of AIO to process the
+ * specified in settings.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 v;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               if (pass_through)
+                       v = PBOUTMXCTR0_ENDIAN_0123 |
+                               PBOUTMXCTR0_MEMFMT_STREAM;
+               else
+                       v = PBOUTMXCTR0_ENDIAN_3210 |
+                               PBOUTMXCTR0_MEMFMT_2CH;
+
+               regmap_write(r, PBOUTMXCTR0(sub->swm->oif.map), v);
+               regmap_write(r, PBOUTMXCTR1(sub->swm->oif.map), 0);
+       } else {
+               regmap_write(r, PBINMXCTR(sub->swm->iif.map),
+                            PBINMXCTR_NCONNECT_CONNECT |
+                            PBINMXCTR_INOUTSEL_IN |
+                            (sub->swm->iport.map << PBINMXCTR_PBINSEL_SHIFT) |
+                            PBINMXCTR_ENDIAN_3210 |
+                            PBINMXCTR_MEMFMT_D0);
+       }
+
+       return 0;
+}
+
+/**
+ * aio_oport_set_stream_type - set parameters of AIO playback port block
+ * @sub: the AIO substream pointer
+ * @pc: Pc type of IEC61937
+ *
+ * Set special setting to output port block of AIO to output the stream
+ * via S/PDIF.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
+                             enum IEC61937_PC pc)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 repet = 0, pause = OPORTMXPAUDAT_PAUSEPC_CMN;
+
+       switch (pc) {
+       case IEC61937_PC_AC3:
+               repet = OPORTMXREPET_STRLENGTH_AC3 |
+                       OPORTMXREPET_PMLENGTH_AC3;
+               pause |= OPORTMXPAUDAT_PAUSEPD_AC3;
+               break;
+       case IEC61937_PC_MPA:
+               repet = OPORTMXREPET_STRLENGTH_MPA |
+                       OPORTMXREPET_PMLENGTH_MPA;
+               pause |= OPORTMXPAUDAT_PAUSEPD_MPA;
+               break;
+       case IEC61937_PC_MP3:
+               repet = OPORTMXREPET_STRLENGTH_MP3 |
+                       OPORTMXREPET_PMLENGTH_MP3;
+               pause |= OPORTMXPAUDAT_PAUSEPD_MP3;
+               break;
+       case IEC61937_PC_DTS1:
+               repet = OPORTMXREPET_STRLENGTH_DTS1 |
+                       OPORTMXREPET_PMLENGTH_DTS1;
+               pause |= OPORTMXPAUDAT_PAUSEPD_DTS1;
+               break;
+       case IEC61937_PC_DTS2:
+               repet = OPORTMXREPET_STRLENGTH_DTS2 |
+                       OPORTMXREPET_PMLENGTH_DTS2;
+               pause |= OPORTMXPAUDAT_PAUSEPD_DTS2;
+               break;
+       case IEC61937_PC_DTS3:
+               repet = OPORTMXREPET_STRLENGTH_DTS3 |
+                       OPORTMXREPET_PMLENGTH_DTS3;
+               pause |= OPORTMXPAUDAT_PAUSEPD_DTS3;
+               break;
+       case IEC61937_PC_AAC:
+               repet = OPORTMXREPET_STRLENGTH_AAC |
+                       OPORTMXREPET_PMLENGTH_AAC;
+               pause |= OPORTMXPAUDAT_PAUSEPD_AAC;
+               break;
+       case IEC61937_PC_PAUSE:
+               /* Do nothing */
+               break;
+       }
+
+       regmap_write(r, OPORTMXREPET(sub->swm->oport.map), repet);
+       regmap_write(r, OPORTMXPAUDAT(sub->swm->oport.map), pause);
+
+       return 0;
+}
+
+/**
+ * aio_src_reset - reset AIO SRC block
+ * @sub: the AIO substream pointer
+ *
+ * Resets the digital signal input/output port with sampling rate converter
+ * block of AIO.
+ * This function has no effect if substream is not supported rate converter.
+ */
+void aio_src_reset(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       if (sub->swm->dir != PORT_DIR_OUTPUT)
+               return;
+
+       regmap_write(r, AOUTSRCRSTCTR0, BIT(sub->swm->oport.map));
+       regmap_write(r, AOUTSRCRSTCTR1, BIT(sub->swm->oport.map));
+}
+
+/**
+ * aio_src_set_param - set parameters of AIO SRC block
+ * @sub: the AIO substream pointer
+ * @params: hardware parameters of ALSA
+ *
+ * Set suitable setting to input/output port with sampling rate converter
+ * block of AIO to process the specified in params.
+ * This function has no effect if substream is not supported rate converter.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int aio_src_set_param(struct uniphier_aio_sub *sub,
+                     const struct snd_pcm_hw_params *params)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 v;
+
+       if (sub->swm->dir != PORT_DIR_OUTPUT)
+               return 0;
+
+       regmap_write(r, OPORTMXSRC1CTR(sub->swm->oport.map),
+                    OPORTMXSRC1CTR_THMODE_SRC |
+                    OPORTMXSRC1CTR_SRCPATH_CALC |
+                    OPORTMXSRC1CTR_SYNC_ASYNC |
+                    OPORTMXSRC1CTR_FSIIPSEL_INNER |
+                    OPORTMXSRC1CTR_FSISEL_ACLK);
+
+       switch (params_rate(params)) {
+       default:
+       case 48000:
+               v = OPORTMXRATE_I_ACLKSEL_APLLA1 |
+                       OPORTMXRATE_I_MCKSEL_36 |
+                       OPORTMXRATE_I_FSSEL_48;
+               break;
+       case 44100:
+               v = OPORTMXRATE_I_ACLKSEL_APLLA2 |
+                       OPORTMXRATE_I_MCKSEL_33 |
+                       OPORTMXRATE_I_FSSEL_44_1;
+               break;
+       case 32000:
+               v = OPORTMXRATE_I_ACLKSEL_APLLA1 |
+                       OPORTMXRATE_I_MCKSEL_36 |
+                       OPORTMXRATE_I_FSSEL_32;
+               break;
+       }
+
+       regmap_write(r, OPORTMXRATE_I(sub->swm->oport.map),
+                    v | OPORTMXRATE_I_ACLKSRC_APLL |
+                    OPORTMXRATE_I_LRCKSTP_STOP);
+       regmap_update_bits(r, OPORTMXRATE_I(sub->swm->oport.map),
+                          OPORTMXRATE_I_LRCKSTP_MASK,
+                          OPORTMXRATE_I_LRCKSTP_START);
+
+       return 0;
+}
+
+int aio_srcif_set_param(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       regmap_write(r, PBINMXCTR(sub->swm->iif.map),
+                    PBINMXCTR_NCONNECT_CONNECT |
+                    PBINMXCTR_INOUTSEL_OUT |
+                    (sub->swm->oport.map << PBINMXCTR_PBINSEL_SHIFT) |
+                    PBINMXCTR_ENDIAN_3210 |
+                    PBINMXCTR_MEMFMT_D0);
+
+       return 0;
+}
+
+int aio_srcch_set_param(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->och.map),
+                    CDA2D_CHMXCTRL1_INDSIZE_INFINITE);
+
+       regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->och.map),
+                    CDA2D_CHMXAMODE_ENDIAN_3210 |
+                    CDA2D_CHMXAMODE_AUPDT_FIX |
+                    CDA2D_CHMXAMODE_TYPE_NORMAL);
+
+       regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->och.map),
+                    CDA2D_CHMXAMODE_ENDIAN_3210 |
+                    CDA2D_CHMXAMODE_AUPDT_INC |
+                    CDA2D_CHMXAMODE_TYPE_RING |
+                    (sub->swm->och.map << CDA2D_CHMXAMODE_RSSEL_SHIFT));
+
+       return 0;
+}
+
+void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 v;
+
+       if (enable)
+               v = CDA2D_STRT0_STOP_START;
+       else
+               v = CDA2D_STRT0_STOP_STOP;
+
+       regmap_write(r, CDA2D_STRT0,
+                    v | BIT(sub->swm->och.map));
+}
+
+int aiodma_ch_set_param(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 v;
+
+       regmap_write(r, CDA2D_CHMXCTRL1(sub->swm->ch.map),
+                    CDA2D_CHMXCTRL1_INDSIZE_INFINITE);
+
+       v = CDA2D_CHMXAMODE_ENDIAN_3210 |
+               CDA2D_CHMXAMODE_AUPDT_INC |
+               CDA2D_CHMXAMODE_TYPE_NORMAL |
+               (sub->swm->rb.map << CDA2D_CHMXAMODE_RSSEL_SHIFT);
+       if (sub->swm->dir == PORT_DIR_OUTPUT)
+               regmap_write(r, CDA2D_CHMXSRCAMODE(sub->swm->ch.map), v);
+       else
+               regmap_write(r, CDA2D_CHMXDSTAMODE(sub->swm->ch.map), v);
+
+       return 0;
+}
+
+void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       if (enable) {
+               regmap_write(r, CDA2D_STRT0,
+                            CDA2D_STRT0_STOP_START | BIT(sub->swm->ch.map));
+
+               regmap_update_bits(r, INTRBIM(0),
+                                  BIT(sub->swm->rb.map),
+                                  BIT(sub->swm->rb.map));
+       } else {
+               regmap_write(r, CDA2D_STRT0,
+                            CDA2D_STRT0_STOP_STOP | BIT(sub->swm->ch.map));
+
+               regmap_update_bits(r, INTRBIM(0),
+                                  BIT(sub->swm->rb.map),
+                                  0);
+       }
+}
+
+static u64 aiodma_rb_get_rp(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 pos_u, pos_l;
+       int i;
+
+       regmap_write(r, CDA2D_RDPTRLOAD,
+                    CDA2D_RDPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map));
+       /* Wait for setup */
+       for (i = 0; i < 6; i++)
+               regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l);
+
+       regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &pos_l);
+       regmap_read(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), &pos_u);
+       pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u);
+
+       return ((u64)pos_u << 32) | pos_l;
+}
+
+static void aiodma_rb_set_rp(struct uniphier_aio_sub *sub, u64 pos)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 tmp;
+       int i;
+
+       regmap_write(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), (u32)pos);
+       regmap_write(r, CDA2D_RBMXRDPTRU(sub->swm->rb.map), (u32)(pos >> 32));
+       regmap_write(r, CDA2D_RDPTRLOAD, BIT(sub->swm->rb.map));
+       /* Wait for setup */
+       for (i = 0; i < 6; i++)
+               regmap_read(r, CDA2D_RBMXRDPTR(sub->swm->rb.map), &tmp);
+}
+
+static u64 aiodma_rb_get_wp(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 pos_u, pos_l;
+       int i;
+
+       regmap_write(r, CDA2D_WRPTRLOAD,
+                    CDA2D_WRPTRLOAD_LSFLAG_STORE | BIT(sub->swm->rb.map));
+       /* Wait for setup */
+       for (i = 0; i < 6; i++)
+               regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l);
+
+       regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &pos_l);
+       regmap_read(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map), &pos_u);
+       pos_u = FIELD_GET(CDA2D_RBMXPTRU_PTRU_MASK, pos_u);
+
+       return ((u64)pos_u << 32) | pos_l;
+}
+
+static void aiodma_rb_set_wp(struct uniphier_aio_sub *sub, u64 pos)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 tmp;
+       int i;
+
+       regmap_write(r, CDA2D_RBMXWRPTR(sub->swm->rb.map),
+                    lower_32_bits(pos));
+       regmap_write(r, CDA2D_RBMXWRPTRU(sub->swm->rb.map),
+                    upper_32_bits(pos));
+       regmap_write(r, CDA2D_WRPTRLOAD, BIT(sub->swm->rb.map));
+       /* Wait for setup */
+       for (i = 0; i < 6; i++)
+               regmap_read(r, CDA2D_RBMXWRPTR(sub->swm->rb.map), &tmp);
+}
+
+int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       if (size <= th)
+               return -EINVAL;
+
+       regmap_write(r, CDA2D_RBMXBTH(sub->swm->rb.map), th);
+       regmap_write(r, CDA2D_RBMXRTH(sub->swm->rb.map), th);
+
+       return 0;
+}
+
+int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
+                        int period)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u64 size = end - start;
+       int ret;
+
+       if (end < start || period < 0)
+               return -EINVAL;
+
+       regmap_write(r, CDA2D_RBMXCNFG(sub->swm->rb.map), 0);
+       regmap_write(r, CDA2D_RBMXBGNADRS(sub->swm->rb.map),
+                    lower_32_bits(start));
+       regmap_write(r, CDA2D_RBMXBGNADRSU(sub->swm->rb.map),
+                    upper_32_bits(start));
+       regmap_write(r, CDA2D_RBMXENDADRS(sub->swm->rb.map),
+                    lower_32_bits(end));
+       regmap_write(r, CDA2D_RBMXENDADRSU(sub->swm->rb.map),
+                    upper_32_bits(end));
+
+       regmap_write(r, CDA2D_RBADRSLOAD, BIT(sub->swm->rb.map));
+
+       ret = aiodma_rb_set_threshold(sub, size, 2 * period);
+       if (ret)
+               return ret;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               aiodma_rb_set_rp(sub, start);
+               aiodma_rb_set_wp(sub, end - period);
+
+               regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map),
+                                  CDA2D_RBMXIX_SPACE,
+                                  CDA2D_RBMXIX_SPACE);
+       } else {
+               aiodma_rb_set_rp(sub, end - period);
+               aiodma_rb_set_wp(sub, start);
+
+               regmap_update_bits(r, CDA2D_RBMXIE(sub->swm->rb.map),
+                                  CDA2D_RBMXIX_REMAIN,
+                                  CDA2D_RBMXIX_REMAIN);
+       }
+
+       sub->threshold = 2 * period;
+       sub->rd_offs = 0;
+       sub->wr_offs = 0;
+       sub->rd_org = 0;
+       sub->wr_org = 0;
+       sub->rd_total = 0;
+       sub->wr_total = 0;
+
+       return 0;
+}
+
+void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
+                   int period)
+{
+       if (sub->swm->dir == PORT_DIR_OUTPUT) {
+               sub->rd_offs = aiodma_rb_get_rp(sub) - start;
+
+               if (sub->use_mmap) {
+                       sub->threshold = 2 * period;
+                       aiodma_rb_set_threshold(sub, size, 2 * period);
+
+                       sub->wr_offs = sub->rd_offs - period;
+                       if (sub->rd_offs < period)
+                               sub->wr_offs += size;
+               }
+               aiodma_rb_set_wp(sub, sub->wr_offs + start);
+       } else {
+               sub->wr_offs = aiodma_rb_get_wp(sub) - start;
+
+               if (sub->use_mmap) {
+                       sub->threshold = 2 * period;
+                       aiodma_rb_set_threshold(sub, size, 2 * period);
+
+                       sub->rd_offs = sub->wr_offs - period;
+                       if (sub->wr_offs < period)
+                               sub->rd_offs += size;
+               }
+               aiodma_rb_set_rp(sub, sub->rd_offs + start);
+       }
+
+       sub->rd_total += sub->rd_offs - sub->rd_org;
+       if (sub->rd_offs < sub->rd_org)
+               sub->rd_total += size;
+       sub->wr_total += sub->wr_offs - sub->wr_org;
+       if (sub->wr_offs < sub->wr_org)
+               sub->wr_total += size;
+
+       sub->rd_org = sub->rd_offs;
+       sub->wr_org = sub->wr_offs;
+}
+
+bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+       u32 ir;
+
+       regmap_read(r, CDA2D_RBMXIR(sub->swm->rb.map), &ir);
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT)
+               return !!(ir & CDA2D_RBMXIX_SPACE);
+       else
+               return !!(ir & CDA2D_RBMXIX_REMAIN);
+}
+
+void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub)
+{
+       struct regmap *r = sub->aio->chip->regmap;
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT)
+               regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map),
+                            CDA2D_RBMXIX_SPACE);
+       else
+               regmap_write(r, CDA2D_RBMXIR(sub->swm->rb.map),
+                            CDA2D_RBMXIX_REMAIN);
+}
diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
new file mode 100644 (file)
index 0000000..1e5eb8e
--- /dev/null
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA CPU DAI driver.
+//
+// Copyright (c) 2016-2018 Socionext Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+
+static bool is_valid_pll(struct uniphier_aio_chip *chip, int pll_id)
+{
+       struct device *dev = &chip->pdev->dev;
+
+       if (pll_id < 0 || chip->num_plls <= pll_id) {
+               dev_err(dev, "PLL(%d) is not supported\n", pll_id);
+               return false;
+       }
+
+       return chip->plls[pll_id].enable;
+}
+
+static bool match_spec(const struct uniphier_aio_spec *spec,
+                      const char *name, int dir)
+{
+       if (dir == SNDRV_PCM_STREAM_PLAYBACK &&
+           spec->swm.dir != PORT_DIR_OUTPUT) {
+               return false;
+       }
+
+       if (dir == SNDRV_PCM_STREAM_CAPTURE &&
+           spec->swm.dir != PORT_DIR_INPUT) {
+               return false;
+       }
+
+       if (spec->name && strcmp(spec->name, name) == 0)
+               return true;
+
+       if (spec->gname && strcmp(spec->gname, name) == 0)
+               return true;
+
+       return false;
+}
+
+/**
+ * find_spec - find HW specification info by name
+ * @aio: the AIO device pointer
+ * @name: name of device
+ * @direction: the direction of substream, SNDRV_PCM_STREAM_*
+ *
+ * Find hardware specification information from list by device name. This
+ * information is used for telling the difference of SoCs to driver.
+ *
+ * Specification list is array of 'struct uniphier_aio_spec' which is defined
+ * in each drivers (see: aio-i2s.c).
+ *
+ * Return: The pointer of hardware specification of AIO if successful,
+ * otherwise NULL on error.
+ */
+static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio,
+                                                const char *name,
+                                                int direction)
+{
+       const struct uniphier_aio_chip_spec *chip_spec = aio->chip->chip_spec;
+       int i;
+
+       for (i = 0; i < chip_spec->num_specs; i++) {
+               const struct uniphier_aio_spec *spec = &chip_spec->specs[i];
+
+               if (match_spec(spec, name, direction))
+                       return spec;
+       }
+
+       return NULL;
+}
+
+/**
+ * find_divider - find clock divider by frequency
+ * @aio: the AIO device pointer
+ * @pll_id: PLL ID, should be AUD_PLL_XX
+ * @freq: required frequency
+ *
+ * Find suitable clock divider by frequency.
+ *
+ * Return: The ID of PLL if successful, otherwise negative error value.
+ */
+static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq)
+{
+       struct uniphier_aio_pll *pll;
+       int mul[] = { 1, 1, 1, 2, };
+       int div[] = { 2, 3, 1, 3, };
+       int i;
+
+       if (!is_valid_pll(aio->chip, pll_id))
+               return -EINVAL;
+
+       pll = &aio->chip->plls[pll_id];
+       for (i = 0; i < ARRAY_SIZE(mul); i++)
+               if (pll->freq * mul[i] / div[i] == freq)
+                       return i;
+
+       return -ENOTSUPP;
+}
+
+static int uniphier_aio_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+                                  unsigned int freq, int dir)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct device *dev = &aio->chip->pdev->dev;
+       bool pll_auto = false;
+       int pll_id, div_id;
+
+       switch (clk_id) {
+       case AUD_CLK_IO:
+               return -ENOTSUPP;
+       case AUD_CLK_A1:
+               pll_id = AUD_PLL_A1;
+               break;
+       case AUD_CLK_F1:
+               pll_id = AUD_PLL_F1;
+               break;
+       case AUD_CLK_A2:
+               pll_id = AUD_PLL_A2;
+               break;
+       case AUD_CLK_F2:
+               pll_id = AUD_PLL_F2;
+               break;
+       case AUD_CLK_A:
+               pll_id = AUD_PLL_A1;
+               pll_auto = true;
+               break;
+       case AUD_CLK_F:
+               pll_id = AUD_PLL_F1;
+               pll_auto = true;
+               break;
+       case AUD_CLK_APLL:
+               pll_id = AUD_PLL_APLL;
+               break;
+       case AUD_CLK_RX0:
+               pll_id = AUD_PLL_RX0;
+               break;
+       case AUD_CLK_USB0:
+               pll_id = AUD_PLL_USB0;
+               break;
+       case AUD_CLK_HSC0:
+               pll_id = AUD_PLL_HSC0;
+               break;
+       default:
+               dev_err(dev, "Sysclk(%d) is not supported\n", clk_id);
+               return -EINVAL;
+       }
+
+       if (pll_auto) {
+               for (pll_id = 0; pll_id < aio->chip->num_plls; pll_id++) {
+                       div_id = find_divider(aio, pll_id, freq);
+                       if (div_id >= 0) {
+                               aio->plldiv = div_id;
+                               break;
+                       }
+               }
+               if (pll_id == aio->chip->num_plls) {
+                       dev_err(dev, "Sysclk frequency is not supported(%d)\n",
+                               freq);
+                       return -EINVAL;
+               }
+       }
+
+       if (dir == SND_SOC_CLOCK_OUT)
+               aio->pll_out = pll_id;
+       else
+               aio->pll_in = pll_id;
+
+       return 0;
+}
+
+static int uniphier_aio_set_pll(struct snd_soc_dai *dai, int pll_id,
+                               int source, unsigned int freq_in,
+                               unsigned int freq_out)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct device *dev = &aio->chip->pdev->dev;
+       int ret;
+
+       if (!is_valid_pll(aio->chip, pll_id))
+               return -EINVAL;
+       if (!aio->chip->plls[pll_id].enable) {
+               dev_err(dev, "PLL(%d) is not implemented\n", pll_id);
+               return -ENOTSUPP;
+       }
+
+       ret = aio_chip_set_pll(aio->chip, pll_id, freq_out);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int uniphier_aio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct device *dev = &aio->chip->pdev->dev;
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_LEFT_J:
+       case SND_SOC_DAIFMT_RIGHT_J:
+       case SND_SOC_DAIFMT_I2S:
+               aio->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+               break;
+       default:
+               dev_err(dev, "Format is not supported(%d)\n",
+                       fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int uniphier_aio_startup(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+       int ret;
+
+       sub->substream = substream;
+       sub->pass_through = 0;
+       sub->use_mmap = true;
+
+       ret = aio_init(sub);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void uniphier_aio_shutdown(struct snd_pcm_substream *substream,
+                                 struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+
+       sub->substream = NULL;
+}
+
+static int uniphier_aio_hw_params(struct snd_pcm_substream *substream,
+                                 struct snd_pcm_hw_params *params,
+                                 struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+       struct device *dev = &aio->chip->pdev->dev;
+       int freq, ret;
+
+       switch (params_rate(params)) {
+       case 48000:
+       case 32000:
+       case 24000:
+               freq = 12288000;
+               break;
+       case 44100:
+       case 22050:
+               freq = 11289600;
+               break;
+       default:
+               dev_err(dev, "Rate is not supported(%d)\n",
+                       params_rate(params));
+               return -EINVAL;
+       }
+       ret = snd_soc_dai_set_sysclk(dai, AUD_CLK_A,
+                                    freq, SND_SOC_CLOCK_OUT);
+       if (ret)
+               return ret;
+
+       sub->params = *params;
+       sub->setting = 1;
+
+       aio_port_reset(sub);
+       aio_src_reset(sub);
+
+       return 0;
+}
+
+static int uniphier_aio_hw_free(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+
+       sub->setting = 0;
+
+       return 0;
+}
+
+static int uniphier_aio_prepare(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+       int ret;
+
+       ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
+       if (ret)
+               return ret;
+       ret = aio_src_set_param(sub, &sub->params);
+       if (ret)
+               return ret;
+       aio_port_set_enable(sub, 1);
+
+       ret = aio_if_set_param(sub, sub->pass_through);
+       if (ret)
+               return ret;
+
+       if (sub->swm->type == PORT_TYPE_CONV) {
+               ret = aio_srcif_set_param(sub);
+               if (ret)
+                       return ret;
+               ret = aio_srcch_set_param(sub);
+               if (ret)
+                       return ret;
+               aio_srcch_set_enable(sub, 1);
+       }
+
+       return 0;
+}
+
+const struct snd_soc_dai_ops uniphier_aio_i2s_ops = {
+       .set_sysclk  = uniphier_aio_set_sysclk,
+       .set_pll     = uniphier_aio_set_pll,
+       .set_fmt     = uniphier_aio_set_fmt,
+       .startup     = uniphier_aio_startup,
+       .shutdown    = uniphier_aio_shutdown,
+       .hw_params   = uniphier_aio_hw_params,
+       .hw_free     = uniphier_aio_hw_free,
+       .prepare     = uniphier_aio_prepare,
+};
+EXPORT_SYMBOL_GPL(uniphier_aio_i2s_ops);
+
+const struct snd_soc_dai_ops uniphier_aio_spdif_ops = {
+       .set_sysclk  = uniphier_aio_set_sysclk,
+       .set_pll     = uniphier_aio_set_pll,
+       .startup     = uniphier_aio_startup,
+       .shutdown    = uniphier_aio_shutdown,
+       .hw_params   = uniphier_aio_hw_params,
+       .hw_free     = uniphier_aio_hw_free,
+       .prepare     = uniphier_aio_prepare,
+};
+EXPORT_SYMBOL_GPL(uniphier_aio_spdif_ops);
+
+int uniphier_aio_dai_probe(struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(aio->sub); i++) {
+               struct uniphier_aio_sub *sub = &aio->sub[i];
+               const struct uniphier_aio_spec *spec;
+
+               spec = find_spec(aio, dai->name, i);
+               if (!spec)
+                       continue;
+
+               sub->swm = &spec->swm;
+               sub->spec = spec;
+       }
+
+       aio_iecout_set_enable(aio->chip, true);
+       aio_chip_init(aio->chip);
+       aio->chip->active = 1;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_probe);
+
+int uniphier_aio_dai_remove(struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+
+       aio->chip->active = 0;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_remove);
+
+int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+
+       reset_control_assert(aio->chip->rst);
+       clk_disable_unprepare(aio->chip->clk);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_suspend);
+
+int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
+{
+       struct uniphier_aio *aio = uniphier_priv(dai);
+       int ret, i;
+
+       if (!aio->chip->active)
+               return 0;
+
+       ret = clk_prepare_enable(aio->chip->clk);
+       if (ret)
+               return ret;
+
+       ret = reset_control_deassert(aio->chip->rst);
+       if (ret)
+               goto err_out_clock;
+
+       aio_iecout_set_enable(aio->chip, true);
+       aio_chip_init(aio->chip);
+
+       for (i = 0; i < ARRAY_SIZE(aio->sub); i++) {
+               struct uniphier_aio_sub *sub = &aio->sub[i];
+
+               if (!sub->spec || !sub->substream)
+                       continue;
+
+               ret = aio_init(sub);
+               if (ret)
+                       goto err_out_clock;
+
+               if (!sub->setting)
+                       continue;
+
+               aio_port_reset(sub);
+               aio_src_reset(sub);
+       }
+
+       return 0;
+
+err_out_clock:
+       clk_disable_unprepare(aio->chip->clk);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_dai_resume);
+
+static const struct snd_soc_component_driver uniphier_aio_component = {
+       .name = "uniphier-aio",
+};
+
+int uniphier_aio_probe(struct platform_device *pdev)
+{
+       struct uniphier_aio_chip *chip;
+       struct device *dev = &pdev->dev;
+       int ret, i, j;
+
+       chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       chip->chip_spec = of_device_get_match_data(dev);
+       if (!chip->chip_spec)
+               return -EINVAL;
+
+       chip->regmap_sg = syscon_regmap_lookup_by_phandle(dev->of_node,
+                                                         "socionext,syscon");
+       if (IS_ERR(chip->regmap_sg)) {
+               if (PTR_ERR(chip->regmap_sg) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               chip->regmap_sg = NULL;
+       }
+
+       chip->clk = devm_clk_get(dev, "aio");
+       if (IS_ERR(chip->clk))
+               return PTR_ERR(chip->clk);
+
+       chip->rst = devm_reset_control_get_shared(dev, "aio");
+       if (IS_ERR(chip->rst))
+               return PTR_ERR(chip->rst);
+
+       chip->num_aios = chip->chip_spec->num_dais;
+       chip->aios = devm_kzalloc(dev,
+                                 sizeof(struct uniphier_aio) * chip->num_aios,
+                                 GFP_KERNEL);
+       if (!chip->aios)
+               return -ENOMEM;
+
+       chip->num_plls = chip->chip_spec->num_plls;
+       chip->plls = devm_kzalloc(dev, sizeof(struct uniphier_aio_pll) *
+                                 chip->num_plls, GFP_KERNEL);
+       if (!chip->plls)
+               return -ENOMEM;
+       memcpy(chip->plls, chip->chip_spec->plls,
+              sizeof(struct uniphier_aio_pll) * chip->num_plls);
+
+       for (i = 0; i < chip->num_aios; i++) {
+               struct uniphier_aio *aio = &chip->aios[i];
+
+               aio->chip = chip;
+               aio->fmt = SND_SOC_DAIFMT_I2S;
+
+               for (j = 0; j < ARRAY_SIZE(aio->sub); j++) {
+                       struct uniphier_aio_sub *sub = &aio->sub[j];
+
+                       sub->aio = aio;
+                       spin_lock_init(&sub->lock);
+               }
+       }
+
+       chip->pdev = pdev;
+       platform_set_drvdata(pdev, chip);
+
+       ret = clk_prepare_enable(chip->clk);
+       if (ret)
+               return ret;
+
+       ret = reset_control_deassert(chip->rst);
+       if (ret)
+               goto err_out_clock;
+
+       ret = devm_snd_soc_register_component(dev, &uniphier_aio_component,
+                                             chip->chip_spec->dais,
+                                             chip->chip_spec->num_dais);
+       if (ret) {
+               dev_err(dev, "Register component failed.\n");
+               goto err_out_reset;
+       }
+
+       ret = uniphier_aiodma_soc_register_platform(pdev);
+       if (ret) {
+               dev_err(dev, "Register platform failed.\n");
+               goto err_out_reset;
+       }
+
+       return 0;
+
+err_out_reset:
+       reset_control_assert(chip->rst);
+
+err_out_clock:
+       clk_disable_unprepare(chip->clk);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_probe);
+
+int uniphier_aio_remove(struct platform_device *pdev)
+{
+       struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
+
+       reset_control_assert(chip->rst);
+       clk_disable_unprepare(chip->clk);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(uniphier_aio_remove);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier AIO CPU DAI driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/uniphier/aio-dma.c b/sound/soc/uniphier/aio-dma.c
new file mode 100644 (file)
index 0000000..ef7bafa
--- /dev/null
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO DMA driver.
+//
+// Copyright (c) 2016-2018 Socionext Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// 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/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "aio.h"
+
+static struct snd_pcm_hardware uniphier_aiodma_hw = {
+       .info = SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_MMAP_VALID |
+               SNDRV_PCM_INFO_INTERLEAVED,
+       .period_bytes_min = 256,
+       .period_bytes_max = 4096,
+       .periods_min      = 4,
+       .periods_max      = 1024,
+       .buffer_bytes_max = 128 * 1024,
+};
+
+static void aiodma_pcm_irq(struct uniphier_aio_sub *sub)
+{
+       struct snd_pcm_runtime *runtime = sub->substream->runtime;
+       int bytes = runtime->period_size *
+               runtime->channels * samples_to_bytes(runtime, 1);
+       int ret;
+
+       spin_lock(&sub->lock);
+       ret = aiodma_rb_set_threshold(sub, runtime->dma_bytes,
+                                     sub->threshold + bytes);
+       if (!ret)
+               sub->threshold += bytes;
+
+       aiodma_rb_sync(sub, runtime->dma_addr, runtime->dma_bytes, bytes);
+       aiodma_rb_clear_irq(sub);
+       spin_unlock(&sub->lock);
+
+       snd_pcm_period_elapsed(sub->substream);
+}
+
+static void aiodma_compr_irq(struct uniphier_aio_sub *sub)
+{
+       struct snd_compr_runtime *runtime = sub->cstream->runtime;
+       int bytes = runtime->fragment_size;
+       int ret;
+
+       spin_lock(&sub->lock);
+       ret = aiodma_rb_set_threshold(sub, sub->compr_bytes,
+                                     sub->threshold + bytes);
+       if (!ret)
+               sub->threshold += bytes;
+
+       aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
+       aiodma_rb_clear_irq(sub);
+       spin_unlock(&sub->lock);
+
+       snd_compr_fragment_elapsed(sub->cstream);
+}
+
+static irqreturn_t aiodma_irq(int irq, void *p)
+{
+       struct platform_device *pdev = p;
+       struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
+       irqreturn_t ret = IRQ_NONE;
+       int i, j;
+
+       for (i = 0; i < chip->num_aios; i++) {
+               struct uniphier_aio *aio = &chip->aios[i];
+
+               for (j = 0; j < ARRAY_SIZE(aio->sub); j++) {
+                       struct uniphier_aio_sub *sub = &aio->sub[j];
+
+                       /* Skip channel that does not trigger */
+                       if (!sub->running || !aiodma_rb_is_irq(sub))
+                               continue;
+
+                       if (sub->substream)
+                               aiodma_pcm_irq(sub);
+                       if (sub->cstream)
+                               aiodma_compr_irq(sub);
+
+                       ret = IRQ_HANDLED;
+               }
+       }
+
+       return ret;
+}
+
+static int uniphier_aiodma_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       snd_soc_set_runtime_hwparams(substream, &uniphier_aiodma_hw);
+
+       return snd_pcm_hw_constraint_step(runtime, 0,
+               SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256);
+}
+
+static int uniphier_aiodma_hw_params(struct snd_pcm_substream *substream,
+                                    struct snd_pcm_hw_params *params)
+{
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+       substream->runtime->dma_bytes = params_buffer_bytes(params);
+
+       return 0;
+}
+
+static int uniphier_aiodma_hw_free(struct snd_pcm_substream *substream)
+{
+       snd_pcm_set_runtime_buffer(substream, NULL);
+       substream->runtime->dma_bytes = 0;
+
+       return 0;
+}
+
+static int uniphier_aiodma_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+       int bytes = runtime->period_size *
+               runtime->channels * samples_to_bytes(runtime, 1);
+       unsigned long flags;
+       int ret;
+
+       ret = aiodma_ch_set_param(sub);
+       if (ret)
+               return ret;
+
+       spin_lock_irqsave(&sub->lock, flags);
+       ret = aiodma_rb_set_buffer(sub, runtime->dma_addr,
+                                  runtime->dma_addr + runtime->dma_bytes,
+                                  bytes);
+       spin_unlock_irqrestore(&sub->lock, flags);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int uniphier_aiodma_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+       struct device *dev = &aio->chip->pdev->dev;
+       int bytes = runtime->period_size *
+               runtime->channels * samples_to_bytes(runtime, 1);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sub->lock, flags);
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               aiodma_rb_sync(sub, runtime->dma_addr, runtime->dma_bytes,
+                              bytes);
+               aiodma_ch_set_enable(sub, 1);
+               sub->running = 1;
+
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               sub->running = 0;
+               aiodma_ch_set_enable(sub, 0);
+
+               break;
+       default:
+               dev_warn(dev, "Unknown trigger(%d) ignored\n", cmd);
+               break;
+       }
+       spin_unlock_irqrestore(&sub->lock, flags);
+
+       return 0;
+}
+
+static snd_pcm_uframes_t uniphier_aiodma_pointer(
+                                       struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
+       struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
+       int bytes = runtime->period_size *
+               runtime->channels * samples_to_bytes(runtime, 1);
+       unsigned long flags;
+       snd_pcm_uframes_t pos;
+
+       spin_lock_irqsave(&sub->lock, flags);
+       aiodma_rb_sync(sub, runtime->dma_addr, runtime->dma_bytes, bytes);
+
+       if (sub->swm->dir == PORT_DIR_OUTPUT)
+               pos = bytes_to_frames(runtime, sub->rd_offs);
+       else
+               pos = bytes_to_frames(runtime, sub->wr_offs);
+       spin_unlock_irqrestore(&sub->lock, flags);
+
+       return pos;
+}
+
+static int uniphier_aiodma_mmap(struct snd_pcm_substream *substream,
+                               struct vm_area_struct *vma)
+{
+       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+       return remap_pfn_range(vma, vma->vm_start,
+                              substream->dma_buffer.addr >> PAGE_SHIFT,
+                              vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
+static const struct snd_pcm_ops uniphier_aiodma_ops = {
+       .open      = uniphier_aiodma_open,
+       .ioctl     = snd_pcm_lib_ioctl,
+       .hw_params = uniphier_aiodma_hw_params,
+       .hw_free   = uniphier_aiodma_hw_free,
+       .prepare   = uniphier_aiodma_prepare,
+       .trigger   = uniphier_aiodma_trigger,
+       .pointer   = uniphier_aiodma_pointer,
+       .mmap      = uniphier_aiodma_mmap,
+};
+
+static int uniphier_aiodma_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct device *dev = rtd->card->snd_card->dev;
+       struct snd_pcm *pcm = rtd->pcm;
+       int ret;
+
+       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
+       if (ret)
+               return ret;
+
+       return snd_pcm_lib_preallocate_pages_for_all(pcm,
+               SNDRV_DMA_TYPE_DEV, dev,
+               uniphier_aiodma_hw.buffer_bytes_max,
+               uniphier_aiodma_hw.buffer_bytes_max);
+}
+
+static void uniphier_aiodma_free(struct snd_pcm *pcm)
+{
+       snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static const struct snd_soc_component_driver uniphier_soc_platform = {
+       .pcm_new   = uniphier_aiodma_new,
+       .pcm_free  = uniphier_aiodma_free,
+       .ops       = &uniphier_aiodma_ops,
+       .compr_ops = &uniphier_aio_compr_ops,
+};
+
+static const struct regmap_config aiodma_regmap_config = {
+       .reg_bits      = 32,
+       .reg_stride    = 4,
+       .val_bits      = 32,
+       .max_register  = 0x7fffc,
+       .cache_type    = REGCACHE_NONE,
+};
+
+/**
+ * uniphier_aiodma_soc_register_platform - register the AIO DMA
+ * @pdev: the platform device
+ *
+ * Register and setup the DMA of AIO to transfer the sound data to device.
+ * This function need to call once at driver startup and need NOT to call
+ * unregister function.
+ *
+ * Return: Zero if successful, otherwise a negative value on error.
+ */
+int uniphier_aiodma_soc_register_platform(struct platform_device *pdev)
+{
+       struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       void __iomem *preg;
+       int irq, ret;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       preg = devm_ioremap_resource(dev, res);
+       if (IS_ERR(preg))
+               return PTR_ERR(preg);
+
+       chip->regmap = devm_regmap_init_mmio(dev, preg,
+                                            &aiodma_regmap_config);
+       if (IS_ERR(chip->regmap))
+               return PTR_ERR(chip->regmap);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "Could not get irq.\n");
+               return irq;
+       }
+
+       ret = devm_request_irq(dev, irq, aiodma_irq,
+                              IRQF_SHARED, dev_name(dev), pdev);
+       if (ret)
+               return ret;
+
+       return devm_snd_soc_register_component(dev, &uniphier_soc_platform,
+                                              NULL, 0);
+}
+EXPORT_SYMBOL_GPL(uniphier_aiodma_soc_register_platform);
diff --git a/sound/soc/uniphier/aio-ld11.c b/sound/soc/uniphier/aio-ld11.c
new file mode 100644 (file)
index 0000000..4c4dd3d
--- /dev/null
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA driver for LD11/LD20.
+//
+// Copyright (c) 2016-2018 Socionext Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+// of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// 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 "aio.h"
+
+static const struct uniphier_aio_spec uniphier_aio_ld11[] = {
+       /* for HDMI PCM In, Pin:AI1Dx */
+       {
+               .name = AUD_NAME_PCMIN1,
+               .gname = AUD_GNAME_HDMI,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_INPUT,
+                       .rb    = { 21, 14, },
+                       .ch    = { 21, 14, },
+                       .iif   = { 5, 3, },
+                       .iport = { 0, AUD_HW_PCMIN1, },
+               },
+       },
+
+       /* for SIF In, Pin:AI2Dx */
+       {
+               .name = AUD_NAME_PCMIN2,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_INPUT,
+                       .rb    = { 22, 15, },
+                       .ch    = { 22, 15, },
+                       .iif   = { 6, 4, },
+                       .iport = { 1, AUD_HW_PCMIN2, },
+               },
+       },
+
+       /* for Line In, Pin:AI3Dx */
+       {
+               .name = AUD_NAME_PCMIN3,
+               .gname = AUD_GNAME_LINE,
+               .swm = {
+                       .type  = PORT_TYPE_EVE,
+                       .dir   = PORT_DIR_INPUT,
+                       .rb    = { 23, 16, },
+                       .ch    = { 23, 16, },
+                       .iif   = { 7, 5, },
+                       .iport = { 2, AUD_HW_PCMIN3, },
+               },
+       },
+
+       /* for S/PDIF In, Pin:AI1IEC */
+       {
+               .name = AUD_NAME_IECIN1,
+               .gname = AUD_GNAME_IEC,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_INPUT,
+                       .rb    = { 26, 17, },
+                       .ch    = { 26, 17, },
+                       .iif   = { 10, 6, },
+                       .iport = { 3, AUD_HW_IECIN1, },
+               },
+       },
+
+       /* for Speaker, Pin:AO1Dx */
+       {
+               .name = AUD_NAME_HPCMOUT1,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 0, 0, },
+                       .ch    = { 0, 0, },
+                       .oif   = { 0, 0, },
+                       .oport = { 0, AUD_HW_HPCMOUT1, },
+               },
+       },
+
+       /* for HDMI PCM, Pin:AO2Dx */
+       {
+               .name = AUD_NAME_PCMOUT1,
+               .gname = AUD_GNAME_HDMI,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 0, 0, },
+                       .ch    = { 0, 0, },
+                       .oif   = { 0, 0, },
+                       .oport = { 3, AUD_HW_PCMOUT1, },
+               },
+       },
+
+       /* for Line Out, Pin:LO2_x */
+       {
+               .name = AUD_NAME_PCMOUT2,
+               .gname = AUD_GNAME_LINE,
+               .swm = {
+                       .type  = PORT_TYPE_EVE,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 2, 2, },
+                       .ch    = { 2, 2, },
+                       .oif   = { 2, 2, },
+                       .oport = { 1, AUD_HW_PCMOUT2, },
+               },
+       },
+
+       /* for Headphone, Pin:HP1_x */
+       {
+               .name = AUD_NAME_PCMOUT3,
+               .swm = {
+                       .type  = PORT_TYPE_EVE,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 3, 3, },
+                       .ch    = { 3, 3, },
+                       .oif   = { 3, 3, },
+                       .oport = { 2, AUD_HW_PCMOUT3, },
+               },
+       },
+
+       /* for HW Sampling Rate Converter */
+       {
+               .name = AUD_NAME_EPCMOUT2,
+               .swm = {
+                       .type  = PORT_TYPE_CONV,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 7, 5, },
+                       .ch    = { 7, 5, },
+                       .oif   = { 7, 5, },
+                       .oport = { 6, AUD_HW_EPCMOUT2, },
+                       .och   = { 17, 12, },
+                       .iif   = { 1, 1, },
+               },
+       },
+
+       /* for HW Sampling Rate Converter 2 */
+       {
+               .name = AUD_NAME_EPCMOUT3,
+               .swm = {
+                       .type  = PORT_TYPE_CONV,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 8, 6, },
+                       .ch    = { 8, 6, },
+                       .oif   = { 8, 6, },
+                       .oport = { 7, AUD_HW_EPCMOUT3, },
+                       .och   = { 18, 13, },
+                       .iif   = { 2, 2, },
+               },
+       },
+
+       /* for S/PDIF Out, Pin:AO1IEC */
+       {
+               .name = AUD_NAME_HIECOUT1,
+               .gname = AUD_GNAME_IEC,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 1, 1, },
+                       .ch    = { 1, 1, },
+                       .oif   = { 1, 1, },
+                       .oport = { 12, AUD_HW_HIECOUT1, },
+               },
+       },
+
+       /* for S/PDIF Out, Pin:AO1IEC, Compress */
+       {
+               .name = AUD_NAME_HIECCOMPOUT1,
+               .gname = AUD_GNAME_IEC,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 1, 1, },
+                       .ch    = { 1, 1, },
+                       .oif   = { 1, 1, },
+                       .oport = { 12, AUD_HW_HIECOUT1, },
+               },
+       },
+};
+
+static const struct uniphier_aio_pll uniphier_aio_pll_ld11[] = {
+       [AUD_PLL_A1]   = { .enable = true, },
+       [AUD_PLL_F1]   = { .enable = true, },
+       [AUD_PLL_A2]   = { .enable = true, },
+       [AUD_PLL_F2]   = { .enable = true, },
+       [AUD_PLL_APLL] = { .enable = true, },
+       [AUD_PLL_RX0]  = { .enable = true, },
+       [AUD_PLL_USB0] = { .enable = true, },
+       [AUD_PLL_HSC0] = { .enable = true, },
+};
+
+static int uniphier_aio_ld11_probe(struct snd_soc_dai *dai)
+{
+       int ret;
+
+       ret = uniphier_aio_dai_probe(dai);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
+       if (ret < 0)
+               return ret;
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
+       if (ret < 0)
+               return ret;
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_dai_driver uniphier_aio_dai_ld11[] = {
+       {
+               .name    = AUD_GNAME_HDMI,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_PCMOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .capture = {
+                       .stream_name = AUD_NAME_PCMIN1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000 |
+                               SNDRV_PCM_RATE_44100 |
+                               SNDRV_PCM_RATE_32000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_PCMIN2,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .capture = {
+                       .stream_name = AUD_NAME_PCMIN2,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_GNAME_LINE,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_PCMOUT2,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .capture = {
+                       .stream_name = AUD_NAME_PCMIN3,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_HPCMOUT1,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_HPCMOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_PCMOUT3,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_PCMOUT3,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_HIECOUT1,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_HIECOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_spdif_ops,
+       },
+       {
+               .name    = AUD_NAME_EPCMOUT2,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_EPCMOUT2,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000 |
+                               SNDRV_PCM_RATE_44100 |
+                               SNDRV_PCM_RATE_32000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_EPCMOUT3,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_EPCMOUT3,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000 |
+                               SNDRV_PCM_RATE_44100 |
+                               SNDRV_PCM_RATE_32000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_HIECCOMPOUT1,
+               .probe   = uniphier_aio_ld11_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .compress_new = snd_soc_new_compress,
+               .playback = {
+                       .stream_name = AUD_NAME_HIECCOMPOUT1,
+                       .channels_min = 1,
+                       .channels_max = 1,
+               },
+               .ops = &uniphier_aio_spdif_ops,
+       },
+};
+
+static const struct uniphier_aio_chip_spec uniphier_aio_ld11_spec = {
+       .specs     = uniphier_aio_ld11,
+       .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
+       .dais      = uniphier_aio_dai_ld11,
+       .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
+       .plls      = uniphier_aio_pll_ld11,
+       .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
+       .addr_ext  = 0,
+};
+
+static const struct uniphier_aio_chip_spec uniphier_aio_ld20_spec = {
+       .specs     = uniphier_aio_ld11,
+       .num_specs = ARRAY_SIZE(uniphier_aio_ld11),
+       .dais      = uniphier_aio_dai_ld11,
+       .num_dais  = ARRAY_SIZE(uniphier_aio_dai_ld11),
+       .plls      = uniphier_aio_pll_ld11,
+       .num_plls  = ARRAY_SIZE(uniphier_aio_pll_ld11),
+       .addr_ext  = 1,
+};
+
+static const struct of_device_id uniphier_aio_of_match[] = {
+       {
+               .compatible = "socionext,uniphier-ld11-aio",
+               .data = &uniphier_aio_ld11_spec,
+       },
+       {
+               .compatible = "socionext,uniphier-ld20-aio",
+               .data = &uniphier_aio_ld20_spec,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
+
+static struct platform_driver uniphier_aio_driver = {
+       .driver = {
+               .name = "snd-uniphier-aio-ld11",
+               .of_match_table = of_match_ptr(uniphier_aio_of_match),
+       },
+       .probe    = uniphier_aio_probe,
+       .remove   = uniphier_aio_remove,
+};
+module_platform_driver(uniphier_aio_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier LD11/LD20 AIO driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/uniphier/aio-pxs2.c b/sound/soc/uniphier/aio-pxs2.c
new file mode 100644 (file)
index 0000000..69cd5b0
--- /dev/null
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext UniPhier AIO ALSA driver for PXs2.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/module.h>
+
+#include "aio.h"
+
+static const struct uniphier_aio_spec uniphier_aio_pxs2[] = {
+       /* for Line PCM In, Pin:AI1Dx */
+       {
+               .name = AUD_NAME_PCMIN1,
+               .gname = AUD_GNAME_LINE,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_INPUT,
+                       .rb    = { 16, 11, },
+                       .ch    = { 16, 11, },
+                       .iif   = { 0, 0, },
+                       .iport = { 0, AUD_HW_PCMIN1, },
+               },
+       },
+
+       /* for Speaker/Headphone/Mic PCM In, Pin:AI2Dx */
+       {
+               .name = AUD_NAME_PCMIN2,
+               .gname = AUD_GNAME_AUX,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_INPUT,
+                       .rb    = { 17, 12, },
+                       .ch    = { 17, 12, },
+                       .iif   = { 1, 1, },
+                       .iport = { 1, AUD_HW_PCMIN2, },
+               },
+       },
+
+       /* for HDMI PCM Out, Pin:AO1Dx (inner) */
+       {
+               .name = AUD_NAME_HPCMOUT1,
+               .gname = AUD_GNAME_HDMI,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 0, 0, },
+                       .ch    = { 0, 0, },
+                       .oif   = { 0, 0, },
+                       .oport = { 3, AUD_HW_HPCMOUT1, },
+               },
+       },
+
+       /* for Line PCM Out, Pin:AO2Dx */
+       {
+               .name = AUD_NAME_PCMOUT1,
+               .gname = AUD_GNAME_LINE,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 1, 1, },
+                       .ch    = { 1, 1, },
+                       .oif   = { 1, 1, },
+                       .oport = { 0, AUD_HW_PCMOUT1, },
+               },
+       },
+
+       /* for Speaker/Headphone/Mic PCM Out, Pin:AO3Dx */
+       {
+               .name = AUD_NAME_PCMOUT2,
+               .gname = AUD_GNAME_AUX,
+               .swm = {
+                       .type  = PORT_TYPE_I2S,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 2, 2, },
+                       .ch    = { 2, 2, },
+                       .oif   = { 2, 2, },
+                       .oport = { 1, AUD_HW_PCMOUT2, },
+               },
+       },
+
+       /* for HDMI Out, Pin:AO1IEC */
+       {
+               .name = AUD_NAME_HIECOUT1,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 6, 4, },
+                       .ch    = { 6, 4, },
+                       .oif   = { 6, 4, },
+                       .oport = { 12, AUD_HW_HIECOUT1, },
+               },
+       },
+
+       /* for HDMI Out, Pin:AO1IEC, Compress */
+       {
+               .name = AUD_NAME_HIECCOMPOUT1,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 6, 4, },
+                       .ch    = { 6, 4, },
+                       .oif   = { 6, 4, },
+                       .oport = { 12, AUD_HW_HIECOUT1, },
+               },
+       },
+
+       /* for S/PDIF Out, Pin:AO2IEC */
+       {
+               .name = AUD_NAME_IECOUT1,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 7, 5, },
+                       .ch    = { 7, 5, },
+                       .oif   = { 7, 5, },
+                       .oport = { 13, AUD_HW_IECOUT1, },
+               },
+       },
+
+       /* for S/PDIF Out, Pin:AO2IEC */
+       {
+               .name = AUD_NAME_IECCOMPOUT1,
+               .swm = {
+                       .type  = PORT_TYPE_SPDIF,
+                       .dir   = PORT_DIR_OUTPUT,
+                       .rb    = { 7, 5, },
+                       .ch    = { 7, 5, },
+                       .oif   = { 7, 5, },
+                       .oport = { 13, AUD_HW_IECOUT1, },
+               },
+       },
+};
+
+static const struct uniphier_aio_pll uniphier_aio_pll_pxs2[] = {
+       [AUD_PLL_A1]   = { .enable = true, },
+       [AUD_PLL_F1]   = { .enable = true, },
+       [AUD_PLL_A2]   = { .enable = true, },
+       [AUD_PLL_F2]   = { .enable = true, },
+       [AUD_PLL_APLL] = { .enable = true, },
+       [AUD_PLL_HSC0] = { .enable = true, },
+};
+
+static int uniphier_aio_pxs2_probe(struct snd_soc_dai *dai)
+{
+       int ret;
+
+       ret = uniphier_aio_dai_probe(dai);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
+       if (ret < 0)
+               return ret;
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
+       if (ret < 0)
+               return ret;
+       ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_dai_driver uniphier_aio_dai_pxs2[] = {
+       {
+               .name    = AUD_GNAME_HDMI,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_HPCMOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_GNAME_LINE,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_PCMOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .capture = {
+                       .stream_name = AUD_NAME_PCMIN1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_GNAME_AUX,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_PCMOUT2,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .capture = {
+                       .stream_name = AUD_NAME_PCMIN2,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_i2s_ops,
+       },
+       {
+               .name    = AUD_NAME_HIECOUT1,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_HIECOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_spdif_ops,
+       },
+       {
+               .name    = AUD_NAME_IECOUT1,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .playback = {
+                       .stream_name = AUD_NAME_IECOUT1,
+                       .formats     = SNDRV_PCM_FMTBIT_S32_LE,
+                       .rates       = SNDRV_PCM_RATE_48000,
+                       .channels_min = 2,
+                       .channels_max = 2,
+               },
+               .ops = &uniphier_aio_spdif_ops,
+       },
+       {
+               .name    = AUD_NAME_HIECCOMPOUT1,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .compress_new = snd_soc_new_compress,
+               .playback = {
+                       .stream_name = AUD_NAME_HIECCOMPOUT1,
+                       .channels_min = 1,
+                       .channels_max = 1,
+               },
+               .ops = &uniphier_aio_spdif_ops,
+       },
+       {
+               .name    = AUD_NAME_IECCOMPOUT1,
+               .probe   = uniphier_aio_pxs2_probe,
+               .remove  = uniphier_aio_dai_remove,
+               .suspend = uniphier_aio_dai_suspend,
+               .resume  = uniphier_aio_dai_resume,
+               .compress_new = snd_soc_new_compress,
+               .playback = {
+                       .stream_name = AUD_NAME_IECCOMPOUT1,
+                       .channels_min = 1,
+                       .channels_max = 1,
+               },
+               .ops = &uniphier_aio_spdif_ops,
+       },
+};
+
+static const struct uniphier_aio_chip_spec uniphier_aio_pxs2_spec = {
+       .specs     = uniphier_aio_pxs2,
+       .num_specs = ARRAY_SIZE(uniphier_aio_pxs2),
+       .dais      = uniphier_aio_dai_pxs2,
+       .num_dais  = ARRAY_SIZE(uniphier_aio_dai_pxs2),
+       .plls      = uniphier_aio_pll_pxs2,
+       .num_plls  = ARRAY_SIZE(uniphier_aio_pll_pxs2),
+       .addr_ext  = 0,
+};
+
+static const struct of_device_id uniphier_aio_of_match[] = {
+       {
+               .compatible = "socionext,uniphier-pxs2-aio",
+               .data = &uniphier_aio_pxs2_spec,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
+
+static struct platform_driver uniphier_aio_driver = {
+       .driver = {
+               .name = "snd-uniphier-aio-pxs2",
+               .of_match_table = of_match_ptr(uniphier_aio_of_match),
+       },
+       .probe    = uniphier_aio_probe,
+       .remove   = uniphier_aio_remove,
+};
+module_platform_driver(uniphier_aio_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/uniphier/aio-reg.h b/sound/soc/uniphier/aio-reg.h
new file mode 100644 (file)
index 0000000..136d356
--- /dev/null
@@ -0,0 +1,465 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier AIO ALSA driver.
+ *
+ * Copyright (c) 2016-2018 Socionext Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SND_UNIPHIER_AIO_REG_H__
+#define SND_UNIPHIER_AIO_REG_H__
+
+#include <linux/bitops.h>
+
+/* soc-glue */
+#define SG_AOUTEN                       0x1c04
+
+/* SW view */
+#define A2CHNMAPCTR0(n)                 (0x00000 + 0x40 * (n))
+#define A2RBNMAPCTR0(n)                 (0x01000 + 0x40 * (n))
+#define A2IPORTNMAPCTR0(n)              (0x02000 + 0x40 * (n))
+#define A2IPORTNMAPCTR1(n)              (0x02004 + 0x40 * (n))
+#define A2IIFNMAPCTR0(n)                (0x03000 + 0x40 * (n))
+#define A2OPORTNMAPCTR0(n)              (0x04000 + 0x40 * (n))
+#define A2OPORTNMAPCTR1(n)              (0x04004 + 0x40 * (n))
+#define A2OPORTNMAPCTR2(n)              (0x04008 + 0x40 * (n))
+#define A2OIFNMAPCTR0(n)                (0x05000 + 0x40 * (n))
+#define A2ATNMAPCTR0(n)                 (0x06000 + 0x40 * (n))
+
+#define MAPCTR0_EN                      0x80000000
+
+/* CTL */
+#define A2APLLCTR0                      0x07000
+#define   A2APLLCTR0_APLLXPOW_MASK        GENMASK(3, 0)
+#define   A2APLLCTR0_APLLXPOW_PWOFF       (0x0 << 0)
+#define   A2APLLCTR0_APLLXPOW_PWON        (0xf << 0)
+#define A2APLLCTR1                      0x07004
+#define   A2APLLCTR1_APLLX_MASK           0x00010101
+#define   A2APLLCTR1_APLLX_36MHZ          0x00000000
+#define   A2APLLCTR1_APLLX_33MHZ          0x00000001
+#define A2EXMCLKSEL0                    0x07030
+#define   A2EXMCLKSEL0_EXMCLK_MASK        GENMASK(2, 0)
+#define   A2EXMCLKSEL0_EXMCLK_OUTPUT      (0x0 << 0)
+#define   A2EXMCLKSEL0_EXMCLK_INPUT       (0x7 << 0)
+#define A2SSIFSW                        0x07050
+#define A2CH22_2CTR                     0x07054
+#define A2AIOINPUTSEL                   0x070e0
+#define   A2AIOINPUTSEL_RXSEL_PCMI1_MASK      GENMASK(2, 0)
+#define   A2AIOINPUTSEL_RXSEL_PCMI1_HDMIRX1   (0x2 << 0)
+#define   A2AIOINPUTSEL_RXSEL_PCMI2_MASK      GENMASK(6, 4)
+#define   A2AIOINPUTSEL_RXSEL_PCMI2_SIF       (0x7 << 4)
+#define   A2AIOINPUTSEL_RXSEL_PCMI3_MASK      GENMASK(10, 8)
+#define   A2AIOINPUTSEL_RXSEL_PCMI3_EVEA      (0x1 << 8)
+#define   A2AIOINPUTSEL_RXSEL_IECI1_MASK      GENMASK(14, 12)
+#define   A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1   (0x2 << 12)
+#define   A2AIOINPUTSEL_RXSEL_MASK        (A2AIOINPUTSEL_RXSEL_PCMI1_MASK | \
+                                          A2AIOINPUTSEL_RXSEL_PCMI2_MASK | \
+                                          A2AIOINPUTSEL_RXSEL_PCMI3_MASK | \
+                                          A2AIOINPUTSEL_RXSEL_IECI1_HDMIRX1)
+
+/* INTC */
+#define INTCHIM(m)                       (0x9028 + 0x80 * (m))
+#define INTRBIM(m)                       (0x9030 + 0x80 * (m))
+#define INTCHID(m)                       (0xa028 + 0x80 * (m))
+#define INTRBID(m)                       (0xa030 + 0x80 * (m))
+
+/* AIN(PCMINN) */
+#define IPORTMXCTR1(n)                   (0x22000 + 0x400 * (n))
+#define   IPORTMXCTR1_LRSEL_MASK           GENMASK(11, 10)
+#define   IPORTMXCTR1_LRSEL_RIGHT          (0x0 << 10)
+#define   IPORTMXCTR1_LRSEL_LEFT           (0x1 << 10)
+#define   IPORTMXCTR1_LRSEL_I2S            (0x2 << 10)
+#define   IPORTMXCTR1_OUTBITSEL_MASK       (0x800003U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_32         (0x800000U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_24         (0x000000U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_20         (0x000001U << 8)
+#define   IPORTMXCTR1_OUTBITSEL_16         (0x000002U << 8)
+#define   IPORTMXCTR1_CHSEL_MASK           GENMASK(6, 4)
+#define   IPORTMXCTR1_CHSEL_ALL            (0x0 << 4)
+#define   IPORTMXCTR1_CHSEL_D0_D2          (0x1 << 4)
+#define   IPORTMXCTR1_CHSEL_D0             (0x2 << 4)
+#define   IPORTMXCTR1_CHSEL_D1             (0x3 << 4)
+#define   IPORTMXCTR1_CHSEL_D2             (0x4 << 4)
+#define   IPORTMXCTR1_CHSEL_DMIX           (0x5 << 4)
+#define   IPORTMXCTR1_FSSEL_MASK           GENMASK(3, 0)
+#define   IPORTMXCTR1_FSSEL_48             (0x0 << 0)
+#define   IPORTMXCTR1_FSSEL_96             (0x1 << 0)
+#define   IPORTMXCTR1_FSSEL_192            (0x2 << 0)
+#define   IPORTMXCTR1_FSSEL_32             (0x3 << 0)
+#define   IPORTMXCTR1_FSSEL_44_1           (0x4 << 0)
+#define   IPORTMXCTR1_FSSEL_88_2           (0x5 << 0)
+#define   IPORTMXCTR1_FSSEL_176_4          (0x6 << 0)
+#define   IPORTMXCTR1_FSSEL_16             (0x8 << 0)
+#define   IPORTMXCTR1_FSSEL_22_05          (0x9 << 0)
+#define   IPORTMXCTR1_FSSEL_24             (0xa << 0)
+#define   IPORTMXCTR1_FSSEL_8              (0xb << 0)
+#define   IPORTMXCTR1_FSSEL_11_025         (0xc << 0)
+#define   IPORTMXCTR1_FSSEL_12             (0xd << 0)
+#define IPORTMXCTR2(n)                   (0x22004 + 0x400 * (n))
+#define   IPORTMXCTR2_ACLKSEL_MASK         GENMASK(19, 16)
+#define   IPORTMXCTR2_ACLKSEL_A1           (0x0 << 16)
+#define   IPORTMXCTR2_ACLKSEL_F1           (0x1 << 16)
+#define   IPORTMXCTR2_ACLKSEL_A2           (0x2 << 16)
+#define   IPORTMXCTR2_ACLKSEL_F2           (0x3 << 16)
+#define   IPORTMXCTR2_ACLKSEL_A2PLL        (0x4 << 16)
+#define   IPORTMXCTR2_ACLKSEL_RX1          (0x5 << 16)
+#define   IPORTMXCTR2_ACLKSEL_RX2          (0x6 << 16)
+#define   IPORTMXCTR2_MSSEL_MASK           BIT(15)
+#define   IPORTMXCTR2_MSSEL_SLAVE          (0x0 << 15)
+#define   IPORTMXCTR2_MSSEL_MASTER         (0x1 << 15)
+#define   IPORTMXCTR2_EXTLSIFSSEL_MASK     BIT(14)
+#define   IPORTMXCTR2_EXTLSIFSSEL_36       (0x0 << 14)
+#define   IPORTMXCTR2_EXTLSIFSSEL_24       (0x1 << 14)
+#define   IPORTMXCTR2_DACCKSEL_MASK        GENMASK(9, 8)
+#define   IPORTMXCTR2_DACCKSEL_1_2         (0x0 << 8)
+#define   IPORTMXCTR2_DACCKSEL_1_3         (0x1 << 8)
+#define   IPORTMXCTR2_DACCKSEL_1_1         (0x2 << 8)
+#define   IPORTMXCTR2_DACCKSEL_2_3         (0x3 << 8)
+#define   IPORTMXCTR2_REQEN_MASK           BIT(0)
+#define   IPORTMXCTR2_REQEN_DISABLE        (0x0 << 0)
+#define   IPORTMXCTR2_REQEN_ENABLE         (0x1 << 0)
+#define IPORTMXCNTCTR(n)                 (0x22010 + 0x400 * (n))
+#define IPORTMXCOUNTER(n)                (0x22014 + 0x400 * (n))
+#define IPORTMXCNTMONI(n)                (0x22018 + 0x400 * (n))
+#define IPORTMXACLKSEL0EX(n)             (0x22020 + 0x400 * (n))
+#define   IPORTMXACLKSEL0EX_ACLKSEL0EX_MASK        GENMASK(3, 0)
+#define   IPORTMXACLKSEL0EX_ACLKSEL0EX_INTERNAL    (0x0 << 0)
+#define   IPORTMXACLKSEL0EX_ACLKSEL0EX_EXTERNAL    (0xf << 0)
+#define IPORTMXEXNOE(n)                  (0x22070 + 0x400 * (n))
+#define   IPORTMXEXNOE_PCMINOE_MASK        BIT(0)
+#define   IPORTMXEXNOE_PCMINOE_OUTPUT      (0x0 << 0)
+#define   IPORTMXEXNOE_PCMINOE_INPUT       (0x1 << 0)
+#define IPORTMXMASK(n)                   (0x22078 + 0x400 * (n))
+#define   IPORTMXMASK_IUXCKMSK_MASK        GENMASK(18, 16)
+#define   IPORTMXMASK_IUXCKMSK_ON          (0x0 << 16)
+#define   IPORTMXMASK_IUXCKMSK_OFF         (0x7 << 16)
+#define   IPORTMXMASK_XCKMSK_MASK          GENMASK(2, 0)
+#define   IPORTMXMASK_XCKMSK_ON            (0x0 << 0)
+#define   IPORTMXMASK_XCKMSK_OFF           (0x7 << 0)
+#define IPORTMXRSTCTR(n)                 (0x2207c + 0x400 * (n))
+#define   IPORTMXRSTCTR_RSTPI_MASK         BIT(7)
+#define   IPORTMXRSTCTR_RSTPI_RELEASE      (0x0 << 7)
+#define   IPORTMXRSTCTR_RSTPI_RESET        (0x1 << 7)
+
+/* AIN(PBinMX) */
+#define PBINMXCTR(n)                     (0x20200 + 0x40 * (n))
+#define   PBINMXCTR_NCONNECT_MASK          BIT(15)
+#define   PBINMXCTR_NCONNECT_CONNECT       (0x0 << 15)
+#define   PBINMXCTR_NCONNECT_DISCONNECT    (0x1 << 15)
+#define   PBINMXCTR_INOUTSEL_MASK          BIT(14)
+#define   PBINMXCTR_INOUTSEL_IN            (0x0 << 14)
+#define   PBINMXCTR_INOUTSEL_OUT           (0x1 << 14)
+#define   PBINMXCTR_PBINSEL_SHIFT          (8)
+#define   PBINMXCTR_ENDIAN_MASK            GENMASK(5, 4)
+#define   PBINMXCTR_ENDIAN_3210            (0x0 << 4)
+#define   PBINMXCTR_ENDIAN_0123            (0x1 << 4)
+#define   PBINMXCTR_ENDIAN_1032            (0x2 << 4)
+#define   PBINMXCTR_ENDIAN_2301            (0x3 << 4)
+#define   PBINMXCTR_MEMFMT_MASK            GENMASK(3, 0)
+#define   PBINMXCTR_MEMFMT_D0              (0x0 << 0)
+#define   PBINMXCTR_MEMFMT_5_1CH_DMIX      (0x1 << 0)
+#define   PBINMXCTR_MEMFMT_6CH             (0x2 << 0)
+#define   PBINMXCTR_MEMFMT_4CH             (0x3 << 0)
+#define   PBINMXCTR_MEMFMT_DMIX            (0x4 << 0)
+#define   PBINMXCTR_MEMFMT_1CH             (0x5 << 0)
+#define   PBINMXCTR_MEMFMT_16LR            (0x6 << 0)
+#define   PBINMXCTR_MEMFMT_7_1CH           (0x7 << 0)
+#define   PBINMXCTR_MEMFMT_7_1CH_DMIX      (0x8 << 0)
+#define   PBINMXCTR_MEMFMT_STREAM          (0xf << 0)
+#define PBINMXPAUSECTR0(n)               (0x20204 + 0x40 * (n))
+#define PBINMXPAUSECTR1(n)               (0x20208 + 0x40 * (n))
+
+/* AOUT */
+#define AOUTENCTR0                       0x40040
+#define AOUTENCTR1                       0x40044
+#define AOUTENCTR2                       0x40048
+#define AOUTRSTCTR0                      0x40060
+#define AOUTRSTCTR1                      0x40064
+#define AOUTRSTCTR2                      0x40068
+#define AOUTSRCRSTCTR0                   0x400c0
+#define AOUTSRCRSTCTR1                   0x400c4
+#define AOUTSRCRSTCTR2                   0x400c8
+
+/* AOUT(PCMOUTN) */
+#define OPORTMXCTR1(n)                   (0x42000 + 0x400 * (n))
+#define   OPORTMXCTR1_I2SLRSEL_MASK        (0x11 << 10)
+#define   OPORTMXCTR1_I2SLRSEL_RIGHT       (0x00 << 10)
+#define   OPORTMXCTR1_I2SLRSEL_LEFT        (0x01 << 10)
+#define   OPORTMXCTR1_I2SLRSEL_I2S         (0x11 << 10)
+#define   OPORTMXCTR1_OUTBITSEL_MASK       (0x800003U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_32         (0x800000U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_24         (0x000000U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_20         (0x000001U << 8)
+#define   OPORTMXCTR1_OUTBITSEL_16         (0x000002U << 8)
+#define   OPORTMXCTR1_FSSEL_MASK           GENMASK(3, 0)
+#define   OPORTMXCTR1_FSSEL_48             (0x0 << 0)
+#define   OPORTMXCTR1_FSSEL_96             (0x1 << 0)
+#define   OPORTMXCTR1_FSSEL_192            (0x2 << 0)
+#define   OPORTMXCTR1_FSSEL_32             (0x3 << 0)
+#define   OPORTMXCTR1_FSSEL_44_1           (0x4 << 0)
+#define   OPORTMXCTR1_FSSEL_88_2           (0x5 << 0)
+#define   OPORTMXCTR1_FSSEL_176_4          (0x6 << 0)
+#define   OPORTMXCTR1_FSSEL_16             (0x8 << 0)
+#define   OPORTMXCTR1_FSSEL_22_05          (0x9 << 0)
+#define   OPORTMXCTR1_FSSEL_24             (0xa << 0)
+#define   OPORTMXCTR1_FSSEL_8              (0xb << 0)
+#define   OPORTMXCTR1_FSSEL_11_025         (0xc << 0)
+#define   OPORTMXCTR1_FSSEL_12             (0xd << 0)
+#define OPORTMXCTR2(n)                   (0x42004 + 0x400 * (n))
+#define   OPORTMXCTR2_ACLKSEL_MASK         GENMASK(19, 16)
+#define   OPORTMXCTR2_ACLKSEL_A1           (0x0 << 16)
+#define   OPORTMXCTR2_ACLKSEL_F1           (0x1 << 16)
+#define   OPORTMXCTR2_ACLKSEL_A2           (0x2 << 16)
+#define   OPORTMXCTR2_ACLKSEL_F2           (0x3 << 16)
+#define   OPORTMXCTR2_ACLKSEL_A2PLL        (0x4 << 16)
+#define   OPORTMXCTR2_ACLKSEL_RX1          (0x5 << 16)
+#define   OPORTMXCTR2_ACLKSEL_RX2          (0x6 << 16)
+#define   OPORTMXCTR2_MSSEL_MASK           BIT(15)
+#define   OPORTMXCTR2_MSSEL_SLAVE          (0x0 << 15)
+#define   OPORTMXCTR2_MSSEL_MASTER         (0x1 << 15)
+#define   OPORTMXCTR2_EXTLSIFSSEL_MASK     BIT(14)
+#define   OPORTMXCTR2_EXTLSIFSSEL_36       (0x0 << 14)
+#define   OPORTMXCTR2_EXTLSIFSSEL_24       (0x1 << 14)
+#define   OPORTMXCTR2_DACCKSEL_MASK        GENMASK(9, 8)
+#define   OPORTMXCTR2_DACCKSEL_1_2         (0x0 << 8)
+#define   OPORTMXCTR2_DACCKSEL_1_3         (0x1 << 8)
+#define   OPORTMXCTR2_DACCKSEL_1_1         (0x2 << 8)
+#define   OPORTMXCTR2_DACCKSEL_2_3         (0x3 << 8)
+#define OPORTMXCTR3(n)                   (0x42008 + 0x400 * (n))
+#define   OPORTMXCTR3_IECTHUR_MASK         BIT(19)
+#define   OPORTMXCTR3_IECTHUR_IECOUT       (0x0 << 19)
+#define   OPORTMXCTR3_IECTHUR_IECIN        (0x1 << 19)
+#define   OPORTMXCTR3_SRCSEL_MASK          GENMASK(18, 16)
+#define   OPORTMXCTR3_SRCSEL_PCM           (0x0 << 16)
+#define   OPORTMXCTR3_SRCSEL_STREAM        (0x1 << 16)
+#define   OPORTMXCTR3_SRCSEL_CDDTS         (0x2 << 16)
+#define   OPORTMXCTR3_VALID_MASK           BIT(12)
+#define   OPORTMXCTR3_VALID_PCM            (0x0 << 12)
+#define   OPORTMXCTR3_VALID_STREAM         (0x1 << 12)
+#define   OPORTMXCTR3_PMSEL_MASK           BIT(3)
+#define   OPORTMXCTR3_PMSEL_MUTE           (0x0 << 3)
+#define   OPORTMXCTR3_PMSEL_PAUSE          (0x1 << 3)
+#define   OPORTMXCTR3_PMSW_MASK            BIT(2)
+#define   OPORTMXCTR3_PMSW_MUTE_OFF        (0x0 << 2)
+#define   OPORTMXCTR3_PMSW_MUTE_ON         (0x1 << 2)
+#define OPORTMXSRC1CTR(n)                (0x4200c + 0x400 * (n))
+#define   OPORTMXSRC1CTR_FSIIPNUM_SHIFT    (24)
+#define   OPORTMXSRC1CTR_THMODE_MASK       BIT(23)
+#define   OPORTMXSRC1CTR_THMODE_SRC        (0x0 << 23)
+#define   OPORTMXSRC1CTR_THMODE_BYPASS     (0x1 << 23)
+#define   OPORTMXSRC1CTR_LOCK_MASK         BIT(16)
+#define   OPORTMXSRC1CTR_LOCK_UNLOCK       (0x0 << 16)
+#define   OPORTMXSRC1CTR_LOCK_LOCK         (0x1 << 16)
+#define   OPORTMXSRC1CTR_SRCPATH_MASK      BIT(15)
+#define   OPORTMXSRC1CTR_SRCPATH_BYPASS    (0x0 << 15)
+#define   OPORTMXSRC1CTR_SRCPATH_CALC      (0x1 << 15)
+#define   OPORTMXSRC1CTR_SYNC_MASK         BIT(14)
+#define   OPORTMXSRC1CTR_SYNC_ASYNC        (0x0 << 14)
+#define   OPORTMXSRC1CTR_SYNC_SYNC         (0x1 << 14)
+#define   OPORTMXSRC1CTR_FSOCK_MASK        GENMASK(11, 10)
+#define   OPORTMXSRC1CTR_FSOCK_44_1        (0x0 << 10)
+#define   OPORTMXSRC1CTR_FSOCK_48          (0x1 << 10)
+#define   OPORTMXSRC1CTR_FSOCK_32          (0x2 << 10)
+#define   OPORTMXSRC1CTR_FSICK_MASK        GENMASK(9, 8)
+#define   OPORTMXSRC1CTR_FSICK_44_1        (0x0 << 8)
+#define   OPORTMXSRC1CTR_FSICK_48          (0x1 << 8)
+#define   OPORTMXSRC1CTR_FSICK_32          (0x2 << 8)
+#define   OPORTMXSRC1CTR_FSIIPSEL_MASK     GENMASK(5, 4)
+#define   OPORTMXSRC1CTR_FSIIPSEL_INNER    (0x0 << 4)
+#define   OPORTMXSRC1CTR_FSIIPSEL_OUTER    (0x1 << 4)
+#define   OPORTMXSRC1CTR_FSISEL_MASK       GENMASK(3, 0)
+#define   OPORTMXSRC1CTR_FSISEL_ACLK       (0x0 << 0)
+#define   OPORTMXSRC1CTR_FSISEL_DD         (0x1 << 0)
+#define OPORTMXDSDMUTEDAT(n)             (0x42020 + 0x400 * (n))
+#define OPORTMXDXDFREQMODE(n)            (0x42024 + 0x400 * (n))
+#define OPORTMXDSDSEL(n)                 (0x42028 + 0x400 * (n))
+#define OPORTMXDSDPORT(n)                (0x4202c + 0x400 * (n))
+#define OPORTMXACLKSEL0EX(n)             (0x42030 + 0x400 * (n))
+#define OPORTMXPATH(n)                   (0x42040 + 0x400 * (n))
+#define OPORTMXSYNC(n)                   (0x42044 + 0x400 * (n))
+#define OPORTMXREPET(n)                  (0x42050 + 0x400 * (n))
+#define   OPORTMXREPET_STRLENGTH_AC3       SBF_(IEC61937_FRM_STR_AC3, 16)
+#define   OPORTMXREPET_STRLENGTH_MPA       SBF_(IEC61937_FRM_STR_MPA, 16)
+#define   OPORTMXREPET_STRLENGTH_MP3       SBF_(IEC61937_FRM_STR_MP3, 16)
+#define   OPORTMXREPET_STRLENGTH_DTS1      SBF_(IEC61937_FRM_STR_DTS1, 16)
+#define   OPORTMXREPET_STRLENGTH_DTS2      SBF_(IEC61937_FRM_STR_DTS2, 16)
+#define   OPORTMXREPET_STRLENGTH_DTS3      SBF_(IEC61937_FRM_STR_DTS3, 16)
+#define   OPORTMXREPET_STRLENGTH_AAC       SBF_(IEC61937_FRM_STR_AAC, 16)
+#define   OPORTMXREPET_PMLENGTH_AC3        SBF_(IEC61937_FRM_PAU_AC3, 0)
+#define   OPORTMXREPET_PMLENGTH_MPA        SBF_(IEC61937_FRM_PAU_MPA, 0)
+#define   OPORTMXREPET_PMLENGTH_MP3        SBF_(IEC61937_FRM_PAU_MP3, 0)
+#define   OPORTMXREPET_PMLENGTH_DTS1       SBF_(IEC61937_FRM_PAU_DTS1, 0)
+#define   OPORTMXREPET_PMLENGTH_DTS2       SBF_(IEC61937_FRM_PAU_DTS2, 0)
+#define   OPORTMXREPET_PMLENGTH_DTS3       SBF_(IEC61937_FRM_PAU_DTS3, 0)
+#define   OPORTMXREPET_PMLENGTH_AAC        SBF_(IEC61937_FRM_PAU_AAC, 0)
+#define OPORTMXPAUDAT(n)                 (0x42054 + 0x400 * (n))
+#define   OPORTMXPAUDAT_PAUSEPC_CMN        (IEC61937_PC_PAUSE << 16)
+#define   OPORTMXPAUDAT_PAUSEPD_AC3        (IEC61937_FRM_PAU_AC3 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_MPA        (IEC61937_FRM_PAU_MPA * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_MP3        (IEC61937_FRM_PAU_MP3 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_DTS1       (IEC61937_FRM_PAU_DTS1 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_DTS2       (IEC61937_FRM_PAU_DTS2 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_DTS3       (IEC61937_FRM_PAU_DTS3 * 4)
+#define   OPORTMXPAUDAT_PAUSEPD_AAC        (IEC61937_FRM_PAU_AAC * 4)
+#define OPORTMXRATE_I(n)                 (0x420e4 + 0x400 * (n))
+#define   OPORTMXRATE_I_EQU_MASK           BIT(31)
+#define   OPORTMXRATE_I_EQU_NOTEQUAL       (0x0 << 31)
+#define   OPORTMXRATE_I_EQU_EQUAL          (0x1 << 31)
+#define   OPORTMXRATE_I_SRCBPMD_MASK       BIT(29)
+#define   OPORTMXRATE_I_SRCBPMD_BYPASS     (0x0 << 29)
+#define   OPORTMXRATE_I_SRCBPMD_SRC        (0x1 << 29)
+#define   OPORTMXRATE_I_LRCKSTP_MASK       BIT(24)
+#define   OPORTMXRATE_I_LRCKSTP_START      (0x0 << 24)
+#define   OPORTMXRATE_I_LRCKSTP_STOP       (0x1 << 24)
+#define   OPORTMXRATE_I_ACLKSRC_MASK       GENMASK(15, 12)
+#define   OPORTMXRATE_I_ACLKSRC_APLL       (0x0 << 12)
+#define   OPORTMXRATE_I_ACLKSRC_USB        (0x1 << 12)
+#define   OPORTMXRATE_I_ACLKSRC_HSC        (0x3 << 12)
+/* if OPORTMXRATE_I_ACLKSRC_APLL */
+#define   OPORTMXRATE_I_ACLKSEL_MASK       GENMASK(11, 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLA1     (0x0 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLF1     (0x1 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLA2     (0x2 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLLF2     (0x3 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_APLL       (0x4 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_HDMI1      (0x5 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_HDMI2      (0x6 << 8)
+#define   OPORTMXRATE_I_ACLKSEL_AI1ADCCK   (0xc << 8)
+#define   OPORTMXRATE_I_ACLKSEL_AI2ADCCK   (0xd << 8)
+#define   OPORTMXRATE_I_ACLKSEL_AI3ADCCK   (0xe << 8)
+#define   OPORTMXRATE_I_MCKSEL_MASK        GENMASK(7, 4)
+#define   OPORTMXRATE_I_MCKSEL_36          (0x0 << 4)
+#define   OPORTMXRATE_I_MCKSEL_33          (0x1 << 4)
+#define   OPORTMXRATE_I_MCKSEL_HSC27       (0xb << 4)
+#define   OPORTMXRATE_I_FSSEL_MASK         GENMASK(3, 0)
+#define   OPORTMXRATE_I_FSSEL_48           (0x0 << 0)
+#define   OPORTMXRATE_I_FSSEL_96           (0x1 << 0)
+#define   OPORTMXRATE_I_FSSEL_192          (0x2 << 0)
+#define   OPORTMXRATE_I_FSSEL_32           (0x3 << 0)
+#define   OPORTMXRATE_I_FSSEL_44_1         (0x4 << 0)
+#define   OPORTMXRATE_I_FSSEL_88_2         (0x5 << 0)
+#define   OPORTMXRATE_I_FSSEL_176_4        (0x6 << 0)
+#define   OPORTMXRATE_I_FSSEL_16           (0x8 << 0)
+#define   OPORTMXRATE_I_FSSEL_22_05        (0x9 << 0)
+#define   OPORTMXRATE_I_FSSEL_24           (0xa << 0)
+#define   OPORTMXRATE_I_FSSEL_8            (0xb << 0)
+#define   OPORTMXRATE_I_FSSEL_11_025       (0xc << 0)
+#define   OPORTMXRATE_I_FSSEL_12           (0xd << 0)
+#define OPORTMXEXNOE(n)                  (0x420f0 + 0x400 * (n))
+#define OPORTMXMASK(n)                   (0x420f8 + 0x400 * (n))
+#define   OPORTMXMASK_IUDXMSK_MASK         GENMASK(28, 24)
+#define   OPORTMXMASK_IUDXMSK_ON           (0x00 << 24)
+#define   OPORTMXMASK_IUDXMSK_OFF          (0x1f << 24)
+#define   OPORTMXMASK_IUXCKMSK_MASK        GENMASK(18, 16)
+#define   OPORTMXMASK_IUXCKMSK_ON          (0x0 << 16)
+#define   OPORTMXMASK_IUXCKMSK_OFF         (0x7 << 16)
+#define   OPORTMXMASK_DXMSK_MASK           GENMASK(12, 8)
+#define   OPORTMXMASK_DXMSK_ON             (0x00 << 8)
+#define   OPORTMXMASK_DXMSK_OFF            (0x1f << 8)
+#define   OPORTMXMASK_XCKMSK_MASK          GENMASK(2, 0)
+#define   OPORTMXMASK_XCKMSK_ON            (0x0 << 0)
+#define   OPORTMXMASK_XCKMSK_OFF           (0x7 << 0)
+#define OPORTMXDEBUG(n)                  (0x420fc + 0x400 * (n))
+#define OPORTMXT0RSTCTR(n)               (0x4211c + 0x400 * (n))
+#define OPORTMXT1RSTCTR(n)               (0x4213c + 0x400 * (n))
+#define OPORTMXT2RSTCTR(n)               (0x4215c + 0x400 * (n))
+#define OPORTMXT3RSTCTR(n)               (0x4217c + 0x400 * (n))
+#define OPORTMXT4RSTCTR(n)               (0x4219c + 0x400 * (n))
+
+#define SBF_(frame, shift)    (((frame) * 2 - 1) << shift)
+
+/* AOUT(PBoutMX) */
+#define PBOUTMXCTR0(n)                   (0x40200 + 0x40 * (n))
+#define   PBOUTMXCTR0_ENDIAN_MASK         GENMASK(5, 4)
+#define   PBOUTMXCTR0_ENDIAN_3210         (0x0 << 4)
+#define   PBOUTMXCTR0_ENDIAN_0123         (0x1 << 4)
+#define   PBOUTMXCTR0_ENDIAN_1032         (0x2 << 4)
+#define   PBOUTMXCTR0_ENDIAN_2301         (0x3 << 4)
+#define   PBOUTMXCTR0_MEMFMT_MASK         GENMASK(3, 0)
+#define   PBOUTMXCTR0_MEMFMT_10CH         (0x0 << 0)
+#define   PBOUTMXCTR0_MEMFMT_8CH          (0x1 << 0)
+#define   PBOUTMXCTR0_MEMFMT_6CH          (0x2 << 0)
+#define   PBOUTMXCTR0_MEMFMT_4CH          (0x3 << 0)
+#define   PBOUTMXCTR0_MEMFMT_2CH          (0x4 << 0)
+#define   PBOUTMXCTR0_MEMFMT_STREAM       (0x5 << 0)
+#define   PBOUTMXCTR0_MEMFMT_1CH          (0x6 << 0)
+#define PBOUTMXCTR1(n)                   (0x40204 + 0x40 * (n))
+#define PBOUTMXINTCTR(n)                 (0x40208 + 0x40 * (n))
+
+/* A2D(subsystem) */
+#define CDA2D_STRT0                      0x10000
+#define   CDA2D_STRT0_STOP_MASK            BIT(31)
+#define   CDA2D_STRT0_STOP_START           (0x0 << 31)
+#define   CDA2D_STRT0_STOP_STOP            (0x1 << 31)
+#define CDA2D_STAT0                      0x10020
+#define CDA2D_TEST                       0x100a0
+#define   CDA2D_TEST_DDR_MODE_MASK         GENMASK(3, 2)
+#define   CDA2D_TEST_DDR_MODE_EXTON0       (0x0 << 2)
+#define   CDA2D_TEST_DDR_MODE_EXTOFF1      (0x3 << 2)
+#define CDA2D_STRTADRSLOAD               0x100b0
+
+#define CDA2D_CHMXCTRL1(n)               (0x12000 + 0x80 * (n))
+#define   CDA2D_CHMXCTRL1_INDSIZE_MASK     BIT(0)
+#define   CDA2D_CHMXCTRL1_INDSIZE_FINITE   (0x0 << 0)
+#define   CDA2D_CHMXCTRL1_INDSIZE_INFINITE (0x1 << 0)
+#define CDA2D_CHMXCTRL2(n)               (0x12004 + 0x80 * (n))
+#define CDA2D_CHMXSRCAMODE(n)            (0x12020 + 0x80 * (n))
+#define CDA2D_CHMXDSTAMODE(n)            (0x12024 + 0x80 * (n))
+#define   CDA2D_CHMXAMODE_ENDIAN_MASK      GENMASK(17, 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_3210      (0x0 << 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_0123      (0x1 << 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_1032      (0x2 << 16)
+#define   CDA2D_CHMXAMODE_ENDIAN_2301      (0x3 << 16)
+#define   CDA2D_CHMXAMODE_RSSEL_SHIFT      (8)
+#define   CDA2D_CHMXAMODE_AUPDT_MASK       GENMASK(5, 4)
+#define   CDA2D_CHMXAMODE_AUPDT_INC        (0x0 << 4)
+#define   CDA2D_CHMXAMODE_AUPDT_FIX        (0x2 << 4)
+#define   CDA2D_CHMXAMODE_TYPE_MASK        GENMASK(3, 2)
+#define   CDA2D_CHMXAMODE_TYPE_NORMAL      (0x0 << 2)
+#define   CDA2D_CHMXAMODE_TYPE_RING        (0x1 << 2)
+#define CDA2D_CHMXSRCSTRTADRS(n)         (0x12030 + 0x80 * (n))
+#define CDA2D_CHMXSRCSTRTADRSU(n)        (0x12034 + 0x80 * (n))
+#define CDA2D_CHMXDSTSTRTADRS(n)         (0x12038 + 0x80 * (n))
+#define CDA2D_CHMXDSTSTRTADRSU(n)        (0x1203c + 0x80 * (n))
+
+/* A2D(ring buffer) */
+#define CDA2D_RBFLUSH0                   0x10040
+#define CDA2D_RBADRSLOAD                 0x100b4
+#define CDA2D_RDPTRLOAD                  0x100b8
+#define   CDA2D_RDPTRLOAD_LSFLAG_LOAD      (0x0 << 31)
+#define   CDA2D_RDPTRLOAD_LSFLAG_STORE     (0x1 << 31)
+#define CDA2D_WRPTRLOAD                  0x100bc
+#define   CDA2D_WRPTRLOAD_LSFLAG_LOAD      (0x0 << 31)
+#define   CDA2D_WRPTRLOAD_LSFLAG_STORE     (0x1 << 31)
+
+#define CDA2D_RBMXBGNADRS(n)             (0x14000 + 0x80 * (n))
+#define CDA2D_RBMXBGNADRSU(n)            (0x14004 + 0x80 * (n))
+#define CDA2D_RBMXENDADRS(n)             (0x14008 + 0x80 * (n))
+#define CDA2D_RBMXENDADRSU(n)            (0x1400c + 0x80 * (n))
+#define CDA2D_RBMXBTH(n)                 (0x14038 + 0x80 * (n))
+#define CDA2D_RBMXRTH(n)                 (0x1403c + 0x80 * (n))
+#define CDA2D_RBMXRDPTR(n)               (0x14020 + 0x80 * (n))
+#define CDA2D_RBMXRDPTRU(n)              (0x14024 + 0x80 * (n))
+#define CDA2D_RBMXWRPTR(n)               (0x14028 + 0x80 * (n))
+#define CDA2D_RBMXWRPTRU(n)              (0x1402c + 0x80 * (n))
+#define   CDA2D_RBMXPTRU_PTRU_MASK         GENMASK(1, 0)
+#define CDA2D_RBMXCNFG(n)                (0x14030 + 0x80 * (n))
+#define CDA2D_RBMXIR(n)                  (0x14014 + 0x80 * (n))
+#define CDA2D_RBMXIE(n)                  (0x14018 + 0x80 * (n))
+#define CDA2D_RBMXID(n)                  (0x1401c + 0x80 * (n))
+#define   CDA2D_RBMXIX_SPACE               BIT(3)
+#define   CDA2D_RBMXIX_REMAIN              BIT(4)
+
+#endif /* SND_UNIPHIER_AIO_REG_H__ */
diff --git a/sound/soc/uniphier/aio.h b/sound/soc/uniphier/aio.h
new file mode 100644 (file)
index 0000000..8cab4a5
--- /dev/null
@@ -0,0 +1,359 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext UniPhier AIO ALSA driver.
+ *
+ * Copyright (c) 2016-2018 Socionext Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SND_UNIPHIER_AIO_H__
+#define SND_UNIPHIER_AIO_H__
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+struct platform_device;
+
+enum ID_PORT_TYPE {
+       PORT_TYPE_UNKNOWN,
+       PORT_TYPE_I2S,
+       PORT_TYPE_SPDIF,
+       PORT_TYPE_EVE,
+       PORT_TYPE_CONV,
+};
+
+enum ID_PORT_DIR {
+       PORT_DIR_OUTPUT,
+       PORT_DIR_INPUT,
+};
+
+enum IEC61937_PC {
+       IEC61937_PC_AC3   = 0x0001,
+       IEC61937_PC_PAUSE = 0x0003,
+       IEC61937_PC_MPA   = 0x0004,
+       IEC61937_PC_MP3   = 0x0005,
+       IEC61937_PC_DTS1  = 0x000b,
+       IEC61937_PC_DTS2  = 0x000c,
+       IEC61937_PC_DTS3  = 0x000d,
+       IEC61937_PC_AAC   = 0x0007,
+};
+
+/* IEC61937 Repetition period of data-burst in IEC60958 frames */
+#define IEC61937_FRM_STR_AC3       1536
+#define IEC61937_FRM_STR_MPA       1152
+#define IEC61937_FRM_STR_MP3       1152
+#define IEC61937_FRM_STR_DTS1      512
+#define IEC61937_FRM_STR_DTS2      1024
+#define IEC61937_FRM_STR_DTS3      2048
+#define IEC61937_FRM_STR_AAC       1024
+
+/* IEC61937 Repetition period of Pause data-burst in IEC60958 frames */
+#define IEC61937_FRM_PAU_AC3       3
+#define IEC61937_FRM_PAU_MPA       32
+#define IEC61937_FRM_PAU_MP3       32
+#define IEC61937_FRM_PAU_DTS1      3
+#define IEC61937_FRM_PAU_DTS2      3
+#define IEC61937_FRM_PAU_DTS3      3
+#define IEC61937_FRM_PAU_AAC       32
+
+/* IEC61937 Pa and Pb */
+#define IEC61937_HEADER_SIGN       0x1f4e72f8
+
+#define AUD_HW_PCMIN1    0
+#define AUD_HW_PCMIN2    1
+#define AUD_HW_PCMIN3    2
+#define AUD_HW_IECIN1    3
+#define AUD_HW_DIECIN1   4
+
+#define AUD_NAME_PCMIN1     "aio-pcmin1"
+#define AUD_NAME_PCMIN2     "aio-pcmin2"
+#define AUD_NAME_PCMIN3     "aio-pcmin3"
+#define AUD_NAME_IECIN1     "aio-iecin1"
+#define AUD_NAME_DIECIN1    "aio-diecin1"
+
+#define AUD_HW_HPCMOUT1    0
+#define AUD_HW_PCMOUT1     1
+#define AUD_HW_PCMOUT2     2
+#define AUD_HW_PCMOUT3     3
+#define AUD_HW_EPCMOUT1    4
+#define AUD_HW_EPCMOUT2    5
+#define AUD_HW_EPCMOUT3    6
+#define AUD_HW_EPCMOUT6    9
+#define AUD_HW_HIECOUT1    10
+#define AUD_HW_IECOUT1     11
+#define AUD_HW_CMASTER     31
+
+#define AUD_NAME_HPCMOUT1        "aio-hpcmout1"
+#define AUD_NAME_PCMOUT1         "aio-pcmout1"
+#define AUD_NAME_PCMOUT2         "aio-pcmout2"
+#define AUD_NAME_PCMOUT3         "aio-pcmout3"
+#define AUD_NAME_EPCMOUT1        "aio-epcmout1"
+#define AUD_NAME_EPCMOUT2        "aio-epcmout2"
+#define AUD_NAME_EPCMOUT3        "aio-epcmout3"
+#define AUD_NAME_EPCMOUT6        "aio-epcmout6"
+#define AUD_NAME_HIECOUT1        "aio-hiecout1"
+#define AUD_NAME_IECOUT1         "aio-iecout1"
+#define AUD_NAME_CMASTER         "aio-cmaster"
+#define AUD_NAME_HIECCOMPOUT1    "aio-hieccompout1"
+#define AUD_NAME_IECCOMPOUT1     "aio-ieccompout1"
+
+#define AUD_GNAME_HDMI    "aio-hdmi"
+#define AUD_GNAME_LINE    "aio-line"
+#define AUD_GNAME_AUX     "aio-aux"
+#define AUD_GNAME_IEC     "aio-iec"
+
+#define AUD_CLK_IO        0
+#define AUD_CLK_A1        1
+#define AUD_CLK_F1        2
+#define AUD_CLK_A2        3
+#define AUD_CLK_F2        4
+#define AUD_CLK_A         5
+#define AUD_CLK_F         6
+#define AUD_CLK_APLL      7
+#define AUD_CLK_RX0       8
+#define AUD_CLK_USB0      9
+#define AUD_CLK_HSC0      10
+
+#define AUD_PLL_A1        0
+#define AUD_PLL_F1        1
+#define AUD_PLL_A2        2
+#define AUD_PLL_F2        3
+#define AUD_PLL_APLL      4
+#define AUD_PLL_RX0       5
+#define AUD_PLL_USB0      6
+#define AUD_PLL_HSC0      7
+
+#define AUD_PLLDIV_1_2    0
+#define AUD_PLLDIV_1_3    1
+#define AUD_PLLDIV_1_1    2
+#define AUD_PLLDIV_2_3    3
+
+#define AUD_RING_SIZE            (128 * 1024)
+
+#define AUD_MIN_FRAGMENT         4
+#define AUD_MAX_FRAGMENT         8
+#define AUD_MIN_FRAGMENT_SIZE    (4 * 1024)
+#define AUD_MAX_FRAGMENT_SIZE    (16 * 1024)
+
+/*
+ * This is a selector for virtual register map of AIO.
+ *
+ * map:  Specify the index of virtual register map.
+ * hw :  Specify the ID of real register map, selector uses this value.
+ *       A meaning of this value depends specification of SoC.
+ */
+struct uniphier_aio_selector {
+       int map;
+       int hw;
+};
+
+/**
+ * 'SoftWare MAPping' setting of UniPhier AIO registers.
+ *
+ * We have to setup 'virtual' register maps to access 'real' registers of AIO.
+ * This feature is legacy and meaningless but AIO needs this to work.
+ *
+ * Each hardware blocks have own virtual register maps as following:
+ *
+ * Address Virtual                      Real
+ * ------- ---------                    ---------------
+ * 0x12000 DMAC map0 --> [selector] --> DMAC hardware 3
+ * 0x12080 DMAC map1 --> [selector] --> DMAC hardware 1
+ * ...
+ * 0x42000 Port map0 --> [selector] --> Port hardware 1
+ * 0x42400 Port map1 --> [selector] --> Port hardware 2
+ * ...
+ *
+ * ch   : Input or output channel of DMAC
+ * rb   : Ring buffer
+ * iport: PCM input port
+ * iif  : Input interface
+ * oport: PCM output port
+ * oif  : Output interface
+ * och  : Output channel of DMAC for sampling rate converter
+ *
+ * These are examples for sound data paths:
+ *
+ * For caputure device:
+ *   (outer of AIO) -> iport -> iif -> ch -> rb -> (CPU)
+ * For playback device:
+ *   (CPU) -> rb -> ch -> oif -> oport -> (outer of AIO)
+ * For sampling rate converter device:
+ *   (CPU) -> rb -> ch -> oif -> (HW SRC) -> iif -> och -> orb -> (CPU)
+ */
+struct uniphier_aio_swmap {
+       int type;
+       int dir;
+
+       struct uniphier_aio_selector ch;
+       struct uniphier_aio_selector rb;
+       struct uniphier_aio_selector iport;
+       struct uniphier_aio_selector iif;
+       struct uniphier_aio_selector oport;
+       struct uniphier_aio_selector oif;
+       struct uniphier_aio_selector och;
+};
+
+struct uniphier_aio_spec {
+       const char *name;
+       const char *gname;
+       struct uniphier_aio_swmap swm;
+};
+
+struct uniphier_aio_pll {
+       bool enable;
+       unsigned int freq;
+};
+
+struct uniphier_aio_chip_spec {
+       const struct uniphier_aio_spec *specs;
+       int num_specs;
+       const struct uniphier_aio_pll *plls;
+       int num_plls;
+       struct snd_soc_dai_driver *dais;
+       int num_dais;
+
+       /* DMA access mode, this is workaround for DMA hungup */
+       int addr_ext;
+};
+
+struct uniphier_aio_sub {
+       struct uniphier_aio *aio;
+
+       /* Guard sub->rd_offs and wr_offs from IRQ handler. */
+       spinlock_t lock;
+
+       const struct uniphier_aio_swmap *swm;
+       const struct uniphier_aio_spec *spec;
+
+       /* For PCM audio */
+       struct snd_pcm_substream *substream;
+       struct snd_pcm_hw_params params;
+
+       /* For compress audio */
+       struct snd_compr_stream *cstream;
+       struct snd_compr_params cparams;
+       unsigned char *compr_area;
+       dma_addr_t compr_addr;
+       size_t compr_bytes;
+       int pass_through;
+       enum IEC61937_PC iec_pc;
+       bool iec_header;
+
+       /* Both PCM and compress audio */
+       bool use_mmap;
+       int setting;
+       int running;
+       u64 rd_offs;
+       u64 wr_offs;
+       u32 threshold;
+       u64 rd_org;
+       u64 wr_org;
+       u64 rd_total;
+       u64 wr_total;
+};
+
+struct uniphier_aio {
+       struct uniphier_aio_chip *chip;
+
+       struct uniphier_aio_sub sub[2];
+
+       unsigned int fmt;
+       /* Set one of AUD_CLK_X */
+       int clk_in;
+       int clk_out;
+       /* Set one of AUD_PLL_X */
+       int pll_in;
+       int pll_out;
+       /* Set one of AUD_PLLDIV_X */
+       int plldiv;
+};
+
+struct uniphier_aio_chip {
+       struct platform_device *pdev;
+       const struct uniphier_aio_chip_spec *chip_spec;
+
+       struct uniphier_aio *aios;
+       int num_aios;
+       struct uniphier_aio_pll *plls;
+       int num_plls;
+
+       struct clk *clk;
+       struct reset_control *rst;
+       struct regmap *regmap;
+       struct regmap *regmap_sg;
+       int active;
+};
+
+static inline struct uniphier_aio *uniphier_priv(struct snd_soc_dai *dai)
+{
+       struct uniphier_aio_chip *chip = snd_soc_dai_get_drvdata(dai);
+
+       return &chip->aios[dai->id];
+}
+
+int uniphier_aiodma_soc_register_platform(struct platform_device *pdev);
+extern const struct snd_compr_ops uniphier_aio_compr_ops;
+
+int uniphier_aio_dai_probe(struct snd_soc_dai *dai);
+int uniphier_aio_dai_remove(struct snd_soc_dai *dai);
+int uniphier_aio_dai_suspend(struct snd_soc_dai *dai);
+int uniphier_aio_dai_resume(struct snd_soc_dai *dai);
+int uniphier_aio_probe(struct platform_device *pdev);
+int uniphier_aio_remove(struct platform_device *pdev);
+extern const struct snd_soc_dai_ops uniphier_aio_i2s_ops;
+extern const struct snd_soc_dai_ops uniphier_aio_spdif_ops;
+
+u64 aio_rb_cnt(struct uniphier_aio_sub *sub);
+u64 aio_rbt_cnt_to_end(struct uniphier_aio_sub *sub);
+u64 aio_rb_space(struct uniphier_aio_sub *sub);
+u64 aio_rb_space_to_end(struct uniphier_aio_sub *sub);
+
+void aio_iecout_set_enable(struct uniphier_aio_chip *chip, bool enable);
+int aio_chip_set_pll(struct uniphier_aio_chip *chip, int pll_id,
+                    unsigned int freq);
+void aio_chip_init(struct uniphier_aio_chip *chip);
+int aio_init(struct uniphier_aio_sub *sub);
+void aio_port_reset(struct uniphier_aio_sub *sub);
+int aio_port_set_rate(struct uniphier_aio_sub *sub, int rate);
+int aio_port_set_fmt(struct uniphier_aio_sub *sub);
+int aio_port_set_clk(struct uniphier_aio_sub *sub);
+int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
+                      const struct snd_pcm_hw_params *params);
+void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable);
+int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through);
+int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
+                             enum IEC61937_PC pc);
+void aio_src_reset(struct uniphier_aio_sub *sub);
+int aio_src_set_param(struct uniphier_aio_sub *sub,
+                     const struct snd_pcm_hw_params *params);
+int aio_srcif_set_param(struct uniphier_aio_sub *sub);
+int aio_srcch_set_param(struct uniphier_aio_sub *sub);
+void aio_srcch_set_enable(struct uniphier_aio_sub *sub, int enable);
+
+int aiodma_ch_set_param(struct uniphier_aio_sub *sub);
+void aiodma_ch_set_enable(struct uniphier_aio_sub *sub, int enable);
+int aiodma_rb_set_threshold(struct uniphier_aio_sub *sub, u64 size, u32 th);
+int aiodma_rb_set_buffer(struct uniphier_aio_sub *sub, u64 start, u64 end,
+                        int period);
+void aiodma_rb_sync(struct uniphier_aio_sub *sub, u64 start, u64 size,
+                   int period);
+bool aiodma_rb_is_irq(struct uniphier_aio_sub *sub);
+void aiodma_rb_clear_irq(struct uniphier_aio_sub *sub);
+
+#endif /* SND_UNIPHIER_AIO_H__ */
index 0cc9efff1d9a557c08fac3dcb30dd553f429070d..73fd6730095c3714a3658b015aaa2f838d434a43 100644 (file)
@@ -1,22 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * Socionext UniPhier EVEA ADC/DAC codec driver.
- *
- * Copyright (c) 2016-2017 Socionext Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
+//
+// Socionext UniPhier EVEA ADC/DAC codec driver.
+//
+// Copyright (c) 2016-2017 Socionext Inc.
 
 #include <linux/clk.h>
 #include <linux/module.h>
@@ -32,6 +18,8 @@
 
 #define AADCPOW(n)                           (0x0078 + 0x04 * (n))
 #define   AADCPOW_AADC_POWD                   BIT(0)
+#define ALINSW1                              0x0088
+#define   ALINSW1_SEL1_SHIFT                  3
 #define AHPOUTPOW                            0x0098
 #define   AHPOUTPOW_HP_ON                     BIT(4)
 #define ALINEPOW                             0x009c
@@ -220,8 +208,8 @@ static void evea_update_switch_all(struct evea_priv *evea)
 static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = evea->switch_lin;
 
@@ -231,8 +219,8 @@ static int evea_get_switch_lin(struct snd_kcontrol *kcontrol,
 static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
                               struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        if (evea->switch_lin == ucontrol->value.integer.value[0])
                return 0;
@@ -245,8 +233,8 @@ static int evea_set_switch_lin(struct snd_kcontrol *kcontrol,
 static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = evea->switch_lo;
 
@@ -256,8 +244,8 @@ static int evea_get_switch_lo(struct snd_kcontrol *kcontrol,
 static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        if (evea->switch_lo == ucontrol->value.integer.value[0])
                return 0;
@@ -270,8 +258,8 @@ static int evea_set_switch_lo(struct snd_kcontrol *kcontrol,
 static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        ucontrol->value.integer.value[0] = evea->switch_hp;
 
@@ -281,8 +269,8 @@ static int evea_get_switch_hp(struct snd_kcontrol *kcontrol,
 static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        if (evea->switch_hp == ucontrol->value.integer.value[0])
                return 0;
@@ -292,7 +280,16 @@ static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
        return evea_update_switch_hp(evea);
 }
 
-static const struct snd_kcontrol_new eva_controls[] = {
+static const char * const linsw1_sel1_text[] = {
+       "LIN1", "LIN2", "LIN3"
+};
+
+static SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
+       ALINSW1, ALINSW1_SEL1_SHIFT,
+       linsw1_sel1_text);
+
+static const struct snd_kcontrol_new evea_controls[] = {
+       SOC_ENUM("Line Capture Source", linsw1_sel1_enum),
        SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0,
                            evea_get_switch_lin, evea_set_switch_lin),
        SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0,
@@ -301,9 +298,9 @@ static const struct snd_kcontrol_new eva_controls[] = {
                            evea_get_switch_hp, evea_set_switch_hp),
 };
 
-static int evea_codec_probe(struct snd_soc_codec *codec)
+static int evea_codec_probe(struct snd_soc_component *component)
 {
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        evea->switch_lin = 1;
        evea->switch_lo = 1;
@@ -315,9 +312,9 @@ static int evea_codec_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int evea_codec_suspend(struct snd_soc_codec *codec)
+static int evea_codec_suspend(struct snd_soc_component *component)
 {
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
 
        evea_set_power_state_off(evea);
 
@@ -331,9 +328,9 @@ static int evea_codec_suspend(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int evea_codec_resume(struct snd_soc_codec *codec)
+static int evea_codec_resume(struct snd_soc_component *component)
 {
-       struct evea_priv *evea = snd_soc_codec_get_drvdata(codec);
+       struct evea_priv *evea = snd_soc_component_get_drvdata(component);
        int ret;
 
        ret = clk_prepare_enable(evea->clk);
@@ -376,19 +373,20 @@ err_out_clock:
        return ret;
 }
 
-static struct snd_soc_codec_driver soc_codec_evea = {
-       .probe   = evea_codec_probe,
-       .suspend = evea_codec_suspend,
-       .resume  = evea_codec_resume,
-
-       .component_driver = {
-               .dapm_widgets = evea_widgets,
-               .num_dapm_widgets = ARRAY_SIZE(evea_widgets),
-               .dapm_routes = evea_routes,
-               .num_dapm_routes = ARRAY_SIZE(evea_routes),
-               .controls = eva_controls,
-               .num_controls = ARRAY_SIZE(eva_controls),
-       },
+static struct snd_soc_component_driver soc_codec_evea = {
+       .probe                  = evea_codec_probe,
+       .suspend                = evea_codec_suspend,
+       .resume                 = evea_codec_resume,
+       .dapm_widgets           = evea_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(evea_widgets),
+       .dapm_routes            = evea_routes,
+       .num_dapm_routes        = ARRAY_SIZE(evea_routes),
+       .controls               = evea_controls,
+       .num_controls           = ARRAY_SIZE(evea_controls),
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static struct snd_soc_dai_driver soc_dai_evea[] = {
@@ -505,7 +503,7 @@ static int evea_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, evea);
 
-       ret = snd_soc_register_codec(&pdev->dev, &soc_codec_evea,
+       ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_evea,
                                     soc_dai_evea, ARRAY_SIZE(soc_dai_evea));
        if (ret)
                goto err_out_reset_adamv;
@@ -534,8 +532,6 @@ static int evea_remove(struct platform_device *pdev)
 {
        struct evea_priv *evea = platform_get_drvdata(pdev);
 
-       snd_soc_unregister_codec(&pdev->dev);
-
        reset_control_assert(evea->rst_adamv);
        reset_control_assert(evea->rst_exiv);
        reset_control_assert(evea->rst);
index 2472144b329efed09b919ae05b65226cc0a01960..5035609166202da0fcdc6b9d383b95eba79f14be 100644 (file)
@@ -483,13 +483,10 @@ static const struct snd_pcm_ops xtfpga_pcm_ops = {
        .pointer        = xtfpga_pcm_pointer,
 };
 
-static const struct snd_soc_platform_driver xtfpga_soc_platform = {
-       .pcm_new        = xtfpga_pcm_new,
-       .ops            = &xtfpga_pcm_ops,
-};
-
 static const struct snd_soc_component_driver xtfpga_i2s_component = {
        .name           = DRV_NAME,
+       .pcm_new        = xtfpga_pcm_new,
+       .ops            = &xtfpga_pcm_ops,
 };
 
 static const struct snd_soc_dai_ops xtfpga_i2s_dai_ops = {
@@ -591,18 +588,13 @@ static int xtfpga_i2s_probe(struct platform_device *pdev)
                goto err;
        }
 
-       err = snd_soc_register_platform(&pdev->dev, &xtfpga_soc_platform);
-       if (err < 0) {
-               dev_err(&pdev->dev, "couldn't register platform\n");
-               goto err;
-       }
        err = devm_snd_soc_register_component(&pdev->dev,
                                              &xtfpga_i2s_component,
                                              xtfpga_i2s_dai,
                                              ARRAY_SIZE(xtfpga_i2s_dai));
        if (err < 0) {
                dev_err(&pdev->dev, "couldn't register component\n");
-               goto err_unregister_platform;
+               goto err;
        }
 
        pm_runtime_enable(&pdev->dev);
@@ -615,8 +607,6 @@ static int xtfpga_i2s_probe(struct platform_device *pdev)
 
 err_pm_disable:
        pm_runtime_disable(&pdev->dev);
-err_unregister_platform:
-       snd_soc_unregister_platform(&pdev->dev);
 err:
        dev_err(&pdev->dev, "%s: err = %d\n", __func__, err);
        return err;
@@ -626,7 +616,6 @@ static int xtfpga_i2s_remove(struct platform_device *pdev)
 {
        struct xtfpga_i2s *i2s = dev_get_drvdata(&pdev->dev);
 
-       snd_soc_unregister_platform(&pdev->dev);
        if (i2s->regmap && !IS_ERR(i2s->regmap)) {
                regmap_write(i2s->regmap, XTFPGA_I2S_CONFIG, 0);
                regmap_write(i2s->regmap, XTFPGA_I2S_INT_MASK, 0);
index 9afb8ab524c7ebfc7979794b169105368a202fce..06b22624ab7a0d9b832980a1d58a4c2a21df3844 100644 (file)
@@ -347,17 +347,20 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
                            int validx, int *value_ret)
 {
        struct snd_usb_audio *chip = cval->head.mixer->chip;
-       unsigned char buf[4 + 3 * sizeof(__u32)]; /* enough space for one range */
+       /* enough space for one range */
+       unsigned char buf[sizeof(__u16) + 3 * sizeof(__u32)];
        unsigned char *val;
-       int idx = 0, ret, size;
+       int idx = 0, ret, val_size, size;
        __u8 bRequest;
 
+       val_size = uac2_ctl_value_size(cval->val_type);
+
        if (request == UAC_GET_CUR) {
                bRequest = UAC2_CS_CUR;
-               size = uac2_ctl_value_size(cval->val_type);
+               size = val_size;
        } else {
                bRequest = UAC2_CS_RANGE;
-               size = sizeof(buf);
+               size = sizeof(__u16) + 3 * val_size;
        }
 
        memset(buf, 0, sizeof(buf));
@@ -390,16 +393,17 @@ error:
                val = buf + sizeof(__u16);
                break;
        case UAC_GET_MAX:
-               val = buf + sizeof(__u16) * 2;
+               val = buf + sizeof(__u16) + val_size;
                break;
        case UAC_GET_RES:
-               val = buf + sizeof(__u16) * 3;
+               val = buf + sizeof(__u16) + val_size * 2;
                break;
        default:
                return -EINVAL;
        }
 
-       *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
+       *value_ret = convert_signed_value(cval,
+                                         snd_usb_combine_bytes(val, val_size));
 
        return 0;
 }
index b9c9a19f9588a8c2eab67e6bd2ad8e5b531c7655..3cbfae6604f98b77f5cc6fe12c32ce4f7ce477c7 100644 (file)
@@ -352,6 +352,15 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
                ep = 0x86;
                iface = usb_ifnum_to_if(dev, 2);
 
+               if (!iface || iface->num_altsetting == 0)
+                       return -EINVAL;
+
+               alts = &iface->altsetting[1];
+               goto add_sync_ep;
+       case USB_ID(0x1397, 0x0002):
+               ep = 0x81;
+               iface = usb_ifnum_to_if(dev, 1);
+
                if (!iface || iface->num_altsetting == 0)
                        return -EINVAL;
 
index 50252046b01df7cdb376e1c8ae8c59559befdd1f..754e632a27bd2e8c15931e821fa158bf50bfdb78 100644 (file)
@@ -3325,4 +3325,51 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
        }
 },
 
+{
+       /*
+        * Bower's & Wilkins PX headphones only support the 48 kHz sample rate
+        * even though it advertises more. The capture interface doesn't work
+        * even on windows.
+        */
+       USB_DEVICE(0x19b5, 0x0021),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = (const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_STANDARD_MIXER,
+                       },
+                       /* Capture */
+                       {
+                               .ifnum = 1,
+                               .type = QUIRK_IGNORE_INTERFACE,
+                       },
+                       /* Playback */
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = &(const struct audioformat) {
+                                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                                       .channels = 2,
+                                       .iface = 2,
+                                       .altsetting = 1,
+                                       .altset_idx = 1,
+                                       .attributes = UAC_EP_CS_ATTR_FILL_MAX |
+                                               UAC_EP_CS_ATTR_SAMPLE_RATE,
+                                       .endpoint = 0x03,
+                                       .ep_attr = USB_ENDPOINT_XFER_ISOC,
+                                       .rates = SNDRV_PCM_RATE_48000,
+                                       .rate_min = 48000,
+                                       .rate_max = 48000,
+                                       .nr_rates = 1,
+                                       .rate_table = (unsigned int[]) {
+                                               48000
+                                       }
+                               }
+                       },
+               }
+       }
+},
+
 #undef USB_DEVICE_VENDOR_SPEC
index a66ef5777887a78d7416e64c049c73b26477c7f7..ea8f3de92fa4bedf6914b91e7f6dbea3841ac8de 100644 (file)
@@ -1363,8 +1363,11 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
                        return SNDRV_PCM_FMTBIT_DSD_U32_BE;
                break;
 
-       /* Amanero Combo384 USB interface with native DSD support */
-       case USB_ID(0x16d0, 0x071a):
+       /* Amanero Combo384 USB based DACs with native DSD support */
+       case USB_ID(0x16d0, 0x071a):  /* Amanero - Combo384 */
+       case USB_ID(0x2ab6, 0x0004):  /* T+A DAC8DSD-V2.0, MP1000E-V2.0, MP2000R-V2.0, MP2500R-V2.0, MP3100HV-V2.0 */
+       case USB_ID(0x2ab6, 0x0005):  /* T+A USB HD Audio 1 */
+       case USB_ID(0x2ab6, 0x0006):  /* T+A USB HD Audio 2 */
                if (fp->altsetting == 2) {
                        switch (le16_to_cpu(chip->dev->descriptor.bcdDevice)) {
                        case 0x199:
index a0951505c7f5b2804c3203fe7eeb0dea7d4935b1..4ed9d0c41843888d6e9c4aa7f79b980c3e0ac74b 100644 (file)
@@ -50,6 +50,7 @@
 /*standard module options for ALSA. This module supports only one card*/
 static int hdmi_card_index = SNDRV_DEFAULT_IDX1;
 static char *hdmi_card_id = SNDRV_DEFAULT_STR1;
+static bool single_port;
 
 module_param_named(index, hdmi_card_index, int, 0444);
 MODULE_PARM_DESC(index,
@@ -57,6 +58,9 @@ MODULE_PARM_DESC(index,
 module_param_named(id, hdmi_card_id, charp, 0444);
 MODULE_PARM_DESC(id,
                "ID string for INTEL Intel HDMI Audio controller.");
+module_param(single_port, bool, 0444);
+MODULE_PARM_DESC(single_port,
+               "Single-port mode (for compatibility)");
 
 /*
  * ELD SA bits in the CEA Speaker Allocation data block
@@ -1579,7 +1583,11 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id)
 static void notify_audio_lpe(struct platform_device *pdev, int port)
 {
        struct snd_intelhad_card *card_ctx = platform_get_drvdata(pdev);
-       struct snd_intelhad *ctx = &card_ctx->pcm_ctx[port];
+       struct snd_intelhad *ctx;
+
+       ctx = &card_ctx->pcm_ctx[single_port ? 0 : port];
+       if (single_port)
+               ctx->port = port;
 
        schedule_work(&ctx->hdmi_audio_wq);
 }
@@ -1743,6 +1751,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
 {
        struct snd_card *card;
        struct snd_intelhad_card *card_ctx;
+       struct snd_intelhad *ctx;
        struct snd_pcm *pcm;
        struct intel_hdmi_lpe_audio_pdata *pdata;
        int irq;
@@ -1787,6 +1796,21 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, card_ctx);
 
+       card_ctx->num_pipes = pdata->num_pipes;
+       card_ctx->num_ports = single_port ? 1 : pdata->num_ports;
+
+       for_each_port(card_ctx, port) {
+               ctx = &card_ctx->pcm_ctx[port];
+               ctx->card_ctx = card_ctx;
+               ctx->dev = card_ctx->dev;
+               ctx->port = single_port ? -1 : port;
+               ctx->pipe = -1;
+
+               spin_lock_init(&ctx->had_spinlock);
+               mutex_init(&ctx->mutex);
+               INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq);
+       }
+
        dev_dbg(&pdev->dev, "%s: mmio_start = 0x%x, mmio_end = 0x%x\n",
                __func__, (unsigned int)res_mmio->start,
                (unsigned int)res_mmio->end);
@@ -1816,19 +1840,12 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
        init_channel_allocations();
 
        card_ctx->num_pipes = pdata->num_pipes;
-       card_ctx->num_ports = pdata->num_ports;
+       card_ctx->num_ports = single_port ? 1 : pdata->num_ports;
 
        for_each_port(card_ctx, port) {
-               struct snd_intelhad *ctx = &card_ctx->pcm_ctx[port];
                int i;
 
-               ctx->card_ctx = card_ctx;
-               ctx->dev = card_ctx->dev;
-               ctx->port = port;
-               ctx->pipe = -1;
-
-               INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq);
-
+               ctx = &card_ctx->pcm_ctx[port];
                ret = snd_pcm_new(card, INTEL_HAD, port, MAX_PB_STREAMS,
                                  MAX_CAP_STREAMS, &pcm);
                if (ret)
index 637b7263cb867f09618cc2a5e7b525686a0ea267..833ed9a16adfd03e0b6cb70adc19fe03055f7344 100644 (file)
@@ -632,6 +632,8 @@ struct kvm_ppc_cpu_char {
 #define KVM_REG_PPC_TIDR       (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
 #define KVM_REG_PPC_PSSCR      (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)
 
+#define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe)
+
 /* Transactional Memory checkpointed state:
  * This is all GPRs, all VSX regs and a subset of SPRs
  */
diff --git a/tools/arch/s390/include/uapi/asm/unistd.h b/tools/arch/s390/include/uapi/asm/unistd.h
deleted file mode 100644 (file)
index 7251209..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- *  S390 version
- *
- *  Derived from "include/asm-i386/unistd.h"
- */
-
-#ifndef _UAPI_ASM_S390_UNISTD_H_
-#define _UAPI_ASM_S390_UNISTD_H_
-
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_exit                 1
-#define __NR_fork                 2
-#define __NR_read                 3
-#define __NR_write                4
-#define __NR_open                 5
-#define __NR_close                6
-#define __NR_restart_syscall     7
-#define __NR_creat                8
-#define __NR_link                 9
-#define __NR_unlink              10
-#define __NR_execve              11
-#define __NR_chdir               12
-#define __NR_mknod               14
-#define __NR_chmod               15
-#define __NR_lseek               19
-#define __NR_getpid              20
-#define __NR_mount               21
-#define __NR_umount              22
-#define __NR_ptrace              26
-#define __NR_alarm               27
-#define __NR_pause               29
-#define __NR_utime               30
-#define __NR_access              33
-#define __NR_nice                34
-#define __NR_sync                36
-#define __NR_kill                37
-#define __NR_rename              38
-#define __NR_mkdir               39
-#define __NR_rmdir               40
-#define __NR_dup                 41
-#define __NR_pipe                42
-#define __NR_times               43
-#define __NR_brk                 45
-#define __NR_signal              48
-#define __NR_acct                51
-#define __NR_umount2             52
-#define __NR_ioctl               54
-#define __NR_fcntl               55
-#define __NR_setpgid             57
-#define __NR_umask               60
-#define __NR_chroot              61
-#define __NR_ustat               62
-#define __NR_dup2                63
-#define __NR_getppid             64
-#define __NR_getpgrp             65
-#define __NR_setsid              66
-#define __NR_sigaction           67
-#define __NR_sigsuspend          72
-#define __NR_sigpending          73
-#define __NR_sethostname         74
-#define __NR_setrlimit           75
-#define __NR_getrusage           77
-#define __NR_gettimeofday        78
-#define __NR_settimeofday        79
-#define __NR_symlink             83
-#define __NR_readlink            85
-#define __NR_uselib              86
-#define __NR_swapon              87
-#define __NR_reboot              88
-#define __NR_readdir             89
-#define __NR_mmap                90
-#define __NR_munmap              91
-#define __NR_truncate            92
-#define __NR_ftruncate           93
-#define __NR_fchmod              94
-#define __NR_getpriority         96
-#define __NR_setpriority         97
-#define __NR_statfs              99
-#define __NR_fstatfs            100
-#define __NR_socketcall         102
-#define __NR_syslog             103
-#define __NR_setitimer          104
-#define __NR_getitimer          105
-#define __NR_stat               106
-#define __NR_lstat              107
-#define __NR_fstat              108
-#define __NR_lookup_dcookie     110
-#define __NR_vhangup            111
-#define __NR_idle               112
-#define __NR_wait4              114
-#define __NR_swapoff            115
-#define __NR_sysinfo            116
-#define __NR_ipc                117
-#define __NR_fsync              118
-#define __NR_sigreturn          119
-#define __NR_clone              120
-#define __NR_setdomainname      121
-#define __NR_uname              122
-#define __NR_adjtimex           124
-#define __NR_mprotect           125
-#define __NR_sigprocmask        126
-#define __NR_create_module      127
-#define __NR_init_module        128
-#define __NR_delete_module      129
-#define __NR_get_kernel_syms    130
-#define __NR_quotactl           131
-#define __NR_getpgid            132
-#define __NR_fchdir             133
-#define __NR_bdflush            134
-#define __NR_sysfs              135
-#define __NR_personality        136
-#define __NR_afs_syscall        137 /* Syscall for Andrew File System */
-#define __NR_getdents           141
-#define __NR_flock              143
-#define __NR_msync              144
-#define __NR_readv              145
-#define __NR_writev             146
-#define __NR_getsid             147
-#define __NR_fdatasync          148
-#define __NR__sysctl            149
-#define __NR_mlock              150
-#define __NR_munlock            151
-#define __NR_mlockall           152
-#define __NR_munlockall         153
-#define __NR_sched_setparam             154
-#define __NR_sched_getparam             155
-#define __NR_sched_setscheduler         156
-#define __NR_sched_getscheduler         157
-#define __NR_sched_yield                158
-#define __NR_sched_get_priority_max     159
-#define __NR_sched_get_priority_min     160
-#define __NR_sched_rr_get_interval      161
-#define __NR_nanosleep          162
-#define __NR_mremap             163
-#define __NR_query_module       167
-#define __NR_poll               168
-#define __NR_nfsservctl         169
-#define __NR_prctl              172
-#define __NR_rt_sigreturn       173
-#define __NR_rt_sigaction       174
-#define __NR_rt_sigprocmask     175
-#define __NR_rt_sigpending      176
-#define __NR_rt_sigtimedwait    177
-#define __NR_rt_sigqueueinfo    178
-#define __NR_rt_sigsuspend      179
-#define __NR_pread64            180
-#define __NR_pwrite64           181
-#define __NR_getcwd             183
-#define __NR_capget             184
-#define __NR_capset             185
-#define __NR_sigaltstack        186
-#define __NR_sendfile           187
-#define __NR_getpmsg           188
-#define __NR_putpmsg           189
-#define __NR_vfork             190
-#define __NR_pivot_root         217
-#define __NR_mincore            218
-#define __NR_madvise            219
-#define __NR_getdents64                220
-#define __NR_readahead         222
-#define __NR_setxattr          224
-#define __NR_lsetxattr         225
-#define __NR_fsetxattr         226
-#define __NR_getxattr          227
-#define __NR_lgetxattr         228
-#define __NR_fgetxattr         229
-#define __NR_listxattr         230
-#define __NR_llistxattr                231
-#define __NR_flistxattr                232
-#define __NR_removexattr       233
-#define __NR_lremovexattr      234
-#define __NR_fremovexattr      235
-#define __NR_gettid            236
-#define __NR_tkill             237
-#define __NR_futex             238
-#define __NR_sched_setaffinity 239
-#define __NR_sched_getaffinity 240
-#define __NR_tgkill            241
-/* Number 242 is reserved for tux */
-#define __NR_io_setup          243
-#define __NR_io_destroy                244
-#define __NR_io_getevents      245
-#define __NR_io_submit         246
-#define __NR_io_cancel         247
-#define __NR_exit_group                248
-#define __NR_epoll_create      249
-#define __NR_epoll_ctl         250
-#define __NR_epoll_wait                251
-#define __NR_set_tid_address   252
-#define __NR_fadvise64         253
-#define __NR_timer_create      254
-#define __NR_timer_settime     255
-#define __NR_timer_gettime     256
-#define __NR_timer_getoverrun  257
-#define __NR_timer_delete      258
-#define __NR_clock_settime     259
-#define __NR_clock_gettime     260
-#define __NR_clock_getres      261
-#define __NR_clock_nanosleep   262
-/* Number 263 is reserved for vserver */
-#define __NR_statfs64          265
-#define __NR_fstatfs64         266
-#define __NR_remap_file_pages  267
-#define __NR_mbind             268
-#define __NR_get_mempolicy     269
-#define __NR_set_mempolicy     270
-#define __NR_mq_open           271
-#define __NR_mq_unlink         272
-#define __NR_mq_timedsend      273
-#define __NR_mq_timedreceive   274
-#define __NR_mq_notify         275
-#define __NR_mq_getsetattr     276
-#define __NR_kexec_load                277
-#define __NR_add_key           278
-#define __NR_request_key       279
-#define __NR_keyctl            280
-#define __NR_waitid            281
-#define __NR_ioprio_set                282
-#define __NR_ioprio_get                283
-#define __NR_inotify_init      284
-#define __NR_inotify_add_watch 285
-#define __NR_inotify_rm_watch  286
-#define __NR_migrate_pages     287
-#define __NR_openat            288
-#define __NR_mkdirat           289
-#define __NR_mknodat           290
-#define __NR_fchownat          291
-#define __NR_futimesat         292
-#define __NR_unlinkat          294
-#define __NR_renameat          295
-#define __NR_linkat            296
-#define __NR_symlinkat         297
-#define __NR_readlinkat                298
-#define __NR_fchmodat          299
-#define __NR_faccessat         300
-#define __NR_pselect6          301
-#define __NR_ppoll             302
-#define __NR_unshare           303
-#define __NR_set_robust_list   304
-#define __NR_get_robust_list   305
-#define __NR_splice            306
-#define __NR_sync_file_range   307
-#define __NR_tee               308
-#define __NR_vmsplice          309
-#define __NR_move_pages                310
-#define __NR_getcpu            311
-#define __NR_epoll_pwait       312
-#define __NR_utimes            313
-#define __NR_fallocate         314
-#define __NR_utimensat         315
-#define __NR_signalfd          316
-#define __NR_timerfd           317
-#define __NR_eventfd           318
-#define __NR_timerfd_create    319
-#define __NR_timerfd_settime   320
-#define __NR_timerfd_gettime   321
-#define __NR_signalfd4         322
-#define __NR_eventfd2          323
-#define __NR_inotify_init1     324
-#define __NR_pipe2             325
-#define __NR_dup3              326
-#define __NR_epoll_create1     327
-#define        __NR_preadv             328
-#define        __NR_pwritev            329
-#define __NR_rt_tgsigqueueinfo 330
-#define __NR_perf_event_open   331
-#define __NR_fanotify_init     332
-#define __NR_fanotify_mark     333
-#define __NR_prlimit64         334
-#define __NR_name_to_handle_at 335
-#define __NR_open_by_handle_at 336
-#define __NR_clock_adjtime     337
-#define __NR_syncfs            338
-#define __NR_setns             339
-#define __NR_process_vm_readv  340
-#define __NR_process_vm_writev 341
-#define __NR_s390_runtime_instr 342
-#define __NR_kcmp              343
-#define __NR_finit_module      344
-#define __NR_sched_setattr     345
-#define __NR_sched_getattr     346
-#define __NR_renameat2         347
-#define __NR_seccomp           348
-#define __NR_getrandom         349
-#define __NR_memfd_create      350
-#define __NR_bpf               351
-#define __NR_s390_pci_mmio_write       352
-#define __NR_s390_pci_mmio_read                353
-#define __NR_execveat          354
-#define __NR_userfaultfd       355
-#define __NR_membarrier                356
-#define __NR_recvmmsg          357
-#define __NR_sendmmsg          358
-#define __NR_socket            359
-#define __NR_socketpair                360
-#define __NR_bind              361
-#define __NR_connect           362
-#define __NR_listen            363
-#define __NR_accept4           364
-#define __NR_getsockopt                365
-#define __NR_setsockopt                366
-#define __NR_getsockname       367
-#define __NR_getpeername       368
-#define __NR_sendto            369
-#define __NR_sendmsg           370
-#define __NR_recvfrom          371
-#define __NR_recvmsg           372
-#define __NR_shutdown          373
-#define __NR_mlock2            374
-#define __NR_copy_file_range   375
-#define __NR_preadv2           376
-#define __NR_pwritev2          377
-#define __NR_s390_guarded_storage      378
-#define __NR_statx             379
-#define __NR_s390_sthyi                380
-#define NR_syscalls 381
-
-/* 
- * There are some system calls that are not present on 64 bit, some
- * have a different name although they do the same (e.g. __NR_chown32
- * is __NR_chown on 64 bit).
- */
-#ifndef __s390x__
-
-#define __NR_time               13
-#define __NR_lchown             16
-#define __NR_setuid             23
-#define __NR_getuid             24
-#define __NR_stime              25
-#define __NR_setgid             46
-#define __NR_getgid             47
-#define __NR_geteuid            49
-#define __NR_getegid            50
-#define __NR_setreuid           70
-#define __NR_setregid           71
-#define __NR_getrlimit          76
-#define __NR_getgroups          80
-#define __NR_setgroups          81
-#define __NR_fchown             95
-#define __NR_ioperm            101
-#define __NR_setfsuid          138
-#define __NR_setfsgid          139
-#define __NR__llseek           140
-#define __NR__newselect        142
-#define __NR_setresuid         164
-#define __NR_getresuid         165
-#define __NR_setresgid         170
-#define __NR_getresgid         171
-#define __NR_chown             182
-#define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
-#define __NR_mmap2             192
-#define __NR_truncate64                193
-#define __NR_ftruncate64       194
-#define __NR_stat64            195
-#define __NR_lstat64           196
-#define __NR_fstat64           197
-#define __NR_lchown32          198
-#define __NR_getuid32          199
-#define __NR_getgid32          200
-#define __NR_geteuid32         201
-#define __NR_getegid32         202
-#define __NR_setreuid32                203
-#define __NR_setregid32                204
-#define __NR_getgroups32       205
-#define __NR_setgroups32       206
-#define __NR_fchown32          207
-#define __NR_setresuid32       208
-#define __NR_getresuid32       209
-#define __NR_setresgid32       210
-#define __NR_getresgid32       211
-#define __NR_chown32           212
-#define __NR_setuid32          213
-#define __NR_setgid32          214
-#define __NR_setfsuid32                215
-#define __NR_setfsgid32                216
-#define __NR_fcntl64           221
-#define __NR_sendfile64                223
-#define __NR_fadvise64_64      264
-#define __NR_fstatat64         293
-
-#else
-
-#define __NR_select            142
-#define __NR_getrlimit         191     /* SuS compliant getrlimit */
-#define __NR_lchown            198
-#define __NR_getuid            199
-#define __NR_getgid            200
-#define __NR_geteuid           201
-#define __NR_getegid           202
-#define __NR_setreuid                  203
-#define __NR_setregid                  204
-#define __NR_getgroups         205
-#define __NR_setgroups         206
-#define __NR_fchown            207
-#define __NR_setresuid         208
-#define __NR_getresuid         209
-#define __NR_setresgid         210
-#define __NR_getresgid         211
-#define __NR_chown             212
-#define __NR_setuid            213
-#define __NR_setgid            214
-#define __NR_setfsuid                  215
-#define __NR_setfsgid                  216
-#define __NR_newfstatat                293
-
-#endif
-
-#endif /* _UAPI_ASM_S390_UNISTD_H_ */
index 1d9199e1c2ad45531b21f5300439b5ef18943193..f41079da38c55f8a2e891b044ac9ffb73919c37e 100644 (file)
 
 #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_SEV                        ( 7*32+20) /* AMD Secure Encrypted Virtualization */
 
 #define X86_FEATURE_USE_IBPB           ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
+#define X86_FEATURE_USE_IBRS_FW                ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW         ( 8*32+ 0) /* Intel TPR Shadow */
index 0b482c0070e04fb06b65eb503959afc06170b472..465995281dcd36f2b25e97aef7316ebd0e441ff5 100644 (file)
 
 #include "main.h"
 
+#ifndef BPF_FS_MAGIC
+#define BPF_FS_MAGIC           0xcafe4a11
+#endif
+
 void p_err(const char *fmt, ...)
 {
        va_list ap;
index 3a0396d87c424954ffe3e6c1111dca2a23bd3776..185acfa229b592f0bf0b62d972e90c3746959283 100644 (file)
@@ -244,7 +244,7 @@ static int do_batch(int argc, char **argv)
        }
 
        if (errno && errno != ENOENT) {
-               perror("reading batch file failed");
+               p_err("reading batch file failed: %s", strerror(errno));
                err = -1;
        } else {
                p_info("processed %d lines", lines);
index e8e2baaf93c2665c4a7cf998a85e35eda76b009d..e549e329be8216646dbab3c11a6485d85d02f1c6 100644 (file)
@@ -774,6 +774,9 @@ static int do_dump(int argc, char **argv)
                              n < 0 ? strerror(errno) : "short write");
                        goto err_free;
                }
+
+               if (json_output)
+                       jsonw_null(json_wtr);
        } else {
                if (member_len == &info.jited_prog_len) {
                        const char *name = NULL;
index 860fa151640abd5823e6551fb75e57fd67a0188a..ffca068e4a761ec02635b2383f46e4e876630bd9 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for cgroup tools
 
-CC = $(CROSS_COMPILE)gcc
 CFLAGS = -Wall -Wextra
 
 all: cgroup_event_listener
index 805a2c0cf4cd37c42eeb19e4c72a2e3bc74ced7f..240eda014b371b4e1c63f607e6853d387f475392 100644 (file)
@@ -12,8 +12,6 @@ endif
 # (this improves performance and avoids hard-to-debug behaviour);
 MAKEFLAGS += -r
 
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
 CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
 
 ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon
index 1139d71fa0cf52aabf15cf2ff82bfe125529fb60..5db5e62cebdaeb3277e927ec396abd3ca412218e 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for Hyper-V tools
 
-CC = $(CROSS_COMPILE)gcc
 WARNINGS = -Wall -Wextra
 CFLAGS = $(WARNINGS) -g $(shell getconf LFS_CFLAGS)
 
index a08e7a47d6a32e858700d43a1bccdef67583b3ef..332ed2f6c2c2e54ae776fba178551f05fbc38851 100644 (file)
@@ -12,8 +12,6 @@ endif
 # (this improves performance and avoids hard-to-debug behaviour);
 MAKEFLAGS += -r
 
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
 CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
 
 ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer
index ac3c6503ca27f156ddbc3dd304bbf91671a9ac2a..536ee4febd746b7d93b4066919d971452df560cc 100644 (file)
@@ -86,6 +86,62 @@ enum i915_mocs_table_index {
        I915_MOCS_CACHED,
 };
 
+/*
+ * Different engines serve different roles, and there may be more than one
+ * engine serving each role. enum drm_i915_gem_engine_class provides a
+ * classification of the role of the engine, which may be used when requesting
+ * operations to be performed on a certain subset of engines, or for providing
+ * information about that group.
+ */
+enum drm_i915_gem_engine_class {
+       I915_ENGINE_CLASS_RENDER        = 0,
+       I915_ENGINE_CLASS_COPY          = 1,
+       I915_ENGINE_CLASS_VIDEO         = 2,
+       I915_ENGINE_CLASS_VIDEO_ENHANCE = 3,
+
+       I915_ENGINE_CLASS_INVALID       = -1
+};
+
+/**
+ * DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915
+ *
+ */
+
+enum drm_i915_pmu_engine_sample {
+       I915_SAMPLE_BUSY = 0,
+       I915_SAMPLE_WAIT = 1,
+       I915_SAMPLE_SEMA = 2
+};
+
+#define I915_PMU_SAMPLE_BITS (4)
+#define I915_PMU_SAMPLE_MASK (0xf)
+#define I915_PMU_SAMPLE_INSTANCE_BITS (8)
+#define I915_PMU_CLASS_SHIFT \
+       (I915_PMU_SAMPLE_BITS + I915_PMU_SAMPLE_INSTANCE_BITS)
+
+#define __I915_PMU_ENGINE(class, instance, sample) \
+       ((class) << I915_PMU_CLASS_SHIFT | \
+       (instance) << I915_PMU_SAMPLE_BITS | \
+       (sample))
+
+#define I915_PMU_ENGINE_BUSY(class, instance) \
+       __I915_PMU_ENGINE(class, instance, I915_SAMPLE_BUSY)
+
+#define I915_PMU_ENGINE_WAIT(class, instance) \
+       __I915_PMU_ENGINE(class, instance, I915_SAMPLE_WAIT)
+
+#define I915_PMU_ENGINE_SEMA(class, instance) \
+       __I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA)
+
+#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x))
+
+#define I915_PMU_ACTUAL_FREQUENCY      __I915_PMU_OTHER(0)
+#define I915_PMU_REQUESTED_FREQUENCY   __I915_PMU_OTHER(1)
+#define I915_PMU_INTERRUPTS            __I915_PMU_OTHER(2)
+#define I915_PMU_RC6_RESIDENCY         __I915_PMU_OTHER(3)
+
+#define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
+
 /* Each region is a minimum of 16k, and there are at most 255 of them.
  */
 #define I915_NR_TEX_REGIONS 255        /* table size 2k - maximum due to use
@@ -450,6 +506,27 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_HAS_EXEC_FENCE_ARRAY  49
 
+/*
+ * Query whether every context (both per-file default and user created) is
+ * isolated (insofar as HW supports). If this parameter is not true, then
+ * freshly created contexts may inherit values from an existing context,
+ * rather than default HW values. If true, it also ensures (insofar as HW
+ * supports) that all state set by this context will not leak to any other
+ * context.
+ *
+ * As not every engine across every gen support contexts, the returned
+ * value reports the support of context isolation for individual engines by
+ * returning a bitmask of each engine class set to true if that class supports
+ * isolation.
+ */
+#define I915_PARAM_HAS_CONTEXT_ISOLATION 50
+
+/* Frequency of the command streamer timestamps given by the *_TIMESTAMP
+ * registers. This used to be fixed per platform but from CNL onwards, this
+ * might vary depending on the parts.
+ */
+#define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51
+
 typedef struct drm_i915_getparam {
        __s32 param;
        /*
index 8616131e2c61d9ff30a204144a02d2450f710461..6d9447700e18c983804e1fecc4a6854e138d10f6 100644 (file)
@@ -163,6 +163,7 @@ enum {
        IFLA_IF_NETNSID,
        IFLA_CARRIER_UP_COUNT,
        IFLA_CARRIER_DOWN_COUNT,
+       IFLA_NEW_IFINDEX,
        __IFLA_MAX
 };
 
index 8fb90a0819c3939eb2a74c6053c9dc5d586d9eab..7b26d4b0b0529649816ec1523d225eec7fa8ee26 100644 (file)
@@ -761,6 +761,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_TRACE_PAUSE           __KVM_DEPRECATED_MAIN_0x07
 #define KVM_TRACE_DISABLE         __KVM_DEPRECATED_MAIN_0x08
 #define KVM_GET_EMULATED_CPUID   _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
+#define KVM_GET_MSR_FEATURE_INDEX_LIST    _IOWR(KVMIO, 0x0a, struct kvm_msr_list)
 
 /*
  * Extension capability list.
@@ -934,6 +935,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_AIS_MIGRATION 150
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
+#define KVM_CAP_GET_MSR_FEATURES 153
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1362,6 +1364,96 @@ struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_S390_CMMA_MIGRATION */
 #define KVM_S390_GET_CMMA_BITS      _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log)
 #define KVM_S390_SET_CMMA_BITS      _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log)
+/* Memory Encryption Commands */
+#define KVM_MEMORY_ENCRYPT_OP      _IOWR(KVMIO, 0xba, unsigned long)
+
+struct kvm_enc_region {
+       __u64 addr;
+       __u64 size;
+};
+
+#define KVM_MEMORY_ENCRYPT_REG_REGION    _IOR(KVMIO, 0xbb, struct kvm_enc_region)
+#define KVM_MEMORY_ENCRYPT_UNREG_REGION  _IOR(KVMIO, 0xbc, struct kvm_enc_region)
+
+/* Secure Encrypted Virtualization command */
+enum sev_cmd_id {
+       /* Guest initialization commands */
+       KVM_SEV_INIT = 0,
+       KVM_SEV_ES_INIT,
+       /* Guest launch commands */
+       KVM_SEV_LAUNCH_START,
+       KVM_SEV_LAUNCH_UPDATE_DATA,
+       KVM_SEV_LAUNCH_UPDATE_VMSA,
+       KVM_SEV_LAUNCH_SECRET,
+       KVM_SEV_LAUNCH_MEASURE,
+       KVM_SEV_LAUNCH_FINISH,
+       /* Guest migration commands (outgoing) */
+       KVM_SEV_SEND_START,
+       KVM_SEV_SEND_UPDATE_DATA,
+       KVM_SEV_SEND_UPDATE_VMSA,
+       KVM_SEV_SEND_FINISH,
+       /* Guest migration commands (incoming) */
+       KVM_SEV_RECEIVE_START,
+       KVM_SEV_RECEIVE_UPDATE_DATA,
+       KVM_SEV_RECEIVE_UPDATE_VMSA,
+       KVM_SEV_RECEIVE_FINISH,
+       /* Guest status and debug commands */
+       KVM_SEV_GUEST_STATUS,
+       KVM_SEV_DBG_DECRYPT,
+       KVM_SEV_DBG_ENCRYPT,
+       /* Guest certificates commands */
+       KVM_SEV_CERT_EXPORT,
+
+       KVM_SEV_NR_MAX,
+};
+
+struct kvm_sev_cmd {
+       __u32 id;
+       __u64 data;
+       __u32 error;
+       __u32 sev_fd;
+};
+
+struct kvm_sev_launch_start {
+       __u32 handle;
+       __u32 policy;
+       __u64 dh_uaddr;
+       __u32 dh_len;
+       __u64 session_uaddr;
+       __u32 session_len;
+};
+
+struct kvm_sev_launch_update_data {
+       __u64 uaddr;
+       __u32 len;
+};
+
+
+struct kvm_sev_launch_secret {
+       __u64 hdr_uaddr;
+       __u32 hdr_len;
+       __u64 guest_uaddr;
+       __u32 guest_len;
+       __u64 trans_uaddr;
+       __u32 trans_len;
+};
+
+struct kvm_sev_launch_measure {
+       __u64 uaddr;
+       __u32 len;
+};
+
+struct kvm_sev_guest_status {
+       __u32 handle;
+       __u32 policy;
+       __u32 state;
+};
+
+struct kvm_sev_dbg {
+       __u64 src_uaddr;
+       __u64 dst_uaddr;
+       __u32 len;
+};
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU    (1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3         (1 << 1)
index a5684d0968b4fd087905e659c0ce80bd170434c2..5898c22ba310bdf27f626a2dfb7bc45e5cf2a505 100755 (executable)
@@ -33,7 +33,7 @@ import resource
 import struct
 import re
 import subprocess
-from collections import defaultdict
+from collections import defaultdict, namedtuple
 
 VMX_EXIT_REASONS = {
     'EXCEPTION_NMI':        0,
@@ -228,6 +228,7 @@ IOCTL_NUMBERS = {
 }
 
 ENCODING = locale.getpreferredencoding(False)
+TRACE_FILTER = re.compile(r'^[^\(]*$')
 
 
 class Arch(object):
@@ -260,6 +261,11 @@ class Arch(object):
                     return ArchX86(SVM_EXIT_REASONS)
                 return
 
+    def tracepoint_is_child(self, field):
+        if (TRACE_FILTER.match(field)):
+            return None
+        return field.split('(', 1)[0]
+
 
 class ArchX86(Arch):
     def __init__(self, exit_reasons):
@@ -267,6 +273,10 @@ class ArchX86(Arch):
         self.ioctl_numbers = IOCTL_NUMBERS
         self.exit_reasons = exit_reasons
 
+    def debugfs_is_child(self, field):
+        """ Returns name of parent if 'field' is a child, None otherwise """
+        return None
+
 
 class ArchPPC(Arch):
     def __init__(self):
@@ -282,6 +292,10 @@ class ArchPPC(Arch):
         self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
         self.exit_reasons = {}
 
+    def debugfs_is_child(self, field):
+        """ Returns name of parent if 'field' is a child, None otherwise """
+        return None
+
 
 class ArchA64(Arch):
     def __init__(self):
@@ -289,6 +303,10 @@ class ArchA64(Arch):
         self.ioctl_numbers = IOCTL_NUMBERS
         self.exit_reasons = AARCH64_EXIT_REASONS
 
+    def debugfs_is_child(self, field):
+        """ Returns name of parent if 'field' is a child, None otherwise """
+        return None
+
 
 class ArchS390(Arch):
     def __init__(self):
@@ -296,6 +314,12 @@ class ArchS390(Arch):
         self.ioctl_numbers = IOCTL_NUMBERS
         self.exit_reasons = None
 
+    def debugfs_is_child(self, field):
+        """ Returns name of parent if 'field' is a child, None otherwise """
+        if field.startswith('instruction_'):
+            return 'exit_instruction'
+
+
 ARCH = Arch.get_arch()
 
 
@@ -331,9 +355,6 @@ class perf_event_attr(ctypes.Structure):
 PERF_TYPE_TRACEPOINT = 2
 PERF_FORMAT_GROUP = 1 << 3
 
-PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
-PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'
-
 
 class Group(object):
     """Represents a perf event group."""
@@ -376,8 +397,8 @@ class Event(object):
         self.syscall = self.libc.syscall
         self.name = name
         self.fd = None
-        self.setup_event(group, trace_cpu, trace_pid, trace_point,
-                         trace_filter, trace_set)
+        self._setup_event(group, trace_cpu, trace_pid, trace_point,
+                          trace_filter, trace_set)
 
     def __del__(self):
         """Closes the event's file descriptor.
@@ -390,7 +411,7 @@ class Event(object):
         if self.fd:
             os.close(self.fd)
 
-    def perf_event_open(self, attr, pid, cpu, group_fd, flags):
+    def _perf_event_open(self, attr, pid, cpu, group_fd, flags):
         """Wrapper for the sys_perf_evt_open() syscall.
 
         Used to set up performance events, returns a file descriptor or -1
@@ -409,7 +430,7 @@ class Event(object):
                             ctypes.c_int(pid), ctypes.c_int(cpu),
                             ctypes.c_int(group_fd), ctypes.c_long(flags))
 
-    def setup_event_attribute(self, trace_set, trace_point):
+    def _setup_event_attribute(self, trace_set, trace_point):
         """Returns an initialized ctype perf_event_attr struct."""
 
         id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
@@ -419,8 +440,8 @@ class Event(object):
         event_attr.config = int(open(id_path).read())
         return event_attr
 
-    def setup_event(self, group, trace_cpu, trace_pid, trace_point,
-                    trace_filter, trace_set):
+    def _setup_event(self, group, trace_cpu, trace_pid, trace_point,
+                     trace_filter, trace_set):
         """Sets up the perf event in Linux.
 
         Issues the syscall to register the event in the kernel and
@@ -428,7 +449,7 @@ class Event(object):
 
         """
 
-        event_attr = self.setup_event_attribute(trace_set, trace_point)
+        event_attr = self._setup_event_attribute(trace_set, trace_point)
 
         # First event will be group leader.
         group_leader = -1
@@ -437,8 +458,8 @@ class Event(object):
         if group.events:
             group_leader = group.events[0].fd
 
-        fd = self.perf_event_open(event_attr, trace_pid,
-                                  trace_cpu, group_leader, 0)
+        fd = self._perf_event_open(event_attr, trace_pid,
+                                   trace_cpu, group_leader, 0)
         if fd == -1:
             err = ctypes.get_errno()
             raise OSError(err, os.strerror(err),
@@ -475,6 +496,10 @@ class Event(object):
 
 class Provider(object):
     """Encapsulates functionalities used by all providers."""
+    def __init__(self, pid):
+        self.child_events = False
+        self.pid = pid
+
     @staticmethod
     def is_field_wanted(fields_filter, field):
         """Indicate whether field is valid according to fields_filter."""
@@ -500,12 +525,12 @@ class TracepointProvider(Provider):
     """
     def __init__(self, pid, fields_filter):
         self.group_leaders = []
-        self.filters = self.get_filters()
+        self.filters = self._get_filters()
         self.update_fields(fields_filter)
-        self.pid = pid
+        super(TracepointProvider, self).__init__(pid)
 
     @staticmethod
-    def get_filters():
+    def _get_filters():
         """Returns a dict of trace events, their filter ids and
         the values that can be filtered.
 
@@ -521,8 +546,8 @@ class TracepointProvider(Provider):
             filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
         return filters
 
-    def get_available_fields(self):
-        """Returns a list of available event's of format 'event name(filter
+    def _get_available_fields(self):
+        """Returns a list of available events of format 'event name(filter
         name)'.
 
         All available events have directories under
@@ -549,11 +574,12 @@ class TracepointProvider(Provider):
 
     def update_fields(self, fields_filter):
         """Refresh fields, applying fields_filter"""
-        self.fields = [field for field in self.get_available_fields()
-                       if self.is_field_wanted(fields_filter, field)]
+        self.fields = [field for field in self._get_available_fields()
+                       if self.is_field_wanted(fields_filter, field) or
+                       ARCH.tracepoint_is_child(field)]
 
     @staticmethod
-    def get_online_cpus():
+    def _get_online_cpus():
         """Returns a list of cpu id integers."""
         def parse_int_list(list_string):
             """Returns an int list from a string of comma separated integers and
@@ -575,17 +601,17 @@ class TracepointProvider(Provider):
             cpu_string = cpu_list.readline()
             return parse_int_list(cpu_string)
 
-    def setup_traces(self):
+    def _setup_traces(self):
         """Creates all event and group objects needed to be able to retrieve
         data."""
-        fields = self.get_available_fields()
+        fields = self._get_available_fields()
         if self._pid > 0:
             # Fetch list of all threads of the monitored pid, as qemu
             # starts a thread for each vcpu.
             path = os.path.join('/proc', str(self._pid), 'task')
             groupids = self.walkdir(path)[1]
         else:
-            groupids = self.get_online_cpus()
+            groupids = self._get_online_cpus()
 
         # The constant is needed as a buffer for python libs, std
         # streams and other files that the script opens.
@@ -663,7 +689,7 @@ class TracepointProvider(Provider):
         # The garbage collector will get rid of all Event/Group
         # objects and open files after removing the references.
         self.group_leaders = []
-        self.setup_traces()
+        self._setup_traces()
         self.fields = self._fields
 
     def read(self, by_guest=0):
@@ -671,8 +697,12 @@ class TracepointProvider(Provider):
         ret = defaultdict(int)
         for group in self.group_leaders:
             for name, val in group.read().items():
-                if name in self._fields:
-                    ret[name] += val
+                if name not in self._fields:
+                    continue
+                parent = ARCH.tracepoint_is_child(name)
+                if parent:
+                    name += ' ' + parent
+                ret[name] += val
         return ret
 
     def reset(self):
@@ -690,11 +720,11 @@ class DebugfsProvider(Provider):
         self._baseline = {}
         self.do_read = True
         self.paths = []
-        self.pid = pid
+        super(DebugfsProvider, self).__init__(pid)
         if include_past:
-            self.restore()
+            self._restore()
 
-    def get_available_fields(self):
+    def _get_available_fields(self):
         """"Returns a list of available fields.
 
         The fields are all available KVM debugfs files
@@ -704,8 +734,9 @@ class DebugfsProvider(Provider):
 
     def update_fields(self, fields_filter):
         """Refresh fields, applying fields_filter"""
-        self._fields = [field for field in self.get_available_fields()
-                        if self.is_field_wanted(fields_filter, field)]
+        self._fields = [field for field in self._get_available_fields()
+                        if self.is_field_wanted(fields_filter, field) or
+                        ARCH.debugfs_is_child(field)]
 
     @property
     def fields(self):
@@ -758,7 +789,7 @@ class DebugfsProvider(Provider):
                     paths.append(dir)
         for path in paths:
             for field in self._fields:
-                value = self.read_field(field, path)
+                value = self._read_field(field, path)
                 key = path + field
                 if reset == 1:
                     self._baseline[key] = value
@@ -766,20 +797,21 @@ class DebugfsProvider(Provider):
                     self._baseline[key] = 0
                 if self._baseline.get(key, -1) == -1:
                     self._baseline[key] = value
-                increment = (results.get(field, 0) + value -
-                             self._baseline.get(key, 0))
-                if by_guest:
-                    pid = key.split('-')[0]
-                    if pid in results:
-                        results[pid] += increment
-                    else:
-                        results[pid] = increment
+                parent = ARCH.debugfs_is_child(field)
+                if parent:
+                    field = field + ' ' + parent
+                else:
+                    if by_guest:
+                        field = key.split('-')[0]    # set 'field' to 'pid'
+                increment = value - self._baseline.get(key, 0)
+                if field in results:
+                    results[field] += increment
                 else:
                     results[field] = increment
 
         return results
 
-    def read_field(self, field, path):
+    def _read_field(self, field, path):
         """Returns the value of a single field from a specific VM."""
         try:
             return int(open(os.path.join(PATH_DEBUGFS_KVM,
@@ -794,12 +826,15 @@ class DebugfsProvider(Provider):
         self._baseline = {}
         self.read(1)
 
-    def restore(self):
+    def _restore(self):
         """Reset field counters"""
         self._baseline = {}
         self.read(2)
 
 
+EventStat = namedtuple('EventStat', ['value', 'delta'])
+
+
 class Stats(object):
     """Manages the data providers and the data they provide.
 
@@ -808,13 +843,13 @@ class Stats(object):
 
     """
     def __init__(self, options):
-        self.providers = self.get_providers(options)
+        self.providers = self._get_providers(options)
         self._pid_filter = options.pid
         self._fields_filter = options.fields
         self.values = {}
+        self._child_events = False
 
-    @staticmethod
-    def get_providers(options):
+    def _get_providers(self, options):
         """Returns a list of data providers depending on the passed options."""
         providers = []
 
@@ -826,7 +861,7 @@ class Stats(object):
 
         return providers
 
-    def update_provider_filters(self):
+    def _update_provider_filters(self):
         """Propagates fields filters to providers."""
         # As we reset the counters when updating the fields we can
         # also clear the cache of old values.
@@ -847,7 +882,7 @@ class Stats(object):
     def fields_filter(self, fields_filter):
         if fields_filter != self._fields_filter:
             self._fields_filter = fields_filter
-            self.update_provider_filters()
+            self._update_provider_filters()
 
     @property
     def pid_filter(self):
@@ -861,16 +896,33 @@ class Stats(object):
             for provider in self.providers:
                 provider.pid = self._pid_filter
 
+    @property
+    def child_events(self):
+        return self._child_events
+
+    @child_events.setter
+    def child_events(self, val):
+        self._child_events = val
+        for provider in self.providers:
+            provider.child_events = val
+
     def get(self, by_guest=0):
         """Returns a dict with field -> (value, delta to last value) of all
-        provider data."""
+        provider data.
+        Key formats:
+          * plain: 'key' is event name
+          * child-parent: 'key' is in format '<child> <parent>'
+          * pid: 'key' is the pid of the guest, and the record contains the
+               aggregated event data
+        These formats are generated by the providers, and handled in class TUI.
+        """
         for provider in self.providers:
             new = provider.read(by_guest=by_guest)
-            for key in new if by_guest else provider.fields:
-                oldval = self.values.get(key, (0, 0))[0]
+            for key in new:
+                oldval = self.values.get(key, EventStat(0, 0)).value
                 newval = new.get(key, 0)
                 newdelta = newval - oldval
-                self.values[key] = (newval, newdelta)
+                self.values[key] = EventStat(newval, newdelta)
         return self.values
 
     def toggle_display_guests(self, to_pid):
@@ -899,10 +951,10 @@ class Stats(object):
         self.get(to_pid)
         return 0
 
+
 DELAY_DEFAULT = 3.0
 MAX_GUEST_NAME_LEN = 48
 MAX_REGEX_LEN = 44
-DEFAULT_REGEX = r'^[^\(]*$'
 SORT_DEFAULT = 0
 
 
@@ -969,7 +1021,7 @@ class Tui(object):
 
         return res
 
-    def print_all_gnames(self, row):
+    def _print_all_gnames(self, row):
         """Print a list of all running guests along with their pids."""
         self.screen.addstr(row, 2, '%8s  %-60s' %
                            ('Pid', 'Guest Name (fuzzy list, might be '
@@ -1032,19 +1084,13 @@ class Tui(object):
 
         return name
 
-    def update_drilldown(self):
-        """Sets or removes a filter that only allows fields without braces."""
-        if not self.stats.fields_filter:
-            self.stats.fields_filter = DEFAULT_REGEX
-
-        elif self.stats.fields_filter == DEFAULT_REGEX:
-            self.stats.fields_filter = None
-
-    def update_pid(self, pid):
+    def _update_pid(self, pid):
         """Propagates pid selection to stats object."""
+        self.screen.addstr(4, 1, 'Updating pid filter...')
+        self.screen.refresh()
         self.stats.pid_filter = pid
 
-    def refresh_header(self, pid=None):
+    def _refresh_header(self, pid=None):
         """Refreshes the header."""
         if pid is None:
             pid = self.stats.pid_filter
@@ -1059,8 +1105,7 @@ class Tui(object):
                                .format(pid, gname), curses.A_BOLD)
         else:
             self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
-        if self.stats.fields_filter and self.stats.fields_filter \
-           != DEFAULT_REGEX:
+        if self.stats.fields_filter:
             regex = self.stats.fields_filter
             if len(regex) > MAX_REGEX_LEN:
                 regex = regex[:MAX_REGEX_LEN] + '...'
@@ -1075,56 +1120,99 @@ class Tui(object):
         self.screen.addstr(4, 1, 'Collecting data...')
         self.screen.refresh()
 
-    def refresh_body(self, sleeptime):
+    def _refresh_body(self, sleeptime):
+        def is_child_field(field):
+            return field.find('(') != -1
+
+        def insert_child(sorted_items, child, values, parent):
+            num = len(sorted_items)
+            for i in range(0, num):
+                # only add child if parent is present
+                if parent.startswith(sorted_items[i][0]):
+                    sorted_items.insert(i + 1, ('  ' + child, values))
+
+        def get_sorted_events(self, stats):
+            """ separate parent and child events """
+            if self._sorting == SORT_DEFAULT:
+                def sortkey((_k, v)):
+                    # sort by (delta value, overall value)
+                    return (v.delta, v.value)
+            else:
+                def sortkey((_k, v)):
+                    # sort by overall value
+                    return v.value
+
+            childs = []
+            sorted_items = []
+            # we can't rule out child events to appear prior to parents even
+            # when sorted - separate out all children first, and add in later
+            for key, values in sorted(stats.items(), key=sortkey,
+                                      reverse=True):
+                if values == (0, 0):
+                    continue
+                if key.find(' ') != -1:
+                    if not self.stats.child_events:
+                        continue
+                    childs.insert(0, (key, values))
+                else:
+                    sorted_items.append((key, values))
+            if self.stats.child_events:
+                for key, values in childs:
+                    (child, parent) = key.split(' ')
+                    insert_child(sorted_items, child, values, parent)
+
+            return sorted_items
+
         row = 3
         self.screen.move(row, 0)
         self.screen.clrtobot()
         stats = self.stats.get(self._display_guests)
-
-        def sortCurAvg(x):
-            # sort by current events if available
-            if stats[x][1]:
-                return (-stats[x][1], -stats[x][0])
+        total = 0.
+        ctotal = 0.
+        for key, values in stats.items():
+            if self._display_guests:
+                if self.get_gname_from_pid(key):
+                    total += values.value
+                continue
+            if not key.find(' ') != -1:
+                total += values.value
             else:
-                return (0, -stats[x][0])
+                ctotal += values.value
+        if total == 0.:
+            # we don't have any fields, or all non-child events are filtered
+            total = ctotal
 
-        def sortTotal(x):
-            # sort by totals
-            return (0, -stats[x][0])
-        total = 0.
-        for key in stats.keys():
-            if key.find('(') is -1:
-                total += stats[key][0]
-        if self._sorting == SORT_DEFAULT:
-            sortkey = sortCurAvg
-        else:
-            sortkey = sortTotal
+        # print events
         tavg = 0
-        for key in sorted(stats.keys(), key=sortkey):
-            if row >= self.screen.getmaxyx()[0] - 1:
-                break
-            values = stats[key]
-            if not values[0] and not values[1]:
+        tcur = 0
+        for key, values in get_sorted_events(self, stats):
+            if row >= self.screen.getmaxyx()[0] - 1 or values == (0, 0):
                 break
-            if values[0] is not None:
-                cur = int(round(values[1] / sleeptime)) if values[1] else ''
-                if self._display_guests:
-                    key = self.get_gname_from_pid(key)
-                self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' %
-                                   (key, values[0], values[0] * 100 / total,
-                                    cur))
-                if cur is not '' and key.find('(') is -1:
-                    tavg += cur
+            if self._display_guests:
+                key = self.get_gname_from_pid(key)
+                if not key:
+                    continue
+            cur = int(round(values.delta / sleeptime)) if values.delta else ''
+            if key[0] != ' ':
+                if values.delta:
+                    tcur += values.delta
+                ptotal = values.value
+                ltotal = total
+            else:
+                ltotal = ptotal
+            self.screen.addstr(row, 1, '%-40s %10d%7.1f %8s' % (key,
+                               values.value,
+                               values.value * 100 / float(ltotal), cur))
             row += 1
         if row == 3:
             self.screen.addstr(4, 1, 'No matching events reported yet')
-        else:
+        if row > 4:
+            tavg = int(round(tcur / sleeptime)) if tcur > 0 else ''
             self.screen.addstr(row, 1, '%-40s %10d        %8s' %
-                               ('Total', total, tavg if tavg else ''),
-                               curses.A_BOLD)
+                               ('Total', total, tavg), curses.A_BOLD)
         self.screen.refresh()
 
-    def show_msg(self, text):
+    def _show_msg(self, text):
         """Display message centered text and exit on key press"""
         hint = 'Press any key to continue'
         curses.cbreak()
@@ -1139,16 +1227,16 @@ class Tui(object):
                            curses.A_STANDOUT)
         self.screen.getkey()
 
-    def show_help_interactive(self):
+    def _show_help_interactive(self):
         """Display help with list of interactive commands"""
         msg = ('   b     toggle events by guests (debugfs only, honors'
                ' filters)',
                '   c     clear filter',
                '   f     filter by regular expression',
-               '   g     filter by guest name',
+               '   g     filter by guest name/PID',
                '   h     display interactive commands reference',
                '   o     toggle sorting order (Total vs CurAvg/s)',
-               '   p     filter by PID',
+               '   p     filter by guest name/PID',
                '   q     quit',
                '   r     reset stats',
                '   s     set update interval',
@@ -1165,14 +1253,15 @@ class Tui(object):
             self.screen.addstr(row, 0, line)
             row += 1
         self.screen.getkey()
-        self.refresh_header()
+        self._refresh_header()
 
-    def show_filter_selection(self):
+    def _show_filter_selection(self):
         """Draws filter selection mask.
 
         Asks for a valid regex and sets the fields filter accordingly.
 
         """
+        msg = ''
         while True:
             self.screen.erase()
             self.screen.addstr(0, 0,
@@ -1181,61 +1270,25 @@ class Tui(object):
             self.screen.addstr(2, 0,
                                "Current regex: {0}"
                                .format(self.stats.fields_filter))
+            self.screen.addstr(5, 0, msg)
             self.screen.addstr(3, 0, "New regex: ")
             curses.echo()
             regex = self.screen.getstr().decode(ENCODING)
             curses.noecho()
             if len(regex) == 0:
-                self.stats.fields_filter = DEFAULT_REGEX
-                self.refresh_header()
+                self.stats.fields_filter = ''
+                self._refresh_header()
                 return
             try:
                 re.compile(regex)
                 self.stats.fields_filter = regex
-                self.refresh_header()
+                self._refresh_header()
                 return
             except re.error:
+                msg = '"' + regex + '": Not a valid regular expression'
                 continue
 
-    def show_vm_selection_by_pid(self):
-        """Draws PID selection mask.
-
-        Asks for a pid until a valid pid or 0 has been entered.
-
-        """
-        msg = ''
-        while True:
-            self.screen.erase()
-            self.screen.addstr(0, 0,
-                               'Show statistics for specific pid.',
-                               curses.A_BOLD)
-            self.screen.addstr(1, 0,
-                               'This might limit the shown data to the trace '
-                               'statistics.')
-            self.screen.addstr(5, 0, msg)
-            self.print_all_gnames(7)
-
-            curses.echo()
-            self.screen.addstr(3, 0, "Pid [0 or pid]: ")
-            pid = self.screen.getstr().decode(ENCODING)
-            curses.noecho()
-
-            try:
-                if len(pid) > 0:
-                    pid = int(pid)
-                    if pid != 0 and not os.path.isdir(os.path.join('/proc/',
-                                                                   str(pid))):
-                        msg = '"' + str(pid) + '": Not a running process'
-                        continue
-                else:
-                    pid = 0
-                self.refresh_header(pid)
-                self.update_pid(pid)
-                break
-            except ValueError:
-                msg = '"' + str(pid) + '": Not a valid pid'
-
-    def show_set_update_interval(self):
+    def _show_set_update_interval(self):
         """Draws update interval selection mask."""
         msg = ''
         while True:
@@ -1265,60 +1318,67 @@ class Tui(object):
 
             except ValueError:
                 msg = '"' + str(val) + '": Invalid value'
-        self.refresh_header()
+        self._refresh_header()
 
-    def show_vm_selection_by_guest_name(self):
+    def _show_vm_selection_by_guest(self):
         """Draws guest selection mask.
 
-        Asks for a guest name until a valid guest name or '' is entered.
+        Asks for a guest name or pid until a valid guest name or '' is entered.
 
         """
         msg = ''
         while True:
             self.screen.erase()
             self.screen.addstr(0, 0,
-                               'Show statistics for specific guest.',
+                               'Show statistics for specific guest or pid.',
                                curses.A_BOLD)
             self.screen.addstr(1, 0,
                                'This might limit the shown data to the trace '
                                'statistics.')
             self.screen.addstr(5, 0, msg)
-            self.print_all_gnames(7)
+            self._print_all_gnames(7)
             curses.echo()
-            self.screen.addstr(3, 0, "Guest [ENTER or guest]: ")
-            gname = self.screen.getstr().decode(ENCODING)
+            curses.curs_set(1)
+            self.screen.addstr(3, 0, "Guest or pid [ENTER exits]: ")
+            guest = self.screen.getstr().decode(ENCODING)
             curses.noecho()
 
-            if not gname:
-                self.refresh_header(0)
-                self.update_pid(0)
+            pid = 0
+            if not guest or guest == '0':
                 break
-            else:
-                pids = []
-                try:
-                    pids = self.get_pid_from_gname(gname)
-                except:
-                    msg = '"' + gname + '": Internal error while searching, ' \
-                          'use pid filter instead'
-                    continue
-                if len(pids) == 0:
-                    msg = '"' + gname + '": Not an active guest'
+            if guest.isdigit():
+                if not os.path.isdir(os.path.join('/proc/', guest)):
+                    msg = '"' + guest + '": Not a running process'
                     continue
-                if len(pids) > 1:
-                    msg = '"' + gname + '": Multiple matches found, use pid ' \
-                          'filter instead'
-                    continue
-                self.refresh_header(pids[0])
-                self.update_pid(pids[0])
+                pid = int(guest)
                 break
+            pids = []
+            try:
+                pids = self.get_pid_from_gname(guest)
+            except:
+                msg = '"' + guest + '": Internal error while searching, ' \
+                      'use pid filter instead'
+                continue
+            if len(pids) == 0:
+                msg = '"' + guest + '": Not an active guest'
+                continue
+            if len(pids) > 1:
+                msg = '"' + guest + '": Multiple matches found, use pid ' \
+                      'filter instead'
+                continue
+            pid = pids[0]
+            break
+        curses.curs_set(0)
+        self._refresh_header(pid)
+        self._update_pid(pid)
 
     def show_stats(self):
         """Refreshes the screen and processes user input."""
         sleeptime = self._delay_initial
-        self.refresh_header()
+        self._refresh_header()
         start = 0.0  # result based on init value never appears on screen
         while True:
-            self.refresh_body(time.time() - start)
+            self._refresh_body(time.time() - start)
             curses.halfdelay(int(sleeptime * 10))
             start = time.time()
             sleeptime = self._delay_regular
@@ -1327,47 +1387,39 @@ class Tui(object):
                 if char == 'b':
                     self._display_guests = not self._display_guests
                     if self.stats.toggle_display_guests(self._display_guests):
-                        self.show_msg(['Command not available with tracepoints'
-                                       ' enabled', 'Restart with debugfs only '
-                                       '(see option \'-d\') and try again!'])
+                        self._show_msg(['Command not available with '
+                                        'tracepoints enabled', 'Restart with '
+                                        'debugfs only (see option \'-d\') and '
+                                        'try again!'])
                         self._display_guests = not self._display_guests
-                    self.refresh_header()
+                    self._refresh_header()
                 if char == 'c':
-                    self.stats.fields_filter = DEFAULT_REGEX
-                    self.refresh_header(0)
-                    self.update_pid(0)
+                    self.stats.fields_filter = ''
+                    self._refresh_header(0)
+                    self._update_pid(0)
                 if char == 'f':
                     curses.curs_set(1)
-                    self.show_filter_selection()
+                    self._show_filter_selection()
                     curses.curs_set(0)
                     sleeptime = self._delay_initial
-                if char == 'g':
-                    curses.curs_set(1)
-                    self.show_vm_selection_by_guest_name()
-                    curses.curs_set(0)
+                if char == 'g' or char == 'p':
+                    self._show_vm_selection_by_guest()
                     sleeptime = self._delay_initial
                 if char == 'h':
-                    self.show_help_interactive()
+                    self._show_help_interactive()
                 if char == 'o':
                     self._sorting = not self._sorting
-                if char == 'p':
-                    curses.curs_set(1)
-                    self.show_vm_selection_by_pid()
-                    curses.curs_set(0)
-                    sleeptime = self._delay_initial
                 if char == 'q':
                     break
                 if char == 'r':
                     self.stats.reset()
                 if char == 's':
                     curses.curs_set(1)
-                    self.show_set_update_interval()
+                    self._show_set_update_interval()
                     curses.curs_set(0)
                     sleeptime = self._delay_initial
                 if char == 'x':
-                    self.update_drilldown()
-                    # prevents display of current values on next refresh
-                    self.stats.get(self._display_guests)
+                    self.stats.child_events = not self.stats.child_events
             except KeyboardInterrupt:
                 break
             except curses.error:
@@ -1380,9 +1432,9 @@ def batch(stats):
         s = stats.get()
         time.sleep(1)
         s = stats.get()
-        for key in sorted(s.keys()):
-            values = s[key]
-            print('%-42s%10d%10d' % (key, values[0], values[1]))
+        for key, values in sorted(s.items()):
+            print('%-42s%10d%10d' % (key.split(' ')[0], values.value,
+                  values.delta))
     except KeyboardInterrupt:
         pass
 
@@ -1392,14 +1444,14 @@ def log(stats):
     keys = sorted(stats.get().keys())
 
     def banner():
-        for k in keys:
-            print(k, end=' ')
+        for key in keys:
+            print(key.split(' ')[0], end=' ')
         print()
 
     def statline():
         s = stats.get()
-        for k in keys:
-            print(' %9d' % s[k][1], end=' ')
+        for key in keys:
+            print(' %9d' % s[key].delta, end=' ')
         print()
     line = 0
     banner_repeat = 20
@@ -1504,7 +1556,7 @@ Press any other key to refresh statistics immediately.
                          )
     optparser.add_option('-f', '--fields',
                          action='store',
-                         default=DEFAULT_REGEX,
+                         default='',
                          dest='fields',
                          help='''fields to display (regex)
                                  "-f help" for a list of available events''',
@@ -1539,17 +1591,6 @@ Press any other key to refresh statistics immediately.
 
 def check_access(options):
     """Exits if the current user can't access all needed directories."""
-    if not os.path.exists('/sys/kernel/debug'):
-        sys.stderr.write('Please enable CONFIG_DEBUG_FS in your kernel.')
-        sys.exit(1)
-
-    if not os.path.exists(PATH_DEBUGFS_KVM):
-        sys.stderr.write("Please make sure, that debugfs is mounted and "
-                         "readable by the current user:\n"
-                         "('mount -t debugfs debugfs /sys/kernel/debug')\n"
-                         "Also ensure, that the kvm modules are loaded.\n")
-        sys.exit(1)
-
     if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints or
                                                      not options.debugfs):
         sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
@@ -1567,7 +1608,33 @@ def check_access(options):
     return options
 
 
+def assign_globals():
+    global PATH_DEBUGFS_KVM
+    global PATH_DEBUGFS_TRACING
+
+    debugfs = ''
+    for line in file('/proc/mounts'):
+        if line.split(' ')[0] == 'debugfs':
+            debugfs = line.split(' ')[1]
+            break
+    if debugfs == '':
+        sys.stderr.write("Please make sure that CONFIG_DEBUG_FS is enabled in "
+                         "your kernel, mounted and\nreadable by the current "
+                         "user:\n"
+                         "('mount -t debugfs debugfs /sys/kernel/debug')\n")
+        sys.exit(1)
+
+    PATH_DEBUGFS_KVM = os.path.join(debugfs, 'kvm')
+    PATH_DEBUGFS_TRACING = os.path.join(debugfs, 'tracing')
+
+    if not os.path.exists(PATH_DEBUGFS_KVM):
+        sys.stderr.write("Please make sure that CONFIG_KVM is enabled in "
+                         "your kernel and that the modules are loaded.\n")
+        sys.exit(1)
+
+
 def main():
+    assign_globals()
     options = get_options()
     options = check_access(options)
 
index b5b3810c9e945d7f3a39568840fbc5b73f84983b..0811d860fe75000de852c569ccaaa3ae1f0aa944 100644 (file)
@@ -35,13 +35,13 @@ INTERACTIVE COMMANDS
 
 *f*::  filter by regular expression
 
-*g*::  filter by guest name
+*g*::  filter by guest name/PID
 
 *h*::  display interactive commands reference
 
 *o*::   toggle sorting order (Total vs CurAvg/s)
 
-*p*::  filter by PID
+*p*::  filter by guest name/PID
 
 *q*::  quit
 
index 5f758c489a208c09fd09274b0b01302d61d56f27..b572d94255f66c518ebd201eab3fb80b8735d0d4 100644 (file)
@@ -2,7 +2,6 @@
 PREFIX ?= /usr
 SBINDIR ?= sbin
 INSTALL ?= install
-CC = $(CROSS_COMPILE)gcc
 
 TARGET = freefall
 
index c379af003807ad6606d432e98e8c2dd413c04e7d..7b6bed13daaaed8b68abcc4b9b2aa8eb96f7974d 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for LEDs tools
 
-CC = $(CROSS_COMPILE)gcc
 CFLAGS = -Wall -Wextra -g -I../../include/uapi
 
 all: uledmon led_hw_brightness_mon
index 97073d649c1a0add9c98f8cc363aa8debad6cff1..5bbbf285af74a0afb01ae4dcaba9a7cdbb3a3e93 100644 (file)
@@ -1060,11 +1060,12 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
                prog->insns = new_insn;
                prog->main_prog_cnt = prog->insns_cnt;
                prog->insns_cnt = new_cnt;
+               pr_debug("added %zd insn from %s to prog %s\n",
+                        text->insns_cnt, text->section_name,
+                        prog->section_name);
        }
        insn = &prog->insns[relo->insn_idx];
        insn->imm += prog->main_prog_cnt - relo->insn_idx;
-       pr_debug("added %zd insn from %s to prog %s\n",
-                text->insns_cnt, text->section_name, prog->section_name);
        return 0;
 }
 
index 57254f5b2779fb02276f00eb82401a05eaaabeb0..694abc628e9b3060b2252c1e8c86af4d6176e518 100644 (file)
@@ -29,7 +29,7 @@
 #include "builtin.h"
 #include "check.h"
 
-bool no_fp, no_unreachable;
+bool no_fp, no_unreachable, retpoline, module;
 
 static const char * const check_usage[] = {
        "objtool check [<options>] file.o",
@@ -39,6 +39,8 @@ static const char * const check_usage[] = {
 const struct option check_options[] = {
        OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"),
        OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"),
+       OPT_BOOLEAN('r', "retpoline", &retpoline, "Validate retpoline assumptions"),
+       OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
        OPT_END(),
 };
 
@@ -53,5 +55,5 @@ int cmd_check(int argc, const char **argv)
 
        objname = argv[0];
 
-       return check(objname, no_fp, no_unreachable, false);
+       return check(objname, false);
 }
index 91e8e19ff5e06193adc55c455b4d97ad947da7ee..77ea2b97117d2fd586e52294593c4d0c23a55ecd 100644 (file)
@@ -25,7 +25,6 @@
  */
 
 #include <string.h>
-#include <subcmd/parse-options.h>
 #include "builtin.h"
 #include "check.h"
 
@@ -36,9 +35,6 @@ static const char *orc_usage[] = {
        NULL,
 };
 
-extern const struct option check_options[];
-extern bool no_fp, no_unreachable;
-
 int cmd_orc(int argc, const char **argv)
 {
        const char *objname;
@@ -54,7 +50,7 @@ int cmd_orc(int argc, const char **argv)
 
                objname = argv[0];
 
-               return check(objname, no_fp, no_unreachable, true);
+               return check(objname, true);
        }
 
        if (!strcmp(argv[0], "dump")) {
index dd526067fed5ebcacbb45b7ce8a686437bd83d1a..28ff40e19a1413823b9b06ae4d1f1b42d922e850 100644 (file)
 #ifndef _BUILTIN_H
 #define _BUILTIN_H
 
+#include <subcmd/parse-options.h>
+
+extern const struct option check_options[];
+extern bool no_fp, no_unreachable, retpoline, module;
+
 extern int cmd_check(int argc, const char **argv);
 extern int cmd_orc(int argc, const char **argv);
 
index b00b1896547e41d12013eeeda60ecc91ee6231ea..92b6a2c21631d810cda14a79ef3fa2d906e6cb50 100644 (file)
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <stdlib.h>
 
+#include "builtin.h"
 #include "check.h"
 #include "elf.h"
 #include "special.h"
@@ -33,7 +34,6 @@ struct alternative {
 };
 
 const char *objname;
-static bool no_fp;
 struct cfi_state initial_func_cfi;
 
 struct instruction *find_insn(struct objtool_file *file,
@@ -497,6 +497,7 @@ static int add_jump_destinations(struct objtool_file *file)
                         * disguise, so convert them accordingly.
                         */
                        insn->type = INSN_JUMP_DYNAMIC;
+                       insn->retpoline_safe = true;
                        continue;
                } else {
                        /* sibling call */
@@ -548,7 +549,8 @@ static int add_call_destinations(struct objtool_file *file)
                        if (!insn->call_dest && !insn->ignore) {
                                WARN_FUNC("unsupported intra-function call",
                                          insn->sec, insn->offset);
-                               WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
+                               if (retpoline)
+                                       WARN("If this is a retpoline, please patch it in with alternatives and annotate it with ANNOTATE_NOSPEC_ALTERNATIVE.");
                                return -1;
                        }
 
@@ -852,8 +854,14 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func,
  *    This is a fairly uncommon pattern which is new for GCC 6.  As of this
  *    writing, there are 11 occurrences of it in the allmodconfig kernel.
  *
+ *    As of GCC 7 there are quite a few more of these and the 'in between' code
+ *    is significant. Esp. with KASAN enabled some of the code between the mov
+ *    and jmpq uses .rodata itself, which can confuse things.
+ *
  *    TODO: Once we have DWARF CFI and smarter instruction decoding logic,
  *    ensure the same register is used in the mov and jump instructions.
+ *
+ *    NOTE: RETPOLINE made it harder still to decode dynamic jumps.
  */
 static struct rela *find_switch_table(struct objtool_file *file,
                                      struct symbol *func,
@@ -875,12 +883,25 @@ static struct rela *find_switch_table(struct objtool_file *file,
                                                text_rela->addend + 4);
                if (!rodata_rela)
                        return NULL;
+
                file->ignore_unreachables = true;
                return rodata_rela;
        }
 
        /* case 3 */
-       func_for_each_insn_continue_reverse(file, func, insn) {
+       /*
+        * Backward search using the @first_jump_src links, these help avoid
+        * much of the 'in between' code. Which avoids us getting confused by
+        * it.
+        */
+       for (insn = list_prev_entry(insn, list);
+
+            &insn->list != &file->insn_list &&
+            insn->sec == func->sec &&
+            insn->offset >= func->offset;
+
+            insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
+
                if (insn->type == INSN_JUMP_DYNAMIC)
                        break;
 
@@ -904,20 +925,42 @@ static struct rela *find_switch_table(struct objtool_file *file,
                if (find_symbol_containing(file->rodata, text_rela->addend))
                        continue;
 
-               return find_rela_by_dest(file->rodata, text_rela->addend);
+               rodata_rela = find_rela_by_dest(file->rodata, text_rela->addend);
+               if (!rodata_rela)
+                       continue;
+
+               return rodata_rela;
        }
 
        return NULL;
 }
 
+
 static int add_func_switch_tables(struct objtool_file *file,
                                  struct symbol *func)
 {
-       struct instruction *insn, *prev_jump = NULL;
+       struct instruction *insn, *last = NULL, *prev_jump = NULL;
        struct rela *rela, *prev_rela = NULL;
        int ret;
 
        func_for_each_insn(file, func, insn) {
+               if (!last)
+                       last = insn;
+
+               /*
+                * Store back-pointers for unconditional forward jumps such
+                * that find_switch_table() can back-track using those and
+                * avoid some potentially confusing code.
+                */
+               if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest &&
+                   insn->offset > last->offset &&
+                   insn->jump_dest->offset > insn->offset &&
+                   !insn->jump_dest->first_jump_src) {
+
+                       insn->jump_dest->first_jump_src = insn;
+                       last = insn->jump_dest;
+               }
+
                if (insn->type != INSN_JUMP_DYNAMIC)
                        continue;
 
@@ -1071,6 +1114,41 @@ static int read_unwind_hints(struct objtool_file *file)
        return 0;
 }
 
+static int read_retpoline_hints(struct objtool_file *file)
+{
+       struct section *sec;
+       struct instruction *insn;
+       struct rela *rela;
+
+       sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe");
+       if (!sec)
+               return 0;
+
+       list_for_each_entry(rela, &sec->rela_list, list) {
+               if (rela->sym->type != STT_SECTION) {
+                       WARN("unexpected relocation symbol type in %s", sec->name);
+                       return -1;
+               }
+
+               insn = find_insn(file, rela->sym->sec, rela->addend);
+               if (!insn) {
+                       WARN("bad .discard.retpoline_safe entry");
+                       return -1;
+               }
+
+               if (insn->type != INSN_JUMP_DYNAMIC &&
+                   insn->type != INSN_CALL_DYNAMIC) {
+                       WARN_FUNC("retpoline_safe hint not an indirect jump/call",
+                                 insn->sec, insn->offset);
+                       return -1;
+               }
+
+               insn->retpoline_safe = true;
+       }
+
+       return 0;
+}
+
 static int decode_sections(struct objtool_file *file)
 {
        int ret;
@@ -1109,6 +1187,10 @@ static int decode_sections(struct objtool_file *file)
        if (ret)
                return ret;
 
+       ret = read_retpoline_hints(file);
+       if (ret)
+               return ret;
+
        return 0;
 }
 
@@ -1854,6 +1936,38 @@ static int validate_unwind_hints(struct objtool_file *file)
        return warnings;
 }
 
+static int validate_retpoline(struct objtool_file *file)
+{
+       struct instruction *insn;
+       int warnings = 0;
+
+       for_each_insn(file, insn) {
+               if (insn->type != INSN_JUMP_DYNAMIC &&
+                   insn->type != INSN_CALL_DYNAMIC)
+                       continue;
+
+               if (insn->retpoline_safe)
+                       continue;
+
+               /*
+                * .init.text code is ran before userspace and thus doesn't
+                * strictly need retpolines, except for modules which are
+                * loaded late, they very much do need retpoline in their
+                * .init.text
+                */
+               if (!strcmp(insn->sec->name, ".init.text") && !module)
+                       continue;
+
+               WARN_FUNC("indirect %s found in RETPOLINE build",
+                         insn->sec, insn->offset,
+                         insn->type == INSN_JUMP_DYNAMIC ? "jump" : "call");
+
+               warnings++;
+       }
+
+       return warnings;
+}
+
 static bool is_kasan_insn(struct instruction *insn)
 {
        return (insn->type == INSN_CALL &&
@@ -1899,13 +2013,19 @@ static bool ignore_unreachable_insn(struct instruction *insn)
                if (is_kasan_insn(insn) || is_ubsan_insn(insn))
                        return true;
 
-               if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest) {
-                       insn = insn->jump_dest;
-                       continue;
+               if (insn->type == INSN_JUMP_UNCONDITIONAL) {
+                       if (insn->jump_dest &&
+                           insn->jump_dest->func == insn->func) {
+                               insn = insn->jump_dest;
+                               continue;
+                       }
+
+                       break;
                }
 
                if (insn->offset + insn->len >= insn->func->offset + insn->func->len)
                        break;
+
                insn = list_next_entry(insn, list);
        }
 
@@ -1979,13 +2099,12 @@ static void cleanup(struct objtool_file *file)
        elf_close(file->elf);
 }
 
-int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc)
+int check(const char *_objname, bool orc)
 {
        struct objtool_file file;
        int ret, warnings = 0;
 
        objname = _objname;
-       no_fp = _no_fp;
 
        file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY);
        if (!file.elf)
@@ -2009,6 +2128,13 @@ int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc)
        if (list_empty(&file.insn_list))
                goto out;
 
+       if (retpoline) {
+               ret = validate_retpoline(&file);
+               if (ret < 0)
+                       return ret;
+               warnings += ret;
+       }
+
        ret = validate_functions(&file);
        if (ret < 0)
                goto out;
index dbadb304a410af0343809752bc6d2869668a9db0..c6b68fcb926ff76c6e44675ff636c16f3552a184 100644 (file)
@@ -45,8 +45,10 @@ struct instruction {
        unsigned char type;
        unsigned long immediate;
        bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts;
+       bool retpoline_safe;
        struct symbol *call_dest;
        struct instruction *jump_dest;
+       struct instruction *first_jump_src;
        struct list_head alts;
        struct symbol *func;
        struct stack_op stack_op;
@@ -62,7 +64,7 @@ struct objtool_file {
        bool ignore_unreachables, c_file, hints;
 };
 
-int check(const char *objname, bool no_fp, bool no_unreachable, bool orc);
+int check(const char *objname, bool orc);
 
 struct instruction *find_insn(struct objtool_file *file,
                              struct section *sec, unsigned long offset);
index f0796a47dfa30ee6523381e069340b3eeeeeb3ef..90bb4aabe4f8d48e928c1fd4ae82d45ae7baeb50 100644 (file)
@@ -30,6 +30,10 @@ OPTIONS for 'convert'
 -i::
        Specify input perf data file path.
 
+-f::
+--force::
+       Don't complain, do it.
+
 -v::
 --verbose::
         Be more verbose (show counter open errors, etc).
index 954ea9e21236dd6b96d6a1a5330ed410ba278ae0..cf9f4040ea5c7ae1b5890d973efa53592efbe56a 100644 (file)
@@ -8,7 +8,7 @@ perf-kallsyms - Searches running kernel for symbols
 SYNOPSIS
 --------
 [verse]
-'perf kallsyms <options> symbol_name[,symbol_name...]'
+'perf kallsyms' [<options>] symbol_name[,symbol_name...]
 
 DESCRIPTION
 -----------
index 9b0351d3ce348844ce6d857c1f9158ed0810dd1e..01232803859406b180eed3d19739f88262fc3e81 100644 (file)
@@ -146,12 +146,6 @@ define allow-override
     $(eval $(1) = $(2)))
 endef
 
-# Allow setting CC and AR and LD, or setting CROSS_COMPILE as a prefix.
-$(call allow-override,CC,$(CROSS_COMPILE)gcc)
-$(call allow-override,AR,$(CROSS_COMPILE)ar)
-$(call allow-override,LD,$(CROSS_COMPILE)ld)
-$(call allow-override,CXX,$(CROSS_COMPILE)g++)
-
 LD += $(EXTRA_LDFLAGS)
 
 HOSTCC  ?= gcc
index 48228de415d00620d0017e1b215d3d09a951e676..dfa6e31034371c26666429678047c037c1aae5dc 100644 (file)
@@ -10,15 +10,19 @@ PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
 
 out    := $(OUTPUT)arch/s390/include/generated/asm
 header := $(out)/syscalls_64.c
-sysdef := $(srctree)/tools/arch/s390/include/uapi/asm/unistd.h
-sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls/
+syskrn := $(srctree)/arch/s390/kernel/syscalls/syscall.tbl
+sysprf := $(srctree)/tools/perf/arch/s390/entry/syscalls
+sysdef := $(sysprf)/syscall.tbl
 systbl := $(sysprf)/mksyscalltbl
 
 # Create output directory if not already present
 _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
 
 $(header): $(sysdef) $(systbl)
-       $(Q)$(SHELL) '$(systbl)' '$(CC)' $(sysdef) > $@
+       @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
+        (diff -B $(sysdef) $(syskrn) >/dev/null) \
+        || echo "Warning: Kernel ABI header at '$(sysdef)' differs from latest version at '$(syskrn)'" >&2 )) || true
+       $(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
 
 clean::
        $(call QUIET_CLEAN, s390) $(RM) $(header)
index 7fa0d0abd4196c52b633ce5a06acb115231133ea..72ecbb67637079f709262298981162b6cbb12c9f 100755 (executable)
@@ -3,25 +3,23 @@
 #
 # Generate system call table for perf
 #
-#
-# Copyright IBM Corp. 2017
+# Copyright IBM Corp. 2017, 2018
 # Author(s):  Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
 #
 
-gcc=$1
-input=$2
+SYSCALL_TBL=$1
 
-if ! test -r $input; then
+if ! test -r $SYSCALL_TBL; then
        echo "Could not read input file" >&2
        exit 1
 fi
 
 create_table()
 {
-       local max_nr
+       local max_nr nr abi sc discard
 
        echo 'static const char *syscalltbl_s390_64[] = {'
-       while read sc nr; do
+       while read nr abi sc discard; do
                printf '\t[%d] = "%s",\n' $nr $sc
                max_nr=$nr
        done
@@ -29,8 +27,6 @@ create_table()
        echo "#define SYSCALLTBL_S390_64_MAX_ID $max_nr"
 }
 
-
-$gcc -m64 -E -dM -x c  $input         \
-       |sed -ne 's/^#define __NR_//p' \
-       |sort -t' ' -k2 -nu            \
+grep -E "^[[:digit:]]+[[:space:]]+(common|64)" $SYSCALL_TBL    \
+       |sort -k1 -n                                    \
        |create_table
diff --git a/tools/perf/arch/s390/entry/syscalls/syscall.tbl b/tools/perf/arch/s390/entry/syscalls/syscall.tbl
new file mode 100644 (file)
index 0000000..b38d484
--- /dev/null
@@ -0,0 +1,390 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# System call table for s390
+#
+# Format:
+#
+# <nr> <abi> <syscall> <entry-64bit> <compat-entry>
+#
+# where <abi> can be common, 64, or 32
+
+1    common    exit                    sys_exit                        sys_exit
+2    common    fork                    sys_fork                        sys_fork
+3    common    read                    sys_read                        compat_sys_s390_read
+4    common    write                   sys_write                       compat_sys_s390_write
+5    common    open                    sys_open                        compat_sys_open
+6    common    close                   sys_close                       sys_close
+7    common    restart_syscall         sys_restart_syscall             sys_restart_syscall
+8    common    creat                   sys_creat                       compat_sys_creat
+9    common    link                    sys_link                        compat_sys_link
+10   common    unlink                  sys_unlink                      compat_sys_unlink
+11   common    execve                  sys_execve                      compat_sys_execve
+12   common    chdir                   sys_chdir                       compat_sys_chdir
+13   32                time                    -                               compat_sys_time
+14   common    mknod                   sys_mknod                       compat_sys_mknod
+15   common    chmod                   sys_chmod                       compat_sys_chmod
+16   32                lchown                  -                               compat_sys_s390_lchown16
+19   common    lseek                   sys_lseek                       compat_sys_lseek
+20   common    getpid                  sys_getpid                      sys_getpid
+21   common    mount                   sys_mount                       compat_sys_mount
+22   common    umount                  sys_oldumount                   compat_sys_oldumount
+23   32                setuid                  -                               compat_sys_s390_setuid16
+24   32                getuid                  -                               compat_sys_s390_getuid16
+25   32                stime                   -                               compat_sys_stime
+26   common    ptrace                  sys_ptrace                      compat_sys_ptrace
+27   common    alarm                   sys_alarm                       sys_alarm
+29   common    pause                   sys_pause                       sys_pause
+30   common    utime                   sys_utime                       compat_sys_utime
+33   common    access                  sys_access                      compat_sys_access
+34   common    nice                    sys_nice                        sys_nice
+36   common    sync                    sys_sync                        sys_sync
+37   common    kill                    sys_kill                        sys_kill
+38   common    rename                  sys_rename                      compat_sys_rename
+39   common    mkdir                   sys_mkdir                       compat_sys_mkdir
+40   common    rmdir                   sys_rmdir                       compat_sys_rmdir
+41   common    dup                     sys_dup                         sys_dup
+42   common    pipe                    sys_pipe                        compat_sys_pipe
+43   common    times                   sys_times                       compat_sys_times
+45   common    brk                     sys_brk                         compat_sys_brk
+46   32                setgid                  -                               compat_sys_s390_setgid16
+47   32                getgid                  -                               compat_sys_s390_getgid16
+48   common    signal                  sys_signal                      compat_sys_signal
+49   32                geteuid                 -                               compat_sys_s390_geteuid16
+50   32                getegid                 -                               compat_sys_s390_getegid16
+51   common    acct                    sys_acct                        compat_sys_acct
+52   common    umount2                 sys_umount                      compat_sys_umount
+54   common    ioctl                   sys_ioctl                       compat_sys_ioctl
+55   common    fcntl                   sys_fcntl                       compat_sys_fcntl
+57   common    setpgid                 sys_setpgid                     sys_setpgid
+60   common    umask                   sys_umask                       sys_umask
+61   common    chroot                  sys_chroot                      compat_sys_chroot
+62   common    ustat                   sys_ustat                       compat_sys_ustat
+63   common    dup2                    sys_dup2                        sys_dup2
+64   common    getppid                 sys_getppid                     sys_getppid
+65   common    getpgrp                 sys_getpgrp                     sys_getpgrp
+66   common    setsid                  sys_setsid                      sys_setsid
+67   common    sigaction               sys_sigaction                   compat_sys_sigaction
+70   32                setreuid                -                               compat_sys_s390_setreuid16
+71   32                setregid                -                               compat_sys_s390_setregid16
+72   common    sigsuspend              sys_sigsuspend                  compat_sys_sigsuspend
+73   common    sigpending              sys_sigpending                  compat_sys_sigpending
+74   common    sethostname             sys_sethostname                 compat_sys_sethostname
+75   common    setrlimit               sys_setrlimit                   compat_sys_setrlimit
+76   32                getrlimit               -                               compat_sys_old_getrlimit
+77   common    getrusage               sys_getrusage                   compat_sys_getrusage
+78   common    gettimeofday            sys_gettimeofday                compat_sys_gettimeofday
+79   common    settimeofday            sys_settimeofday                compat_sys_settimeofday
+80   32                getgroups               -                               compat_sys_s390_getgroups16
+81   32                setgroups               -                               compat_sys_s390_setgroups16
+83   common    symlink                 sys_symlink                     compat_sys_symlink
+85   common    readlink                sys_readlink                    compat_sys_readlink
+86   common    uselib                  sys_uselib                      compat_sys_uselib
+87   common    swapon                  sys_swapon                      compat_sys_swapon
+88   common    reboot                  sys_reboot                      compat_sys_reboot
+89   common    readdir                 -                               compat_sys_old_readdir
+90   common    mmap                    sys_old_mmap                    compat_sys_s390_old_mmap
+91   common    munmap                  sys_munmap                      compat_sys_munmap
+92   common    truncate                sys_truncate                    compat_sys_truncate
+93   common    ftruncate               sys_ftruncate                   compat_sys_ftruncate
+94   common    fchmod                  sys_fchmod                      sys_fchmod
+95   32                fchown                  -                               compat_sys_s390_fchown16
+96   common    getpriority             sys_getpriority                 sys_getpriority
+97   common    setpriority             sys_setpriority                 sys_setpriority
+99   common    statfs                  sys_statfs                      compat_sys_statfs
+100  common    fstatfs                 sys_fstatfs                     compat_sys_fstatfs
+101  32                ioperm                  -                               -
+102  common    socketcall              sys_socketcall                  compat_sys_socketcall
+103  common    syslog                  sys_syslog                      compat_sys_syslog
+104  common    setitimer               sys_setitimer                   compat_sys_setitimer
+105  common    getitimer               sys_getitimer                   compat_sys_getitimer
+106  common    stat                    sys_newstat                     compat_sys_newstat
+107  common    lstat                   sys_newlstat                    compat_sys_newlstat
+108  common    fstat                   sys_newfstat                    compat_sys_newfstat
+110  common    lookup_dcookie          sys_lookup_dcookie              compat_sys_lookup_dcookie
+111  common    vhangup                 sys_vhangup                     sys_vhangup
+112  common    idle                    -                               -
+114  common    wait4                   sys_wait4                       compat_sys_wait4
+115  common    swapoff                 sys_swapoff                     compat_sys_swapoff
+116  common    sysinfo                 sys_sysinfo                     compat_sys_sysinfo
+117  common    ipc                     sys_s390_ipc                    compat_sys_s390_ipc
+118  common    fsync                   sys_fsync                       sys_fsync
+119  common    sigreturn               sys_sigreturn                   compat_sys_sigreturn
+120  common    clone                   sys_clone                       compat_sys_clone
+121  common    setdomainname           sys_setdomainname               compat_sys_setdomainname
+122  common    uname                   sys_newuname                    compat_sys_newuname
+124  common    adjtimex                sys_adjtimex                    compat_sys_adjtimex
+125  common    mprotect                sys_mprotect                    compat_sys_mprotect
+126  common    sigprocmask             sys_sigprocmask                 compat_sys_sigprocmask
+127  common    create_module           -                               -
+128  common    init_module             sys_init_module                 compat_sys_init_module
+129  common    delete_module           sys_delete_module               compat_sys_delete_module
+130  common    get_kernel_syms         -                               -
+131  common    quotactl                sys_quotactl                    compat_sys_quotactl
+132  common    getpgid                 sys_getpgid                     sys_getpgid
+133  common    fchdir                  sys_fchdir                      sys_fchdir
+134  common    bdflush                 sys_bdflush                     compat_sys_bdflush
+135  common    sysfs                   sys_sysfs                       compat_sys_sysfs
+136  common    personality             sys_s390_personality            sys_s390_personality
+137  common    afs_syscall             -                               -
+138  32                setfsuid                -                               compat_sys_s390_setfsuid16
+139  32                setfsgid                -                               compat_sys_s390_setfsgid16
+140  32                _llseek                 -                               compat_sys_llseek
+141  common    getdents                sys_getdents                    compat_sys_getdents
+142  32                _newselect              -                               compat_sys_select
+142  64                select                  sys_select                      -
+143  common    flock                   sys_flock                       sys_flock
+144  common    msync                   sys_msync                       compat_sys_msync
+145  common    readv                   sys_readv                       compat_sys_readv
+146  common    writev                  sys_writev                      compat_sys_writev
+147  common    getsid                  sys_getsid                      sys_getsid
+148  common    fdatasync               sys_fdatasync                   sys_fdatasync
+149  common    _sysctl                 sys_sysctl                      compat_sys_sysctl
+150  common    mlock                   sys_mlock                       compat_sys_mlock
+151  common    munlock                 sys_munlock                     compat_sys_munlock
+152  common    mlockall                sys_mlockall                    sys_mlockall
+153  common    munlockall              sys_munlockall                  sys_munlockall
+154  common    sched_setparam          sys_sched_setparam              compat_sys_sched_setparam
+155  common    sched_getparam          sys_sched_getparam              compat_sys_sched_getparam
+156  common    sched_setscheduler      sys_sched_setscheduler          compat_sys_sched_setscheduler
+157  common    sched_getscheduler      sys_sched_getscheduler          sys_sched_getscheduler
+158  common    sched_yield             sys_sched_yield                 sys_sched_yield
+159  common    sched_get_priority_max  sys_sched_get_priority_max      sys_sched_get_priority_max
+160  common    sched_get_priority_min  sys_sched_get_priority_min      sys_sched_get_priority_min
+161  common    sched_rr_get_interval   sys_sched_rr_get_interval       compat_sys_sched_rr_get_interval
+162  common    nanosleep               sys_nanosleep                   compat_sys_nanosleep
+163  common    mremap                  sys_mremap                      compat_sys_mremap
+164  32                setresuid               -                               compat_sys_s390_setresuid16
+165  32                getresuid               -                               compat_sys_s390_getresuid16
+167  common    query_module            -                               -
+168  common    poll                    sys_poll                        compat_sys_poll
+169  common    nfsservctl              -                               -
+170  32                setresgid               -                               compat_sys_s390_setresgid16
+171  32                getresgid               -                               compat_sys_s390_getresgid16
+172  common    prctl                   sys_prctl                       compat_sys_prctl
+173  common    rt_sigreturn            sys_rt_sigreturn                compat_sys_rt_sigreturn
+174  common    rt_sigaction            sys_rt_sigaction                compat_sys_rt_sigaction
+175  common    rt_sigprocmask          sys_rt_sigprocmask              compat_sys_rt_sigprocmask
+176  common    rt_sigpending           sys_rt_sigpending               compat_sys_rt_sigpending
+177  common    rt_sigtimedwait         sys_rt_sigtimedwait             compat_sys_rt_sigtimedwait
+178  common    rt_sigqueueinfo         sys_rt_sigqueueinfo             compat_sys_rt_sigqueueinfo
+179  common    rt_sigsuspend           sys_rt_sigsuspend               compat_sys_rt_sigsuspend
+180  common    pread64                 sys_pread64                     compat_sys_s390_pread64
+181  common    pwrite64                sys_pwrite64                    compat_sys_s390_pwrite64
+182  32                chown                   -                               compat_sys_s390_chown16
+183  common    getcwd                  sys_getcwd                      compat_sys_getcwd
+184  common    capget                  sys_capget                      compat_sys_capget
+185  common    capset                  sys_capset                      compat_sys_capset
+186  common    sigaltstack             sys_sigaltstack                 compat_sys_sigaltstack
+187  common    sendfile                sys_sendfile64                  compat_sys_sendfile
+188  common    getpmsg                 -                               -
+189  common    putpmsg                 -                               -
+190  common    vfork                   sys_vfork                       sys_vfork
+191  32                ugetrlimit              -                               compat_sys_getrlimit
+191  64                getrlimit               sys_getrlimit                   -
+192  32                mmap2                   -                               compat_sys_s390_mmap2
+193  32                truncate64              -                               compat_sys_s390_truncate64
+194  32                ftruncate64             -                               compat_sys_s390_ftruncate64
+195  32                stat64                  -                               compat_sys_s390_stat64
+196  32                lstat64                 -                               compat_sys_s390_lstat64
+197  32                fstat64                 -                               compat_sys_s390_fstat64
+198  32                lchown32                -                               compat_sys_lchown
+198  64                lchown                  sys_lchown                      -
+199  32                getuid32                -                               sys_getuid
+199  64                getuid                  sys_getuid                      -
+200  32                getgid32                -                               sys_getgid
+200  64                getgid                  sys_getgid                      -
+201  32                geteuid32               -                               sys_geteuid
+201  64                geteuid                 sys_geteuid                     -
+202  32                getegid32               -                               sys_getegid
+202  64                getegid                 sys_getegid                     -
+203  32                setreuid32              -                               sys_setreuid
+203  64                setreuid                sys_setreuid                    -
+204  32                setregid32              -                               sys_setregid
+204  64                setregid                sys_setregid                    -
+205  32                getgroups32             -                               compat_sys_getgroups
+205  64                getgroups               sys_getgroups                   -
+206  32                setgroups32             -                               compat_sys_setgroups
+206  64                setgroups               sys_setgroups                   -
+207  32                fchown32                -                               sys_fchown
+207  64                fchown                  sys_fchown                      -
+208  32                setresuid32             -                               sys_setresuid
+208  64                setresuid               sys_setresuid                   -
+209  32                getresuid32             -                               compat_sys_getresuid
+209  64                getresuid               sys_getresuid                   -
+210  32                setresgid32             -                               sys_setresgid
+210  64                setresgid               sys_setresgid                   -
+211  32                getresgid32             -                               compat_sys_getresgid
+211  64                getresgid               sys_getresgid                   -
+212  32                chown32                 -                               compat_sys_chown
+212  64                chown                   sys_chown                       -
+213  32                setuid32                -                               sys_setuid
+213  64                setuid                  sys_setuid                      -
+214  32                setgid32                -                               sys_setgid
+214  64                setgid                  sys_setgid                      -
+215  32                setfsuid32              -                               sys_setfsuid
+215  64                setfsuid                sys_setfsuid                    -
+216  32                setfsgid32              -                               sys_setfsgid
+216  64                setfsgid                sys_setfsgid                    -
+217  common    pivot_root              sys_pivot_root                  compat_sys_pivot_root
+218  common    mincore                 sys_mincore                     compat_sys_mincore
+219  common    madvise                 sys_madvise                     compat_sys_madvise
+220  common    getdents64              sys_getdents64                  compat_sys_getdents64
+221  32                fcntl64                 -                               compat_sys_fcntl64
+222  common    readahead               sys_readahead                   compat_sys_s390_readahead
+223  32                sendfile64              -                               compat_sys_sendfile64
+224  common    setxattr                sys_setxattr                    compat_sys_setxattr
+225  common    lsetxattr               sys_lsetxattr                   compat_sys_lsetxattr
+226  common    fsetxattr               sys_fsetxattr                   compat_sys_fsetxattr
+227  common    getxattr                sys_getxattr                    compat_sys_getxattr
+228  common    lgetxattr               sys_lgetxattr                   compat_sys_lgetxattr
+229  common    fgetxattr               sys_fgetxattr                   compat_sys_fgetxattr
+230  common    listxattr               sys_listxattr                   compat_sys_listxattr
+231  common    llistxattr              sys_llistxattr                  compat_sys_llistxattr
+232  common    flistxattr              sys_flistxattr                  compat_sys_flistxattr
+233  common    removexattr             sys_removexattr                 compat_sys_removexattr
+234  common    lremovexattr            sys_lremovexattr                compat_sys_lremovexattr
+235  common    fremovexattr            sys_fremovexattr                compat_sys_fremovexattr
+236  common    gettid                  sys_gettid                      sys_gettid
+237  common    tkill                   sys_tkill                       sys_tkill
+238  common    futex                   sys_futex                       compat_sys_futex
+239  common    sched_setaffinity       sys_sched_setaffinity           compat_sys_sched_setaffinity
+240  common    sched_getaffinity       sys_sched_getaffinity           compat_sys_sched_getaffinity
+241  common    tgkill                  sys_tgkill                      sys_tgkill
+243  common    io_setup                sys_io_setup                    compat_sys_io_setup
+244  common    io_destroy              sys_io_destroy                  compat_sys_io_destroy
+245  common    io_getevents            sys_io_getevents                compat_sys_io_getevents
+246  common    io_submit               sys_io_submit                   compat_sys_io_submit
+247  common    io_cancel               sys_io_cancel                   compat_sys_io_cancel
+248  common    exit_group              sys_exit_group                  sys_exit_group
+249  common    epoll_create            sys_epoll_create                sys_epoll_create
+250  common    epoll_ctl               sys_epoll_ctl                   compat_sys_epoll_ctl
+251  common    epoll_wait              sys_epoll_wait                  compat_sys_epoll_wait
+252  common    set_tid_address         sys_set_tid_address             compat_sys_set_tid_address
+253  common    fadvise64               sys_fadvise64_64                compat_sys_s390_fadvise64
+254  common    timer_create            sys_timer_create                compat_sys_timer_create
+255  common    timer_settime           sys_timer_settime               compat_sys_timer_settime
+256  common    timer_gettime           sys_timer_gettime               compat_sys_timer_gettime
+257  common    timer_getoverrun        sys_timer_getoverrun            sys_timer_getoverrun
+258  common    timer_delete            sys_timer_delete                sys_timer_delete
+259  common    clock_settime           sys_clock_settime               compat_sys_clock_settime
+260  common    clock_gettime           sys_clock_gettime               compat_sys_clock_gettime
+261  common    clock_getres            sys_clock_getres                compat_sys_clock_getres
+262  common    clock_nanosleep         sys_clock_nanosleep             compat_sys_clock_nanosleep
+264  32                fadvise64_64            -                               compat_sys_s390_fadvise64_64
+265  common    statfs64                sys_statfs64                    compat_sys_statfs64
+266  common    fstatfs64               sys_fstatfs64                   compat_sys_fstatfs64
+267  common    remap_file_pages        sys_remap_file_pages            compat_sys_remap_file_pages
+268  common    mbind                   sys_mbind                       compat_sys_mbind
+269  common    get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
+270  common    set_mempolicy           sys_set_mempolicy               compat_sys_set_mempolicy
+271  common    mq_open                 sys_mq_open                     compat_sys_mq_open
+272  common    mq_unlink               sys_mq_unlink                   compat_sys_mq_unlink
+273  common    mq_timedsend            sys_mq_timedsend                compat_sys_mq_timedsend
+274  common    mq_timedreceive         sys_mq_timedreceive             compat_sys_mq_timedreceive
+275  common    mq_notify               sys_mq_notify                   compat_sys_mq_notify
+276  common    mq_getsetattr           sys_mq_getsetattr               compat_sys_mq_getsetattr
+277  common    kexec_load              sys_kexec_load                  compat_sys_kexec_load
+278  common    add_key                 sys_add_key                     compat_sys_add_key
+279  common    request_key             sys_request_key                 compat_sys_request_key
+280  common    keyctl                  sys_keyctl                      compat_sys_keyctl
+281  common    waitid                  sys_waitid                      compat_sys_waitid
+282  common    ioprio_set              sys_ioprio_set                  sys_ioprio_set
+283  common    ioprio_get              sys_ioprio_get                  sys_ioprio_get
+284  common    inotify_init            sys_inotify_init                sys_inotify_init
+285  common    inotify_add_watch       sys_inotify_add_watch           compat_sys_inotify_add_watch
+286  common    inotify_rm_watch        sys_inotify_rm_watch            sys_inotify_rm_watch
+287  common    migrate_pages           sys_migrate_pages               compat_sys_migrate_pages
+288  common    openat                  sys_openat                      compat_sys_openat
+289  common    mkdirat                 sys_mkdirat                     compat_sys_mkdirat
+290  common    mknodat                 sys_mknodat                     compat_sys_mknodat
+291  common    fchownat                sys_fchownat                    compat_sys_fchownat
+292  common    futimesat               sys_futimesat                   compat_sys_futimesat
+293  32                fstatat64               -                               compat_sys_s390_fstatat64
+293  64                newfstatat              sys_newfstatat                  -
+294  common    unlinkat                sys_unlinkat                    compat_sys_unlinkat
+295  common    renameat                sys_renameat                    compat_sys_renameat
+296  common    linkat                  sys_linkat                      compat_sys_linkat
+297  common    symlinkat               sys_symlinkat                   compat_sys_symlinkat
+298  common    readlinkat              sys_readlinkat                  compat_sys_readlinkat
+299  common    fchmodat                sys_fchmodat                    compat_sys_fchmodat
+300  common    faccessat               sys_faccessat                   compat_sys_faccessat
+301  common    pselect6                sys_pselect6                    compat_sys_pselect6
+302  common    ppoll                   sys_ppoll                       compat_sys_ppoll
+303  common    unshare                 sys_unshare                     compat_sys_unshare
+304  common    set_robust_list         sys_set_robust_list             compat_sys_set_robust_list
+305  common    get_robust_list         sys_get_robust_list             compat_sys_get_robust_list
+306  common    splice                  sys_splice                      compat_sys_splice
+307  common    sync_file_range         sys_sync_file_range             compat_sys_s390_sync_file_range
+308  common    tee                     sys_tee                         compat_sys_tee
+309  common    vmsplice                sys_vmsplice                    compat_sys_vmsplice
+310  common    move_pages              sys_move_pages                  compat_sys_move_pages
+311  common    getcpu                  sys_getcpu                      compat_sys_getcpu
+312  common    epoll_pwait             sys_epoll_pwait                 compat_sys_epoll_pwait
+313  common    utimes                  sys_utimes                      compat_sys_utimes
+314  common    fallocate               sys_fallocate                   compat_sys_s390_fallocate
+315  common    utimensat               sys_utimensat                   compat_sys_utimensat
+316  common    signalfd                sys_signalfd                    compat_sys_signalfd
+317  common    timerfd                 -                               -
+318  common    eventfd                 sys_eventfd                     sys_eventfd
+319  common    timerfd_create          sys_timerfd_create              sys_timerfd_create
+320  common    timerfd_settime         sys_timerfd_settime             compat_sys_timerfd_settime
+321  common    timerfd_gettime         sys_timerfd_gettime             compat_sys_timerfd_gettime
+322  common    signalfd4               sys_signalfd4                   compat_sys_signalfd4
+323  common    eventfd2                sys_eventfd2                    sys_eventfd2
+324  common    inotify_init1           sys_inotify_init1               sys_inotify_init1
+325  common    pipe2                   sys_pipe2                       compat_sys_pipe2
+326  common    dup3                    sys_dup3                        sys_dup3
+327  common    epoll_create1           sys_epoll_create1               sys_epoll_create1
+328  common    preadv                  sys_preadv                      compat_sys_preadv
+329  common    pwritev                 sys_pwritev                     compat_sys_pwritev
+330  common    rt_tgsigqueueinfo       sys_rt_tgsigqueueinfo           compat_sys_rt_tgsigqueueinfo
+331  common    perf_event_open         sys_perf_event_open             compat_sys_perf_event_open
+332  common    fanotify_init           sys_fanotify_init               sys_fanotify_init
+333  common    fanotify_mark           sys_fanotify_mark               compat_sys_fanotify_mark
+334  common    prlimit64               sys_prlimit64                   compat_sys_prlimit64
+335  common    name_to_handle_at       sys_name_to_handle_at           compat_sys_name_to_handle_at
+336  common    open_by_handle_at       sys_open_by_handle_at           compat_sys_open_by_handle_at
+337  common    clock_adjtime           sys_clock_adjtime               compat_sys_clock_adjtime
+338  common    syncfs                  sys_syncfs                      sys_syncfs
+339  common    setns                   sys_setns                       sys_setns
+340  common    process_vm_readv        sys_process_vm_readv            compat_sys_process_vm_readv
+341  common    process_vm_writev       sys_process_vm_writev           compat_sys_process_vm_writev
+342  common    s390_runtime_instr      sys_s390_runtime_instr          sys_s390_runtime_instr
+343  common    kcmp                    sys_kcmp                        compat_sys_kcmp
+344  common    finit_module            sys_finit_module                compat_sys_finit_module
+345  common    sched_setattr           sys_sched_setattr               compat_sys_sched_setattr
+346  common    sched_getattr           sys_sched_getattr               compat_sys_sched_getattr
+347  common    renameat2               sys_renameat2                   compat_sys_renameat2
+348  common    seccomp                 sys_seccomp                     compat_sys_seccomp
+349  common    getrandom               sys_getrandom                   compat_sys_getrandom
+350  common    memfd_create            sys_memfd_create                compat_sys_memfd_create
+351  common    bpf                     sys_bpf                         compat_sys_bpf
+352  common    s390_pci_mmio_write     sys_s390_pci_mmio_write         compat_sys_s390_pci_mmio_write
+353  common    s390_pci_mmio_read      sys_s390_pci_mmio_read          compat_sys_s390_pci_mmio_read
+354  common    execveat                sys_execveat                    compat_sys_execveat
+355  common    userfaultfd             sys_userfaultfd                 sys_userfaultfd
+356  common    membarrier              sys_membarrier                  sys_membarrier
+357  common    recvmmsg                sys_recvmmsg                    compat_sys_recvmmsg
+358  common    sendmmsg                sys_sendmmsg                    compat_sys_sendmmsg
+359  common    socket                  sys_socket                      sys_socket
+360  common    socketpair              sys_socketpair                  compat_sys_socketpair
+361  common    bind                    sys_bind                        compat_sys_bind
+362  common    connect                 sys_connect                     compat_sys_connect
+363  common    listen                  sys_listen                      sys_listen
+364  common    accept4                 sys_accept4                     compat_sys_accept4
+365  common    getsockopt              sys_getsockopt                  compat_sys_getsockopt
+366  common    setsockopt              sys_setsockopt                  compat_sys_setsockopt
+367  common    getsockname             sys_getsockname                 compat_sys_getsockname
+368  common    getpeername             sys_getpeername                 compat_sys_getpeername
+369  common    sendto                  sys_sendto                      compat_sys_sendto
+370  common    sendmsg                 sys_sendmsg                     compat_sys_sendmsg
+371  common    recvfrom                sys_recvfrom                    compat_sys_recvfrom
+372  common    recvmsg                 sys_recvmsg                     compat_sys_recvmsg
+373  common    shutdown                sys_shutdown                    sys_shutdown
+374  common    mlock2                  sys_mlock2                      compat_sys_mlock2
+375  common    copy_file_range         sys_copy_file_range             compat_sys_copy_file_range
+376  common    preadv2                 sys_preadv2                     compat_sys_preadv2
+377  common    pwritev2                sys_pwritev2                    compat_sys_pwritev2
+378  common    s390_guarded_storage    sys_s390_guarded_storage        compat_sys_s390_guarded_storage
+379  common    statx                   sys_statx                       compat_sys_statx
+380  common    s390_sthyi              sys_s390_sthyi                  compat_sys_s390_sthyi
index c0815a37fdb5a357615be3da2df2fffe62b25222..539c3d4601586ab925549e433ee0e5f0c954ae43 100644 (file)
@@ -2245,7 +2245,7 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
        c2c_browser__update_nr_entries(browser);
 
        while (1) {
-               key = hist_browser__run(browser, "? - help");
+               key = hist_browser__run(browser, "? - help", true);
 
                switch (key) {
                case 's':
@@ -2314,7 +2314,7 @@ static int perf_c2c__hists_browse(struct hists *hists)
        c2c_browser__update_nr_entries(browser);
 
        while (1) {
-               key = hist_browser__run(browser, "? - help");
+               key = hist_browser__run(browser, "? - help", true);
 
                switch (key) {
                case 'q':
index bf4ca749d1ac42db783446d4e36e7420dd461b95..a217623fec2ea626494dc046d35a0bda02f20f04 100644 (file)
@@ -881,6 +881,15 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                }
        }
 
+       /*
+        * If we have just single event and are sending data
+        * through pipe, we need to force the ids allocation,
+        * because we synthesize event name through the pipe
+        * and need the id for that.
+        */
+       if (data->is_pipe && rec->evlist->nr_entries == 1)
+               rec->opts.sample_id = true;
+
        if (record__open(rec) != 0) {
                err = -1;
                goto out_child;
index 42a52dcc41cd4f31e60910eed0adc0e0eda313a0..4ad5dc649716eb7a0a865a1e0af07175d87928c8 100644 (file)
@@ -530,7 +530,8 @@ static int report__browse_hists(struct report *rep)
        case 1:
                ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
                                                    rep->min_percent,
-                                                   &session->header.env);
+                                                   &session->header.env,
+                                                   true);
                /*
                 * Usually "ret" is the last pressed key, and we only
                 * care if the key notifies us to switch data file.
index 98bf9d32f2222247bf2b39d98dab62d9cafe1770..54a4c152edb3917405dd064a1f79037acbb0d239 100644 (file)
@@ -917,7 +917,7 @@ static void print_metric_csv(void *ctx,
        char buf[64], *vals, *ends;
 
        if (unit == NULL || fmt == NULL) {
-               fprintf(out, "%s%s%s%s", csv_sep, csv_sep, csv_sep, csv_sep);
+               fprintf(out, "%s%s", csv_sep, csv_sep);
                return;
        }
        snprintf(buf, sizeof(buf), fmt, val);
index c6ccda52117d3076e9d46bc1101f090a48d32e65..35ac016fcb988997437230103987aaa59415e70a 100644 (file)
@@ -283,8 +283,9 @@ static void perf_top__print_sym_table(struct perf_top *top)
 
        printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
 
-       if (hists->stats.nr_lost_warned !=
-           hists->stats.nr_events[PERF_RECORD_LOST]) {
+       if (!top->record_opts.overwrite &&
+           (hists->stats.nr_lost_warned !=
+           hists->stats.nr_events[PERF_RECORD_LOST])) {
                hists->stats.nr_lost_warned =
                              hists->stats.nr_events[PERF_RECORD_LOST];
                color_fprintf(stdout, PERF_COLOR_RED,
@@ -611,7 +612,8 @@ static void *display_thread_tui(void *arg)
 
        perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
                                      top->min_percent,
-                                     &top->session->header.env);
+                                     &top->session->header.env,
+                                     !top->record_opts.overwrite);
 
        done = 1;
        return NULL;
@@ -807,15 +809,23 @@ static void perf_event__process_sample(struct perf_tool *tool,
 
 static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
 {
+       struct record_opts *opts = &top->record_opts;
+       struct perf_evlist *evlist = top->evlist;
        struct perf_sample sample;
        struct perf_evsel *evsel;
+       struct perf_mmap *md;
        struct perf_session *session = top->session;
        union perf_event *event;
        struct machine *machine;
+       u64 end, start;
        int ret;
 
-       while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
-               ret = perf_evlist__parse_sample(top->evlist, event, &sample);
+       md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx];
+       if (perf_mmap__read_init(md, opts->overwrite, &start, &end) < 0)
+               return;
+
+       while ((event = perf_mmap__read_event(md, opts->overwrite, &start, end)) != NULL) {
+               ret = perf_evlist__parse_sample(evlist, event, &sample);
                if (ret) {
                        pr_err("Can't parse sample, err = %d\n", ret);
                        goto next_event;
@@ -869,16 +879,120 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
                } else
                        ++session->evlist->stats.nr_unknown_events;
 next_event:
-               perf_evlist__mmap_consume(top->evlist, idx);
+               perf_mmap__consume(md, opts->overwrite);
        }
+
+       perf_mmap__read_done(md);
 }
 
 static void perf_top__mmap_read(struct perf_top *top)
 {
+       bool overwrite = top->record_opts.overwrite;
+       struct perf_evlist *evlist = top->evlist;
+       unsigned long long start, end;
        int i;
 
+       start = rdclock();
+       if (overwrite)
+               perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING);
+
        for (i = 0; i < top->evlist->nr_mmaps; i++)
                perf_top__mmap_read_idx(top, i);
+
+       if (overwrite) {
+               perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_EMPTY);
+               perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING);
+       }
+       end = rdclock();
+
+       if ((end - start) > (unsigned long long)top->delay_secs * NSEC_PER_SEC)
+               ui__warning("Too slow to read ring buffer.\n"
+                           "Please try increasing the period (-c) or\n"
+                           "decreasing the freq (-F) or\n"
+                           "limiting the number of CPUs (-C)\n");
+}
+
+/*
+ * Check per-event overwrite term.
+ * perf top should support consistent term for all events.
+ * - All events don't have per-event term
+ *   E.g. "cpu/cpu-cycles/,cpu/instructions/"
+ *   Nothing change, return 0.
+ * - All events have same per-event term
+ *   E.g. "cpu/cpu-cycles,no-overwrite/,cpu/instructions,no-overwrite/
+ *   Using the per-event setting to replace the opts->overwrite if
+ *   they are different, then return 0.
+ * - Events have different per-event term
+ *   E.g. "cpu/cpu-cycles,overwrite/,cpu/instructions,no-overwrite/"
+ *   Return -1
+ * - Some of the event set per-event term, but some not.
+ *   E.g. "cpu/cpu-cycles/,cpu/instructions,no-overwrite/"
+ *   Return -1
+ */
+static int perf_top__overwrite_check(struct perf_top *top)
+{
+       struct record_opts *opts = &top->record_opts;
+       struct perf_evlist *evlist = top->evlist;
+       struct perf_evsel_config_term *term;
+       struct list_head *config_terms;
+       struct perf_evsel *evsel;
+       int set, overwrite = -1;
+
+       evlist__for_each_entry(evlist, evsel) {
+               set = -1;
+               config_terms = &evsel->config_terms;
+               list_for_each_entry(term, config_terms, list) {
+                       if (term->type == PERF_EVSEL__CONFIG_TERM_OVERWRITE)
+                               set = term->val.overwrite ? 1 : 0;
+               }
+
+               /* no term for current and previous event (likely) */
+               if ((overwrite < 0) && (set < 0))
+                       continue;
+
+               /* has term for both current and previous event, compare */
+               if ((overwrite >= 0) && (set >= 0) && (overwrite != set))
+                       return -1;
+
+               /* no term for current event but has term for previous one */
+               if ((overwrite >= 0) && (set < 0))
+                       return -1;
+
+               /* has term for current event */
+               if ((overwrite < 0) && (set >= 0)) {
+                       /* if it's first event, set overwrite */
+                       if (evsel == perf_evlist__first(evlist))
+                               overwrite = set;
+                       else
+                               return -1;
+               }
+       }
+
+       if ((overwrite >= 0) && (opts->overwrite != overwrite))
+               opts->overwrite = overwrite;
+
+       return 0;
+}
+
+static int perf_top_overwrite_fallback(struct perf_top *top,
+                                      struct perf_evsel *evsel)
+{
+       struct record_opts *opts = &top->record_opts;
+       struct perf_evlist *evlist = top->evlist;
+       struct perf_evsel *counter;
+
+       if (!opts->overwrite)
+               return 0;
+
+       /* only fall back when first event fails */
+       if (evsel != perf_evlist__first(evlist))
+               return 0;
+
+       evlist__for_each_entry(evlist, counter)
+               counter->attr.write_backward = false;
+       opts->overwrite = false;
+       pr_debug2("fall back to non-overwrite mode\n");
+       return 1;
 }
 
 static int perf_top__start_counters(struct perf_top *top)
@@ -888,12 +1002,33 @@ static int perf_top__start_counters(struct perf_top *top)
        struct perf_evlist *evlist = top->evlist;
        struct record_opts *opts = &top->record_opts;
 
+       if (perf_top__overwrite_check(top)) {
+               ui__error("perf top only support consistent per-event "
+                         "overwrite setting for all events\n");
+               goto out_err;
+       }
+
        perf_evlist__config(evlist, opts, &callchain_param);
 
        evlist__for_each_entry(evlist, counter) {
 try_again:
                if (perf_evsel__open(counter, top->evlist->cpus,
                                     top->evlist->threads) < 0) {
+
+                       /*
+                        * Specially handle overwrite fall back.
+                        * Because perf top is the only tool which has
+                        * overwrite mode by default, support
+                        * both overwrite and non-overwrite mode, and
+                        * require consistent mode for all events.
+                        *
+                        * May move it to generic code with more tools
+                        * have similar attribute.
+                        */
+                       if (perf_missing_features.write_backward &&
+                           perf_top_overwrite_fallback(top, counter))
+                               goto try_again;
+
                        if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
                                if (verbose > 0)
                                        ui__warning("%s\n", msg);
@@ -1033,7 +1168,7 @@ static int __cmd_top(struct perf_top *top)
 
                perf_top__mmap_read(top);
 
-               if (hits == top->samples)
+               if (opts->overwrite || (hits == top->samples))
                        ret = perf_evlist__poll(top->evlist, 100);
 
                if (resize) {
@@ -1127,6 +1262,7 @@ int cmd_top(int argc, const char **argv)
                                .uses_mmap   = true,
                        },
                        .proc_map_timeout    = 500,
+                       .overwrite      = 1,
                },
                .max_stack           = sysctl_perf_event_max_stack,
                .sym_pcnt_filter     = 5,
index 51abdb0a404749922ba57a7337b140f984be4126..790ec25919a0eb73fe4642ed8ad349aef4d32890 100755 (executable)
@@ -33,7 +33,6 @@ arch/s390/include/uapi/asm/kvm.h
 arch/s390/include/uapi/asm/kvm_perf.h
 arch/s390/include/uapi/asm/ptrace.h
 arch/s390/include/uapi/asm/sie.h
-arch/s390/include/uapi/asm/unistd.h
 arch/arm/include/uapi/asm/kvm.h
 arch/arm64/include/uapi/asm/kvm.h
 arch/alpha/include/uapi/asm/errno.h
index cfe46236a5e5b7d641523e3eb25a3d0acc11eaa4..57b9b342d533592ca698544172098c551c223f4b 100644 (file)
@@ -61,6 +61,7 @@ struct record_opts {
        bool         tail_synthesize;
        bool         overwrite;
        bool         ignore_missing_thread;
+       bool         sample_id;
        unsigned int freq;
        unsigned int mmap_pages;
        unsigned int auxtrace_mmap_pages;
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/branch.json
new file mode 100644 (file)
index 0000000..3b62087
--- /dev/null
@@ -0,0 +1,27 @@
+[
+  {,
+    "EventCode": "0x7A",
+    "EventName": "BR_INDIRECT_SPEC",
+    "BriefDescription": "Branch speculatively executed - Indirect branch"
+  },
+  {,
+    "EventCode": "0xC9",
+    "EventName": "BR_COND",
+    "BriefDescription": "Conditional branch executed"
+  },
+  {,
+    "EventCode": "0xCA",
+    "EventName": "BR_INDIRECT_MISPRED",
+    "BriefDescription": "Indirect branch mispredicted"
+  },
+  {,
+    "EventCode": "0xCB",
+    "EventName": "BR_INDIRECT_MISPRED_ADDR",
+    "BriefDescription": "Indirect branch mispredicted because of address miscompare"
+  },
+  {,
+    "EventCode": "0xCC",
+    "EventName": "BR_COND_MISPRED",
+    "BriefDescription": "Conditional branch mispredicted"
+  }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/bus.json
new file mode 100644 (file)
index 0000000..480d9f7
--- /dev/null
@@ -0,0 +1,22 @@
+[
+  {,
+    "EventCode": "0x60",
+    "EventName": "BUS_ACCESS_LD",
+    "BriefDescription": "Bus access - Read"
+  },
+  {,
+    "EventCode": "0x61",
+    "EventName": "BUS_ACCESS_ST",
+    "BriefDescription": "Bus access - Write"
+  },
+  {,
+    "EventCode": "0xC0",
+    "EventName": "EXT_MEM_REQ",
+    "BriefDescription": "External memory request"
+  },
+  {,
+    "EventCode": "0xC1",
+    "EventName": "EXT_MEM_REQ_NC",
+    "BriefDescription": "Non-cacheable external memory request"
+  }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/cache.json
new file mode 100644 (file)
index 0000000..11baad6
--- /dev/null
@@ -0,0 +1,27 @@
+[
+  {,
+    "EventCode": "0xC2",
+    "EventName": "PREFETCH_LINEFILL",
+    "BriefDescription": "Linefill because of prefetch"
+  },
+  {,
+    "EventCode": "0xC3",
+    "EventName": "PREFETCH_LINEFILL_DROP",
+    "BriefDescription": "Instruction Cache Throttle occurred"
+  },
+  {,
+    "EventCode": "0xC4",
+    "EventName": "READ_ALLOC_ENTER",
+    "BriefDescription": "Entering read allocate mode"
+  },
+  {,
+    "EventCode": "0xC5",
+    "EventName": "READ_ALLOC",
+    "BriefDescription": "Read allocate mode"
+  },
+  {,
+    "EventCode": "0xC8",
+    "EventName": "EXT_SNOOP",
+    "BriefDescription": "SCU Snooped data from another CPU for this CPU"
+  }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/memory.json
new file mode 100644 (file)
index 0000000..480d9f7
--- /dev/null
@@ -0,0 +1,22 @@
+[
+  {,
+    "EventCode": "0x60",
+    "EventName": "BUS_ACCESS_LD",
+    "BriefDescription": "Bus access - Read"
+  },
+  {,
+    "EventCode": "0x61",
+    "EventName": "BUS_ACCESS_ST",
+    "BriefDescription": "Bus access - Write"
+  },
+  {,
+    "EventCode": "0xC0",
+    "EventName": "EXT_MEM_REQ",
+    "BriefDescription": "External memory request"
+  },
+  {,
+    "EventCode": "0xC1",
+    "EventName": "EXT_MEM_REQ_NC",
+    "BriefDescription": "Non-cacheable external memory request"
+  }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/other.json
new file mode 100644 (file)
index 0000000..73a2240
--- /dev/null
@@ -0,0 +1,32 @@
+[
+  {,
+    "EventCode": "0x86",
+    "EventName": "EXC_IRQ",
+    "BriefDescription": "Exception taken, IRQ"
+  },
+  {,
+    "EventCode": "0x87",
+    "EventName": "EXC_FIQ",
+    "BriefDescription": "Exception taken, FIQ"
+  },
+  {,
+    "EventCode": "0xC6",
+    "EventName": "PRE_DECODE_ERR",
+    "BriefDescription": "Pre-decode error"
+  },
+  {,
+    "EventCode": "0xD0",
+    "EventName": "L1I_CACHE_ERR",
+    "BriefDescription": "L1 Instruction Cache (data or tag) memory error"
+  },
+  {,
+    "EventCode": "0xD1",
+    "EventName": "L1D_CACHE_ERR",
+    "BriefDescription": "L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable"
+  },
+  {,
+    "EventCode": "0xD2",
+    "EventName": "TLB_ERR",
+    "BriefDescription": "TLB memory error"
+  }
+]
diff --git a/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json b/tools/perf/pmu-events/arch/arm64/cortex-a53/pipeline.json
new file mode 100644 (file)
index 0000000..3149fb9
--- /dev/null
@@ -0,0 +1,52 @@
+[
+  {,
+    "EventCode": "0xC7",
+    "EventName": "STALL_SB_FULL",
+    "BriefDescription": "Data Write operation that stalls the pipeline because the store buffer is full"
+  },
+  {,
+    "EventCode": "0xE0",
+    "EventName": "OTHER_IQ_DEP_STALL",
+    "BriefDescription": "Cycles that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error"
+  },
+  {,
+    "EventCode": "0xE1",
+    "EventName": "IC_DEP_STALL",
+    "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction cache miss being processed"
+  },
+  {,
+    "EventCode": "0xE2",
+    "EventName": "IUTLB_DEP_STALL",
+    "BriefDescription": "Cycles the DPU IQ is empty and there is an instruction micro-TLB miss being processed"
+  },
+  {,
+    "EventCode": "0xE3",
+    "EventName": "DECODE_DEP_STALL",
+    "BriefDescription": "Cycles the DPU IQ is empty and there is a pre-decode error being processed"
+  },
+  {,
+    "EventCode": "0xE4",
+    "EventName": "OTHER_INTERLOCK_STALL",
+    "BriefDescription": "Cycles there is an interlock other than  Advanced SIMD/Floating-point instructions or load/store instruction"
+  },
+  {,
+    "EventCode": "0xE5",
+    "EventName": "AGU_DEP_STALL",
+    "BriefDescription": "Cycles there is an interlock for a load/store instruction waiting for data to calculate the address in the AGU"
+  },
+  {,
+    "EventCode": "0xE6",
+    "EventName": "SIMD_DEP_STALL",
+    "BriefDescription": "Cycles there is an interlock for an Advanced SIMD/Floating-point operation."
+  },
+  {,
+    "EventCode": "0xE7",
+    "EventName": "LD_DEP_STALL",
+    "BriefDescription": "Cycles there is a stall in the Wr stage because of a load miss"
+  },
+  {,
+    "EventCode": "0xE8",
+    "EventName": "ST_DEP_STALL",
+    "BriefDescription": "Cycles there is a stall in the Wr stage because of a store"
+  }
+]
index 219d6756134ee068797786a5caa4463f1506d2c5..e61c9ca6cf9e67fe52605b3b277d1b5fb1157782 100644 (file)
@@ -13,3 +13,4 @@
 #
 #Family-model,Version,Filename,EventType
 0x00000000420f5160,v1,cavium,core
+0x00000000410fd03[[:xdigit:]],v1,cortex-a53,core
index 4035d43523c3ed952ba53201e7666bc87f19ebd7..e0b1b414d466b4601fb9033717b9bed5f0bd9c3e 100644 (file)
@@ -31,10 +31,12 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count,
        int i;
 
        for (i = 0; i < evlist->nr_mmaps; i++) {
+               struct perf_mmap *map = &evlist->overwrite_mmap[i];
                union perf_event *event;
+               u64 start, end;
 
-               perf_mmap__read_catchup(&evlist->overwrite_mmap[i]);
-               while ((event = perf_mmap__read_backward(&evlist->overwrite_mmap[i])) != NULL) {
+               perf_mmap__read_init(map, true, &start, &end);
+               while ((event = perf_mmap__read_event(map, true, &start, end)) != NULL) {
                        const u32 type = event->header.type;
 
                        switch (type) {
@@ -49,6 +51,7 @@ static int count_samples(struct perf_evlist *evlist, int *sample_count,
                                return TEST_FAIL;
                        }
                }
+               perf_mmap__read_done(map);
        }
        return TEST_OK;
 }
index 8b3da21a08f19a110a3e9c2519495460da2eb310..c446c894b2973ab7e89d8d910e574f2206cc3ace 100755 (executable)
@@ -22,10 +22,23 @@ trace_libc_inet_pton_backtrace() {
        expected[4]="rtt min.*"
        expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)"
        expected[6]=".*inet_pton[[:space:]]\($libc\)$"
-       expected[7]="getaddrinfo[[:space:]]\($libc\)$"
-       expected[8]=".*\(.*/bin/ping.*\)$"
-
-       perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do
+       case "$(uname -m)" in
+       s390x)
+               eventattr='call-graph=dwarf'
+               expected[7]="gaih_inet[[:space:]]\(inlined\)$"
+               expected[8]="__GI_getaddrinfo[[:space:]]\(inlined\)$"
+               expected[9]="main[[:space:]]\(.*/bin/ping.*\)$"
+               expected[10]="__libc_start_main[[:space:]]\($libc\)$"
+               expected[11]="_start[[:space:]]\(.*/bin/ping.*\)$"
+               ;;
+       *)
+               eventattr='max-stack=3'
+               expected[7]="getaddrinfo[[:space:]]\($libc\)$"
+               expected[8]=".*\(.*/bin/ping.*\)$"
+               ;;
+       esac
+
+       perf trace --no-syscalls -e probe_libc:inet_pton/$eventattr/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do
                echo $line
                echo "$line" | egrep -q "${expected[$idx]}"
                if [ $? -ne 0 ] ; then
@@ -33,7 +46,7 @@ trace_libc_inet_pton_backtrace() {
                        exit 1
                fi
                let idx+=1
-               [ $idx -eq 9 ] && break
+               [ -z "${expected[$idx]}" ] && break
        done
 }
 
index 2864279751122aa8efc518778759cc04589e12ba..fbf927cf775dce38511d864d81780191d2745444 100644 (file)
@@ -327,7 +327,32 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
        if (!disasm_line__is_valid_jump(cursor, sym))
                return;
 
+       /*
+        * This first was seen with a gcc function, _cpp_lex_token, that
+        * has the usual jumps:
+        *
+        *  â”‚1159e6c: â†“ jne    115aa32 <_cpp_lex_token@@Base+0xf92>
+        *
+        * I.e. jumps to a label inside that function (_cpp_lex_token), and
+        * those works, but also this kind:
+        *
+        *  â”‚1159e8b: â†“ jne    c469be <cpp_named_operator2name@@Base+0xa72>
+        *
+        *  I.e. jumps to another function, outside _cpp_lex_token, which
+        *  are not being correctly handled generating as a side effect references
+        *  to ab->offset[] entries that are set to NULL, so to make this code
+        *  more robust, check that here.
+        *
+        *  A proper fix for will be put in place, looking at the function
+        *  name right after the '<' token and probably treating this like a
+        *  'call' instruction.
+        */
        target = ab->offsets[cursor->ops.target.offset];
+       if (target == NULL) {
+               ui_helpline__printf("WARN: jump target inconsistency, press 'o', ab->offsets[%#x] = NULL\n",
+                                   cursor->ops.target.offset);
+               return;
+       }
 
        bcursor = browser_line(&cursor->al);
        btarget = browser_line(target);
index 68146f4620a5730028c24c364001ce5e21766aad..6495ee55d9c38feb75e207549e5634e36fd2c378 100644 (file)
@@ -608,7 +608,8 @@ static int hist_browser__title(struct hist_browser *browser, char *bf, size_t si
        return browser->title ? browser->title(browser, bf, size) : 0;
 }
 
-int hist_browser__run(struct hist_browser *browser, const char *help)
+int hist_browser__run(struct hist_browser *browser, const char *help,
+                     bool warn_lost_event)
 {
        int key;
        char title[160];
@@ -638,8 +639,9 @@ int hist_browser__run(struct hist_browser *browser, const char *help)
                        nr_entries = hist_browser__nr_entries(browser);
                        ui_browser__update_nr_entries(&browser->b, nr_entries);
 
-                       if (browser->hists->stats.nr_lost_warned !=
-                           browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
+                       if (warn_lost_event &&
+                           (browser->hists->stats.nr_lost_warned !=
+                           browser->hists->stats.nr_events[PERF_RECORD_LOST])) {
                                browser->hists->stats.nr_lost_warned =
                                        browser->hists->stats.nr_events[PERF_RECORD_LOST];
                                ui_browser__warn_lost_events(&browser->b);
@@ -2763,7 +2765,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
                                    bool left_exits,
                                    struct hist_browser_timer *hbt,
                                    float min_pcnt,
-                                   struct perf_env *env)
+                                   struct perf_env *env,
+                                   bool warn_lost_event)
 {
        struct hists *hists = evsel__hists(evsel);
        struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env);
@@ -2844,7 +2847,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 
                nr_options = 0;
 
-               key = hist_browser__run(browser, helpline);
+               key = hist_browser__run(browser, helpline,
+                                       warn_lost_event);
 
                if (browser->he_selection != NULL) {
                        thread = hist_browser__selected_thread(browser);
@@ -3184,7 +3188,8 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
 
 static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
                                int nr_events, const char *help,
-                               struct hist_browser_timer *hbt)
+                               struct hist_browser_timer *hbt,
+                               bool warn_lost_event)
 {
        struct perf_evlist *evlist = menu->b.priv;
        struct perf_evsel *pos;
@@ -3203,7 +3208,9 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
                case K_TIMER:
                        hbt->timer(hbt->arg);
 
-                       if (!menu->lost_events_warned && menu->lost_events) {
+                       if (!menu->lost_events_warned &&
+                           menu->lost_events &&
+                           warn_lost_event) {
                                ui_browser__warn_lost_events(&menu->b);
                                menu->lost_events_warned = true;
                        }
@@ -3224,7 +3231,8 @@ browse_hists:
                        key = perf_evsel__hists_browse(pos, nr_events, help,
                                                       true, hbt,
                                                       menu->min_pcnt,
-                                                      menu->env);
+                                                      menu->env,
+                                                      warn_lost_event);
                        ui_browser__show_title(&menu->b, title);
                        switch (key) {
                        case K_TAB:
@@ -3282,7 +3290,8 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
                                           int nr_entries, const char *help,
                                           struct hist_browser_timer *hbt,
                                           float min_pcnt,
-                                          struct perf_env *env)
+                                          struct perf_env *env,
+                                          bool warn_lost_event)
 {
        struct perf_evsel *pos;
        struct perf_evsel_menu menu = {
@@ -3309,13 +3318,15 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
                        menu.b.width = line_len;
        }
 
-       return perf_evsel_menu__run(&menu, nr_entries, help, hbt);
+       return perf_evsel_menu__run(&menu, nr_entries, help,
+                                   hbt, warn_lost_event);
 }
 
 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
                                  struct hist_browser_timer *hbt,
                                  float min_pcnt,
-                                 struct perf_env *env)
+                                 struct perf_env *env,
+                                 bool warn_lost_event)
 {
        int nr_entries = evlist->nr_entries;
 
@@ -3325,7 +3336,7 @@ single_entry:
 
                return perf_evsel__hists_browse(first, nr_entries, help,
                                                false, hbt, min_pcnt,
-                                               env);
+                                               env, warn_lost_event);
        }
 
        if (symbol_conf.event_group) {
@@ -3342,5 +3353,6 @@ single_entry:
        }
 
        return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
-                                              hbt, min_pcnt, env);
+                                              hbt, min_pcnt, env,
+                                              warn_lost_event);
 }
index ba431777f5590838aded811a70ad1d50ac492198..9428bee076f24cecc65581c85544f5e4ba68bd26 100644 (file)
@@ -28,7 +28,8 @@ struct hist_browser {
 
 struct hist_browser *hist_browser__new(struct hists *hists);
 void hist_browser__delete(struct hist_browser *browser);
-int hist_browser__run(struct hist_browser *browser, const char *help);
+int hist_browser__run(struct hist_browser *browser, const char *help,
+                     bool warn_lost_event);
 void hist_browser__init(struct hist_browser *browser,
                        struct hists *hists);
 #endif /* _PERF_UI_BROWSER_HISTS_H_ */
index 9faf3b5367db03babf42cba25d808bb6e7a5d0b4..6470ea2aa25eea686b4f37050140a66e4fabda1b 100644 (file)
 #include "sane_ctype.h"
 #include "symbol/kallsyms.h"
 
+static bool auxtrace__dont_decode(struct perf_session *session)
+{
+       return !session->itrace_synth_opts ||
+              session->itrace_synth_opts->dont_decode;
+}
+
 int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
                        struct auxtrace_mmap_params *mp,
                        void *userpg, int fd)
@@ -762,6 +768,9 @@ int auxtrace_queues__process_index(struct auxtrace_queues *queues,
        size_t i;
        int err;
 
+       if (auxtrace__dont_decode(session))
+               return 0;
+
        list_for_each_entry(auxtrace_index, &session->auxtrace_index, list) {
                for (i = 0; i < auxtrace_index->nr; i++) {
                        ent = &auxtrace_index->entries[i];
@@ -892,12 +901,6 @@ out_free:
        return err;
 }
 
-static bool auxtrace__dont_decode(struct perf_session *session)
-{
-       return !session->itrace_synth_opts ||
-              session->itrace_synth_opts->dont_decode;
-}
-
 int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
                                      union perf_event *event,
                                      struct perf_session *session)
index ac35cd214feb224cfc61ed743c257dffaad19699..e5fc14e53c0510cff4676b6620d507fbd563b9ac 100644 (file)
@@ -715,28 +715,11 @@ union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist, int
        return perf_mmap__read_forward(md);
 }
 
-union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist, int idx)
-{
-       struct perf_mmap *md = &evlist->mmap[idx];
-
-       /*
-        * No need to check messup for backward ring buffer:
-        * We can always read arbitrary long data from a backward
-        * ring buffer unless we forget to pause it before reading.
-        */
-       return perf_mmap__read_backward(md);
-}
-
 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
 {
        return perf_evlist__mmap_read_forward(evlist, idx);
 }
 
-void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx)
-{
-       perf_mmap__read_catchup(&evlist->mmap[idx]);
-}
-
 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
 {
        perf_mmap__consume(&evlist->mmap[idx], false);
index 75f8e0ad5d765f3412c5b34734bb019189056b54..336b838e6957e503da3f73276d828067c8484386 100644 (file)
@@ -133,10 +133,6 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx);
 
 union perf_event *perf_evlist__mmap_read_forward(struct perf_evlist *evlist,
                                                 int idx);
-union perf_event *perf_evlist__mmap_read_backward(struct perf_evlist *evlist,
-                                                 int idx);
-void perf_evlist__mmap_read_catchup(struct perf_evlist *evlist, int idx);
-
 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
 
 int perf_evlist__open(struct perf_evlist *evlist);
index ff359c9ece2e76c3d15fb8d2acf36e4c3bf8ade6..ef351688b79798a1c46b95094fb078c6daee14aa 100644 (file)
 
 #include "sane_ctype.h"
 
-static struct {
-       bool sample_id_all;
-       bool exclude_guest;
-       bool mmap2;
-       bool cloexec;
-       bool clockid;
-       bool clockid_wrong;
-       bool lbr_flags;
-       bool write_backward;
-       bool group_read;
-} perf_missing_features;
+struct perf_missing_features perf_missing_features;
 
 static clockid_t clockid;
 
index 846e416445254f6090a1280305106a6c581b715a..a7487c6d186607e9ca9fc4858c36c29f82015e1d 100644 (file)
@@ -149,6 +149,20 @@ union u64_swap {
        u32 val32[2];
 };
 
+struct perf_missing_features {
+       bool sample_id_all;
+       bool exclude_guest;
+       bool mmap2;
+       bool cloexec;
+       bool clockid;
+       bool clockid_wrong;
+       bool lbr_flags;
+       bool write_backward;
+       bool group_read;
+};
+
+extern struct perf_missing_features perf_missing_features;
+
 struct cpu_map;
 struct target;
 struct thread_map;
index f6630cb95effc353deba329a77dc6a87e0f6279f..02721b5797464605519967969e0ec78f0038123c 100644 (file)
@@ -430,7 +430,8 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
 int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
                                  struct hist_browser_timer *hbt,
                                  float min_pcnt,
-                                 struct perf_env *env);
+                                 struct perf_env *env,
+                                 bool warn_lost_event);
 int script_browse(const char *script_opt);
 #else
 static inline
@@ -438,7 +439,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
                                  const char *help __maybe_unused,
                                  struct hist_browser_timer *hbt __maybe_unused,
                                  float min_pcnt __maybe_unused,
-                                 struct perf_env *env __maybe_unused)
+                                 struct perf_env *env __maybe_unused,
+                                 bool warn_lost_event __maybe_unused)
 {
        return 0;
 }
index 05076e6839382e4d098562f3c42e317d038e971a..91531a7c8fbf38606ee52ca0c3fef57bb2a9cff9 100644 (file)
@@ -22,29 +22,27 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map)
 
 /* When check_messup is true, 'end' must points to a good entry */
 static union perf_event *perf_mmap__read(struct perf_mmap *map,
-                                        u64 start, u64 end, u64 *prev)
+                                        u64 *startp, u64 end)
 {
        unsigned char *data = map->base + page_size;
        union perf_event *event = NULL;
-       int diff = end - start;
+       int diff = end - *startp;
 
        if (diff >= (int)sizeof(event->header)) {
                size_t size;
 
-               event = (union perf_event *)&data[start & map->mask];
+               event = (union perf_event *)&data[*startp & map->mask];
                size = event->header.size;
 
-               if (size < sizeof(event->header) || diff < (int)size) {
-                       event = NULL;
-                       goto broken_event;
-               }
+               if (size < sizeof(event->header) || diff < (int)size)
+                       return NULL;
 
                /*
                 * Event straddles the mmap boundary -- header should always
                 * be inside due to u64 alignment of output.
                 */
-               if ((start & map->mask) + size != ((start + size) & map->mask)) {
-                       unsigned int offset = start;
+               if ((*startp & map->mask) + size != ((*startp + size) & map->mask)) {
+                       unsigned int offset = *startp;
                        unsigned int len = min(sizeof(*event), size), cpy;
                        void *dst = map->event_copy;
 
@@ -59,20 +57,19 @@ static union perf_event *perf_mmap__read(struct perf_mmap *map,
                        event = (union perf_event *)map->event_copy;
                }
 
-               start += size;
+               *startp += size;
        }
 
-broken_event:
-       if (prev)
-               *prev = start;
-
        return event;
 }
 
+/*
+ * legacy interface for mmap read.
+ * Don't use it. Use perf_mmap__read_event().
+ */
 union perf_event *perf_mmap__read_forward(struct perf_mmap *map)
 {
        u64 head;
-       u64 old = map->prev;
 
        /*
         * Check if event was unmapped due to a POLLHUP/POLLERR.
@@ -82,13 +79,26 @@ union perf_event *perf_mmap__read_forward(struct perf_mmap *map)
 
        head = perf_mmap__read_head(map);
 
-       return perf_mmap__read(map, old, head, &map->prev);
+       return perf_mmap__read(map, &map->prev, head);
 }
 
-union perf_event *perf_mmap__read_backward(struct perf_mmap *map)
+/*
+ * Read event from ring buffer one by one.
+ * Return one event for each call.
+ *
+ * Usage:
+ * perf_mmap__read_init()
+ * while(event = perf_mmap__read_event()) {
+ *     //process the event
+ *     perf_mmap__consume()
+ * }
+ * perf_mmap__read_done()
+ */
+union perf_event *perf_mmap__read_event(struct perf_mmap *map,
+                                       bool overwrite,
+                                       u64 *startp, u64 end)
 {
-       u64 head, end;
-       u64 start = map->prev;
+       union perf_event *event;
 
        /*
         * Check if event was unmapped due to a POLLHUP/POLLERR.
@@ -96,40 +106,19 @@ union perf_event *perf_mmap__read_backward(struct perf_mmap *map)
        if (!refcount_read(&map->refcnt))
                return NULL;
 
-       head = perf_mmap__read_head(map);
-       if (!head)
+       if (startp == NULL)
                return NULL;
 
-       /*
-        * 'head' pointer starts from 0. Kernel minus sizeof(record) form
-        * it each time when kernel writes to it, so in fact 'head' is
-        * negative. 'end' pointer is made manually by adding the size of
-        * the ring buffer to 'head' pointer, means the validate data can
-        * read is the whole ring buffer. If 'end' is positive, the ring
-        * buffer has not fully filled, so we must adjust 'end' to 0.
-        *
-        * However, since both 'head' and 'end' is unsigned, we can't
-        * simply compare 'end' against 0. Here we compare '-head' and
-        * the size of the ring buffer, where -head is the number of bytes
-        * kernel write to the ring buffer.
-        */
-       if (-head < (u64)(map->mask + 1))
-               end = 0;
-       else
-               end = head + map->mask + 1;
-
-       return perf_mmap__read(map, start, end, &map->prev);
-}
+       /* non-overwirte doesn't pause the ringbuffer */
+       if (!overwrite)
+               end = perf_mmap__read_head(map);
 
-void perf_mmap__read_catchup(struct perf_mmap *map)
-{
-       u64 head;
+       event = perf_mmap__read(map, startp, end);
 
-       if (!refcount_read(&map->refcnt))
-               return;
+       if (!overwrite)
+               map->prev = *startp;
 
-       head = perf_mmap__read_head(map);
-       map->prev = head;
+       return event;
 }
 
 static bool perf_mmap__empty(struct perf_mmap *map)
@@ -267,41 +256,60 @@ static int overwrite_rb_find_range(void *buf, int mask, u64 head, u64 *start, u6
        return -1;
 }
 
-int perf_mmap__push(struct perf_mmap *md, bool overwrite,
-                   void *to, int push(void *to, void *buf, size_t size))
+/*
+ * Report the start and end of the available data in ringbuffer
+ */
+int perf_mmap__read_init(struct perf_mmap *md, bool overwrite,
+                        u64 *startp, u64 *endp)
 {
        u64 head = perf_mmap__read_head(md);
        u64 old = md->prev;
-       u64 end = head, start = old;
        unsigned char *data = md->base + page_size;
        unsigned long size;
-       void *buf;
-       int rc = 0;
 
-       start = overwrite ? head : old;
-       end = overwrite ? old : head;
+       *startp = overwrite ? head : old;
+       *endp = overwrite ? old : head;
 
-       if (start == end)
-               return 0;
+       if (*startp == *endp)
+               return -EAGAIN;
 
-       size = end - start;
+       size = *endp - *startp;
        if (size > (unsigned long)(md->mask) + 1) {
                if (!overwrite) {
                        WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n");
 
                        md->prev = head;
                        perf_mmap__consume(md, overwrite);
-                       return 0;
+                       return -EAGAIN;
                }
 
                /*
                 * Backward ring buffer is full. We still have a chance to read
                 * most of data from it.
                 */
-               if (overwrite_rb_find_range(data, md->mask, head, &start, &end))
-                       return -1;
+               if (overwrite_rb_find_range(data, md->mask, head, startp, endp))
+                       return -EINVAL;
        }
 
+       return 0;
+}
+
+int perf_mmap__push(struct perf_mmap *md, bool overwrite,
+                   void *to, int push(void *to, void *buf, size_t size))
+{
+       u64 head = perf_mmap__read_head(md);
+       u64 end, start;
+       unsigned char *data = md->base + page_size;
+       unsigned long size;
+       void *buf;
+       int rc = 0;
+
+       rc = perf_mmap__read_init(md, overwrite, &start, &end);
+       if (rc < 0)
+               return (rc == -EAGAIN) ? 0 : -1;
+
+       size = end - start;
+
        if ((start & md->mask) + size != (end & md->mask)) {
                buf = &data[start & md->mask];
                size = md->mask + 1 - (start & md->mask);
@@ -327,3 +335,14 @@ int perf_mmap__push(struct perf_mmap *md, bool overwrite,
 out:
        return rc;
 }
+
+/*
+ * Mandatory for overwrite mode
+ * The direction of overwrite mode is backward.
+ * The last perf_mmap__read() will set tail to map->prev.
+ * Need to correct the map->prev to head which is the end of next read.
+ */
+void perf_mmap__read_done(struct perf_mmap *map)
+{
+       map->prev = perf_mmap__read_head(map);
+}
index e43d7b55a55f6578615cb1597bd676bf90924a78..ec7d3a24e276fbbe16aff12abf56363cc684cce5 100644 (file)
@@ -65,8 +65,6 @@ void perf_mmap__put(struct perf_mmap *map);
 
 void perf_mmap__consume(struct perf_mmap *map, bool overwrite);
 
-void perf_mmap__read_catchup(struct perf_mmap *md);
-
 static inline u64 perf_mmap__read_head(struct perf_mmap *mm)
 {
        struct perf_event_mmap_page *pc = mm->base;
@@ -87,11 +85,17 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail)
 }
 
 union perf_event *perf_mmap__read_forward(struct perf_mmap *map);
-union perf_event *perf_mmap__read_backward(struct perf_mmap *map);
+
+union perf_event *perf_mmap__read_event(struct perf_mmap *map,
+                                       bool overwrite,
+                                       u64 *startp, u64 end);
 
 int perf_mmap__push(struct perf_mmap *md, bool backward,
                    void *to, int push(void *to, void *buf, size_t size));
 
 size_t perf_mmap__mmap_len(struct perf_mmap *map);
 
+int perf_mmap__read_init(struct perf_mmap *md, bool overwrite,
+                        u64 *startp, u64 *endp);
+void perf_mmap__read_done(struct perf_mmap *map);
 #endif /*__PERF_MMAP_H */
index 1e97937b03a933890e7101ecad982c99e564836c..6f09e4962dade1e64512f64da99528ca1d649986 100644 (file)
@@ -137,6 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
        struct perf_evsel *evsel;
        bool use_sample_identifier = false;
        bool use_comm_exec;
+       bool sample_id = opts->sample_id;
 
        /*
         * Set the evsel leader links before we configure attributes,
@@ -163,8 +164,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
                 * match the id.
                 */
                use_sample_identifier = perf_can_sample_identifier();
-               evlist__for_each_entry(evlist, evsel)
-                       perf_evsel__set_sample_id(evsel, use_sample_identifier);
+               sample_id = true;
        } else if (evlist->nr_entries > 1) {
                struct perf_evsel *first = perf_evlist__first(evlist);
 
@@ -174,6 +174,10 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
                        use_sample_identifier = perf_can_sample_identifier();
                        break;
                }
+               sample_id = true;
+       }
+
+       if (sample_id) {
                evlist__for_each_entry(evlist, evsel)
                        perf_evsel__set_sample_id(evsel, use_sample_identifier);
        }
index 370138e7e35ca3f4046516dfe8fc2c304fa7abc5..88223bc7c82b923e3cc4274899bf24bea5d23a64 100644 (file)
@@ -12,7 +12,7 @@
  * States and transits:
  *
  *
- *  OFF--(on)--> READY --(hit)--> HIT
+ *  OFF--> ON --> READY --(hit)--> HIT
  *                 ^               |
  *                 |            (ready)
  *                 |               |
@@ -27,8 +27,9 @@ struct trigger {
        volatile enum {
                TRIGGER_ERROR           = -2,
                TRIGGER_OFF             = -1,
-               TRIGGER_READY           = 0,
-               TRIGGER_HIT             = 1,
+               TRIGGER_ON              = 0,
+               TRIGGER_READY           = 1,
+               TRIGGER_HIT             = 2,
        } state;
        const char *name;
 };
@@ -50,7 +51,7 @@ static inline bool trigger_is_error(struct trigger *t)
 static inline void trigger_on(struct trigger *t)
 {
        TRIGGER_WARN_ONCE(t, TRIGGER_OFF);
-       t->state = TRIGGER_READY;
+       t->state = TRIGGER_ON;
 }
 
 static inline void trigger_ready(struct trigger *t)
index 443892dabedbe319d8f1f582c3a255c03da5d748..1019bbc5dbd8a00ffb98fa90080fe8881f4d8a78 100644 (file)
@@ -340,35 +340,15 @@ size_t hex_width(u64 v)
        return n;
 }
 
-static int hex(char ch)
-{
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       if ((ch >= 'A') && (ch <= 'F'))
-               return ch - 'A' + 10;
-       return -1;
-}
-
 /*
  * While we find nice hex chars, build a long_val.
  * Return number of chars processed.
  */
 int hex2u64(const char *ptr, u64 *long_val)
 {
-       const char *p = ptr;
-       *long_val = 0;
-
-       while (*p) {
-               const int hex_val = hex(*p);
+       char *p;
 
-               if (hex_val < 0)
-                       break;
-
-               *long_val = (*long_val << 4) | hex_val;
-               p++;
-       }
+       *long_val = strtoull(ptr, &p, 16);
 
        return p - ptr;
 }
index a1883bbb014478d9239d24fda259c61bde853b23..2cccbba644187fd7815e2a3fb38f91308cf04de4 100644 (file)
@@ -56,9 +56,6 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM}
 # to compile vs uClibc, that can be done here as well.
 CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
 CROSS_COMPILE ?= $(CROSS)
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)gcc
-STRIP = $(CROSS_COMPILE)strip
 HOSTCC = gcc
 
 # check if compiler option is supported
index fcb3ed0be5f81ea89585af09b814ce3b0a7610c3..dd614463d4d6978d54afc1007c93ce6fdb0e57d1 100644 (file)
@@ -42,6 +42,24 @@ EXTRA_WARNINGS += -Wformat
 
 CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
 
+# Makefiles suck: This macro sets a default value of $(2) for the
+# variable named by $(1), unless the variable has been set by
+# environment or command line. This is necessary for CC and AR
+# because make sets default values, so the simpler ?= approach
+# won't work as expected.
+define allow-override
+  $(if $(or $(findstring environment,$(origin $(1))),\
+            $(findstring command line,$(origin $(1)))),,\
+    $(eval $(1) = $(2)))
+endef
+
+# Allow setting various cross-compile vars or setting CROSS_COMPILE as a prefix.
+$(call allow-override,CC,$(CROSS_COMPILE)gcc)
+$(call allow-override,AR,$(CROSS_COMPILE)ar)
+$(call allow-override,LD,$(CROSS_COMPILE)ld)
+$(call allow-override,CXX,$(CROSS_COMPILE)g++)
+$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
+
 ifeq ($(CC_NO_CLANG), 1)
 EXTRA_WARNINGS += -Wstrict-aliasing=3
 endif
index 90615e10c79af1c766f0d9a629bdac862f7cb507..815d155891779ddddeec284b5c5ce5a0c530cb98 100644 (file)
@@ -11,8 +11,6 @@ endif
 # (this improves performance and avoids hard-to-debug behaviour);
 MAKEFLAGS += -r
 
-CC = $(CROSS_COMPILE)gcc
-LD = $(CROSS_COMPILE)ld
 CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
 
 ALL_TARGETS := spidev_test spidev_fdx
index 44ef9eba5a7a2181004676cfa28f330cfb576b6a..6c645eb77d4218fd102968fb2a24b19350e3edd9 100644 (file)
@@ -178,6 +178,55 @@ void idr_get_next_test(int base)
        idr_destroy(&idr);
 }
 
+int idr_u32_cb(int id, void *ptr, void *data)
+{
+       BUG_ON(id < 0);
+       BUG_ON(ptr != DUMMY_PTR);
+       return 0;
+}
+
+void idr_u32_test1(struct idr *idr, u32 handle)
+{
+       static bool warned = false;
+       u32 id = handle;
+       int sid = 0;
+       void *ptr;
+
+       BUG_ON(idr_alloc_u32(idr, DUMMY_PTR, &id, id, GFP_KERNEL));
+       BUG_ON(id != handle);
+       BUG_ON(idr_alloc_u32(idr, DUMMY_PTR, &id, id, GFP_KERNEL) != -ENOSPC);
+       BUG_ON(id != handle);
+       if (!warned && id > INT_MAX)
+               printk("vvv Ignore these warnings\n");
+       ptr = idr_get_next(idr, &sid);
+       if (id > INT_MAX) {
+               BUG_ON(ptr != NULL);
+               BUG_ON(sid != 0);
+       } else {
+               BUG_ON(ptr != DUMMY_PTR);
+               BUG_ON(sid != id);
+       }
+       idr_for_each(idr, idr_u32_cb, NULL);
+       if (!warned && id > INT_MAX) {
+               printk("^^^ Warnings over\n");
+               warned = true;
+       }
+       BUG_ON(idr_remove(idr, id) != DUMMY_PTR);
+       BUG_ON(!idr_is_empty(idr));
+}
+
+void idr_u32_test(int base)
+{
+       DEFINE_IDR(idr);
+       idr_init_base(&idr, base);
+       idr_u32_test1(&idr, 10);
+       idr_u32_test1(&idr, 0x7fffffff);
+       idr_u32_test1(&idr, 0x80000000);
+       idr_u32_test1(&idr, 0x80000001);
+       idr_u32_test1(&idr, 0xffe00000);
+       idr_u32_test1(&idr, 0xffffffff);
+}
+
 void idr_checks(void)
 {
        unsigned long i;
@@ -248,6 +297,9 @@ void idr_checks(void)
        idr_get_next_test(0);
        idr_get_next_test(1);
        idr_get_next_test(4);
+       idr_u32_test(4);
+       idr_u32_test(1);
+       idr_u32_test(0);
 }
 
 /*
index 6903ccf35595f560350a26d03e3eb4369fbb128b..44a0d1ad4408429d67378bf185773f77b3461ab8 100644 (file)
@@ -29,7 +29,7 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
 {
        struct radix_tree_node *node;
 
-       if (flags & __GFP_NOWARN)
+       if (!(flags & __GFP_DIRECT_RECLAIM))
                return NULL;
 
        pthread_mutex_lock(&cachep->lock);
@@ -73,10 +73,17 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 
 void *kmalloc(size_t size, gfp_t gfp)
 {
-       void *ret = malloc(size);
+       void *ret;
+
+       if (!(gfp & __GFP_DIRECT_RECLAIM))
+               return NULL;
+
+       ret = malloc(size);
        uatomic_inc(&nr_allocated);
        if (kmalloc_verbose)
                printf("Allocating %p from malloc\n", ret);
+       if (gfp & __GFP_ZERO)
+               memset(ret, 0, size);
        return ret;
 }
 
diff --git a/tools/testing/radix-tree/linux/compiler_types.h b/tools/testing/radix-tree/linux/compiler_types.h
new file mode 100644 (file)
index 0000000..e69de29
index e9fff59dfd8a86cb6022d0dc6e5321a3d9a4f636..e3201ccf54c3c46dc7ffaf9bc6185edd406a6b95 100644 (file)
@@ -11,6 +11,7 @@
 #define __GFP_IO               0x40u
 #define __GFP_FS               0x80u
 #define __GFP_NOWARN           0x200u
+#define __GFP_ZERO             0x8000u
 #define __GFP_ATOMIC           0x80000u
 #define __GFP_ACCOUNT          0x100000u
 #define __GFP_DIRECT_RECLAIM   0x400000u
index 979baeec7e706aee05ef6bdfbf8dd91494284dd2..a037def0dec637ef9a38b034de5ac1fed4d32d8e 100644 (file)
@@ -3,6 +3,7 @@
 #define SLAB_H
 
 #include <linux/types.h>
+#include <linux/gfp.h>
 
 #define SLAB_HWCACHE_ALIGN 1
 #define SLAB_PANIC 2
 void *kmalloc(size_t size, gfp_t);
 void kfree(void *);
 
+static inline void *kzalloc(size_t size, gfp_t gfp)
+{
+        return kmalloc(size, gfp | __GFP_ZERO);
+}
+
 void *kmem_cache_alloc(struct kmem_cache *cachep, int flags);
 void kmem_cache_free(struct kmem_cache *cachep, void *objp);
 
index 1a74922689930ce1829afaa5f91b701f97861b07..f6304d2be90c16e7b818415d867704abda3ecf09 100644 (file)
@@ -11,11 +11,11 @@ all:
                BUILD_TARGET=$(OUTPUT)/$$DIR;   \
                mkdir $$BUILD_TARGET  -p;       \
                make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
-               #SUBDIR test prog name should be in the form: SUBDIR_test.sh
+               #SUBDIR test prog name should be in the form: SUBDIR_test.sh \
                TEST=$$DIR"_test.sh"; \
-               if [ -e $$DIR/$$TEST ]; then
-                       rsync -a $$DIR/$$TEST $$BUILD_TARGET/;
-               fi
+               if [ -e $$DIR/$$TEST ]; then \
+                       rsync -a $$DIR/$$TEST $$BUILD_TARGET/; \
+               fi \
        done
 
 override define RUN_TESTS
index cc15af2e54fe8651e7b88caaccf8481871c983bc..9cf83f895d98873ec81044ce4c4c0ecb89ac5ec3 100644 (file)
@@ -11,3 +11,4 @@ test_progs
 test_tcpbpf_user
 test_verifier_log
 feature
+test_libbpf_open
index 436c4c72414f4b3720be09fc00c88ccea564b1e3..9e03a4c356a496e3f57d18058254df464c206278 100644 (file)
@@ -126,6 +126,8 @@ static void test_hashmap_sizes(int task, void *data)
                        fd = bpf_create_map(BPF_MAP_TYPE_HASH, i, j,
                                            2, map_flags);
                        if (fd < 0) {
+                               if (errno == ENOMEM)
+                                       return;
                                printf("Failed to create hashmap key=%d value=%d '%s'\n",
                                       i, j, strerror(errno));
                                exit(1);
index 57119ad57a3fbf6e1e8b1b35d9c74b9ab201715e..3e645ee41ed5fcc033266645b8e893c143fb79fc 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
 #include <linux/ip.h>
-#include <linux/in6.h>
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/tcp.h>
index c0f16e93f9bd14b3ef98b323c6830ca14645509b..437c0b1c9d21835b081a3992e303493d030d004e 100644 (file)
@@ -2586,6 +2586,32 @@ static struct bpf_test tests[] = {
                .result_unpriv = REJECT,
                .result = ACCEPT,
        },
+       {
+               "runtime/jit: pass negative index to tail_call",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_3, -1),
+                       BPF_LD_MAP_FD(BPF_REG_2, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_tail_call),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_prog = { 1 },
+               .result = ACCEPT,
+       },
+       {
+               "runtime/jit: pass > 32bit index to tail_call",
+               .insns = {
+                       BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
+                       BPF_LD_MAP_FD(BPF_REG_2, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_tail_call),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_prog = { 2 },
+               .result = ACCEPT,
+       },
        {
                "stack pointer arithmetic",
                .insns = {
@@ -11137,6 +11163,64 @@ static struct bpf_test tests[] = {
                .result = REJECT,
                .prog_type = BPF_PROG_TYPE_TRACEPOINT,
        },
+       {
+               "xadd/w check unaligned stack",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_0, 1),
+                       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
+                       BPF_STX_XADD(BPF_W, BPF_REG_10, BPF_REG_0, -7),
+                       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
+                       BPF_EXIT_INSN(),
+               },
+               .result = REJECT,
+               .errstr = "misaligned stack access off",
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       },
+       {
+               "xadd/w check unaligned map",
+               .insns = {
+                       BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+                       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+                       BPF_LD_MAP_FD(BPF_REG_1, 0),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                                    BPF_FUNC_map_lookup_elem),
+                       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
+                       BPF_EXIT_INSN(),
+                       BPF_MOV64_IMM(BPF_REG_1, 1),
+                       BPF_STX_XADD(BPF_W, BPF_REG_0, BPF_REG_1, 3),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 3),
+                       BPF_EXIT_INSN(),
+               },
+               .fixup_map1 = { 3 },
+               .result = REJECT,
+               .errstr = "misaligned value access off",
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       },
+       {
+               "xadd/w check unaligned pkt",
+               .insns = {
+                       BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
+                                   offsetof(struct xdp_md, data)),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
+                                   offsetof(struct xdp_md, data_end)),
+                       BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+                       BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 2),
+                       BPF_MOV64_IMM(BPF_REG_0, 99),
+                       BPF_JMP_IMM(BPF_JA, 0, 0, 6),
+                       BPF_MOV64_IMM(BPF_REG_0, 1),
+                       BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
+                       BPF_ST_MEM(BPF_W, BPF_REG_2, 3, 0),
+                       BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 1),
+                       BPF_STX_XADD(BPF_W, BPF_REG_2, BPF_REG_0, 2),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 1),
+                       BPF_EXIT_INSN(),
+               },
+               .result = REJECT,
+               .errstr = "BPF_XADD stores into R2 packet",
+               .prog_type = BPF_PROG_TYPE_XDP,
+       },
 };
 
 static int probe_filter_length(const struct bpf_insn *fp)
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
new file mode 100644 (file)
index 0000000..5ba7303
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe event string type argument
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+echo 0 > events/enable
+echo > kprobe_events
+
+case `uname -m` in
+x86_64)
+  ARG2=%si
+  OFFS=8
+;;
+i[3456]86)
+  ARG2=%cx
+  OFFS=4
+;;
+aarch64)
+  ARG2=%x1
+  OFFS=8
+;;
+arm*)
+  ARG2=%r1
+  OFFS=4
+;;
+*)
+  echo "Please implement other architecture here"
+  exit_untested
+esac
+
+: "Test get argument (1)"
+echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string" > kprobe_events
+echo 1 > events/kprobes/testprobe/enable
+! echo test >> kprobe_events
+tail -n 1 trace | grep -qe "testprobe.* arg1=\"test\""
+
+echo 0 > events/kprobes/testprobe/enable
+: "Test get argument (2)"
+echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string arg2=+0(+${OFFS}(${ARG2})):string" > kprobe_events
+echo 1 > events/kprobes/testprobe/enable
+! echo test1 test2 >> kprobe_events
+tail -n 1 trace | grep -qe "testprobe.* arg1=\"test1\" arg2=\"test2\""
+
+echo 0 > events/enable
+echo > kprobe_events
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
new file mode 100644 (file)
index 0000000..231bcd2
--- /dev/null
@@ -0,0 +1,97 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe event argument syntax
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue
+
+echo 0 > events/enable
+echo > kprobe_events
+
+PROBEFUNC="vfs_read"
+GOODREG=
+BADREG=
+GOODSYM="_sdata"
+if ! grep -qw ${GOODSYM} /proc/kallsyms ; then
+  GOODSYM=$PROBEFUNC
+fi
+BADSYM="deaqswdefr"
+SYMADDR=0x`grep -w ${GOODSYM} /proc/kallsyms | cut -f 1 -d " "`
+GOODTYPE="x16"
+BADTYPE="y16"
+
+case `uname -m` in
+x86_64|i[3456]86)
+  GOODREG=%ax
+  BADREG=%ex
+;;
+aarch64)
+  GOODREG=%x0
+  BADREG=%ax
+;;
+arm*)
+  GOODREG=%r0
+  BADREG=%ax
+;;
+esac
+
+test_goodarg() # Good-args
+{
+  while [ "$1" ]; do
+    echo "p ${PROBEFUNC} $1" > kprobe_events
+    shift 1
+  done;
+}
+
+test_badarg() # Bad-args
+{
+  while [ "$1" ]; do
+    ! echo "p ${PROBEFUNC} $1" > kprobe_events
+    shift 1
+  done;
+}
+
+echo > kprobe_events
+
+: "Register access"
+test_goodarg ${GOODREG}
+test_badarg ${BADREG}
+
+: "Symbol access"
+test_goodarg "@${GOODSYM}" "@${SYMADDR}" "@${GOODSYM}+10" "@${GOODSYM}-10"
+test_badarg "@" "@${BADSYM}" "@${GOODSYM}*10" "@${GOODSYM}/10" \
+           "@${GOODSYM}%10" "@${GOODSYM}&10" "@${GOODSYM}|10"
+
+: "Stack access"
+test_goodarg "\$stack" "\$stack0" "\$stack1"
+test_badarg "\$stackp" "\$stack0+10" "\$stack1-10"
+
+: "Retval access"
+echo "r ${PROBEFUNC} \$retval" > kprobe_events
+! echo "p ${PROBEFUNC} \$retval" > kprobe_events
+
+: "Comm access"
+test_goodarg "\$comm"
+
+: "Indirect memory access"
+test_goodarg "+0(${GOODREG})" "-0(${GOODREG})" "+10(\$stack)" \
+       "+0(\$stack1)" "+10(@${GOODSYM}-10)" "+0(+10(+20(\$stack)))"
+test_badarg "+(${GOODREG})" "(${GOODREG}+10)" "-(${GOODREG})" "(${GOODREG})" \
+       "+10(\$comm)" "+0(${GOODREG})+10"
+
+: "Name assignment"
+test_goodarg "varname=${GOODREG}"
+test_badarg "varname=varname2=${GOODREG}"
+
+: "Type syntax"
+test_goodarg "${GOODREG}:${GOODTYPE}"
+test_badarg "${GOODREG}::${GOODTYPE}" "${GOODREG}:${BADTYPE}" \
+       "${GOODTYPE}:${GOODREG}"
+
+: "Combination check"
+
+test_goodarg "\$comm:string" "+0(\$stack):string"
+test_badarg "\$comm:x64" "\$stack:string" "${GOODREG}:string"
+
+echo > kprobe_events
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc b/tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc
new file mode 100644 (file)
index 0000000..4fda01a
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe events - probe points
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+TARGET_FUNC=create_trace_kprobe
+
+dec_addr() { # hexaddr
+  printf "%d" "0x"`echo $1 | tail -c 8`
+}
+
+set_offs() { # prev target next
+  A1=`dec_addr $1`
+  A2=`dec_addr $2`
+  A3=`dec_addr $3`
+  TARGET="0x$2" # an address
+  PREV=`expr $A1 - $A2` # offset to previous symbol
+  NEXT=+`expr $A3 - $A2` # offset to next symbol
+  OVERFLOW=+`printf "0x%x" ${PREV}` # overflow offset to previous symbol
+}
+
+# We have to decode symbol addresses to get correct offsets.
+# If the offset is not an instruction boundary, it cause -EILSEQ.
+set_offs `grep -A1 -B1 ${TARGET_FUNC} /proc/kallsyms | cut -f 1 -d " " | xargs`
+
+UINT_TEST=no
+# printf "%x" -1 returns (unsigned long)-1.
+if [ `printf "%x" -1 | wc -c` != 9 ]; then
+  UINT_TEST=yes
+fi
+
+echo 0 > events/enable
+echo > kprobe_events
+echo "p:testprobe ${TARGET_FUNC}" > kprobe_events
+echo "p:testprobe ${TARGET}" > kprobe_events
+echo "p:testprobe ${TARGET_FUNC}${NEXT}" > kprobe_events
+! echo "p:testprobe ${TARGET_FUNC}${PREV}" > kprobe_events
+if [ "${UINT_TEST}" = yes ]; then
+! echo "p:testprobe ${TARGET_FUNC}${OVERFLOW}" > kprobe_events
+fi
+echo > kprobe_events
+clear_trace
index cea4adcd42b8877f7e5a05d57a837bcc61c1d97d..a63e8453984d2793eb38b706236f31dc49527e9b 100644 (file)
@@ -12,9 +12,9 @@ all:
                BUILD_TARGET=$(OUTPUT)/$$DIR;   \
                mkdir $$BUILD_TARGET  -p;       \
                make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
-               if [ -e $$DIR/$(TEST_PROGS) ]; then
-                       rsync -a $$DIR/$(TEST_PROGS) $$BUILD_TARGET/;
-               fi
+               if [ -e $$DIR/$(TEST_PROGS) ]; then \
+                       rsync -a $$DIR/$(TEST_PROGS) $$BUILD_TARGET/; \
+               fi \
        done
 
 override define RUN_TESTS
index a5276a91dfbfc91806d737d561acbbfd2bc7f748..0862e6f47a38c8ae56870809c87806cca0e39c95 100644 (file)
@@ -5,6 +5,7 @@ CFLAGS += -I../../../../include/
 CFLAGS += -I../../../../usr/include/
 
 TEST_PROGS := run_tests.sh
+TEST_FILES := run_fuse_test.sh
 TEST_GEN_FILES := memfd_test fuse_mnt fuse_test
 
 fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
diff --git a/tools/testing/selftests/memfd/config b/tools/testing/selftests/memfd/config
new file mode 100644 (file)
index 0000000..835c7f4
--- /dev/null
@@ -0,0 +1 @@
+CONFIG_FUSE_FS=m
index 86636d207adf72c12403355cae88d3bfe819fd80..686da510f9895bf850a96a17a6eeeb1d17607cad 100644 (file)
@@ -4,8 +4,9 @@ all:
 include ../lib.mk
 
 TEST_PROGS := mem-on-off-test.sh
-override RUN_TESTS := ./mem-on-off-test.sh -r 2 && echo "selftests: memory-hotplug [PASS]" || echo "selftests: memory-hotplug [FAIL]"
-override EMIT_TESTS := echo "$(RUN_TESTS)"
+override RUN_TESTS := @./mem-on-off-test.sh -r 2 && echo "selftests: memory-hotplug [PASS]" || echo "selftests: memory-hotplug [FAIL]"
+
+override EMIT_TESTS := echo "$(subst @,,$(RUN_TESTS))"
 
 run_full_test:
        @/bin/bash ./mem-on-off-test.sh && echo "memory-hotplug selftests: [PASS]" || echo "memory-hotplug selftests: [FAIL]"
index 39fd362415cfe1a71c9c58eb634b91fc9f676bb2..0f2698f9fd6d8a2547ffe6094ced70c820a894ae 100644 (file)
@@ -57,7 +57,7 @@ volatile int gotsig;
 
 void sighandler(int sig, siginfo_t *info, void *ctx)
 {
-       struct ucontext *ucp = ctx;
+       ucontext_t *ucp = ctx;
 
        if (!testing) {
                signal(sig, SIG_DFL);
index 35ade7406dcdbbc778dbf7f39d46fafee0b0148f..3ae77ba93208f15f0d720325c269c7a95af2c6fa 100644 (file)
@@ -135,6 +135,16 @@ static int run_test(void *addr, unsigned long size)
        return 0;
 }
 
+static int syscall_available(void)
+{
+       int rc;
+
+       errno = 0;
+       rc = syscall(__NR_subpage_prot, 0, 0, 0);
+
+       return rc == 0 || (errno != ENOENT && errno != ENOSYS);
+}
+
 int test_anon(void)
 {
        unsigned long align;
@@ -145,6 +155,8 @@ int test_anon(void)
        void *mallocblock;
        unsigned long mallocsize;
 
+       SKIP_IF(!syscall_available());
+
        if (getpagesize() != 0x10000) {
                fprintf(stderr, "Kernel page size must be 64K!\n");
                return 1;
@@ -180,6 +192,8 @@ int test_file(void)
        off_t filesize;
        int fd;
 
+       SKIP_IF(!syscall_available());
+
        fd = open(file_name, O_RDWR);
        if (fd == -1) {
                perror("failed to open file");
index a23453943ad2b95538571015c066eaa2c2deb711..5c72ff978f2784babc71464b2baeb62c44089ce2 100644 (file)
@@ -16,7 +16,7 @@ $(OUTPUT)/tm-syscall: tm-syscall-asm.S
 $(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include
 $(OUTPUT)/tm-tmspr: CFLAGS += -pthread
 $(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64
-$(OUTPUT)/tm-resched-dscr: ../pmu/lib.o
+$(OUTPUT)/tm-resched-dscr: ../pmu/lib.c
 $(OUTPUT)/tm-unavailable: CFLAGS += -O0 -pthread -m64 -Wno-error=uninitialized -mvsx
 $(OUTPUT)/tm-trap: CFLAGS += -O0 -pthread -m64
 
index 5d92c23ee6cbd2cf1ba157fc41b37168ee8887c7..179d592f0073c36498d91e15c2142a560ec1e88d 100644 (file)
@@ -255,6 +255,8 @@ int tm_trap_test(void)
 
        struct sigaction trap_sa;
 
+       SKIP_IF(!have_htm());
+
        trap_sa.sa_flags = SA_SIGINFO;
        trap_sa.sa_sigaction = trap_signal_handler;
        sigaction(SIGTRAP, &trap_sa, NULL);
index 6a8e5a9bfc1065a3e860cd5b31e7aea2d508bea8..d148f9f89fb64cf325a546a1855c1e1cc5fc8a21 100644 (file)
@@ -2,3 +2,4 @@ CONFIG_MISC_FILESYSTEMS=y
 CONFIG_PSTORE=y
 CONFIG_PSTORE_PMSG=y
 CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_RAM=m
index 0b457e8e0f0c103281b5b55006729ffac77ad8f0..5df609950a666f8000307653a0b1e8d4368549a2 100644 (file)
@@ -141,6 +141,15 @@ struct seccomp_data {
 #define SECCOMP_FILTER_FLAG_LOG 2
 #endif
 
+#ifndef PTRACE_SECCOMP_GET_METADATA
+#define PTRACE_SECCOMP_GET_METADATA    0x420d
+
+struct seccomp_metadata {
+       __u64 filter_off;       /* Input: which filter */
+       __u64 flags;             /* Output: filter's flags */
+};
+#endif
+
 #ifndef seccomp
 int seccomp(unsigned int op, unsigned int flags, void *args)
 {
@@ -2845,6 +2854,58 @@ TEST(get_action_avail)
        EXPECT_EQ(errno, EOPNOTSUPP);
 }
 
+TEST(get_metadata)
+{
+       pid_t pid;
+       int pipefd[2];
+       char buf;
+       struct seccomp_metadata md;
+
+       ASSERT_EQ(0, pipe(pipefd));
+
+       pid = fork();
+       ASSERT_GE(pid, 0);
+       if (pid == 0) {
+               struct sock_filter filter[] = {
+                       BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+               };
+               struct sock_fprog prog = {
+                       .len = (unsigned short)ARRAY_SIZE(filter),
+                       .filter = filter,
+               };
+
+               /* one with log, one without */
+               ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER,
+                                    SECCOMP_FILTER_FLAG_LOG, &prog));
+               ASSERT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog));
+
+               ASSERT_EQ(0, close(pipefd[0]));
+               ASSERT_EQ(1, write(pipefd[1], "1", 1));
+               ASSERT_EQ(0, close(pipefd[1]));
+
+               while (1)
+                       sleep(100);
+       }
+
+       ASSERT_EQ(0, close(pipefd[1]));
+       ASSERT_EQ(1, read(pipefd[0], &buf, 1));
+
+       ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid));
+       ASSERT_EQ(pid, waitpid(pid, NULL, 0));
+
+       md.filter_off = 0;
+       ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md));
+       EXPECT_EQ(md.flags, SECCOMP_FILTER_FLAG_LOG);
+       EXPECT_EQ(md.filter_off, 0);
+
+       md.filter_off = 1;
+       ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md));
+       EXPECT_EQ(md.flags, 0);
+       EXPECT_EQ(md.filter_off, 1);
+
+       ASSERT_EQ(0, kill(pid, SIGKILL));
+}
+
 /*
  * TODO:
  * - add microbenchmarks
index b3c8ba3cb66855ff93d6581f7428982be41fca60..d0121a8a3523a948af699e52b6adbf1cde37b030 100644 (file)
@@ -30,7 +30,7 @@ $(TEST_CUSTOM_PROGS): $(TESTS) $(OBJS)
        $(CC) -o $(TEST_CUSTOM_PROGS) $(OBJS) $(TESTS) $(CFLAGS) $(LDFLAGS)
 
 $(OBJS): $(OUTPUT)/%.o: %.c
-       $(CC) -c $^ -o $@
+       $(CC) -c $^ -o $@ $(CFLAGS)
 
 $(TESTS): $(OUTPUT)/%.o: %.c
        $(CC) -c $^ -o $@
index e34075059c26cb26143d3c992dfa7920fbb02485..90bba48c3f07fa4c8567290b64777c548d846958 100644 (file)
         "cmdUnderTest": "$TC actions ls action skbmod",
         "expExitCode": "0",
         "verifyCmd": "$TC actions get action skbmod index 4",
-        "matchPattern": "action order [0-9]*: skbmod pipe set etype 0x0031",
+        "matchPattern": "action order [0-9]*: skbmod pipe set etype 0x31",
         "matchCount": "1",
         "teardown": [
             "$TC actions flush action skbmod"
index 3d5a62ff7d31ed437fc5457a501ec9b606839f92..f5d7a7851e2177b315111f4e8ae3f0b0a716487d 100644 (file)
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+include ../lib.mk
+
 ifndef CROSS_COMPILE
 CFLAGS := -std=gnu99
 CFLAGS_vdso_standalone_test_x86 := -nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector
@@ -6,16 +8,14 @@ ifeq ($(CONFIG_X86_32),y)
 LDLIBS += -lgcc_s
 endif
 
-TEST_PROGS := vdso_test vdso_standalone_test_x86
+TEST_PROGS := $(OUTPUT)/vdso_test $(OUTPUT)/vdso_standalone_test_x86
 
 all: $(TEST_PROGS)
-vdso_test: parse_vdso.c vdso_test.c
-vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
+$(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c
+$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
        $(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
                vdso_standalone_test_x86.c parse_vdso.c \
-               -o vdso_standalone_test_x86
+               -o $@
 
-include ../lib.mk
-clean:
-       rm -fr $(TEST_PROGS)
+EXTRA_CLEAN := $(TEST_PROGS)
 endif
index 63c94d776e8970de2703b7416a76bffdeb101361..342c7bc9dc8c5d29441e27da5131d5312ea4bca8 100644 (file)
@@ -11,3 +11,4 @@ mlock-intersect-test
 mlock-random-test
 virtual_address_range
 gup_benchmark
+va_128TBswitch
index d2561895a021a4fc87822938c4485fcf85aff933..22d56467383029b24b52b95e6ee09cc0bb6bf835 100755 (executable)
@@ -2,25 +2,33 @@
 # SPDX-License-Identifier: GPL-2.0
 #please run as root
 
-#we need 256M, below is the size in kB
-needmem=262144
 mnt=./huge
 exitcode=0
 
-#get pagesize and freepages from /proc/meminfo
+#get huge pagesize and freepages from /proc/meminfo
 while read name size unit; do
        if [ "$name" = "HugePages_Free:" ]; then
                freepgs=$size
        fi
        if [ "$name" = "Hugepagesize:" ]; then
-               pgsize=$size
+               hpgsize_KB=$size
        fi
 done < /proc/meminfo
 
+# Simple hugetlbfs tests have a hardcoded minimum requirement of
+# huge pages totaling 256MB (262144KB) in size.  The userfaultfd
+# hugetlb test requires a minimum of 2 * nr_cpus huge pages.  Take
+# both of these requirements into account and attempt to increase
+# number of huge pages available.
+nr_cpus=$(nproc)
+hpgsize_MB=$((hpgsize_KB / 1024))
+half_ufd_size_MB=$((((nr_cpus * hpgsize_MB + 127) / 128) * 128))
+needmem_KB=$((half_ufd_size_MB * 2 * 1024))
+
 #set proper nr_hugepages
-if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then
+if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
        nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
-       needpgs=`expr $needmem / $pgsize`
+       needpgs=$((needmem_KB / hpgsize_KB))
        tries=2
        while [ $tries -gt 0 ] && [ $freepgs -lt $needpgs ]; do
                lackpgs=$(( $needpgs - $freepgs ))
@@ -107,8 +115,9 @@ fi
 echo "---------------------------"
 echo "running userfaultfd_hugetlb"
 echo "---------------------------"
-# 256MB total huge pages == 128MB src and 128MB dst
-./userfaultfd hugetlb 128 32 $mnt/ufd_test_file
+# Test requires source and destination huge pages.  Size of source
+# (half_ufd_size_MB) is passed as argument to test.
+./userfaultfd hugetlb $half_ufd_size_MB 32 $mnt/ufd_test_file
 if [ $? -ne 0 ]; then
        echo "[FAIL]"
        exitcode=1
index 10ca46df144921ee3bdc60aa6974802dfffa77e8..d744991c0f4f44d56bda208ad3039ad81500f303 100644 (file)
@@ -5,16 +5,26 @@ include ../lib.mk
 
 .PHONY: all all_32 all_64 warn_32bit_failure clean
 
-TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \
-                       check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \
+UNAME_M := $(shell uname -m)
+CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32)
+CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c)
+
+TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
+                       check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \
                        protection_keys test_vdso test_vsyscall
 TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
                        test_FCMOV test_FCOMI test_FISTTP \
                        vdso_restorer
-TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 5lvl
+TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip
+# Some selftests require 32bit support enabled also on 64bit systems
+TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall
 
-TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
+TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) $(TARGETS_C_32BIT_NEEDED)
 TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
+ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),11)
+TARGETS_C_64BIT_ALL += $(TARGETS_C_32BIT_NEEDED)
+endif
+
 BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
 BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64)
 
@@ -23,10 +33,6 @@ BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64))
 
 CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -no-pie
 
-UNAME_M := $(shell uname -m)
-CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32)
-CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c)
-
 define gen-target-rule-32
 $(1) $(1)_32: $(OUTPUT)/$(1)_32
 .PHONY: $(1) $(1)_32
@@ -40,12 +46,14 @@ endef
 ifeq ($(CAN_BUILD_I386),1)
 all: all_32
 TEST_PROGS += $(BINARIES_32)
+EXTRA_CFLAGS += -DCAN_BUILD_32
 $(foreach t,$(TARGETS_C_32BIT_ALL),$(eval $(call gen-target-rule-32,$(t))))
 endif
 
 ifeq ($(CAN_BUILD_X86_64),1)
 all: all_64
 TEST_PROGS += $(BINARIES_64)
+EXTRA_CFLAGS += -DCAN_BUILD_64
 $(foreach t,$(TARGETS_C_64BIT_ALL),$(eval $(call gen-target-rule-64,$(t))))
 endif
 
index 361466a2eaef34492e24588d4ef52d8aa68a53ac..ade443a8842106e49aabc1f2d36dc9d4f8b75b65 100644 (file)
@@ -95,6 +95,10 @@ asm (
        "int3\n\t"
        "vmcode_int80:\n\t"
        "int $0x80\n\t"
+       "vmcode_popf_hlt:\n\t"
+       "push %ax\n\t"
+       "popf\n\t"
+       "hlt\n\t"
        "vmcode_umip:\n\t"
        /* addressing via displacements */
        "smsw (2052)\n\t"
@@ -124,8 +128,8 @@ asm (
 
 extern unsigned char vmcode[], end_vmcode[];
 extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[],
-       vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[],
-       vmcode_umip_str[], vmcode_umip_sldt[];
+       vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_popf_hlt[],
+       vmcode_umip[], vmcode_umip_str[], vmcode_umip_sldt[];
 
 /* Returns false if the test was skipped. */
 static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
@@ -175,7 +179,7 @@ static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
            (VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) {
                printf("[OK]\tReturned correctly\n");
        } else {
-               printf("[FAIL]\tIncorrect return reason\n");
+               printf("[FAIL]\tIncorrect return reason (started at eip = 0x%lx, ended at eip = 0x%lx)\n", eip, v86->regs.eip);
                nerrs++;
        }
 
@@ -264,6 +268,9 @@ int main(void)
        v86.regs.ds = load_addr / 16;
        v86.regs.es = load_addr / 16;
 
+       /* Use the end of the page as our stack. */
+       v86.regs.esp = 4096;
+
        assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
 
        /* #BR -- should deliver SIG??? */
@@ -295,6 +302,23 @@ int main(void)
        v86.regs.eflags &= ~X86_EFLAGS_IF;
        do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set");
 
+       /* POPF with VIP set but IF clear: should not trap */
+       v86.regs.eflags = X86_EFLAGS_VIP;
+       v86.regs.eax = 0;
+       do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP set and IF clear");
+
+       /* POPF with VIP set and IF set: should trap */
+       v86.regs.eflags = X86_EFLAGS_VIP;
+       v86.regs.eax = X86_EFLAGS_IF;
+       do_test(&v86, vmcode_popf_hlt - vmcode, VM86_STI, 0, "POPF with VIP and IF set");
+
+       /* POPF with VIP clear and IF set: should not trap */
+       v86.regs.eflags = 0;
+       v86.regs.eax = X86_EFLAGS_IF;
+       do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP clear and IF set");
+
+       v86.regs.eflags = 0;
+
        /* INT3 -- should cause #BP */
        do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3");
 
@@ -318,7 +342,7 @@ int main(void)
        clearhandler(SIGSEGV);
 
        /* Make sure nothing explodes if we fork. */
-       if (fork() > 0)
+       if (fork() == 0)
                return 0;
 
        return (nerrs == 0 ? 0 : 1);
index ec0f6b45ce8b4d5f303528daf6efba71258c39c6..9c0325e1ea6844f666bfdcc8204763a8614b9875 100644 (file)
@@ -315,11 +315,39 @@ static inline void *__si_bounds_upper(siginfo_t *si)
        return si->si_upper;
 }
 #else
+
+/*
+ * This deals with old version of _sigfault in some distros:
+ *
+
+old _sigfault:
+        struct {
+            void *si_addr;
+       } _sigfault;
+
+new _sigfault:
+       struct {
+               void __user *_addr;
+               int _trapno;
+               short _addr_lsb;
+               union {
+                       struct {
+                               void __user *_lower;
+                               void __user *_upper;
+                       } _addr_bnd;
+                       __u32 _pkey;
+               };
+       } _sigfault;
+ *
+ */
+
 static inline void **__si_bounds_hack(siginfo_t *si)
 {
        void *sigfault = &si->_sifields._sigfault;
        void *end_sigfault = sigfault + sizeof(si->_sifields._sigfault);
-       void **__si_lower = end_sigfault;
+       int *trapno = (int*)end_sigfault;
+       /* skip _trapno and _addr_lsb */
+       void **__si_lower = (void**)(trapno + 2);
 
        return __si_lower;
 }
@@ -331,7 +359,7 @@ static inline void *__si_bounds_lower(siginfo_t *si)
 
 static inline void *__si_bounds_upper(siginfo_t *si)
 {
-       return (*__si_bounds_hack(si)) + sizeof(void *);
+       return *(__si_bounds_hack(si) + 1);
 }
 #endif
 
index bc1b0735bb50ed02963e834c7dc38395f7c6d834..f15aa5a76fe3457e96e438c15e7ad40d3c7fbce0 100644 (file)
@@ -393,34 +393,6 @@ pid_t fork_lazy_child(void)
        return forkret;
 }
 
-void davecmp(void *_a, void *_b, int len)
-{
-       int i;
-       unsigned long *a = _a;
-       unsigned long *b = _b;
-
-       for (i = 0; i < len / sizeof(*a); i++) {
-               if (a[i] == b[i])
-                       continue;
-
-               dprintf3("[%3d]: a: %016lx b: %016lx\n", i, a[i], b[i]);
-       }
-}
-
-void dumpit(char *f)
-{
-       int fd = open(f, O_RDONLY);
-       char buf[100];
-       int nr_read;
-
-       dprintf2("maps fd: %d\n", fd);
-       do {
-               nr_read = read(fd, &buf[0], sizeof(buf));
-               write(1, buf, nr_read);
-       } while (nr_read > 0);
-       close(fd);
-}
-
 #define PKEY_DISABLE_ACCESS    0x1
 #define PKEY_DISABLE_WRITE     0x2
 
index 1ae1c5a7392ead3c8b8a108f70bdddbf0d4f100e..6f22238f32173db4ef4d710666807cb5397f7dc0 100644 (file)
@@ -183,8 +183,10 @@ static void test_ptrace_syscall_restart(void)
                if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
                        err(1, "PTRACE_TRACEME");
 
+               pid_t pid = getpid(), tid = syscall(SYS_gettid);
+
                printf("\tChild will make one syscall\n");
-               raise(SIGSTOP);
+               syscall(SYS_tgkill, pid, tid, SIGSTOP);
 
                syscall(SYS_gettid, 10, 11, 12, 13, 14, 15);
                _exit(0);
@@ -301,9 +303,11 @@ static void test_restart_under_ptrace(void)
                if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
                        err(1, "PTRACE_TRACEME");
 
+               pid_t pid = getpid(), tid = syscall(SYS_gettid);
+
                printf("\tChild will take a nap until signaled\n");
                setsigign(SIGUSR1, SA_RESTART);
-               raise(SIGSTOP);
+               syscall(SYS_tgkill, pid, tid, SIGSTOP);
 
                syscall(SYS_pause, 0, 0, 0, 0, 0, 0);
                _exit(0);
index a48da95c18fdf1f0ea46e7cb628ff9a9caba931b..ddfdd635de16c68b13c01a8782ebdc0ecd3b8b0d 100644 (file)
@@ -119,7 +119,9 @@ static void check_result(void)
 
 int main()
 {
+#ifdef CAN_BUILD_32
        int tmp;
+#endif
 
        sethandler(SIGTRAP, sigtrap, 0);
 
@@ -139,12 +141,13 @@ int main()
                      : : "c" (post_nop) : "r11");
        check_result();
 #endif
-
+#ifdef CAN_BUILD_32
        printf("[RUN]\tSet TF and check int80\n");
        set_eflags(get_eflags() | X86_EFLAGS_TF);
        asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid)
                        : INT80_CLOBBERS);
        check_result();
+#endif
 
        /*
         * This test is particularly interesting if fast syscalls use
index bf0d687c7db75e5b03cf756f731082ca08229799..64f11c8d9b767d31bb3247e7424fd8f708d85d05 100644 (file)
@@ -90,8 +90,12 @@ int main(int argc, char **argv, char **envp)
                        vdso_size += PAGE_SIZE;
                }
 
+#ifdef __i386__
                /* Glibc is likely to explode now - exit with raw syscall */
                asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret));
+#else /* __x86_64__ */
+               syscall(SYS_exit, ret);
+#endif
        } else {
                int status;
 
index 29973cde06d3db08f5219dc692c82be82624e581..2352590117042ebf79ddd946a00d8c49d38d786e 100644 (file)
 # endif
 #endif
 
+/* max length of lines in /proc/self/maps - anything longer is skipped here */
+#define MAPS_LINE_LEN 128
+
 int nerrs = 0;
 
+typedef long (*getcpu_t)(unsigned *, unsigned *, void *);
+
+getcpu_t vgetcpu;
+getcpu_t vdso_getcpu;
+
+static void *vsyscall_getcpu(void)
+{
 #ifdef __x86_64__
-# define VSYS(x) (x)
+       FILE *maps;
+       char line[MAPS_LINE_LEN];
+       bool found = false;
+
+       maps = fopen("/proc/self/maps", "r");
+       if (!maps) /* might still be present, but ignore it here, as we test vDSO not vsyscall */
+               return NULL;
+
+       while (fgets(line, MAPS_LINE_LEN, maps)) {
+               char r, x;
+               void *start, *end;
+               char name[MAPS_LINE_LEN];
+
+               /* sscanf() is safe here as strlen(name) >= strlen(line) */
+               if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s",
+                          &start, &end, &r, &x, name) != 5)
+                       continue;
+
+               if (strcmp(name, "[vsyscall]"))
+                       continue;
+
+               /* assume entries are OK, as we test vDSO here not vsyscall */
+               found = true;
+               break;
+       }
+
+       fclose(maps);
+
+       if (!found) {
+               printf("Warning: failed to find vsyscall getcpu\n");
+               return NULL;
+       }
+       return (void *) (0xffffffffff600800);
 #else
-# define VSYS(x) 0
+       return NULL;
 #endif
+}
 
-typedef long (*getcpu_t)(unsigned *, unsigned *, void *);
-
-const getcpu_t vgetcpu = (getcpu_t)VSYS(0xffffffffff600800);
-getcpu_t vdso_getcpu;
 
-void fill_function_pointers()
+static void fill_function_pointers()
 {
        void *vdso = dlopen("linux-vdso.so.1",
                            RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
@@ -54,6 +93,8 @@ void fill_function_pointers()
        vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
        if (!vdso_getcpu)
                printf("Warning: failed to find getcpu in vDSO\n");
+
+       vgetcpu = (getcpu_t) vsyscall_getcpu();
 }
 
 static long sys_getcpu(unsigned * cpu, unsigned * node,
index 7a744fa7b78655dfc9327e5f50d40dd1dd80476a..0b4f1cc2291c660df97a984065b4cdc3384e2c98 100644 (file)
@@ -33,6 +33,9 @@
 # endif
 #endif
 
+/* max length of lines in /proc/self/maps - anything longer is skipped here */
+#define MAPS_LINE_LEN 128
+
 static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
                       int flags)
 {
@@ -98,7 +101,7 @@ static int init_vsys(void)
 #ifdef __x86_64__
        int nerrs = 0;
        FILE *maps;
-       char line[128];
+       char line[MAPS_LINE_LEN];
        bool found = false;
 
        maps = fopen("/proc/self/maps", "r");
@@ -108,10 +111,12 @@ static int init_vsys(void)
                return 0;
        }
 
-       while (fgets(line, sizeof(line), maps)) {
+       while (fgets(line, MAPS_LINE_LEN, maps)) {
                char r, x;
                void *start, *end;
-               char name[128];
+               char name[MAPS_LINE_LEN];
+
+               /* sscanf() is safe here as strlen(name) >= strlen(line) */
                if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s",
                           &start, &end, &r, &x, name) != 5)
                        continue;
@@ -445,7 +450,7 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
                num_vsyscall_traps++;
 }
 
-static int test_native_vsyscall(void)
+static int test_emulation(void)
 {
        time_t tmp;
        bool is_native;
@@ -453,7 +458,7 @@ static int test_native_vsyscall(void)
        if (!vtime)
                return 0;
 
-       printf("[RUN]\tchecking for native vsyscall\n");
+       printf("[RUN]\tchecking that vsyscalls are emulated\n");
        sethandler(SIGTRAP, sigtrap, 0);
        set_eflags(get_eflags() | X86_EFLAGS_TF);
        vtime(&tmp);
@@ -469,11 +474,12 @@ static int test_native_vsyscall(void)
         */
        is_native = (num_vsyscall_traps > 1);
 
-       printf("\tvsyscalls are %s (%d instructions in vsyscall page)\n",
+       printf("[%s]\tvsyscalls are %s (%d instructions in vsyscall page)\n",
+              (is_native ? "FAIL" : "OK"),
               (is_native ? "native" : "emulated"),
               (int)num_vsyscall_traps);
 
-       return 0;
+       return is_native;
 }
 #endif
 
@@ -493,7 +499,7 @@ int main(int argc, char **argv)
        nerrs += test_vsys_r();
 
 #ifdef __x86_64__
-       nerrs += test_native_vsyscall();
+       nerrs += test_emulation();
 #endif
 
        return nerrs ? 1 : 0;
index 4e6506078494fbe160ea511b91dfcddd5768793b..01d758d73b6db1b442d85387871442cdf9c39017 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for USB tools
 
-CC = $(CROSS_COMPILE)gcc
 PTHREAD_LIBS = -lpthread
 WARNINGS = -Wall -Wextra
 CFLAGS = $(WARNINGS) -g -I../include
index be320b905ea75db150da97dfac999b0f7e90b47b..20f6cf04377f0c257aeb4bacb3133b6a35e9e9b6 100644 (file)
@@ -6,7 +6,6 @@ TARGETS=page-types slabinfo page_owner_sort
 LIB_DIR = ../lib/api
 LIBS = $(LIB_DIR)/libapi.a
 
-CC = $(CROSS_COMPILE)gcc
 CFLAGS = -Wall -Wextra -I../lib/
 LDFLAGS = $(LIBS)
 
index e664f1167388a99a76828981237e38049c6c193f..e0e87239126b5494e358ade6083658a2b7b9ad6a 100644 (file)
@@ -2,7 +2,6 @@ PREFIX ?= /usr
 SBINDIR ?= sbin
 INSTALL ?= install
 CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
-CC = $(CROSS_COMPILE)gcc
 
 TARGET = dell-smbios-example
 
index 70268c0bec799c0ce85c2f27267e0ab514c5f852..282389eb204f40f5857fe34f5f4ddb4e8c6e2200 100644 (file)
@@ -36,6 +36,8 @@ static struct timecounter *timecounter;
 static unsigned int host_vtimer_irq;
 static u32 host_vtimer_irq_flags;
 
+static DEFINE_STATIC_KEY_FALSE(has_gic_active_state);
+
 static const struct kvm_irq_level default_ptimer_irq = {
        .irq    = 30,
        .level  = 1,
@@ -56,6 +58,12 @@ u64 kvm_phys_timer_read(void)
        return timecounter->cc->read(timecounter->cc);
 }
 
+static inline bool userspace_irqchip(struct kvm *kvm)
+{
+       return static_branch_unlikely(&userspace_irqchip_in_use) &&
+               unlikely(!irqchip_in_kernel(kvm));
+}
+
 static void soft_timer_start(struct hrtimer *hrt, u64 ns)
 {
        hrtimer_start(hrt, ktime_add_ns(ktime_get(), ns),
@@ -69,25 +77,6 @@ static void soft_timer_cancel(struct hrtimer *hrt, struct work_struct *work)
                cancel_work_sync(work);
 }
 
-static void kvm_vtimer_update_mask_user(struct kvm_vcpu *vcpu)
-{
-       struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
-
-       /*
-        * When using a userspace irqchip with the architected timers, we must
-        * prevent continuously exiting from the guest, and therefore mask the
-        * physical interrupt by disabling it on the host interrupt controller
-        * when the virtual level is high, such that the guest can make
-        * forward progress.  Once we detect the output level being
-        * de-asserted, we unmask the interrupt again so that we exit from the
-        * guest when the timer fires.
-        */
-       if (vtimer->irq.level)
-               disable_percpu_irq(host_vtimer_irq);
-       else
-               enable_percpu_irq(host_vtimer_irq, 0);
-}
-
 static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
 {
        struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
@@ -106,9 +95,9 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
        if (kvm_timer_should_fire(vtimer))
                kvm_timer_update_irq(vcpu, true, vtimer);
 
-       if (static_branch_unlikely(&userspace_irqchip_in_use) &&
-           unlikely(!irqchip_in_kernel(vcpu->kvm)))
-               kvm_vtimer_update_mask_user(vcpu);
+       if (userspace_irqchip(vcpu->kvm) &&
+           !static_branch_unlikely(&has_gic_active_state))
+               disable_percpu_irq(host_vtimer_irq);
 
        return IRQ_HANDLED;
 }
@@ -290,8 +279,7 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
        trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_ctx->irq.irq,
                                   timer_ctx->irq.level);
 
-       if (!static_branch_unlikely(&userspace_irqchip_in_use) ||
-           likely(irqchip_in_kernel(vcpu->kvm))) {
+       if (!userspace_irqchip(vcpu->kvm)) {
                ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
                                          timer_ctx->irq.irq,
                                          timer_ctx->irq.level,
@@ -350,12 +338,6 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
        phys_timer_emulate(vcpu);
 }
 
-static void __timer_snapshot_state(struct arch_timer_context *timer)
-{
-       timer->cnt_ctl = read_sysreg_el0(cntv_ctl);
-       timer->cnt_cval = read_sysreg_el0(cntv_cval);
-}
-
 static void vtimer_save_state(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
@@ -367,8 +349,10 @@ static void vtimer_save_state(struct kvm_vcpu *vcpu)
        if (!vtimer->loaded)
                goto out;
 
-       if (timer->enabled)
-               __timer_snapshot_state(vtimer);
+       if (timer->enabled) {
+               vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
+               vtimer->cnt_cval = read_sysreg_el0(cntv_cval);
+       }
 
        /* Disable the virtual timer */
        write_sysreg_el0(0, cntv_ctl);
@@ -460,23 +444,43 @@ static void set_cntvoff(u64 cntvoff)
        kvm_call_hyp(__kvm_timer_set_cntvoff, low, high);
 }
 
-static void kvm_timer_vcpu_load_vgic(struct kvm_vcpu *vcpu)
+static inline void set_vtimer_irq_phys_active(struct kvm_vcpu *vcpu, bool active)
+{
+       int r;
+       r = irq_set_irqchip_state(host_vtimer_irq, IRQCHIP_STATE_ACTIVE, active);
+       WARN_ON(r);
+}
+
+static void kvm_timer_vcpu_load_gic(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
        bool phys_active;
-       int ret;
-
-       phys_active = kvm_vgic_map_is_active(vcpu, vtimer->irq.irq);
 
-       ret = irq_set_irqchip_state(host_vtimer_irq,
-                                   IRQCHIP_STATE_ACTIVE,
-                                   phys_active);
-       WARN_ON(ret);
+       if (irqchip_in_kernel(vcpu->kvm))
+               phys_active = kvm_vgic_map_is_active(vcpu, vtimer->irq.irq);
+       else
+               phys_active = vtimer->irq.level;
+       set_vtimer_irq_phys_active(vcpu, phys_active);
 }
 
-static void kvm_timer_vcpu_load_user(struct kvm_vcpu *vcpu)
+static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu)
 {
-       kvm_vtimer_update_mask_user(vcpu);
+       struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
+
+       /*
+        * When using a userspace irqchip with the architected timers and a
+        * host interrupt controller that doesn't support an active state, we
+        * must still prevent continuously exiting from the guest, and
+        * therefore mask the physical interrupt by disabling it on the host
+        * interrupt controller when the virtual level is high, such that the
+        * guest can make forward progress.  Once we detect the output level
+        * being de-asserted, we unmask the interrupt again so that we exit
+        * from the guest when the timer fires.
+        */
+       if (vtimer->irq.level)
+               disable_percpu_irq(host_vtimer_irq);
+       else
+               enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags);
 }
 
 void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
@@ -487,10 +491,10 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
        if (unlikely(!timer->enabled))
                return;
 
-       if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
-               kvm_timer_vcpu_load_user(vcpu);
+       if (static_branch_likely(&has_gic_active_state))
+               kvm_timer_vcpu_load_gic(vcpu);
        else
-               kvm_timer_vcpu_load_vgic(vcpu);
+               kvm_timer_vcpu_load_nogic(vcpu);
 
        set_cntvoff(vtimer->cntvoff);
 
@@ -555,22 +559,29 @@ static void unmask_vtimer_irq_user(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
 
-       if (unlikely(!irqchip_in_kernel(vcpu->kvm))) {
-               __timer_snapshot_state(vtimer);
-               if (!kvm_timer_should_fire(vtimer)) {
-                       kvm_timer_update_irq(vcpu, false, vtimer);
-                       kvm_vtimer_update_mask_user(vcpu);
-               }
+       if (!kvm_timer_should_fire(vtimer)) {
+               kvm_timer_update_irq(vcpu, false, vtimer);
+               if (static_branch_likely(&has_gic_active_state))
+                       set_vtimer_irq_phys_active(vcpu, false);
+               else
+                       enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags);
        }
 }
 
 void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
 {
-       unmask_vtimer_irq_user(vcpu);
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+
+       if (unlikely(!timer->enabled))
+               return;
+
+       if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
+               unmask_vtimer_irq_user(vcpu);
 }
 
 int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 {
+       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
        struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
        struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
 
@@ -584,6 +595,9 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
        ptimer->cnt_ctl = 0;
        kvm_timer_update_state(vcpu);
 
+       if (timer->enabled && irqchip_in_kernel(vcpu->kvm))
+               kvm_vgic_reset_mapped_irq(vcpu, vtimer->irq.irq);
+
        return 0;
 }
 
@@ -753,9 +767,11 @@ int kvm_timer_hyp_init(bool has_gic)
                        kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
                        goto out_free_irq;
                }
+
+               static_branch_enable(&has_gic_active_state);
        }
 
-       kvm_info("virtual timer IRQ%d\n", host_vtimer_irq);
+       kvm_debug("virtual timer IRQ%d\n", host_vtimer_irq);
 
        cpuhp_setup_state(CPUHP_AP_KVM_ARM_TIMER_STARTING,
                          "kvm/arm/timer:starting", kvm_timer_starting_cpu,
index 86941f6181bb0ee168918ce2436ed19c12dc4a07..53572304843b2e8e78d6010c6ba7d5003bb97ded 100644 (file)
@@ -384,14 +384,11 @@ static void vcpu_power_off(struct kvm_vcpu *vcpu)
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
                                    struct kvm_mp_state *mp_state)
 {
-       vcpu_load(vcpu);
-
        if (vcpu->arch.power_off)
                mp_state->mp_state = KVM_MP_STATE_STOPPED;
        else
                mp_state->mp_state = KVM_MP_STATE_RUNNABLE;
 
-       vcpu_put(vcpu);
        return 0;
 }
 
@@ -400,8 +397,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
 {
        int ret = 0;
 
-       vcpu_load(vcpu);
-
        switch (mp_state->mp_state) {
        case KVM_MP_STATE_RUNNABLE:
                vcpu->arch.power_off = false;
@@ -413,7 +408,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
                ret = -EINVAL;
        }
 
-       vcpu_put(vcpu);
        return ret;
 }
 
@@ -1036,8 +1030,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        struct kvm_device_attr attr;
        long r;
 
-       vcpu_load(vcpu);
-
        switch (ioctl) {
        case KVM_ARM_VCPU_INIT: {
                struct kvm_vcpu_init init;
@@ -1114,7 +1106,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                r = -EINVAL;
        }
 
-       vcpu_put(vcpu);
        return r;
 }
 
index f5c3d6d7019ea63a7d2376c68f6c392cd2036aaf..b89ce5432214358e594c536bedf371a1b986e5ae 100644 (file)
@@ -215,7 +215,8 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
         * are now visible to the system register interface.
         */
        if (!cpu_if->vgic_sre) {
-               dsb(st);
+               dsb(sy);
+               isb();
                cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
        }
 
index ec62d1cccab7c92dddb4eea86f2be22f7d4d0adc..b960acdd0c0518c1b0ccae81f847e6a0f4094f4d 100644 (file)
@@ -1810,9 +1810,9 @@ int kvm_mmu_init(void)
         */
        BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK);
 
-       kvm_info("IDMAP page: %lx\n", hyp_idmap_start);
-       kvm_info("HYP VA range: %lx:%lx\n",
-                kern_hyp_va(PAGE_OFFSET), kern_hyp_va(~0UL));
+       kvm_debug("IDMAP page: %lx\n", hyp_idmap_start);
+       kvm_debug("HYP VA range: %lx:%lx\n",
+                 kern_hyp_va(PAGE_OFFSET), kern_hyp_va(~0UL));
 
        if (hyp_idmap_start >= kern_hyp_va(PAGE_OFFSET) &&
            hyp_idmap_start <  kern_hyp_va(~0UL) &&
index 83d82bd7dc4e714f61669e6aaf9e937b67f5eea1..dbe99d635c80435ffd938999c4246ce6f45307c7 100644 (file)
@@ -113,9 +113,12 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
        /* Loop over all IRQs affected by this read */
        for (i = 0; i < len * 8; i++) {
                struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
+               unsigned long flags;
 
+               spin_lock_irqsave(&irq->irq_lock, flags);
                if (irq_is_pending(irq))
                        value |= (1U << i);
+               spin_unlock_irqrestore(&irq->irq_lock, flags);
 
                vgic_put_irq(vcpu->kvm, irq);
        }
index c32d7b93ffd194313f8cc062d2960d6a04a38d16..29556f71b691fb401baf31be47367b7c49c696fd 100644 (file)
@@ -37,6 +37,13 @@ void vgic_v2_init_lrs(void)
                vgic_v2_write_lr(i, 0);
 }
 
+void vgic_v2_set_npie(struct kvm_vcpu *vcpu)
+{
+       struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
+
+       cpuif->vgic_hcr |= GICH_HCR_NPIE;
+}
+
 void vgic_v2_set_underflow(struct kvm_vcpu *vcpu)
 {
        struct vgic_v2_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v2;
@@ -64,7 +71,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
        int lr;
        unsigned long flags;
 
-       cpuif->vgic_hcr &= ~GICH_HCR_UIE;
+       cpuif->vgic_hcr &= ~(GICH_HCR_UIE | GICH_HCR_NPIE);
 
        for (lr = 0; lr < vgic_cpu->used_lrs; lr++) {
                u32 val = cpuif->vgic_lr[lr];
@@ -410,7 +417,7 @@ int vgic_v2_probe(const struct gic_kvm_info *info)
        kvm_vgic_global_state.type = VGIC_V2;
        kvm_vgic_global_state.max_gic_vcpus = VGIC_V2_MAX_CPUS;
 
-       kvm_info("vgic-v2@%llx\n", info->vctrl.start);
+       kvm_debug("vgic-v2@%llx\n", info->vctrl.start);
 
        return 0;
 out:
index 6b329414e57a3c16207ab8e5ad81a0cc002b7f51..0ff2006f37817c0ee9fc8887fecb6ea6dd2f30ad 100644 (file)
@@ -26,6 +26,13 @@ static bool group1_trap;
 static bool common_trap;
 static bool gicv4_enable;
 
+void vgic_v3_set_npie(struct kvm_vcpu *vcpu)
+{
+       struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3;
+
+       cpuif->vgic_hcr |= ICH_HCR_NPIE;
+}
+
 void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
 {
        struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3;
@@ -47,7 +54,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
        int lr;
        unsigned long flags;
 
-       cpuif->vgic_hcr &= ~ICH_HCR_UIE;
+       cpuif->vgic_hcr &= ~(ICH_HCR_UIE | ICH_HCR_NPIE);
 
        for (lr = 0; lr < vgic_cpu->used_lrs; lr++) {
                u64 val = cpuif->vgic_lr[lr];
index c7c5ef190afa0c3984d5b9051f59ca72c696eb20..8201899126f6bf338247be84dc1b91cd390b608b 100644 (file)
@@ -495,6 +495,32 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
        return ret;
 }
 
+/**
+ * kvm_vgic_reset_mapped_irq - Reset a mapped IRQ
+ * @vcpu: The VCPU pointer
+ * @vintid: The INTID of the interrupt
+ *
+ * Reset the active and pending states of a mapped interrupt.  Kernel
+ * subsystems injecting mapped interrupts should reset their interrupt lines
+ * when we are doing a reset of the VM.
+ */
+void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid)
+{
+       struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
+       unsigned long flags;
+
+       if (!irq->hw)
+               goto out;
+
+       spin_lock_irqsave(&irq->irq_lock, flags);
+       irq->active = false;
+       irq->pending_latch = false;
+       irq->line_level = false;
+       spin_unlock_irqrestore(&irq->irq_lock, flags);
+out:
+       vgic_put_irq(vcpu->kvm, irq);
+}
+
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
 {
        struct vgic_irq *irq;
@@ -684,22 +710,37 @@ static inline void vgic_set_underflow(struct kvm_vcpu *vcpu)
                vgic_v3_set_underflow(vcpu);
 }
 
+static inline void vgic_set_npie(struct kvm_vcpu *vcpu)
+{
+       if (kvm_vgic_global_state.type == VGIC_V2)
+               vgic_v2_set_npie(vcpu);
+       else
+               vgic_v3_set_npie(vcpu);
+}
+
 /* Requires the ap_list_lock to be held. */
-static int compute_ap_list_depth(struct kvm_vcpu *vcpu)
+static int compute_ap_list_depth(struct kvm_vcpu *vcpu,
+                                bool *multi_sgi)
 {
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_irq *irq;
        int count = 0;
 
+       *multi_sgi = false;
+
        DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock));
 
        list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
                spin_lock(&irq->irq_lock);
                /* GICv2 SGIs can count for more than one... */
-               if (vgic_irq_is_sgi(irq->intid) && irq->source)
-                       count += hweight8(irq->source);
-               else
+               if (vgic_irq_is_sgi(irq->intid) && irq->source) {
+                       int w = hweight8(irq->source);
+
+                       count += w;
+                       *multi_sgi |= (w > 1);
+               } else {
                        count++;
+               }
                spin_unlock(&irq->irq_lock);
        }
        return count;
@@ -710,28 +751,43 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
 {
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_irq *irq;
-       int count = 0;
+       int count;
+       bool npie = false;
+       bool multi_sgi;
+       u8 prio = 0xff;
 
        DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock));
 
-       if (compute_ap_list_depth(vcpu) > kvm_vgic_global_state.nr_lr)
+       count = compute_ap_list_depth(vcpu, &multi_sgi);
+       if (count > kvm_vgic_global_state.nr_lr || multi_sgi)
                vgic_sort_ap_list(vcpu);
 
+       count = 0;
+
        list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
                spin_lock(&irq->irq_lock);
 
-               if (unlikely(vgic_target_oracle(irq) != vcpu))
-                       goto next;
-
                /*
-                * If we get an SGI with multiple sources, try to get
-                * them in all at once.
+                * If we have multi-SGIs in the pipeline, we need to
+                * guarantee that they are all seen before any IRQ of
+                * lower priority. In that case, we need to filter out
+                * these interrupts by exiting early. This is easy as
+                * the AP list has been sorted already.
                 */
-               do {
+               if (multi_sgi && irq->priority > prio) {
+                       spin_unlock(&irq->irq_lock);
+                       break;
+               }
+
+               if (likely(vgic_target_oracle(irq) == vcpu)) {
                        vgic_populate_lr(vcpu, irq, count++);
-               } while (irq->source && count < kvm_vgic_global_state.nr_lr);
 
-next:
+                       if (irq->source) {
+                               npie = true;
+                               prio = irq->priority;
+                       }
+               }
+
                spin_unlock(&irq->irq_lock);
 
                if (count == kvm_vgic_global_state.nr_lr) {
@@ -742,6 +798,9 @@ next:
                }
        }
 
+       if (npie)
+               vgic_set_npie(vcpu);
+
        vcpu->arch.vgic_cpu.used_lrs = count;
 
        /* Nuke remaining LRs */
index 12c37b89f7a38212c5eec4a115b9e2bb20d28fdc..f5b8519e55463d298e05888b3f2c5a71cf1ee7d6 100644 (file)
@@ -96,6 +96,7 @@
 /* we only support 64 kB translation table page size */
 #define KVM_ITS_L1E_ADDR_MASK          GENMASK_ULL(51, 16)
 
+/* Requires the irq_lock to be held by the caller. */
 static inline bool irq_is_pending(struct vgic_irq *irq)
 {
        if (irq->config == VGIC_CONFIG_EDGE)
@@ -159,6 +160,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu);
 void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
 void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr);
 void vgic_v2_set_underflow(struct kvm_vcpu *vcpu);
+void vgic_v2_set_npie(struct kvm_vcpu *vcpu);
 int vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr);
 int vgic_v2_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
                         int offset, u32 *val);
@@ -188,6 +190,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);
 void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
 void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr);
 void vgic_v3_set_underflow(struct kvm_vcpu *vcpu);
+void vgic_v3_set_npie(struct kvm_vcpu *vcpu);
 void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
 void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
 void vgic_v3_enable(struct kvm_vcpu *vcpu);
index 4501e658e8d6fc97f39b54bceff8f8b1f36cb95a..65dea3ffef68ede4ca8d8e5bb7d9c2d3edd3352a 100644 (file)
@@ -969,8 +969,7 @@ int __kvm_set_memory_region(struct kvm *kvm,
                /* Check for overlaps */
                r = -EEXIST;
                kvm_for_each_memslot(slot, __kvm_memslots(kvm, as_id)) {
-                       if ((slot->id >= KVM_USER_MEM_SLOTS) ||
-                           (slot->id == id))
+                       if (slot->id == id)
                                continue;
                        if (!((base_gfn + npages <= slot->base_gfn) ||
                              (base_gfn >= slot->base_gfn + slot->npages)))