Merge remote-tracking branch 'asoc/topic/wm0010' into asoc-next
authorMark Brown <broonie@linaro.org>
Mon, 17 Jun 2013 16:20:31 +0000 (17:20 +0100)
committerMark Brown <broonie@linaro.org>
Mon, 17 Jun 2013 16:20:31 +0000 (17:20 +0100)
836 files changed:
Documentation/bcache.txt
Documentation/devices.txt
Documentation/devicetree/bindings/mfd/arizona.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
Documentation/devicetree/bindings/sound/adi,adau1701.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/mxs-saif.txt
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/rt5640.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/sgtl5000.txt
Documentation/devicetree/bindings/sound/spdif-receiver.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/spdif-transmitter.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/ssm2518.txt [new file with mode: 0644]
Documentation/dmatest.txt
Documentation/filesystems/xfs.txt
Documentation/kernel-parameters.txt
Documentation/m68k/kernel-options.txt
Documentation/powerpc/transactional_memory.txt
MAINTAINERS
Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/debug.S
arch/arm/boot/compressed/head-sa1100.S
arch/arm/boot/compressed/head-shark.S
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/armada-xp-gp.dts
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx27.dtsi
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/omap4-panda-common.dtsi
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap5.dtsi
arch/arm/configs/exynos_defconfig
arch/arm/include/asm/percpu.h
arch/arm/include/asm/tlb.h
arch/arm/kernel/topology.c
arch/arm/kvm/arm.c
arch/arm/kvm/mmu.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/common.c
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/include/mach/pm-core.h
arch/arm/mach-exynos/mach-universal_c210.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-kirkwood/board-ts219.c
arch/arm/mach-kirkwood/mpp.c
arch/arm/mach-mvebu/coherency_ll.S
arch/arm/mach-omap2/clock36xx.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-prima2/pm.c
arch/arm/mach-prima2/rstc.c
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-ux500/board-mop500-regulators.c
arch/arm/mach-ux500/cpuidle.c
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/include/plat/uncompress.h
arch/arm/plat-samsung/pm.c
arch/arm64/kernel/arm64ksyms.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/traps.c
arch/arm64/mm/fault.c
arch/blackfin/mach-bf527/boards/ad7160eval.c
arch/blackfin/mach-bf527/boards/ezkit.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf609/boards/ezkit.c
arch/ia64/include/asm/tlb.h
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/include/asm/Kbuild
arch/m68k/include/asm/futex.h [new file with mode: 0644]
arch/m68k/include/asm/gpio.h
arch/m68k/kernel/head.S
arch/microblaze/include/asm/cacheflush.h
arch/microblaze/include/asm/futex.h
arch/microblaze/include/asm/io.h
arch/microblaze/include/asm/uaccess.h
arch/microblaze/kernel/cpu/cache.c
arch/mips/cavium-octeon/setup.c
arch/mips/include/asm/kvm_host.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/ptrace.h
arch/mips/include/uapi/asm/kvm.h
arch/mips/include/uapi/asm/ptrace.h
arch/mips/kernel/binfmt_elfn32.c
arch/mips/kernel/binfmt_elfo32.c
arch/mips/kernel/ftrace.c
arch/mips/kernel/idle.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/traps.c
arch/mips/kvm/kvm_mips.c
arch/mips/kvm/kvm_trap_emul.c
arch/mips/mm/tlbex.c
arch/mips/ralink/of.c
arch/mn10300/include/asm/pci.h
arch/mn10300/kernel/entry.S
arch/mn10300/unit-asb2305/pci.c
arch/parisc/Makefile
arch/parisc/include/asm/mmzone.h
arch/parisc/kernel/drivers.c
arch/parisc/kernel/setup.c
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/include/asm/hvcall.h
arch/powerpc/include/asm/kvm_asm.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/signal.h
arch/powerpc/include/asm/tm.h
arch/powerpc/include/uapi/asm/Kbuild
arch/powerpc/include/uapi/asm/tm.h [new file with mode: 0644]
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/signal.c
arch/powerpc/kernel/signal.h
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/traps.c
arch/powerpc/kvm/44x_tlb.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_pr_papr.c
arch/powerpc/kvm/book3s_xics.c
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/e500_mmu.c
arch/powerpc/kvm/e500mc.c
arch/powerpc/lib/copypage_power7.S
arch/powerpc/lib/copyuser_power7.S
arch/powerpc/mm/hash_native_64.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/eeh_pseries.c
arch/powerpc/sysdev/mpic.c
arch/s390/appldata/appldata_base.c
arch/s390/include/asm/dma-mapping.h
arch/s390/include/asm/io.h
arch/s390/include/asm/pgtable.h
arch/s390/kernel/dumpstack.c
arch/s390/kernel/irq.c
arch/s390/kernel/sclp.S
arch/s390/kernel/smp.c
arch/s390/mm/pgtable.c
arch/s390/pci/pci.c
arch/sparc/kernel/prom_common.c
arch/x86/boot/compressed/eboot.c
arch/x86/crypto/crc32-pclmul_asm.S
arch/x86/crypto/sha256-avx-asm.S
arch/x86/crypto/sha256-ssse3-asm.S
arch/x86/include/asm/efi.h
arch/x86/include/asm/inst.h
arch/x86/include/uapi/asm/bootparam.h
arch/x86/kernel/head_64.S
arch/x86/kernel/i387.c
arch/x86/kernel/relocate_kernel_64.S
arch/x86/kvm/emulate.c
arch/x86/kvm/lapic.c
arch/x86/mm/init.c
arch/x86/pci/common.c
arch/x86/platform/efi/efi.c
arch/x86/tools/relocs.c
arch/x86/xen/smp.c
arch/x86/xen/smp.h
block/blk-core.c
crypto/Kconfig
drivers/acpi/apei/cper.c
drivers/acpi/apei/ghes.c
drivers/acpi/device_pm.c
drivers/acpi/scan.c
drivers/acpi/video.c
drivers/ata/acard-ahci.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ata_piix.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pdc_adma.c
drivers/ata/sata_promise.c
drivers/ata/sata_rcar.c
drivers/ata/sata_sil.c
drivers/ata/sata_sx4.c
drivers/ata/sata_via.c
drivers/base/regmap/regcache-rbtree.c
drivers/base/regmap/regcache.c
drivers/base/regmap/regmap-debugfs.c
drivers/block/cciss.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/nvme-core.c
drivers/block/nvme-scsi.c
drivers/block/pktcdvd.c
drivers/block/rbd.c
drivers/bluetooth/Kconfig
drivers/bluetooth/btmrvl_sdio.c
drivers/clk/clk-si5351.c
drivers/clk/clk-vt8500.c
drivers/clk/mxs/clk-imx28.c
drivers/clk/samsung/clk-exynos4.c
drivers/clk/ux500/clk-sysctrl.c
drivers/clk/ux500/u8500_clk.c
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/cpufreq_governor.c
drivers/crypto/caam/caamalg.c
drivers/crypto/sahara.c
drivers/dma/dmatest.c
drivers/dma/ste_dma40.c
drivers/firmware/efi/efivars.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/exynos/exynos_drm_fimc.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.c
drivers/gpu/drm/exynos/exynos_drm_ipp.c
drivers/gpu/drm/exynos/exynos_drm_rotator.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/gma500/cdv_intel_display.c
drivers/gpu/drm/gma500/framebuffer.c
drivers/gpu/drm/gma500/psb_intel_display.c
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/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c
drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/core/include/core/class.h
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/omapdrm/omap_drv.c
drivers/gpu/drm/qxl/Kconfig
drivers/gpu/drm/qxl/qxl_ioctl.c
drivers/gpu/drm/qxl/qxl_kms.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/shmobile/shmob_drm_crtc.c
drivers/gpu/drm/tilcdc/Kconfig
drivers/hid/hid-multitouch.c
drivers/hwmon/adm1021.c
drivers/iio/buffer_cb.c
drivers/iio/frequency/adf4350.c
drivers/iio/inkern.c
drivers/infiniband/hw/qib/qib_keys.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/infiniband/ulp/srpt/ib_srpt.h
drivers/input/mouse/synaptics.c
drivers/input/tablet/wacom_wac.c
drivers/irqchip/irq-mxs.c
drivers/irqchip/irq-versatile-fpga.c
drivers/irqchip/irq-vic.c
drivers/md/bcache/Kconfig
drivers/md/bcache/bcache.h
drivers/md/bcache/stats.c
drivers/md/bcache/super.c
drivers/md/bcache/writeback.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/pci/zoran/zoran.h
drivers/media/pci/zoran/zoran_driver.c
drivers/media/platform/omap/omap_vout.c
drivers/mfd/arizona-core.c
drivers/mfd/arizona-i2c.c
drivers/mfd/arizona-spi.c
drivers/mfd/arizona.h
drivers/mfd/wm5102-tables.c
drivers/mfd/wm5110-tables.c
drivers/misc/atmel-ssc.c
drivers/misc/mei/init.c
drivers/misc/mei/nfc.c
drivers/misc/mei/pci-me.c
drivers/misc/sgi-gru/grufile.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-pci.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/can/usb/esd_usb2.c
drivers/net/can/usb/kvaser_usb.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.c
drivers/net/can/usb/peak_usb/pcan_usb_pro.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h
drivers/net/ethernet/dec/tulip/interrupt.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/ti/davinci_mdio.c
drivers/net/ethernet/xilinx/xilinx_emaclite.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/macvlan.c
drivers/net/phy/phy.c
drivers/net/team/team.c
drivers/net/team/team_mode_random.c
drivers/net/team/team_mode_roundrobin.c
drivers/net/tun.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/qmi_wwan.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/Makefile
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/atmel.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/fweh.c
drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
drivers/net/wireless/brcm80211/brcmfmac/p2p.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
drivers/net/wireless/iwlegacy/common.h
drivers/net/wireless/iwlwifi/dvm/sta.c
drivers/net/wireless/mwifiex/debugfs.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/ti/wl12xx/scan.c
drivers/net/wireless/ti/wl12xx/wl12xx.h
drivers/net/wireless/ti/wl18xx/scan.c
drivers/net/xen-netback/netback.c
drivers/nfc/Kconfig
drivers/nfc/mei_phy.c
drivers/nfc/microread/mei.c
drivers/nfc/pn544/mei.c
drivers/of/base.c
drivers/parisc/lba_pci.c
drivers/parport/Kconfig
drivers/parport/parport_gsc.c
drivers/parport/parport_gsc.h
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/aer/aerdrv_errprint.c
drivers/pinctrl/pinconf.c
drivers/pinctrl/pinctrl-coh901.c
drivers/pinctrl/pinctrl-exynos.c
drivers/pinctrl/pinctrl-exynos.h
drivers/pinctrl/pinctrl-samsung.c
drivers/pinctrl/pinctrl-samsung.h
drivers/pinctrl/pinctrl-sunxi.c
drivers/pinctrl/sh-pfc/pfc-r8a7779.c
drivers/pinctrl/vt8500/pinctrl-wmt.c
drivers/platform/x86/hp-wmi.c
drivers/ptp/ptp_pch.c
drivers/regulator/core.c
drivers/regulator/dbx500-prcmu.c
drivers/regulator/palmas-regulator.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-tps6586x.c
drivers/rtc/rtc-twl.c
drivers/s390/block/dasd.c
drivers/s390/net/netiucv.c
drivers/scsi/qla2xxx/tcm_qla2xxx.c
drivers/scsi/scsi_proc.c
drivers/spi/spi-sh-hspi.c
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-xilinx.c
drivers/staging/android/alarm-dev.c
drivers/staging/dwc2/hcd.c
drivers/staging/imx-drm/ipuv3-crtc.c
drivers/staging/zcache/ramster.h
drivers/staging/zcache/ramster/debug.c
drivers/staging/zcache/ramster/ramster.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_erl2.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/target/iscsi/iscsi_target_parameters.h
drivers/target/iscsi/iscsi_target_util.c
drivers/target/iscsi/iscsi_target_util.h
drivers/target/target_core_file.c
drivers/target/target_core_transport.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/imx.c
drivers/tty/serial/samsung.c
drivers/usb/chipidea/core.c
drivers/usb/chipidea/udc.c
drivers/usb/core/devio.c
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_host.h
drivers/usb/serial/ark3116.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/cypress_m8.h
drivers/usb/serial/f81232.c
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/spcp8x5.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/serial/zte_ev.c
drivers/vfio/vfio.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/atmel_lcdfb.c
drivers/video/omap2/dss/core.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/ps3fb.c
drivers/xen/tmem.c
drivers/xen/xen-pciback/pci_stub.c
drivers/xen/xenbus/xenbus_client.c
drivers/xen/xenbus/xenbus_comms.h
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe.h
drivers/xen/xenbus/xenbus_probe_frontend.c
fs/aio.c
fs/befs/linuxvfs.c
fs/btrfs/disk-io.c
fs/btrfs/inode.c
fs/btrfs/relocation.c
fs/ceph/locks.c
fs/ceph/mds_client.c
fs/ceph/super.h
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifsfs.c
fs/cifs/connect.c
fs/cifs/dns_resolve.c
fs/ecryptfs/file.c
fs/efivarfs/file.c
fs/file_table.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/inode.c
fs/gfs2/bmap.c
fs/gfs2/dir.c
fs/gfs2/file.c
fs/gfs2/inode.c
fs/gfs2/lops.c
fs/gfs2/rgrp.c
fs/gfs2/super.c
fs/hpfs/dir.c
fs/hpfs/file.c
fs/jfs/jfs_logmgr.c
fs/jfs/super.c
fs/namei.c
fs/ncpfs/dir.c
fs/nfs/nfs4proc.c
fs/nfs/super.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/namei.c
fs/pnode.c
fs/proc/base.c
fs/proc/kmsg.c
fs/qnx6/dir.c
fs/reiserfs/dir.c
fs/reiserfs/inode.c
fs/reiserfs/xattr.c
fs/reiserfs/xattr_acl.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_acl.h
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_attr_leaf.h
fs/xfs/xfs_attr_remote.c
fs/xfs/xfs_attr_remote.h
fs/xfs/xfs_btree.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_dir2_format.h
fs/xfs/xfs_dir2_node.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_fs.h
fs/xfs/xfs_fsops.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_qm_syscalls.c
fs/xfs/xfs_quota.h
fs/xfs/xfs_super.c
fs/xfs/xfs_symlink.c
include/asm-generic/io.h
include/asm-generic/kvm_para.h
include/asm-generic/tlb.h
include/linux/aer.h
include/linux/cgroup.h
include/linux/cpu.h
include/linux/filter.h
include/linux/if_team.h
include/linux/list.h
include/linux/math64.h
include/linux/mfd/arizona/core.h
include/linux/mfd/arizona/pdata.h
include/linux/mfd/arizona/registers.h
include/linux/netfilter_ipv6.h
include/linux/platform_data/ssm2518.h [new file with mode: 0644]
include/linux/rculist.h
include/linux/rculist_nulls.h
include/linux/rcupdate.h
include/linux/scatterlist.h
include/linux/skbuff.h
include/linux/smp.h
include/linux/socket.h
include/linux/swapops.h
include/linux/syslog.h
include/linux/tracepoint.h
include/net/addrconf.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt.h
include/net/ip_tunnels.h
include/net/sch_generic.h
include/net/xfrm.h
include/sound/rt5640.h [new file with mode: 0644]
include/sound/soc-dapm.h
include/target/target_core_base.h
include/target/target_core_fabric.h
include/uapi/linux/kvm.h
include/video/omapdss.h
include/xen/xenbus.h
init/Kconfig
kernel/audit.c
kernel/audit_tree.c
kernel/cgroup.c
kernel/cpu.c
kernel/exit.c
kernel/irq/irqdomain.c
kernel/printk.c
kernel/range.c
kernel/rcutree.c
kernel/rcutree.h
kernel/softirq.c
kernel/sys.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/timekeeping.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_selftest.c
lib/mpi/mpicoder.c
mm/frontswap.c
mm/hugetlb.c
mm/memcontrol.c
mm/memory.c
mm/migrate.c
mm/page_alloc.c
mm/swap_state.c
mm/swapfile.c
net/9p/client.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/sysfs.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bluetooth/mgmt.c
net/bluetooth/smp.c
net/ceph/osd_client.c
net/compat.c
net/core/dev_addr_lists.c
net/core/filter.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_vti.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/netfilter.c
net/ipv6/proc.c
net/ipv6/udp_offload.c
net/key/af_key.c
net/l2tp/l2tp_ppp.c
net/mac80211/iface.c
net/mac80211/mlme.c
net/netfilter/core.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_sh.c
net/netfilter/nfnetlink_acct.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nfnetlink_queue_core.c
net/netfilter/xt_LOG.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_addrtype.c
net/netlink/af_netlink.c
net/nfc/Makefile
net/packet/af_packet.c
net/sched/act_police.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sched/sch_htb.c
net/sched/sch_tbf.c
net/sctp/outqueue.c
net/sctp/socket.c
net/socket.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/svcauth_unix.c
net/wireless/nl80211.c
net/wireless/sme.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
scripts/Makefile.lib
scripts/config
scripts/dtc/dtc-lexer.l
scripts/dtc/dtc-lexer.lex.c_shipped
scripts/dtc/dtc-parser.tab.c_shipped
scripts/dtc/dtc-parser.tab.h_shipped
scripts/kconfig/lxdialog/menubox.c
scripts/kconfig/mconf.c
scripts/kconfig/menu.c
security/selinux/xfrm.c
sound/core/pcm_native.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_via.c
sound/pci/sis7019.c
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/atmel/sam9g20_wm8731.c
sound/soc/blackfin/Kconfig
sound/soc/blackfin/Makefile
sound/soc/blackfin/bf5xx-ac97-pcm.c
sound/soc/blackfin/bf5xx-ac97-pcm.h [deleted file]
sound/soc/blackfin/bf5xx-ac97.c
sound/soc/blackfin/bf5xx-ad1836.c
sound/soc/blackfin/bf5xx-ad193x.c
sound/soc/blackfin/bf5xx-ad1980.c
sound/soc/blackfin/bf5xx-ad73311.c
sound/soc/blackfin/bf5xx-i2s-pcm.c
sound/soc/blackfin/bf5xx-i2s-pcm.h
sound/soc/blackfin/bf5xx-i2s.c
sound/soc/blackfin/bf5xx-sport.c
sound/soc/blackfin/bf5xx-sport.h
sound/soc/blackfin/bf5xx-ssm2602.c
sound/soc/blackfin/bf5xx-tdm-pcm.c [deleted file]
sound/soc/blackfin/bf5xx-tdm-pcm.h [deleted file]
sound/soc/blackfin/bf5xx-tdm.c [deleted file]
sound/soc/blackfin/bf5xx-tdm.h [deleted file]
sound/soc/cirrus/Kconfig
sound/soc/cirrus/ep93xx-ac97.c
sound/soc/cirrus/ep93xx-i2s.c
sound/soc/cirrus/ep93xx-pcm.c
sound/soc/codecs/88pm860x-codec.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ab8500-codec.c
sound/soc/codecs/ab8500-codec.h
sound/soc/codecs/adau1701.c
sound/soc/codecs/arizona.c
sound/soc/codecs/arizona.h
sound/soc/codecs/bt-sco.c [moved from sound/soc/codecs/dfbmcs320.c with 53% similarity]
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l52.h
sound/soc/codecs/hdmi.c [moved from sound/soc/codecs/omap-hdmi.c with 69% similarity]
sound/soc/codecs/jz4740.c
sound/soc/codecs/max98090.c
sound/soc/codecs/rt5640.c [new file with mode: 0644]
sound/soc/codecs/rt5640.h [new file with mode: 0644]
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/sn95031.c
sound/soc/codecs/spdif_receiver.c
sound/soc/codecs/spdif_transmitter.c [moved from sound/soc/codecs/spdif_transciever.c with 88% similarity]
sound/soc/codecs/ssm2518.c [new file with mode: 0644]
sound/soc/codecs/ssm2518.h [new file with mode: 0644]
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm_adsp.c
sound/soc/codecs/wm_adsp.h
sound/soc/davinci/Kconfig
sound/soc/davinci/Makefile
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-sffsdr.c [deleted file]
sound/soc/dwc/designware_i2s.c
sound/soc/fsl/Kconfig
sound/soc/fsl/Makefile
sound/soc/fsl/eukrea-tlv320.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/imx-audmux.c
sound/soc/fsl/imx-mc13783.c
sound/soc/fsl/imx-pcm-dma.c
sound/soc/fsl/imx-pcm-fiq.c
sound/soc/fsl/imx-pcm.c [deleted file]
sound/soc/fsl/imx-pcm.h
sound/soc/fsl/imx-sgtl5000.c
sound/soc/fsl/imx-ssi.c
sound/soc/fsl/imx-ssi.h
sound/soc/fsl/imx-wm8962.c [new file with mode: 0644]
sound/soc/fsl/mx27vis-aic32x4.c
sound/soc/fsl/phycore-ac97.c
sound/soc/fsl/wm1133-ev1.c
sound/soc/jz4740/jz4740-i2s.c
sound/soc/kirkwood/kirkwood-dma.c
sound/soc/mxs/mxs-pcm.c
sound/soc/mxs/mxs-pcm.h
sound/soc/mxs/mxs-saif.c
sound/soc/mxs/mxs-saif.h
sound/soc/mxs/mxs-sgtl5000.c
sound/soc/omap/Makefile
sound/soc/omap/omap-hdmi-card.c
sound/soc/omap/omap-mcbsp.c
sound/soc/pxa/Kconfig
sound/soc/pxa/Makefile
sound/soc/pxa/mmp-pcm.c
sound/soc/pxa/mmp-sspa.c
sound/soc/pxa/saarb.c [deleted file]
sound/soc/pxa/tavorevb3.c [deleted file]
sound/soc/pxa/zylonite.c
sound/soc/samsung/Kconfig
sound/soc/samsung/bells.c
sound/soc/samsung/neo1973_wm8753.c
sound/soc/samsung/smdk_wm8580pcm.c
sound/soc/samsung/smdk_wm8994pcm.c
sound/soc/sh/fsi.c
sound/soc/soc-compress.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-pcm.c
sound/soc/soc-utils.c
sound/soc/spear/Kconfig [new file with mode: 0644]
sound/soc/spear/Makefile [new file with mode: 0644]
sound/soc/spear/spdif_in.c
sound/soc/spear/spdif_out.c
sound/soc/spear/spear_pcm.c
sound/soc/tegra/Kconfig
sound/soc/tegra/Makefile
sound/soc/tegra/tegra30_ahub.c
sound/soc/tegra/tegra30_i2s.c
sound/soc/tegra/tegra_asoc_utils.c
sound/soc/tegra/tegra_rt5640.c [new file with mode: 0644]
sound/soc/ux500/mop500.c
sound/soc/ux500/mop500_ab8500.c
sound/soc/ux500/ux500_msp_dai.c
sound/soc/ux500/ux500_msp_dai.h
sound/soc/ux500/ux500_msp_i2s.c
sound/soc/ux500/ux500_msp_i2s.h
sound/soc/ux500/ux500_pcm.c
sound/usb/6fire/firmware.c
sound/usb/mixer.c
sound/usb/quirks-table.h
tools/power/x86/turbostat/turbostat.c

index 77db880..b3a7e7d 100644 (file)
@@ -319,7 +319,10 @@ cache<0..n>
   Symlink to each of the cache devices comprising this cache set. 
 
 cache_available_percent
-  Percentage of cache device free.
+  Percentage of cache device which doesn't contain dirty data, and could
+  potentially be used for writeback.  This doesn't mean this space isn't used
+  for clean cached data; the unused statistic (in priority_stats) is typically
+  much lower.
 
 clear_stats
   Clears the statistics associated with this cache
@@ -423,8 +426,11 @@ nbuckets
   Total buckets in this cache
 
 priority_stats
-  Statistics about how recently data in the cache has been accessed.  This can
-  reveal your working set size.
+  Statistics about how recently data in the cache has been accessed.
+  This can reveal your working set size.  Unused is the percentage of
+  the cache that doesn't contain any data.  Metadata is bcache's
+  metadata overhead.  Average is the average priority of cache buckets.
+  Next is a list of quantiles with the priority threshold of each.
 
 written
   Sum of all data that has been written to the cache; comparison with
index 08f01e7..b901591 100644 (file)
@@ -498,12 +498,8 @@ Your cooperation is appreciated.
 
                Each device type has 5 bits (32 minors).
 
- 13 block      8-bit MFM/RLL/IDE controller
-                 0 = /dev/xda          First XT disk whole disk
-                64 = /dev/xdb          Second XT disk whole disk
-
-               Partitions are handled in the same way as IDE disks
-               (see major number 3).
+ 13 block      Previously used for the XT disk (/dev/xdN)
+               Deleted in kernel v3.9.
 
  14 char       Open Sound System (OSS)
                  0 = /dev/mixer        Mixer control
diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt
new file mode 100644 (file)
index 0000000..0e295c9
--- /dev/null
@@ -0,0 +1,62 @@
+Wolfson Arizona class audio SoCs
+
+These devices are audio SoCs with extensive digital capabilites and a range
+of analogue I/O.
+
+Required properties:
+
+  - compatible : one of the following chip-specific strings:
+       "wlf,wm5102"
+       "wlf,wm5110"
+  - reg : I2C slave address when connected using I2C, chip select number when
+    using SPI.
+
+  - interrupts : The interrupt line the /IRQ signal for the device is
+    connected to.
+  - interrupt-controller : Arizona class devices contain interrupt controllers
+    and may provide interrupt services to other devices.
+  - interrupt-parent : The parent interrupt controller.
+  - #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
+    The first cell is the IRQ number.
+    The second cell is the flags, encoded as the trigger masks from
+    Documentation/devicetree/bindings/interrupts.txt
+
+  - gpio-controller : Indicates this device is a GPIO controller.
+  - #gpio-cells : Must be 2. The first cell is the pin number and the
+    second cell is used to specify optional parameters (currently unused).
+
+  - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
+    SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
+    in Documentation/devicetree/bindings/regulator/regulator.txt
+
+Optional properties:
+
+  - wlf,reset : GPIO specifier for the GPIO controlling /RESET
+  - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
+
+  - wlf,gpio-defaults : A list of GPIO configuration register values. If
+    absent, no configuration of these registers is performed. If any
+    entry has a value that is out of range for a 16 bit register then
+    the chip default will be used.  If present exactly five values must
+    be specified.
+
+Example:
+
+codec: wm5102@1a {
+       compatible = "wlf,wm5102";
+       reg = <0x1a>;
+       interrupts = <347>;
+       #interrupt-cells = <2>;
+        interrupt-parent = <&gic>;
+
+       gpio-controller;
+       #gpio-cells = <2>;
+
+       wlf,gpio-defaults = <
+               0x00000000, /* AIF1TXLRCLK */
+               0xffffffff,
+               0xffffffff,
+               0xffffffff,
+               0xffffffff,
+       >;
+};
index 2a3feab..34c1505 100644 (file)
@@ -1,7 +1,7 @@
 Atmel AT91RM9200 Real Time Clock
 
 Required properties:
-- compatible: should be: "atmel,at91rm9200-rtc"
+- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
 - reg: physical base address of the controller and length of memory mapped
   region.
 - interrupts: rtc alarm/event interrupt
diff --git a/Documentation/devicetree/bindings/sound/adi,adau1701.txt b/Documentation/devicetree/bindings/sound/adi,adau1701.txt
new file mode 100644 (file)
index 0000000..3afeda7
--- /dev/null
@@ -0,0 +1,23 @@
+Analog Devices ADAU1701
+
+Required properties:
+
+ - compatible:         Should contain "adi,adau1701"
+ - reg:                        The i2c address. Value depends on the state of ADDR0
+                       and ADDR1, as wired in hardware.
+
+Optional properties:
+
+ - reset-gpio:                 A GPIO spec to define which pin is connected to the
+                       chip's !RESET pin. If specified, the driver will
+                       assert a hardware reset at probe time.
+
+Examples:
+
+       i2c_bus {
+               adau1701@34 {
+                       compatible = "adi,adau1701";
+                       reg = <0x34>;
+                       reset-gpio = <&gpio 23 0>;
+               };
+       };
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt b/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
new file mode 100644 (file)
index 0000000..f49450a
--- /dev/null
@@ -0,0 +1,46 @@
+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 c37ba61..7ba07a1 100644 (file)
@@ -3,8 +3,11 @@
 Required properties:
 - compatible: Should be "fsl,<chip>-saif"
 - reg: Should contain registers location and length
-- interrupts: Should contain ERROR and DMA interrupts
-- fsl,saif-dma-channel: APBX DMA channel for the SAIF
+- interrupts: Should contain ERROR interrupt number
+- dmas: DMA specifier, consisting of a phandle to DMA controller node
+  and SAIF DMA channel ID.
+  Refer to dma.txt and fsl-mxs-dma.txt for details.
+- dma-names: Must be "rx-tx".
 
 Optional properties:
 - fsl,saif-master: phandle to the master SAIF.  It's only required for
@@ -23,14 +26,16 @@ aliases {
 saif0: saif@80042000 {
        compatible = "fsl,imx28-saif";
        reg = <0x80042000 2000>;
-       interrupts = <59 80>;
-       fsl,saif-dma-channel = <4>;
+       interrupts = <59>;
+       dmas = <&dma_apbx 4>;
+       dma-names = "rx-tx";
 };
 
 saif1: saif@80046000 {
        compatible = "fsl,imx28-saif";
        reg = <0x80046000 2000>;
-       interrupts = <58 81>;
-       fsl,saif-dma-channel = <5>;
+       interrupts = <58>;
+       dmas = <&dma_apbx 5>;
+       dma-names = "rx-tx";
        fsl,saif-master = <&saif0>;
 };
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt
new file mode 100644 (file)
index 0000000..d130818
--- /dev/null
@@ -0,0 +1,71 @@
+NVIDIA Tegra audio complex, with RT5640 CODEC
+
+Required properties:
+- compatible : "nvidia,tegra-audio-rt5640"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
+- nvidia,model : The user-visible name of this sound complex.
+- nvidia,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 for sources and
+  sinks are the RT5640's pins, and the jacks on the board:
+
+  RT5640 pins:
+
+  * DMIC1
+  * DMIC2
+  * MICBIAS1
+  * IN1P
+  * IN1R
+  * IN2P
+  * IN2R
+  * HPOL
+  * HPOR
+  * LOUTL
+  * LOUTR
+  * MONOP
+  * MONON
+  * SPOLP
+  * SPOLN
+  * SPORP
+  * SPORN
+
+  Board connectors:
+
+  * Headphones
+  * Speakers
+
+- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
+  connected to the CODEC.
+- nvidia,audio-codec : The phandle of the RT5640 audio codec. This binding
+  assumes that AIF1 on the CODEC is connected to Tegra.
+
+Optional properties:
+- nvidia,hp-det-gpios : The GPIO that detects headphones are plugged in
+
+Example:
+
+sound {
+       compatible = "nvidia,tegra-audio-rt5640-dalmore",
+                       "nvidia,tegra-audio-rt5640";
+       nvidia,model = "NVIDIA Tegra Dalmore";
+
+       nvidia,audio-routing =
+               "Headphones", "HPOR",
+               "Headphones", "HPOL",
+               "Speakers", "SPORP",
+               "Speakers", "SPORN",
+               "Speakers", "SPOLP",
+               "Speakers", "SPOLN";
+
+       nvidia,i2s-controller = <&tegra_i2s1>;
+       nvidia,audio-codec = <&rt5640>;
+
+       nvidia,hp-det-gpios = <&gpio 143 0>; /* GPIO PR7 */
+
+       clocks = <&tegra_car 216>, <&tegra_car 217>, <&tegra_car 120>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
+};
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
new file mode 100644 (file)
index 0000000..005bcb2
--- /dev/null
@@ -0,0 +1,30 @@
+RT5640 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "realtek,rt5640".
+
+- reg : The I2C address of the device.
+
+- interrupts : The CODEC's interrupt output.
+
+Optional properties:
+
+- realtek,in1-differential
+- realtek,in2-differential
+  Boolean. Indicate MIC1/2 input are differential, rather than single-ended.
+
+- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
+
+Example:
+
+rt5640 {
+       compatible = "realtek,rt5640";
+       reg = <0x1c>;
+       interrupt-parent = <&gpio>;
+       interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+       realtek,ldo1-en-gpios =
+               <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+};
index 9cc4444..955df60 100644 (file)
@@ -5,9 +5,12 @@ Required properties:
 
 - reg : the I2C address of the device
 
+- clocks : the clock provider of SYS_MCLK
+
 Example:
 
 codec: sgtl5000@0a {
        compatible = "fsl,sgtl5000";
        reg = <0x0a>;
+       clocks = <&clks 150>;
 };
diff --git a/Documentation/devicetree/bindings/sound/spdif-receiver.txt b/Documentation/devicetree/bindings/sound/spdif-receiver.txt
new file mode 100644 (file)
index 0000000..80f807b
--- /dev/null
@@ -0,0 +1,10 @@
+Device-Tree bindings for dummy spdif receiver
+
+Required properties:
+       - compatible: should be "linux,spdif-dir".
+
+Example node:
+
+       codec: spdif-receiver {
+               compatible = "linux,spdif-dir";
+       };
diff --git a/Documentation/devicetree/bindings/sound/spdif-transmitter.txt b/Documentation/devicetree/bindings/sound/spdif-transmitter.txt
new file mode 100644 (file)
index 0000000..55a8584
--- /dev/null
@@ -0,0 +1,10 @@
+Device-Tree bindings for dummy spdif transmitter
+
+Required properties:
+       - compatible: should be "linux,spdif-dit".
+
+Example node:
+
+       codec: spdif-transmitter {
+               compatible = "linux,spdif-dit";
+       };
diff --git a/Documentation/devicetree/bindings/sound/ssm2518.txt b/Documentation/devicetree/bindings/sound/ssm2518.txt
new file mode 100644 (file)
index 0000000..59381a7
--- /dev/null
@@ -0,0 +1,20 @@
+SSM2518 audio amplifier
+
+This device supports I2C only.
+
+Required properties:
+  - compatible : Must be "adi,ssm2518"
+  - reg : the I2C address of the device. This will either be 0x34 (ADDR pin low)
+       or 0x35 (ADDR pin high)
+
+Optional properties:
+  - gpios : GPIO connected to the nSD pin. If the property is not present it is
+               assumed that the nSD pin is hardwired to always on.
+
+Example:
+
+       ssm2518: ssm2518@34 {
+               compatible = "adi,ssm2518";
+               reg = <0x34>;
+               gpios = <&gpio 5 0>;
+       };
index 279ac0a..132a094 100644 (file)
@@ -34,7 +34,7 @@ command:
 After a while you will start to get messages about current status or error like
 in the original code.
 
-Note that running a new test will stop any in progress test.
+Note that running a new test will not stop any in progress test.
 
 The following command should return actual state of the test.
        % cat /sys/kernel/debug/dmatest/run
@@ -52,8 +52,8 @@ To wait for test done the user may perform a busy loop that checks the state.
 
 The module parameters that is supplied to the kernel command line will be used
 for the first performed test. After user gets a control, the test could be
-interrupted or re-run with same or different parameters. For the details see
-the above section "Part 2 - When dmatest is built as a module..."
+re-run with the same or different parameters. For the details see the above
+section "Part 2 - When dmatest is built as a module..."
 
 In both cases the module parameters are used as initial values for the test case.
 You always could check them at run-time by running
index 3e4b3dd..83577f0 100644 (file)
@@ -33,6 +33,9 @@ When mounting an XFS filesystem, the following options are accepted.
        removing extended attributes) the on-disk superblock feature
        bit field will be updated to reflect this format being in use.
 
+       CRC enabled filesystems always use the attr2 format, and so
+       will reject the noattr2 mount option if it is set.
+
   barrier
        Enables the use of block layer write barriers for writes into
        the journal and unwritten extent conversion.  This allows for
index 6e3b18a..2fe6e76 100644 (file)
@@ -3351,9 +3351,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        plus one apbt timer for broadcast timer.
                        x86_mrst_timer=apbt_only | lapic_and_apbt
 
-       xd=             [HW,XT] Original XT pre-IDE (RLL encoded) disks.
-       xd_geo=         See header of drivers/block/xd.c.
-
        xen_emul_unplug=                [HW,X86,XEN]
                        Unplug Xen emulated devices
                        Format: [unplug0,][unplug1]
index 97d45f2..eaf32a1 100644 (file)
@@ -80,8 +80,6 @@ Valid names are:
   /dev/sdd: -> 0x0830 (forth SCSI disk)
   /dev/sde: -> 0x0840 (fifth SCSI disk)
   /dev/fd : -> 0x0200 (floppy disk)
-  /dev/xda: -> 0x0c00 (first XT disk, unused in Linux/m68k)
-  /dev/xdb: -> 0x0c40 (second XT disk, unused in Linux/m68k)
 
   The name must be followed by a decimal number, that stands for the
 partition number. Internally, the value of the number is just
index c907be4..dc23e58 100644 (file)
@@ -147,6 +147,25 @@ Example signal handler:
       fix_the_problem(ucp->dar);
     }
 
+When in an active transaction that takes a signal, we need to be careful with
+the stack.  It's possible that the stack has moved back up after the tbegin.
+The obvious case here is when the tbegin is called inside a function that
+returns before a tend.  In this case, the stack is part of the checkpointed
+transactional memory state.  If we write over this non transactionally or in
+suspend, we are in trouble because if we get a tm abort, the program counter and
+stack pointer will be back at the tbegin but our in memory stack won't be valid
+anymore.
+
+To avoid this, when taking a signal in an active transaction, we need to use
+the stack pointer from the checkpointed state, rather than the speculated
+state.  This ensures that the signal context (written tm suspended) will be
+written below the stack required for the rollback.  The transaction is aborted
+becuase of the treclaim, so any memory written between the tbegin and the
+signal will be rolled back anyway.
+
+For signals taken in non-TM or suspended mode, we use the
+normal/non-checkpointed stack pointer.
+
 
 Failure cause codes used by kernel
 ==================================
@@ -155,14 +174,18 @@ These are defined in <asm/reg.h>, and distinguish different reasons why the
 kernel aborted a transaction:
 
  TM_CAUSE_RESCHED       Thread was rescheduled.
+ TM_CAUSE_TLBI          Software TLB invalide.
  TM_CAUSE_FAC_UNAV      FP/VEC/VSX unavailable trap.
  TM_CAUSE_SYSCALL       Currently unused; future syscalls that must abort
                         transactions for consistency will use this.
  TM_CAUSE_SIGNAL        Signal delivered.
  TM_CAUSE_MISC          Currently unused.
+ TM_CAUSE_ALIGNMENT     Alignment fault.
+ TM_CAUSE_EMULATE       Emulation that touched memory.
 
-These can be checked by the user program's abort handler as TEXASR[0:7].
-
+These can be checked by the user program's abort handler as TEXASR[0:7].  If
+bit 7 is set, it indicates that the error is consider persistent.  For example
+a TM_CAUSE_ALIGNMENT will be persistent while a TM_CAUSE_RESCHED will not.q
 
 GDB
 ===
index fd3a495..5be702c 100644 (file)
@@ -2890,8 +2890,8 @@ F:        drivers/media/dvb-frontends/ec100*
 
 ECRYPT FILE SYSTEM
 M:     Tyler Hicks <tyhicks@canonical.com>
-M:     Dustin Kirkland <dustin.kirkland@gazzang.com>
 L:     ecryptfs@vger.kernel.org
+W:     http://ecryptfs.org
 W:     https://launchpad.net/ecryptfs
 S:     Supported
 F:     Documentation/filesystems/ecryptfs.txt
@@ -3322,11 +3322,12 @@ F:      drivers/net/wan/dlci.c
 F:     drivers/net/wan/sdla.c
 
 FRAMEBUFFER LAYER
-M:     Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+M:     Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
+M:     Tomi Valkeinen <tomi.valkeinen@ti.com>
 L:     linux-fbdev@vger.kernel.org
 W:     http://linux-fbdev.sourceforge.net/
 Q:     http://patchwork.kernel.org/project/linux-fbdev/list/
-T:     git git://github.com/schandinat/linux-2.6.git fbdev-next
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/plagnioj/linux-fbdev.git
 S:     Maintained
 F:     Documentation/fb/
 F:     Documentation/devicetree/bindings/fb/
@@ -4447,6 +4448,16 @@ S:       Maintained
 F:     drivers/scsi/*iscsi*
 F:     include/scsi/*iscsi*
 
+ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR
+M:     Or Gerlitz <ogerlitz@mellanox.com>
+M:     Roi Dayan <roid@mellanox.com>
+L:     linux-rdma@vger.kernel.org
+S:     Supported
+W:     http://www.openfabrics.org
+W:     www.open-iscsi.org
+Q:     http://patchwork.kernel.org/project/linux-rdma/list/
+F:     drivers/infiniband/ulp/iser
+
 ISDN SUBSYSTEM
 M:     Karsten Keil <isdn@linux-pingi.de>
 L:     isdn4linux@listserv.isdn4linux.de (subscribers-only)
@@ -5755,7 +5766,7 @@ M:        Matthew Wilcox <willy@linux.intel.com>
 L:     linux-nvme@lists.infradead.org
 T:     git git://git.infradead.org/users/willy/linux-nvme.git
 S:     Supported
-F:     drivers/block/nvme.c
+F:     drivers/block/nvme*
 F:     include/linux/nvme.h
 
 OMAP SUPPORT
@@ -6087,7 +6098,15 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
 S:     Maintained
 F:     arch/parisc/
+F:     Documentation/parisc/
 F:     drivers/parisc/
+F:     drivers/char/agp/parisc-agp.c
+F:     drivers/input/serio/gscps2.c
+F:     drivers/parport/parport_gsc.*
+F:     drivers/tty/serial/8250/8250_gsc.c
+F:     drivers/video/sti*
+F:     drivers/video/console/sti*
+F:     drivers/video/logo/logo_parisc*
 
 PC87360 HARDWARE MONITORING DRIVER
 M:     Jim Cromie <jim.cromie@gmail.com>
@@ -7605,7 +7624,7 @@ F:        drivers/clk/spear/
 SPI SUBSYSTEM
 M:     Mark Brown <broonie@kernel.org>
 M:     Grant Likely <grant.likely@linaro.org>
-L:     spi-devel-general@lists.sourceforge.net
+L:     linux-spi@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git
 Q:     http://patchwork.kernel.org/project/spi-devel-general/list/
 S:     Maintained
@@ -8985,7 +9004,7 @@ S:        Maintained
 F:     drivers/net/wireless/wl3501*
 
 WM97XX TOUCHSCREEN DRIVERS
-M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
+M:     Mark Brown <broonie@kernel.org>
 M:     Liam Girdwood <lrg@slimlogic.co.uk>
 L:     linux-input@vger.kernel.org
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-touch
@@ -8995,7 +9014,6 @@ F:        drivers/input/touchscreen/*wm97*
 F:     include/linux/wm97xx.h
 
 WOLFSON MICROELECTRONICS DRIVERS
-M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
 L:     patches@opensource.wolfsonmicro.com
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-asoc
 T:     git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
index 73e20db..c6863b5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 10
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc6
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index 3580d57..79e9bdb 100644 (file)
@@ -124,7 +124,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 
 ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all -DZIMAGE
+asflags-y := -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
index 6e8382d..5392ee6 100644 (file)
@@ -1,6 +1,8 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+#ifndef CONFIG_DEBUG_SEMIHOSTING
+
 #include CONFIG_DEBUG_LL_INCLUDE
 
 ENTRY(putc)
@@ -10,3 +12,29 @@ ENTRY(putc)
        busyuart r3, r1
        mov      pc, lr
 ENDPROC(putc)
+
+#else
+
+ENTRY(putc)
+       adr     r1, 1f
+       ldmia   r1, {r2, r3}
+       add     r2, r2, r1
+       ldr     r1, [r2, r3]
+       strb    r0, [r1]
+       mov     r0, #0x03               @ SYS_WRITEC
+   ARM(        svc     #0x123456       )
+ THUMB(        svc     #0xab           )
+       mov     pc, lr
+       .align  2
+1:     .word   _GLOBAL_OFFSET_TABLE_ - .
+       .word   semi_writec_buf(GOT)
+ENDPROC(putc)
+
+       .bss
+       .global semi_writec_buf
+       .type   semi_writec_buf, %object
+semi_writec_buf:
+       .space  4
+       .size   semi_writec_buf, 4
+
+#endif
index 6179d94..3115e31 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/mach-types.h>
 
                .section        ".start", "ax"
+               .arch   armv4
 
 __SA1100_start:
 
index 089c560..92b5689 100644 (file)
@@ -18,6 +18,7 @@
        
                .section        ".start", "ax"
 
+               .arch armv4
                b       __beginning
        
 __ofw_data:    .long   0                               @ the number of memory blocks
index fe4d9c3..032a8d9 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+       .arch   armv7-a
 /*
  * Debugging stuff
  *
@@ -805,8 +806,8 @@ call_cache_fn:      adr     r12, proc_types
                .align  2
                .type   proc_types,#object
 proc_types:
-               .word   0x00000000              @ old ARM ID
-               .word   0x0000f000
+               .word   0x41000000              @ old ARM ID
+               .word   0xff00f000
                mov     pc, lr
  THUMB(                nop                             )
                mov     pc, lr
index 1460d9b..8e1248f 100644 (file)
                        ti,hwmods = "gpmc";
                        reg = <0x50000000 0x2000>;
                        interrupts = <100>;
-                       num-cs = <7>;
-                       num-waitpins = <2>;
+                       gpmc,num-cs = <7>;
+                       gpmc,num-waitpins = <2>;
                        #address-cells = <2>;
                        #size-cells = <1>;
                        status = "disabled";
index 3ee63d1..76db557 100644 (file)
@@ -39,8 +39,9 @@
        };
 
        soc {
-               ranges = <0          0 0xd0000000 0x100000
-                         0xf0000000 0 0xf0000000 0x1000000>;
+               ranges = <0          0 0xd0000000 0x100000  /* Internal registers 1MiB */
+                         0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
+                         0xf0000000 0 0xf0000000 0x1000000 /* Device Bus, NOR 16MiB  */>;
 
                internal-regs {
                        serial@12000 {
index 46b7850..fdea75c 100644 (file)
@@ -27,8 +27,9 @@
        };
 
        soc {
-               ranges = <0          0 0xd0000000 0x100000
-                         0xf0000000 0 0xf0000000 0x8000000>;
+               ranges = <0          0 0xd0000000 0x100000      /* Internal registers 1MiB */
+                         0xe0000000 0 0xe0000000 0x8100000     /* PCIe */
+                         0xf0000000 0 0xf0000000 0x8000000     /* Device Bus, NOR 128MiB   */>;
 
                internal-regs {
                        serial@12000 {
index f0052dc..1e12aef 100644 (file)
@@ -44,6 +44,7 @@
                        reg = <0x7e201000 0x1000>;
                        interrupts = <2 25>;
                        clock-frequency = <3000000>;
+                       arm,primecell-periphid = <0x00241011>;
                };
 
                gpio: gpio {
index 98dfc3e..0673524 100644 (file)
                clock-names = "usbhost";
        };
 
+       usbphy@12130000 {
+               compatible = "samsung,exynos5250-usb2phy";
+               reg = <0x12130000 0x100>;
+               clocks = <&clock 1>, <&clock 285>;
+               clock-names = "ext_xtal", "usbhost";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               usbphy-sys {
+                       reg = <0x10040704 0x8>,
+                             <0x10050230 0x4>;
+               };
+       };
+
        amba {
                #address-cells = <1>;
                #size-cells = <1>;
index d2550e0..7011539 100644 (file)
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                reg = <0x43fa4000 0x4000>;
-                               clocks = <&clks 62>;
-                               clock-names = "ipg";
+                               clocks = <&clks 62>, <&clks 62>;
+                               clock-names = "ipg", "per";
                                interrupts = <14>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                reg = <0x50004000 0x4000>;
                                interrupts = <0>;
-                               clocks = <&clks 80>;
-                               clock-names = "ipg";
+                               clocks = <&clks 80>, <&clks 80>;
+                               clock-names = "ipg", "per";
                                status = "disabled";
                        };
 
                                #size-cells = <0>;
                                compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
                                reg = <0x50010000 0x4000>;
-                               clocks = <&clks 79>;
-                               clock-names = "ipg";
+                               clocks = <&clks 79>, <&clks 79>;
+                               clock-names = "ipg", "per";
                                interrupts = <13>;
                                status = "disabled";
                        };
index ff4bd48..75bd113 100644 (file)
                                compatible = "fsl,imx27-cspi";
                                reg = <0x1000e000 0x1000>;
                                interrupts = <16>;
-                               clocks = <&clks 53>, <&clks 0>;
+                               clocks = <&clks 53>, <&clks 53>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx27-cspi";
                                reg = <0x1000f000 0x1000>;
                                interrupts = <15>;
-                               clocks = <&clks 52>, <&clks 0>;
+                               clocks = <&clks 52>, <&clks 52>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
                                compatible = "fsl,imx27-cspi";
                                reg = <0x10017000 0x1000>;
                                interrupts = <6>;
-                               clocks = <&clks 51>, <&clks 0>;
+                               clocks = <&clks 51>, <&clks 51>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
index 21bb786..53fdde6 100644 (file)
                                compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
                                reg = <0x83fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 0>;
+                               clocks = <&clks 55>, <&clks 55>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
index 845982e..eb83aa0 100644 (file)
                                compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
                                reg = <0x63fc0000 0x4000>;
                                interrupts = <38>;
-                               clocks = <&clks 55>, <&clks 0>;
+                               clocks = <&clks 55>, <&clks 55>;
                                clock-names = "ipg", "per";
                                status = "disabled";
                        };
index 03bd60d..eeb734e 100644 (file)
        };
 };
 
+&omap4_pmx_wkup {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &twl6030_wkup_pins
+       >;
+
+       twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
+               pinctrl-single,pins = <
+                       0x14 0x2        /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */
+               >;
+       };
+};
+
 &omap4_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
+                       &twl6030_pins
                        &twl6040_pins
                        &mcpdm_pins
                        &mcbsp1_pins
                        &tpd12s015_pins
        >;
 
+       twl6030_pins: pinmux_twl6030_pins {
+               pinctrl-single,pins = <
+                       0x15e 0x4118    /* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */
+               >;
+       };
+
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
                        0xe0 0x3        /* hdq_sio.gpio_127 OUTPUT | MODE3 */
index a35d9cd..98505a2 100644 (file)
        };
 };
 
+&omap4_pmx_wkup {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &twl6030_wkup_pins
+       >;
+
+       twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
+               pinctrl-single,pins = <
+                       0x14 0x2        /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */
+               >;
+       };
+};
+
 &omap4_pmx_core {
        pinctrl-names = "default";
        pinctrl-0 = <
+                       &twl6030_pins
                        &twl6040_pins
                        &mcpdm_pins
                        &dmic_pins
                >;
        };
 
+       twl6030_pins: pinmux_twl6030_pins {
+               pinctrl-single,pins = <
+                       0x15e 0x4118    /* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */
+               >;
+       };
+
        twl6040_pins: pinmux_twl6040_pins {
                pinctrl-single,pins = <
                        0xe0 0x3        /* hdq_sio.gpio_127 OUTPUT | MODE3 */
index 3dd7ff8..635cae2 100644 (file)
                        interrupts = <0 41 0x4>;
                        ti,hwmods = "timer5";
                        ti,timer-dsp;
+                       ti,timer-pwm;
                };
 
                timer6: timer@4013a000 {
                        reg = <0x4803e000 0x80>;
                        interrupts = <0 45 0x4>;
                        ti,hwmods = "timer9";
+                       ti,timer-pwm;
                };
 
                timer10: timer@48086000 {
                        reg = <0x48086000 0x80>;
                        interrupts = <0 46 0x4>;
                        ti,hwmods = "timer10";
+                       ti,timer-pwm;
                };
 
                timer11: timer@48088000 {
index e40b435..227abf9 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BLK_DEV_INITRD=y
@@ -7,17 +7,18 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
 CONFIG_ARCH_EXYNOS=y
-CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_LOWLEVEL_UART_PORT=3
 CONFIG_S3C24XX_PWM=y
 CONFIG_ARCH_EXYNOS5=y
 CONFIG_MACH_EXYNOS4_DT=y
-CONFIG_MACH_EXYNOS5_DT=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
@@ -30,35 +31,58 @@ CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_RFKILL_REGULATOR=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
 CONFIG_NETDEVICES=y
 CONFIG_SMSC911X=y
 CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC75XX=y
 CONFIG_USB_NET_SMSC95XX=y
 CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
+CONFIG_KEYBOARD_CROS_EC=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_CYAPA=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_SAMSUNG=y
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_HW_RANDOM=y
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS_I2C_INFINEON=y
 CONFIG_I2C=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_ARB_GPIO_CHALLENGE=y
+CONFIG_I2C_S3C2410=y
+CONFIG_DEBUG_GPIO=y
 # CONFIG_HWMON is not set
+CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_I2C=y
+CONFIG_MFD_MAX77686=y
+CONFIG_MFD_MAX8997=y
+CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_TPS65090=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8997=y
+CONFIG_REGULATOR_MAX77686=y
+CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_TPS65090=y
 CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SIMPLE=y
 CONFIG_EXYNOS_VIDEO=y
 CONFIG_EXYNOS_MIPI_DSI=y
 CONFIG_EXYNOS_DP=y
@@ -67,6 +91,20 @@ CONFIG_FONTS=y
 CONFIG_FONT_7x14=y
 CONFIG_LOGO=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_S5P=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_PHY=y
+CONFIG_SAMSUNG_USB2PHY=y
+CONFIG_SAMSUNG_USB3PHY=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_EXYNOS=y
+CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
@@ -79,6 +117,7 @@ CONFIG_ROMFS_FS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
@@ -87,6 +126,5 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_SHA256=y
 CONFIG_CRC_CCITT=y
index 968c0a1..209e650 100644 (file)
@@ -30,8 +30,15 @@ static inline void set_my_cpu_offset(unsigned long off)
 static inline unsigned long __my_cpu_offset(void)
 {
        unsigned long off;
-       /* Read TPIDRPRW */
-       asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : : "memory");
+       register unsigned long *sp asm ("sp");
+
+       /*
+        * Read TPIDRPRW.
+        * We want to allow caching the value, so avoid using volatile and
+        * instead use a fake stack read to hazard against barrier().
+        */
+       asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp));
+
        return off;
 }
 #define __my_cpu_offset __my_cpu_offset()
index 99a1951..bdf2b84 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 
-/*
- * We need to delay page freeing for SMP as other CPUs can access pages
- * which have been removed but not yet had their TLB entries invalidated.
- * Also, as ARMv7 speculative prefetch can drag new entries into the TLB,
- * we need to apply this same delaying tactic to ensure correct operation.
- */
-#if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7)
-#define tlb_fast_mode(tlb)     0
-#else
-#define tlb_fast_mode(tlb)     1
-#endif
-
 #define MMU_GATHER_BUNDLE      8
 
 /*
@@ -112,12 +100,10 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
        tlb_flush(tlb);
-       if (!tlb_fast_mode(tlb)) {
-               free_pages_and_swap_cache(tlb->pages, tlb->nr);
-               tlb->nr = 0;
-               if (tlb->pages == tlb->local)
-                       __tlb_alloc_page(tlb);
-       }
+       free_pages_and_swap_cache(tlb->pages, tlb->nr);
+       tlb->nr = 0;
+       if (tlb->pages == tlb->local)
+               __tlb_alloc_page(tlb);
 }
 
 static inline void
@@ -178,11 +164,6 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
 
 static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
-       if (tlb_fast_mode(tlb)) {
-               free_page_and_swap_cache(page);
-               return 1; /* avoid calling tlb_flush_mmu */
-       }
-
        tlb->pages[tlb->nr++] = page;
        VM_BUG_ON(tlb->nr > tlb->max);
        return tlb->max - tlb->nr;
index f10316b..c5a5954 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/export.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
 #include <linux/node.h>
@@ -200,6 +201,7 @@ static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
  * cpu topology table
  */
 struct cputopo_arm cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
 
 const struct cpumask *cpu_coregroup_mask(int cpu)
 {
index 37d216d..ef1703b 100644 (file)
@@ -492,6 +492,11 @@ static void vcpu_pause(struct kvm_vcpu *vcpu)
        wait_event_interruptible(*wq, !vcpu->arch.pause);
 }
 
+static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.target >= 0;
+}
+
 /**
  * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
  * @vcpu:      The VCPU pointer
@@ -508,8 +513,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
        int ret;
        sigset_t sigsaved;
 
-       /* Make sure they initialize the vcpu with KVM_ARM_VCPU_INIT */
-       if (unlikely(vcpu->arch.target < 0))
+       if (unlikely(!kvm_vcpu_initialized(vcpu)))
                return -ENOEXEC;
 
        ret = kvm_vcpu_first_run_init(vcpu);
@@ -710,6 +714,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        case KVM_SET_ONE_REG:
        case KVM_GET_ONE_REG: {
                struct kvm_one_reg reg;
+
+               if (unlikely(!kvm_vcpu_initialized(vcpu)))
+                       return -ENOEXEC;
+
                if (copy_from_user(&reg, argp, sizeof(reg)))
                        return -EFAULT;
                if (ioctl == KVM_SET_ONE_REG)
@@ -722,6 +730,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                struct kvm_reg_list reg_list;
                unsigned n;
 
+               if (unlikely(!kvm_vcpu_initialized(vcpu)))
+                       return -ENOEXEC;
+
                if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
                        return -EFAULT;
                n = reg_list.n;
index 9657065..84ba67b 100644 (file)
@@ -43,7 +43,14 @@ static phys_addr_t hyp_idmap_vector;
 
 static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 {
-       kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
+       /*
+        * This function also gets called when dealing with HYP page
+        * tables. As HYP doesn't have an associated struct kvm (and
+        * the HYP page tables are fairly static), we don't do
+        * anything there.
+        */
+       if (kvm)
+               kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
 }
 
 static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
@@ -78,18 +85,20 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
        return p;
 }
 
-static void clear_pud_entry(pud_t *pud)
+static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr)
 {
        pmd_t *pmd_table = pmd_offset(pud, 0);
        pud_clear(pud);
+       kvm_tlb_flush_vmid_ipa(kvm, addr);
        pmd_free(NULL, pmd_table);
        put_page(virt_to_page(pud));
 }
 
-static void clear_pmd_entry(pmd_t *pmd)
+static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr)
 {
        pte_t *pte_table = pte_offset_kernel(pmd, 0);
        pmd_clear(pmd);
+       kvm_tlb_flush_vmid_ipa(kvm, addr);
        pte_free_kernel(NULL, pte_table);
        put_page(virt_to_page(pmd));
 }
@@ -100,11 +109,12 @@ static bool pmd_empty(pmd_t *pmd)
        return page_count(pmd_page) == 1;
 }
 
-static void clear_pte_entry(pte_t *pte)
+static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr)
 {
        if (pte_present(*pte)) {
                kvm_set_pte(pte, __pte(0));
                put_page(virt_to_page(pte));
+               kvm_tlb_flush_vmid_ipa(kvm, addr);
        }
 }
 
@@ -114,7 +124,8 @@ static bool pte_empty(pte_t *pte)
        return page_count(pte_page) == 1;
 }
 
-static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size)
+static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
+                       unsigned long long start, u64 size)
 {
        pgd_t *pgd;
        pud_t *pud;
@@ -138,15 +149,15 @@ static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size)
                }
 
                pte = pte_offset_kernel(pmd, addr);
-               clear_pte_entry(pte);
+               clear_pte_entry(kvm, pte, addr);
                range = PAGE_SIZE;
 
                /* If we emptied the pte, walk back up the ladder */
                if (pte_empty(pte)) {
-                       clear_pmd_entry(pmd);
+                       clear_pmd_entry(kvm, pmd, addr);
                        range = PMD_SIZE;
                        if (pmd_empty(pmd)) {
-                               clear_pud_entry(pud);
+                               clear_pud_entry(kvm, pud, addr);
                                range = PUD_SIZE;
                        }
                }
@@ -165,14 +176,14 @@ void free_boot_hyp_pgd(void)
        mutex_lock(&kvm_hyp_pgd_mutex);
 
        if (boot_hyp_pgd) {
-               unmap_range(boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
-               unmap_range(boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
+               unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
+               unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
                kfree(boot_hyp_pgd);
                boot_hyp_pgd = NULL;
        }
 
        if (hyp_pgd)
-               unmap_range(hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
+               unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
 
        kfree(init_bounce_page);
        init_bounce_page = NULL;
@@ -200,9 +211,10 @@ void free_hyp_pgds(void)
 
        if (hyp_pgd) {
                for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE)
-                       unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+                       unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
                for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE)
-                       unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+                       unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
+
                kfree(hyp_pgd);
                hyp_pgd = NULL;
        }
@@ -393,7 +405,7 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
  */
 static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)
 {
-       unmap_range(kvm->arch.pgd, start, size);
+       unmap_range(kvm, kvm->arch.pgd, start, size);
 }
 
 /**
@@ -675,7 +687,6 @@ static void handle_hva_to_gpa(struct kvm *kvm,
 static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data)
 {
        unmap_stage2_range(kvm, gpa, PAGE_SIZE);
-       kvm_tlb_flush_vmid_ipa(kvm, gpa);
 }
 
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
index d19edff..ff18fc2 100644 (file)
@@ -250,6 +250,7 @@ config MACH_ARMLEX4210
 config MACH_UNIVERSAL_C210
        bool "Mobile UNIVERSAL_C210 Board"
        select CLKSRC_MMIO
+       select CLKSRC_SAMSUNG_PWM
        select CPU_EXYNOS4210
        select EXYNOS4_SETUP_FIMC
        select EXYNOS4_SETUP_FIMD0
@@ -281,7 +282,6 @@ config MACH_UNIVERSAL_C210
        select S5P_DEV_TV
        select S5P_GPIO_INT
        select S5P_SETUP_MIPIPHY
-       select SAMSUNG_HRT
        help
          Machine support for Samsung Mobile Universal S5PC210 Reference
          Board.
@@ -410,6 +410,7 @@ config MACH_EXYNOS4_DT
        depends on ARCH_EXYNOS4
        select ARM_AMBA
        select CLKSRC_OF
+       select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210
        select CPU_EXYNOS4210
        select KEYBOARD_SAMSUNG if INPUT_KEYBOARD
        select PINCTRL
index 745e304..f7e504b 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/bitops.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/gpio.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/sched.h>
 #include <linux/serial_core.h>
 #include <linux/of.h>
@@ -302,6 +304,13 @@ static struct map_desc exynos5440_iodesc0[] __initdata = {
        },
 };
 
+static struct samsung_pwm_variant exynos4_pwm_variant = {
+       .bits           = 32,
+       .div_base       = 0,
+       .has_tint_cstat = true,
+       .tclk_mask      = 0,
+};
+
 void exynos4_restart(char mode, const char *cmd)
 {
        __raw_writel(0x1, S5P_SWRESET);
@@ -317,9 +326,16 @@ void exynos5_restart(char mode, const char *cmd)
                val = 0x1;
                addr = EXYNOS_SWRESET;
        } else if (of_machine_is_compatible("samsung,exynos5440")) {
+               u32 status;
                np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
+
+               addr = of_iomap(np, 0) + 0xbc;
+               status = __raw_readl(addr);
+
                addr = of_iomap(np, 0) + 0xcc;
-               val = (0xfff << 20) | (0x1 << 16);
+               val = __raw_readl(addr);
+
+               val = (val & 0xffff0000) | (status & 0xffff);
        } else {
                pr_err("%s: cannot support non-DT\n", __func__);
                return;
@@ -370,6 +386,8 @@ int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
 
 void __init exynos_init_io(struct map_desc *mach_desc, int size)
 {
+       debug_ll_io_init();
+
 #ifdef CONFIG_OF
        if (initial_boot_params)
                of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
@@ -442,8 +460,20 @@ static void __init exynos5440_map_io(void)
        iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
 }
 
+void __init exynos_set_timer_source(u8 channels)
+{
+       exynos4_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+       exynos4_pwm_variant.output_mask &= ~channels;
+}
+
 void __init exynos_init_time(void)
 {
+       unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+               EXYNOS4_IRQ_TIMER0_VIC, EXYNOS4_IRQ_TIMER1_VIC,
+               EXYNOS4_IRQ_TIMER2_VIC, EXYNOS4_IRQ_TIMER3_VIC,
+               EXYNOS4_IRQ_TIMER4_VIC,
+       };
+
        if (of_have_populated_dt()) {
 #ifdef CONFIG_OF
                of_clk_init(NULL);
@@ -455,7 +485,14 @@ void __init exynos_init_time(void)
                exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1);
                exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
 #endif
-               mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1);
+#ifdef CONFIG_CLKSRC_SAMSUNG_PWM
+               if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
+                       samsung_pwm_clocksource_init(S3C_VA_TIMER,
+                                       timer_irqs, &exynos4_pwm_variant);
+               else
+#endif
+                       mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0,
+                                       EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1);
        }
 }
 
index 60dd35c..11fc1e2 100644 (file)
@@ -32,6 +32,8 @@ void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
 
 void exynos_firmware_init(void);
 
+void exynos_set_timer_source(u8 channels);
+
 #ifdef CONFIG_PM_GENERIC_DOMAINS
 int exynos_pm_late_initcall(void);
 #else
index 7dbbfec..296090e 100644 (file)
 #ifndef __ASM_ARCH_PM_CORE_H
 #define __ASM_ARCH_PM_CORE_H __FILE__
 
+#include <linux/of.h>
 #include <mach/regs-pmu.h>
 
+#ifdef CONFIG_PINCTRL_EXYNOS
+extern u32 exynos_get_eint_wake_mask(void);
+#else
+static inline u32 exynos_get_eint_wake_mask(void) { return 0xffffffff; }
+#endif
+
 static inline void s3c_pm_debug_init_uart(void)
 {
        /* nothing here yet */
@@ -27,7 +34,12 @@ static inline void s3c_pm_debug_init_uart(void)
 
 static inline void s3c_pm_arch_prepare_irqs(void)
 {
-       __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+       u32 eintmask = s3c_irqwake_eintmask;
+
+       if (of_have_populated_dt())
+               eintmask = exynos_get_eint_wake_mask();
+
+       __raw_writel(eintmask, S5P_EINT_WAKEUP_MASK);
        __raw_writel(s3c_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
 }
 
index 327d50d..74ddb2b 100644 (file)
@@ -41,7 +41,6 @@
 #include <plat/mfc.h>
 #include <plat/sdhci.h>
 #include <plat/fimc-core.h>
-#include <plat/samsung-time.h>
 #include <plat/camport.h>
 
 #include <mach/map.h>
@@ -1094,7 +1093,7 @@ static void __init universal_map_io(void)
 {
        exynos_init_io(NULL, 0);
        s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
-       samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4);
+       exynos_set_timer_source(BIT(2) | BIT(4));
        xxti_f = 0;
        xusbxti_f = 24000000;
 }
@@ -1154,7 +1153,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
        .map_io         = universal_map_io,
        .init_machine   = universal_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = samsung_timer_init,
+       .init_time      = exynos_init_time,
        .reserve        = &universal_reserve,
        .restart        = exynos4_restart,
 MACHINE_END
index dda9a2b..4e3148c 100644 (file)
@@ -181,14 +181,14 @@ static const char *periph_clk2_sels[]     = { "pll3_usb_otg", "osc", "osc", "dummy",
 static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
 static const char *periph_sels[]       = { "periph_pre", "periph_clk2", };
 static const char *periph2_sels[]      = { "periph2_pre", "periph2_clk2", };
-static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", };
 static const char *audio_sels[]        = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
 static const char *gpu_axi_sels[]      = { "axi", "ahb", };
 static const char *gpu2d_core_sels[]   = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
 static const char *gpu3d_core_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
 static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
 static const char *ipu_sels[]          = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
-static const char *ldb_di_sels[]       = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
+static const char *ldb_di_sels[]       = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
 static const char *ipu_di_pre_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
 static const char *ipu1_di0_sels[]     = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *ipu1_di1_sels[]     = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
index acb0187..4695d5f 100644 (file)
@@ -41,13 +41,3 @@ void __init qnap_dt_ts219_init(void)
 
        pm_power_off = qnap_tsx1x_power_off;
 }
-
-/* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */
-static int __init ts219_pci_init(void)
-{
-       if (machine_is_ts219())
-               kirkwood_pcie_init(KW_PCIE0);
-
-       return 0;
-}
-subsys_initcall(ts219_pci_init);
index 827cde4..e96fd71 100644 (file)
@@ -22,9 +22,10 @@ static unsigned int __init kirkwood_variant(void)
 
        kirkwood_pcie_id(&dev, &rev);
 
-       if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) ||
-           (dev == MV88F6282_DEV_ID))
+       if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0)
                return MPP_F6281_MASK;
+       if (dev == MV88F6282_DEV_ID)
+               return MPP_F6282_MASK;
        if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
                return MPP_F6192_MASK;
        if (dev == MV88F6180_DEV_ID)
index 53e8391..5476669 100644 (file)
@@ -32,15 +32,21 @@ ENTRY(ll_set_cpu_coherent)
 
        /* Add CPU to SMP group - Atomic */
        add     r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
-       ldr     r2, [r3]
+1:
+       ldrex   r2, [r3]
        orr     r2, r2, r1
-       str     r2, [r3]
+       strex   r0, r2, [r3]
+       cmp     r0, #0
+       bne 1b
 
        /* Enable coherency on CPU - Atomic */
-       add     r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET
-       ldr     r2, [r3]
+       add     r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET
+1:
+       ldrex   r2, [r3]
        orr     r2, r2, r1
-       str     r2, [r3]
+       strex   r0, r2, [r3]
+       cmp     r0, #0
+       bne 1b
 
        dsb
 
index 8f3bf4e..bbd6a3f 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/io.h>
 
 #include "clock.h"
 #include "clock36xx.h"
-
+#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
 
 /**
  * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
  */
 int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
 {
-       struct clk_hw_omap *parent;
+       struct clk_divider *parent;
        struct clk_hw *parent_hw;
-       u32 dummy_v, orig_v, clksel_shift;
+       u32 dummy_v, orig_v;
        int ret;
 
        /* Clear PWRDN bit of HSDIVIDER */
        ret = omap2_dflt_clk_enable(clk);
 
        parent_hw = __clk_get_hw(__clk_get_parent(clk->clk));
-       parent = to_clk_hw_omap(parent_hw);
+       parent = to_clk_divider(parent_hw);
 
        /* Restore the dividers */
        if (!ret) {
-               clksel_shift = __ffs(parent->clksel_mask);
-               orig_v = __raw_readl(parent->clksel_reg);
+               orig_v = __raw_readl(parent->reg);
                dummy_v = orig_v;
 
                /* Write any other value different from the Read value */
-               dummy_v ^= (1 << clksel_shift);
-               __raw_writel(dummy_v, parent->clksel_reg);
+               dummy_v ^= (1 << parent->shift);
+               __raw_writel(dummy_v, parent->reg);
 
                /* Write the original divider */
-               __raw_writel(orig_v, parent->clksel_reg);
+               __raw_writel(orig_v, parent->reg);
        }
 
        return ret;
index 075f7cc..69337af 100644 (file)
@@ -2007,6 +2007,13 @@ static struct omap_hwmod am33xx_uart1_hwmod = {
        },
 };
 
+/* uart2 */
+static struct omap_hwmod_dma_info uart2_edma_reqs[] = {
+       { .name = "tx", .dma_req = 28, },
+       { .name = "rx", .dma_req = 29, },
+       { .dma_req = -1 }
+};
+
 static struct omap_hwmod_irq_info am33xx_uart2_irqs[] = {
        { .irq = 73 + OMAP_INTC_START, },
        { .irq = -1 },
@@ -2018,7 +2025,7 @@ static struct omap_hwmod am33xx_uart2_hwmod = {
        .clkdm_name     = "l4ls_clkdm",
        .flags          = HWMOD_SWSUP_SIDLE_ACT,
        .mpu_irqs       = am33xx_uart2_irqs,
-       .sdma_reqs      = uart1_edma_reqs,
+       .sdma_reqs      = uart2_edma_reqs,
        .main_clk       = "dpll_per_m2_div4_ck",
        .prcm           = {
                .omap4  = {
index c018593..5a2d803 100644 (file)
@@ -546,8 +546,10 @@ static void __init prcm_setup_regs(void)
        /* Clear any pending PRCM interrupts */
        omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-       if (omap3_has_iva())
-               omap3_iva_idle();
+       /*
+        * We need to idle iva2_pwrdm even on am3703 with no iva2.
+        */
+       omap3_iva_idle();
 
        omap3_d2d_idle();
 }
index 9936c18..8f595c0 100644 (file)
@@ -101,8 +101,10 @@ static int __init sirfsoc_of_pwrc_init(void)
        struct device_node *np;
 
        np = of_find_matching_node(NULL, pwrc_ids);
-       if (!np)
-               panic("unable to find compatible pwrc node in dtb\n");
+       if (!np) {
+               pr_err("unable to find compatible sirf pwrc node in dtb\n");
+               return -ENOENT;
+       }
 
        /*
         * pwrc behind rtciobrg is not located in memory space
index 435019c..d5e0cbc 100644 (file)
@@ -28,8 +28,10 @@ static int __init sirfsoc_of_rstc_init(void)
        struct device_node *np;
 
        np = of_find_matching_node(NULL, rstc_ids);
-       if (!np)
-               panic("unable to find compatible rstc node in dtb\n");
+       if (!np) {
+               pr_err("unable to find compatible sirf rstc node in dtb\n");
+               return -ENOENT;
+       }
 
        sirfsoc_rstc_base = of_iomap(np, 0);
        if (!sirfsoc_rstc_base)
index fdf3894..9696f36 100644 (file)
@@ -252,7 +252,7 @@ static struct sh_timer_config cmt10_platform_data = {
        .name = "CMT10",
        .channel_offset = 0x10,
        .timer_bit = 0,
-       .clockevent_rating = 125,
+       .clockevent_rating = 80,
        .clocksource_rating = 125,
 };
 
index 33c353b..d6b7c85 100644 (file)
@@ -374,6 +374,7 @@ static struct ab8500_regulator_reg_init ab8500_reg_init[] = {
 static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
        /* supplies to the display/camera */
        [AB8500_LDO_AUX1] = {
+               .supply_regulator = "ab8500-ext-supply3",
                .constraints = {
                        .name = "V-DISPLAY",
                        .min_uV = 2800000,
@@ -387,6 +388,7 @@ static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
        },
        /* supplies to the on-board eMMC */
        [AB8500_LDO_AUX2] = {
+               .supply_regulator = "ab8500-ext-supply3",
                .constraints = {
                        .name = "V-eMMC1",
                        .min_uV = 1100000,
@@ -402,6 +404,7 @@ static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
        },
        /* supply for VAUX3, supplies to SDcard slots */
        [AB8500_LDO_AUX3] = {
+               .supply_regulator = "ab8500-ext-supply3",
                .constraints = {
                        .name = "V-MMC-SD",
                        .min_uV = 1100000,
index 317a2be..a45dd09 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/proc-fns.h>
 
 #include "db8500-regs.h"
+#include "id.h"
 
 static atomic_t master = ATOMIC_INIT(0);
 static DEFINE_SPINLOCK(master_lock);
@@ -114,6 +115,9 @@ static struct cpuidle_driver ux500_idle_driver = {
 
 int __init ux500_idle_init(void)
 {
+       if (!(cpu_is_u8500_family() || cpu_is_ux540_family()))
+               return -ENODEV;
+
        /* Configure wake up reasons */
        prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
                             PRCMU_WAKEUP(ABB));
index 30c2fe2..0f9c3f4 100644 (file)
@@ -311,9 +311,9 @@ struct platform_device s5p_device_jpeg = {
 #ifdef CONFIG_S5P_DEV_FIMD0
 static struct resource s5p_fimd0_resource[] = {
        [0] = DEFINE_RES_MEM(S5P_PA_FIMD0, SZ_32K),
-       [1] = DEFINE_RES_IRQ(IRQ_FIMD0_VSYNC),
-       [2] = DEFINE_RES_IRQ(IRQ_FIMD0_FIFO),
-       [3] = DEFINE_RES_IRQ(IRQ_FIMD0_SYSTEM),
+       [1] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_VSYNC, "vsync"),
+       [2] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_FIFO, "fifo"),
+       [3] = DEFINE_RES_IRQ_NAMED(IRQ_FIMD0_SYSTEM, "lcd_sys"),
 };
 
 struct platform_device s5p_device_fimd0 = {
index 438b248..02b66d7 100644 (file)
@@ -66,6 +66,9 @@ uart_rd(unsigned int reg)
 
 static void putc(int ch)
 {
+       if (!config_enabled(CONFIG_DEBUG_LL))
+               return;
+
        if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
                int level;
 
@@ -118,7 +121,12 @@ static void arch_decomp_error(const char *x)
 #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
 static inline void arch_enable_uart_fifo(void)
 {
-       u32 fifocon = uart_rd(S3C2410_UFCON);
+       u32 fifocon;
+
+       if (!config_enabled(CONFIG_DEBUG_LL))
+               return;
+
+       fifocon = uart_rd(S3C2410_UFCON);
 
        if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
                fifocon |= S3C2410_UFCON_RESETBOTH;
index 53210ec..bd7124c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/suspend.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 #include <linux/serial_core.h>
 #include <linux/io.h>
 
@@ -261,7 +262,8 @@ static int s3c_pm_enter(suspend_state_t state)
         * require a full power-cycle)
        */
 
-       if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+       if (!of_have_populated_dt() &&
+           !any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
            !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
                printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
                printk(KERN_ERR "%s: Aborting sleep\n", __func__);
@@ -270,8 +272,11 @@ static int s3c_pm_enter(suspend_state_t state)
 
        /* save all necessary core registers not covered by the drivers */
 
-       samsung_pm_save_gpios();
-       samsung_pm_saved_gpios();
+       if (!of_have_populated_dt()) {
+               samsung_pm_save_gpios();
+               samsung_pm_saved_gpios();
+       }
+
        s3c_pm_save_uarts();
        s3c_pm_save_core();
 
@@ -310,8 +315,11 @@ static int s3c_pm_enter(suspend_state_t state)
 
        s3c_pm_restore_core();
        s3c_pm_restore_uarts();
-       samsung_pm_restore_gpios();
-       s3c_pm_restored_gpios();
+
+       if (!of_have_populated_dt()) {
+               samsung_pm_restore_gpios();
+               s3c_pm_restored_gpios();
+       }
 
        s3c_pm_debug_init();
 
index 7df1aad..41b4f62 100644 (file)
@@ -34,6 +34,7 @@ EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 
 EXPORT_SYMBOL(copy_page);
+EXPORT_SYMBOL(clear_page);
 
 EXPORT_SYMBOL(__copy_from_user);
 EXPORT_SYMBOL(__copy_to_user);
index c7e0470..1d13142 100644 (file)
@@ -390,6 +390,16 @@ el0_sync_compat:
        b.eq    el0_fpsimd_exc
        cmp     x24, #ESR_EL1_EC_UNKNOWN        // unknown exception in EL0
        b.eq    el0_undef
+       cmp     x24, #ESR_EL1_EC_CP15_32        // CP15 MRC/MCR trap
+       b.eq    el0_undef
+       cmp     x24, #ESR_EL1_EC_CP15_64        // CP15 MRRC/MCRR trap
+       b.eq    el0_undef
+       cmp     x24, #ESR_EL1_EC_CP14_MR        // CP14 MRC/MCR trap
+       b.eq    el0_undef
+       cmp     x24, #ESR_EL1_EC_CP14_LS        // CP14 LDC/STC trap
+       b.eq    el0_undef
+       cmp     x24, #ESR_EL1_EC_CP14_64        // CP14 MRRC/MCRR trap
+       b.eq    el0_undef
        cmp     x24, #ESR_EL1_EC_BREAKPT_EL0    // debug exception in EL0
        b.ge    el0_dbg
        b       el0_inv
index 61d7dd2..f30852d 100644 (file)
@@ -267,7 +267,8 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
                return;
 #endif
 
-       if (show_unhandled_signals) {
+       if (show_unhandled_signals && unhandled_signal(current, SIGILL) &&
+           printk_ratelimit()) {
                pr_info("%s[%d]: undefined instruction: pc=%p\n",
                        current->comm, task_pid_nr(current), pc);
                dump_instr(KERN_INFO, regs);
@@ -294,7 +295,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
        }
 #endif
 
-       if (show_unhandled_signals) {
+       if (show_unhandled_signals && printk_ratelimit()) {
                pr_info("%s[%d]: syscall %d\n", current->comm,
                        task_pid_nr(current), (int)regs->syscallno);
                dump_instr("", regs);
@@ -310,14 +311,20 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
  */
 asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
 {
+       siginfo_t info;
+       void __user *pc = (void __user *)instruction_pointer(regs);
        console_verbose();
 
        pr_crit("Bad mode in %s handler detected, code 0x%08x\n",
                handler[reason], esr);
+       __show_regs(regs);
+
+       info.si_signo = SIGILL;
+       info.si_errno = 0;
+       info.si_code  = ILL_ILLOPC;
+       info.si_addr  = pc;
 
-       die("Oops - bad mode", regs, 0);
-       local_irq_disable();
-       panic("bad mode");
+       arm64_notify_die("Oops - bad mode", regs, &info, 0);
 }
 
 void __pte_error(const char *file, int line, unsigned long val)
index 98af6e7..1426468 100644 (file)
@@ -113,7 +113,8 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
 {
        struct siginfo si;
 
-       if (show_unhandled_signals) {
+       if (show_unhandled_signals && unhandled_signal(tsk, sig) &&
+           printk_ratelimit()) {
                pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n",
                        tsk->comm, task_pid_nr(tsk), fault_name(esr), sig,
                        addr, esr);
index d58f50e..1e7be62 100644 (file)
@@ -283,14 +283,6 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       /* TODO: add platform data here */
-};
-#endif
-
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MTD_M25P80) \
        || defined(CONFIG_MTD_M25P80_MODULE)
@@ -800,10 +792,6 @@ static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
        &bfin_i2s,
 #endif
-
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm,
-#endif
 };
 
 static int __init ad7160eval_init(void)
index 29f16e5..d0a0c5e 100644 (file)
@@ -493,8 +493,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-       defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
 
 static const u16 bfin_snd_pin[][7] = {
        {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
@@ -549,13 +548,6 @@ static struct platform_device bfin_i2s_pcm = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-       .name = "bfin-tdm-pcm-audio",
-       .id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
        .name = "bfin-ac97-pcm-audio",
@@ -575,22 +567,10 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       .num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-       .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-       .dev = {
-               .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-       },
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
                || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-       "bfin-tdm.0",
+       "bfin-i2s.0",
        "spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -1269,10 +1249,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_i2s_pcm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm_pcm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97_pcm,
 #endif
@@ -1281,10 +1257,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
        defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
        &bfin_ad1836_machine,
index 07811c2..90fb0d1 100644 (file)
@@ -450,14 +450,6 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       /* TODO: add platform data here */
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
        .name = "bfin-ac97",
@@ -516,10 +508,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
        &bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97,
 #endif
index 6fca869..4a8c2e3 100644 (file)
@@ -542,8 +542,7 @@ static struct platform_device bfin_dpmc = {
 };
 
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-       defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) \
-       || defined(CONFIG_SND_BF5XX_AC97) || \
+       defined(CONFIG_SND_BF5XX_AC97) || \
        defined(CONFIG_SND_BF5XX_AC97_MODULE)
 
 #include <asm/bfin_sport.h>
@@ -603,13 +602,6 @@ static struct platform_device bfin_i2s_pcm = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-       .name = "bfin-tdm-pcm-audio",
-       .id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
        .name = "bfin-ac97-pcm-audio",
@@ -620,7 +612,7 @@ static struct platform_device bfin_ac97_pcm = {
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
                || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-       "bfin-tdm.0",
+       "bfin-i2s.0",
        "spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -675,20 +667,6 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
-       defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       .num_resources =
-               ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-       .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-       .dev = {
-               .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-       },
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
        defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
@@ -761,10 +739,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_i2s_pcm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm_pcm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97_pcm,
 #endif
@@ -792,11 +766,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
-       defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-       &bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
        defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
        &bfin_ac97,
index 6a3a14b..44fd1d4 100644 (file)
@@ -2570,7 +2570,6 @@ static struct platform_device bfin_dpmc = {
 };
 
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-       defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
        defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 
 #define SPORT_REQ(x) \
@@ -2628,13 +2627,6 @@ static struct platform_device bfin_i2s_pcm = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-       .name = "bfin-tdm-pcm-audio",
-       .id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
        .name = "bfin-ac97-pcm-audio",
@@ -2645,7 +2637,7 @@ static struct platform_device bfin_ac97_pcm = {
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
                || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-       "bfin-tdm.0",
+       "bfin-i2s.0",
        "spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -2699,18 +2691,6 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       .num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-       .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-       .dev = {
-               .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-       },
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
        .name = "bfin-ac97",
@@ -2935,10 +2915,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_i2s_pcm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm_pcm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97_pcm,
 #endif
@@ -2961,10 +2937,6 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-       &bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
        &bfin_ac97,
 #endif
index c4d07f0..372eb54 100644 (file)
@@ -1393,7 +1393,6 @@ static struct platform_device bfin_dpmc = {
 };
 
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-       defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
        defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 
 #define SPORT_REQ(x) \
@@ -1461,13 +1460,6 @@ static struct platform_device bfin_i2s_pcm = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-       .name = "bfin-tdm-pcm-audio",
-       .id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
        .name = "bfin-ac97-pcm-audio",
@@ -1501,18 +1493,6 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       .num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-       .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-       .dev = {
-               .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-       },
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
        .name = "bfin-ac97",
@@ -1646,9 +1626,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
        &bfin_i2s_pcm,
 #endif
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm_pcm,
-#endif
+
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97_pcm,
 #endif
@@ -1661,10 +1639,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
        &bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97,
 #endif
index 551f866..92938e7 100644 (file)
@@ -523,14 +523,6 @@ static struct platform_device bfin_i2s = {
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-       .name = "bfin-tdm",
-       .id = CONFIG_SND_BF5XX_SPORT_NUM,
-       /* TODO: add platform data here */
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
        .name = "bfin-ac97",
@@ -542,7 +534,7 @@ static struct platform_device bfin_ac97 = {
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
                || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-       "bfin-tdm.0",
+       "bfin-i2s.0",
        "spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -611,10 +603,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
        &bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-       &bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
        &bfin_ac97,
 #endif
index 97d7016..bba40ae 100644 (file)
@@ -821,7 +821,7 @@ static struct platform_device bfin_i2s = {
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
                || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-       "bfin-tdm.0",
+       "bfin-i2s.0",
        "spi0.76",
 };
 static struct platform_device bfin_ad1836_machine = {
index c3ffe3e..ef3a9de 100644 (file)
 #include <asm/tlbflush.h>
 #include <asm/machvec.h>
 
-#ifdef CONFIG_SMP
-# define tlb_fast_mode(tlb)    ((tlb)->nr == ~0U)
-#else
-# define tlb_fast_mode(tlb)    (1)
-#endif
-
 /*
  * If we can't allocate a page to make a big batch of page pointers
  * to work on, then just handle a few from the on-stack structure.
@@ -60,7 +54,7 @@
 
 struct mmu_gather {
        struct mm_struct        *mm;
-       unsigned int            nr;             /* == ~0U => fast mode */
+       unsigned int            nr;
        unsigned int            max;
        unsigned char           fullmm;         /* non-zero means full mm flush */
        unsigned char           need_flush;     /* really unmapped some PTEs? */
@@ -103,6 +97,7 @@ extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS];
 static inline void
 ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
+       unsigned long i;
        unsigned int nr;
 
        if (!tlb->need_flush)
@@ -141,13 +136,11 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e
 
        /* lastly, release the freed pages */
        nr = tlb->nr;
-       if (!tlb_fast_mode(tlb)) {
-               unsigned long i;
-               tlb->nr = 0;
-               tlb->start_addr = ~0UL;
-               for (i = 0; i < nr; ++i)
-                       free_page_and_swap_cache(tlb->pages[i]);
-       }
+
+       tlb->nr = 0;
+       tlb->start_addr = ~0UL;
+       for (i = 0; i < nr; ++i)
+               free_page_and_swap_cache(tlb->pages[i]);
 }
 
 static inline void __tlb_alloc_page(struct mmu_gather *tlb)
@@ -167,20 +160,7 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_m
        tlb->mm = mm;
        tlb->max = ARRAY_SIZE(tlb->local);
        tlb->pages = tlb->local;
-       /*
-        * Use fast mode if only 1 CPU is online.
-        *
-        * It would be tempting to turn on fast-mode for full_mm_flush as well.  But this
-        * doesn't work because of speculative accesses and software prefetching: the page
-        * table of "mm" may (and usually is) the currently active page table and even
-        * though the kernel won't do any user-space accesses during the TLB shoot down, a
-        * compiler might use speculation or lfetch.fault on what happens to be a valid
-        * user-space address.  This in turn could trigger a TLB miss fault (or a VHPT
-        * walk) and re-insert a TLB entry we just removed.  Slow mode avoids such
-        * problems.  (We could make fast-mode work by switching the current task to a
-        * different "mm" during the shootdown.) --davidm 08/02/2002
-        */
-       tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
+       tlb->nr = 0;
        tlb->fullmm = full_mm_flush;
        tlb->start_addr = ~0UL;
 }
@@ -214,11 +194,6 @@ static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
        tlb->need_flush = 1;
 
-       if (tlb_fast_mode(tlb)) {
-               free_page_and_swap_cache(page);
-               return 1; /* avoid calling tlb_flush_mmu */
-       }
-
        if (!tlb->nr && tlb->pages == tlb->local)
                __tlb_alloc_page(tlb);
 
index 90d3109..19325e1 100644 (file)
@@ -1,55 +1,78 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-amiga"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_AMIGA=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
 CONFIG_M68060=y
-CONFIG_BINFMT_AOUT=m
-CONFIG_BINFMT_MISC=m
+CONFIG_AMIGA=y
 CONFIG_ZORRO=y
 CONFIG_AMIGA_PCMCIA=y
-CONFIG_HEARTBEAT=y
-CONFIG_PROC_HARDWARE=y
 CONFIG_ZORRO_NAMES=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -57,25 +80,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -86,6 +121,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -99,22 +136,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -124,7 +170,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -133,18 +178,30 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_PARPORT=m
 CONFIG_PARPORT_AMIGA=m
@@ -154,11 +211,13 @@ CONFIG_AMIGA_FLOPPY=y
 CONFIG_AMIGA_Z2RAM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
+CONFIG_IDE_GD_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_GAYLE=y
 CONFIG_BLK_DEV_BUDDHA=y
@@ -172,57 +231,77 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_A3000_SCSI=y
 CONFIG_A2091_SCSI=y
 CONFIG_GVP11_SCSI=y
 CONFIG_SCSI_A4000T=y
 CONFIG_SCSI_ZORRO7XX=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
-CONFIG_ARIADNE=y
+# CONFIG_NET_VENDOR_3COM is not set
 CONFIG_A2065=y
+CONFIG_ARIADNE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FUJITSU is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
 CONFIG_HYDRA=y
-CONFIG_ZORRO8390=y
 CONFIG_APNE=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_ZORRO8390=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 CONFIG_KEYBOARD_AMIGA=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_MOUSE_PS2 is not set
@@ -233,11 +312,14 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_M68K_BEEP=m
 # CONFIG_SERIO is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_PRINTER=m
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_PARPORT=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FB_CIRRUS=y
@@ -252,48 +334,64 @@ CONFIG_SOUND=m
 CONFIG_DMASOUND_PAULA=m
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MSM6242=m
+CONFIG_RTC_DRV_RP5C01=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HEARTBEAT=y
+CONFIG_PROC_HARDWARE=y
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -332,10 +430,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -345,19 +456,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -373,6 +481,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 8f4f657..14dc6cc 100644 (file)
@@ -1,55 +1,76 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-apollo"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_APOLLO=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
 CONFIG_M68060=y
+CONFIG_APOLLO=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_HEARTBEAT=y
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -57,25 +78,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -86,6 +119,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -99,22 +134,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -124,7 +168,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -133,21 +176,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -162,57 +218,74 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
 CONFIG_SERIO=m
-# CONFIG_SERIO_SERPORT is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -221,47 +294,61 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HEARTBEAT=y
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -300,10 +387,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -313,19 +413,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -341,6 +438,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 4571d33..6d5370c 100644 (file)
@@ -1,53 +1,75 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-atari"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_ATARI=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
 CONFIG_M68060=y
+CONFIG_ATARI=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_STRAM_PROC=y
-CONFIG_HEARTBEAT=y
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -55,25 +77,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -84,6 +118,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -97,22 +133,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -122,7 +167,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -131,18 +175,30 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_PARPORT=m
 CONFIG_PARPORT_ATARI=m
@@ -150,11 +206,13 @@ CONFIG_PARPORT_1284=y
 CONFIG_ATARI_FLOPPY=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
+CONFIG_IDE_GD_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_FALCON_IDE=y
 CONFIG_RAID_ATTRS=m
@@ -167,63 +225,81 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_ATARI_SCSI=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
-CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_VETH=m
 CONFIG_ATARILANCE=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 CONFIG_KEYBOARD_ATARI=y
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_ATARI=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_M68K_BEEP=m
-# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_PRINTER=m
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_PARPORT=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FB_ATARI=y
@@ -233,47 +309,64 @@ CONFIG_SOUND=m
 CONFIG_DMASOUND_ATARI=m
 CONFIG_HID=m
 CONFIG_HIDRAW=y
-# CONFIG_USB_SUPPORT is not set
+CONFIG_UHID=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HEARTBEAT=y
+CONFIG_PROC_HARDWARE=y
+CONFIG_NATFEAT=y
+CONFIG_NFBLOCK=y
+CONFIG_NFCON=y
+CONFIG_NFETH=y
 CONFIG_ATARI_DSP56K=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -312,10 +405,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -325,19 +431,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -353,6 +456,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 12f2117..c015ddb 100644 (file)
@@ -1,53 +1,74 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-bvme6000"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_VME=y
-CONFIG_BVME6000=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68040=y
 CONFIG_M68060=y
+CONFIG_VME=y
+CONFIG_BVME6000=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -55,25 +76,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -84,6 +117,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -97,22 +132,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -122,7 +166,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -131,21 +174,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -160,103 +216,131 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_BVME6000_SCSI=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
 CONFIG_BVME6000_NET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_SERIAL=m
-CONFIG_SERIO=m
-# CONFIG_SERIO_SERPORT is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -295,10 +379,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -308,19 +405,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -336,7 +430,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
-CONFIG_CRC32=m
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 215389a..ec7382d 100644 (file)
@@ -1,54 +1,76 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-hp300"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_HP300=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
 CONFIG_M68060=y
+CONFIG_HP300=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -56,25 +78,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -85,6 +119,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -98,22 +134,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -123,7 +168,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -132,21 +176,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -161,59 +218,77 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
 CONFIG_HPLANCE=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
 CONFIG_INPUT_MISC=y
 CONFIG_HP_SDC_RTC=m
-# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_SERPORT=m
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -222,47 +297,60 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -301,10 +389,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -314,19 +415,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -342,6 +440,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index cb9dfb3..7d46fbe 100644 (file)
@@ -1,49 +1,75 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-mac"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_MAC=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
+CONFIG_M68KFPU_EMU=y
+CONFIG_MAC=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -51,25 +77,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -80,6 +118,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -93,22 +133,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -118,7 +167,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -127,31 +175,45 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
 CONFIG_IPDDP=m
 CONFIG_IPDDP_ENCAP=y
 CONFIG_IPDDP_DECAP=y
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
-CONFIG_BLK_DEV_SWIM=y
+CONFIG_BLK_DEV_SWIM=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
+CONFIG_IDE_GD_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_MAC_IDE=y
 CONFIG_RAID_ATTRS=m
@@ -164,29 +226,30 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_MAC_SCSI=y
 CONFIG_SCSI_MAC_ESP=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_ADB=y
 CONFIG_ADB_MACII=y
-CONFIG_ADB_MACIISI=y
 CONFIG_ADB_IOP=y
 CONFIG_ADB_PMU68K=y
 CONFIG_ADB_CUDA=y
@@ -194,46 +257,61 @@ CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
-CONFIG_MAC8390=y
-CONFIG_MAC89x0=m
-CONFIG_MACSONIC=m
 CONFIG_MACMACE=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_MAC89x0=y
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+CONFIG_MACSONIC=y
+CONFIG_MAC8390=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_M68K_BEEP=m
 CONFIG_SERIO=m
-# CONFIG_SERIO_SERPORT is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_PMACZILOG=y
 CONFIG_SERIAL_PMACZILOG_TTYS=y
 CONFIG_SERIAL_PMACZILOG_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FB_VALKYRIE=y
@@ -242,46 +320,60 @@ CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=y
-CONFIG_HFSPLUS_FS=y
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
+CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -320,10 +412,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -333,19 +438,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -361,6 +463,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 8d5def4..0f795d8 100644 (file)
@@ -1,15 +1,29 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-multi"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_M68020=y
+CONFIG_M68040=y
+CONFIG_M68060=y
+CONFIG_M68KFPU_EMU=y
 CONFIG_AMIGA=y
 CONFIG_ATARI=y
 CONFIG_MAC=y
@@ -21,48 +35,50 @@ CONFIG_BVME6000=y
 CONFIG_HP300=y
 CONFIG_SUN3X=y
 CONFIG_Q40=y
-CONFIG_M68020=y
-CONFIG_M68040=y
-CONFIG_M68060=y
-CONFIG_BINFMT_AOUT=m
-CONFIG_BINFMT_MISC=m
 CONFIG_ZORRO=y
 CONFIG_AMIGA_PCMCIA=y
-CONFIG_STRAM_PROC=y
-CONFIG_HEARTBEAT=y
-CONFIG_PROC_HARDWARE=y
 CONFIG_ZORRO_NAMES=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -70,25 +86,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -99,6 +127,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -112,22 +142,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -137,7 +176,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -146,22 +184,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
 CONFIG_IPDDP=m
 CONFIG_IPDDP_ENCAP=y
 CONFIG_IPDDP_DECAP=y
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_PARPORT=m
 CONFIG_PARPORT_AMIGA=m
@@ -170,15 +220,17 @@ CONFIG_PARPORT_ATARI=m
 CONFIG_PARPORT_1284=y
 CONFIG_AMIGA_FLOPPY=y
 CONFIG_ATARI_FLOPPY=y
-CONFIG_BLK_DEV_SWIM=y
+CONFIG_BLK_DEV_SWIM=m
 CONFIG_AMIGA_Z2RAM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
+CONFIG_IDE_GD_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_GAYLE=y
 CONFIG_BLK_DEV_BUDDHA=y
@@ -195,11 +247,9 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_A3000_SCSI=y
 CONFIG_A2091_SCSI=y
 CONFIG_GVP11_SCSI=y
@@ -213,21 +263,24 @@ CONFIG_MVME16x_SCSI=y
 CONFIG_BVME6000_SCSI=y
 CONFIG_SUN3X_ESP=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_ADB=y
 CONFIG_ADB_MACII=y
-CONFIG_ADB_MACIISI=y
 CONFIG_ADB_IOP=y
 CONFIG_ADB_PMU68K=y
 CONFIG_ADB_CUDA=y
@@ -235,49 +288,64 @@ CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
-CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-CONFIG_ARIADNE=y
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_3COM is not set
 CONFIG_A2065=y
-CONFIG_HYDRA=y
-CONFIG_ZORRO8390=y
-CONFIG_APNE=y
-CONFIG_MAC8390=y
-CONFIG_MAC89x0=y
-CONFIG_MACSONIC=y
-CONFIG_MACMACE=y
-CONFIG_MVME147_NET=y
-CONFIG_MVME16x_NET=y
-CONFIG_BVME6000_NET=y
+CONFIG_ARIADNE=y
 CONFIG_ATARILANCE=y
-CONFIG_SUN3LANCE=y
 CONFIG_HPLANCE=y
+CONFIG_MVME147_NET=y
+CONFIG_SUN3LANCE=y
+CONFIG_MACMACE=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_MAC89x0=y
+# CONFIG_NET_VENDOR_FUJITSU is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_BVME6000_NET=y
+CONFIG_MVME16x_NET=y
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+CONFIG_MACSONIC=y
+CONFIG_HYDRA=y
+CONFIG_MAC8390=y
 CONFIG_NE2000=m
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+CONFIG_APNE=y
+CONFIG_ZORRO8390=y
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 CONFIG_KEYBOARD_AMIGA=y
 CONFIG_KEYBOARD_ATARI=y
 # CONFIG_KEYBOARD_ATKBD is not set
 CONFIG_KEYBOARD_SUNKBD=y
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
 CONFIG_MOUSE_AMIGA=m
 CONFIG_MOUSE_ATARI=m
@@ -285,18 +353,20 @@ CONFIG_INPUT_JOYSTICK=y
 CONFIG_JOYSTICK_AMIGA=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_M68K_BEEP=m
-CONFIG_HP_SDC_RTC=y
-# CONFIG_SERIO_SERPORT is not set
+CONFIG_HP_SDC_RTC=m
 CONFIG_SERIO_Q40KBD=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_PMACZILOG=y
 CONFIG_SERIAL_PMACZILOG_TTYS=y
 CONFIG_SERIAL_PMACZILOG_CONSOLE=y
 CONFIG_PRINTER=m
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=y
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_PARPORT=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FB_CIRRUS=y
@@ -316,7 +386,20 @@ CONFIG_DMASOUND_PAULA=m
 CONFIG_DMASOUND_Q40=m
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MSM6242=m
+CONFIG_RTC_DRV_RP5C01=m
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HEARTBEAT=y
+CONFIG_PROC_HARDWARE=y
+CONFIG_NATFEAT=y
+CONFIG_NFBLOCK=y
+CONFIG_NFCON=y
+CONFIG_NFETH=y
 CONFIG_ATARI_DSP56K=m
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
@@ -324,42 +407,49 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=y
-CONFIG_HFSPLUS_FS=y
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -398,10 +488,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -411,19 +514,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -439,6 +539,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index e2af46f..5586c65 100644 (file)
@@ -1,52 +1,73 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-mvme147"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_M68030=y
 CONFIG_VME=y
 CONFIG_MVME147=y
-CONFIG_M68030=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -54,25 +75,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -83,6 +116,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -96,22 +131,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -121,7 +165,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -130,21 +173,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -159,103 +215,132 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_MVME147_SCSI=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
 CONFIG_MVME147_NET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_SERIAL=m
-CONFIG_SERIO=m
-# CONFIG_SERIO_SERPORT is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -294,10 +379,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -307,19 +405,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -335,6 +430,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 7c9402b..e5e8262 100644 (file)
@@ -1,53 +1,74 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-mvme16x"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_VME=y
-CONFIG_MVME16x=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68040=y
 CONFIG_M68060=y
+CONFIG_VME=y
+CONFIG_MVME16x=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -55,25 +76,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -84,6 +117,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -97,22 +132,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -122,7 +166,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -131,21 +174,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -160,103 +216,131 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_MVME16x_SCSI=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
 CONFIG_MVME16x_NET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_SERIAL=m
-CONFIG_SERIO=m
-# CONFIG_SERIO_SERPORT is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -295,10 +379,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -308,19 +405,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -336,6 +430,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index 19d23db..8982370 100644 (file)
@@ -1,49 +1,74 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-q40"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_Q40=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_SUN_PARTITION=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_M68040=y
 CONFIG_M68060=y
+CONFIG_Q40=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_HEARTBEAT=y
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -51,25 +76,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -80,6 +117,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -93,22 +132,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -118,7 +166,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -127,26 +174,40 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
 CONFIG_IDE=y
+CONFIG_IDE_GD_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_Q40IDE=y
 CONFIG_RAID_ATTRS=m
@@ -159,61 +220,82 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FUJITSU is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
 CONFIG_NE2000=m
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_M68K_BEEP=m
-CONFIG_SERIO=m
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_Q40KBD=m
+CONFIG_SERIO_Q40KBD=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -222,46 +304,61 @@ CONFIG_SOUND=m
 CONFIG_DMASOUND_Q40=m
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HEARTBEAT=y
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -300,10 +397,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -313,19 +423,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -341,6 +448,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index ca6c0b4..54674d6 100644 (file)
@@ -1,50 +1,71 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-sun3"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_SUN3=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -52,25 +73,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -81,6 +114,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -94,22 +129,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -119,7 +163,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -128,21 +171,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -157,107 +213,136 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_SUN3_SCSI=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
 CONFIG_SUN3LANCE=y
+# CONFIG_NET_CADENCE is not set
 CONFIG_SUN3_82586=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
 CONFIG_KEYBOARD_SUNKBD=y
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
-# CONFIG_SERIO_SERPORT is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -296,10 +381,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -309,19 +407,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -337,6 +432,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index c80941c..832d953 100644 (file)
@@ -1,50 +1,71 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-sun3x"
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
 CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_RELAY=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_EFI_PARTITION is not set
+CONFIG_SYSV68_PARTITION=y
+CONFIG_IOSCHED_DEADLINE=m
 CONFIG_SUN3X=y
+# CONFIG_COMPACTION is not set
+CONFIG_CLEANCACHE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_AOUT=m
 CONFIG_BINFMT_MISC=m
-CONFIG_PROC_HARDWARE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
 CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_MIGRATE=y
 CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
 CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NET_IPGRE=m
 CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
 CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_GRE=m
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
 # CONFIG_NF_CT_PROTO_DCCP is not set
 CONFIG_NF_CT_PROTO_UDPLITE=m
 CONFIG_NF_CONNTRACK_AMANDA=m
@@ -52,25 +73,37 @@ CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
 CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
 CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SANE=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
 CONFIG_NETFILTER_XT_TARGET_TRACE=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
 CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -81,6 +114,8 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
 CONFIG_NETFILTER_XT_MATCH_OWNER=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
@@ -94,22 +129,31 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
+CONFIG_NF_NAT_IPV4=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_NETMAP=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -119,7 +163,6 @@ CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -128,21 +171,34 @@ CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_HL=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
 CONFIG_IP_DCCP=m
 # CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_SCTP_COOKIE_HMAC_SHA1=y
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_L2TP=m
 CONFIG_ATALK=m
+CONFIG_BATMAN_ADV=m
+CONFIG_BATMAN_ADV_DAT=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_CDROM_PKTCDVD=m
@@ -157,106 +213,136 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
 CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
 CONFIG_SUN3X_ESP=y
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID456=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
 CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 CONFIG_DM_UEVENT=y
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_MACVLAN=m
 CONFIG_EQUALIZER=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_VXLAN=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
-CONFIG_NET_ETHERNET=y
 CONFIG_SUN3LANCE=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_PPP=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
 CONFIG_SLIP=m
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NETCONSOLE=m
-CONFIG_NETCONSOLE_DYNAMIC=y
-CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_KEYBOARD_ATKBD is not set
 CONFIG_KEYBOARD_SUNKBD=y
-CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_SERIAL=m
-# CONFIG_SERIO_SERPORT is not set
 CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=m
-CONFIG_GEN_RTC_X=y
+CONFIG_NTP_PPS=y
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_HID=m
 CONFIG_HIDRAW=y
+CONFIG_UHID=m
+# CONFIG_HID_GENERIC is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GENERIC=m
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PROC_HARDWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
 CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
-# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
+CONFIG_FANOTIFY=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=y
+CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_PROC_KCORE=y
 CONFIG_TMPFS=y
 CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
 CONFIG_HFS_FS=m
 CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
-CONFIG_MINIX_FS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
 CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_QNX6FS_FS=m
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_SWAP=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
 CONFIG_CODA_FS=m
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
@@ -295,10 +381,23 @@ CONFIG_NLS_ISO8859_14=m
 CONFIG_NLS_ISO8859_15=m
 CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
 CONFIG_DLM=m
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_ASYNC_RAID6_TEST=m
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_USER=m
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_TEST=m
@@ -308,19 +407,16 @@ CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_VMAC=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
@@ -336,6 +432,14 @@ CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_ZLIB=m
 CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC16=m
 CONFIG_CRC_T10DIF=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_TEST=m
index c7933e4..09d77a8 100644 (file)
@@ -6,7 +6,6 @@ generic-y += device.h
 generic-y += emergency-restart.h
 generic-y += errno.h
 generic-y += exec.h
-generic-y += futex.h
 generic-y += hw_irq.h
 generic-y += ioctl.h
 generic-y += ipcbuf.h
diff --git a/arch/m68k/include/asm/futex.h b/arch/m68k/include/asm/futex.h
new file mode 100644 (file)
index 0000000..bc868af
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef _ASM_M68K_FUTEX_H
+#define _ASM_M68K_FUTEX_H
+
+#ifdef __KERNEL__
+#if !defined(CONFIG_MMU)
+#include <asm-generic/futex.h>
+#else  /* CONFIG_MMU */
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+                             u32 oldval, u32 newval)
+{
+       u32 val;
+
+       if (unlikely(get_user(val, uaddr) != 0))
+               return -EFAULT;
+
+       if (val == oldval && unlikely(put_user(newval, uaddr) != 0))
+               return -EFAULT;
+
+       *uval = val;
+
+       return 0;
+}
+
+static inline int
+futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+{
+       int op = (encoded_op >> 28) & 7;
+       int cmp = (encoded_op >> 24) & 15;
+       int oparg = (encoded_op << 8) >> 20;
+       int cmparg = (encoded_op << 20) >> 20;
+       int oldval, ret;
+       u32 tmp;
+
+       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+               oparg = 1 << oparg;
+
+       pagefault_disable();    /* implies preempt_disable() */
+
+       ret = -EFAULT;
+       if (unlikely(get_user(oldval, uaddr) != 0))
+               goto out_pagefault_enable;
+
+       ret = 0;
+       tmp = oldval;
+
+       switch (op) {
+       case FUTEX_OP_SET:
+               tmp = oparg;
+               break;
+       case FUTEX_OP_ADD:
+               tmp += oparg;
+               break;
+       case FUTEX_OP_OR:
+               tmp |= oparg;
+               break;
+       case FUTEX_OP_ANDN:
+               tmp &= ~oparg;
+               break;
+       case FUTEX_OP_XOR:
+               tmp ^= oparg;
+               break;
+       default:
+               ret = -ENOSYS;
+       }
+
+       if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
+               ret = -EFAULT;
+
+out_pagefault_enable:
+       pagefault_enable();     /* subsumes preempt_enable() */
+
+       if (ret == 0) {
+               switch (cmp) {
+               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+               default: ret = -ENOSYS;
+               }
+       }
+       return ret;
+}
+
+#endif /* CONFIG_MMU */
+#endif /* __KERNEL__ */
+#endif /* _ASM_M68K_FUTEX_H */
index 8cc8343..2f6eec1 100644 (file)
@@ -86,6 +86,7 @@ static inline int gpio_cansleep(unsigned gpio)
        return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
 }
 
+#ifndef CONFIG_GPIOLIB
 static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
 {
        int err;
@@ -105,5 +106,5 @@ static inline int gpio_request_one(unsigned gpio, unsigned long flags, const cha
 
        return err;
 }
-
+#endif /* !CONFIG_GPIOLIB */
 #endif
index d197e7f..ac85f16 100644 (file)
@@ -2752,11 +2752,9 @@ func_return      get_new_page
 #ifdef CONFIG_MAC
 
 L(scc_initable_mac):
-       .byte   9,12            /* Reset */
        .byte   4,0x44          /* x16, 1 stopbit, no parity */
        .byte   3,0xc0          /* receiver: 8 bpc */
        .byte   5,0xe2          /* transmitter: 8 bpc, assert dtr/rts */
-       .byte   9,0             /* no interrupts */
        .byte   10,0            /* NRZ */
        .byte   11,0x50         /* use baud rate generator */
        .byte   12,1,13,0       /* 38400 baud */
@@ -2899,6 +2897,7 @@ func_start        serial_init,%d0/%d1/%a0/%a1
        is_not_mac(L(serial_init_not_mac))
 
 #ifdef SERIAL_DEBUG
+
 /* You may define either or both of these. */
 #define MAC_USE_SCC_A /* Modem port */
 #define MAC_USE_SCC_B /* Printer port */
@@ -2908,9 +2907,21 @@ func_start       serial_init,%d0/%d1/%a0/%a1
 #define mac_scc_cha_b_data_offset      0x4
 #define mac_scc_cha_a_data_offset      0x6
 
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
+       movel   %pc@(L(mac_sccbase)),%a0
+       /* Reset SCC device */
+       moveb   #9,%a0@(mac_scc_cha_a_ctrl_offset)
+       moveb   #0xc0,%a0@(mac_scc_cha_a_ctrl_offset)
+       /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */
+       /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */
+       movel   #35,%d0
+5:
+       subq    #1,%d0
+       jne     5b
+#endif
+
 #ifdef MAC_USE_SCC_A
        /* Initialize channel A */
-       movel   %pc@(L(mac_sccbase)),%a0
        lea     %pc@(L(scc_initable_mac)),%a1
 5:     moveb   %a1@+,%d0
        jmi     6f
@@ -2922,9 +2933,6 @@ func_start        serial_init,%d0/%d1/%a0/%a1
 
 #ifdef MAC_USE_SCC_B
        /* Initialize channel B */
-#ifndef MAC_USE_SCC_A  /* Load mac_sccbase only if needed */
-       movel   %pc@(L(mac_sccbase)),%a0
-#endif /* MAC_USE_SCC_A */
        lea     %pc@(L(scc_initable_mac)),%a1
 7:     moveb   %a1@+,%d0
        jmi     8f
@@ -2933,6 +2941,7 @@ func_start        serial_init,%d0/%d1/%a0/%a1
        jra     7b
 8:
 #endif /* MAC_USE_SCC_B */
+
 #endif /* SERIAL_DEBUG */
 
        jra     L(serial_init_done)
@@ -3006,17 +3015,17 @@ func_start      serial_putc,%d0/%d1/%a0/%a1
 
 #ifdef SERIAL_DEBUG
 
-#ifdef MAC_USE_SCC_A
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
        movel   %pc@(L(mac_sccbase)),%a1
+#endif
+
+#ifdef MAC_USE_SCC_A
 3:     btst    #2,%a1@(mac_scc_cha_a_ctrl_offset)
        jeq     3b
        moveb   %d0,%a1@(mac_scc_cha_a_data_offset)
 #endif /* MAC_USE_SCC_A */
 
 #ifdef MAC_USE_SCC_B
-#ifndef MAC_USE_SCC_A  /* Load mac_sccbase only if needed */
-       movel   %pc@(L(mac_sccbase)),%a1
-#endif /* MAC_USE_SCC_A */
 4:     btst    #2,%a1@(mac_scc_cha_b_ctrl_offset)
        jeq     4b
        moveb   %d0,%a1@(mac_scc_cha_b_data_offset)
index 0f553bc..ffea82a 100644 (file)
@@ -102,21 +102,23 @@ do { \
 
 #define flush_cache_range(vma, start, len) do { } while (0)
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)             \
-do {                                                                   \
-       u32 addr = virt_to_phys(dst);                                   \
-       memcpy((dst), (src), (len));                                    \
-       if (vma->vm_flags & VM_EXEC) {                                  \
-               invalidate_icache_range((unsigned) (addr),              \
-                                       (unsigned) (addr) + PAGE_SIZE); \
-               flush_dcache_range((unsigned) (addr),                   \
-                                       (unsigned) (addr) + PAGE_SIZE); \
-       }                                                               \
-} while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len)           \
-do {                                                                   \
-       memcpy((dst), (src), (len));                                    \
-} while (0)
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+                                    struct page *page, unsigned long vaddr,
+                                    void *dst, void *src, int len)
+{
+       u32 addr = virt_to_phys(dst);
+       memcpy(dst, src, len);
+       if (vma->vm_flags & VM_EXEC) {
+               invalidate_icache_range(addr, addr + PAGE_SIZE);
+               flush_dcache_range(addr, addr + PAGE_SIZE);
+       }
+}
+
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+                                      struct page *page, unsigned long vaddr,
+                                      void *dst, void *src, int len)
+{
+       memcpy(dst, src, len);
+}
 
 #endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
index ff8cde1..01848f0 100644 (file)
@@ -105,7 +105,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 
        __asm__ __volatile__ ("1:       lwx     %1, %3, r0;             \
                                        cmp     %2, %1, %4;             \
-                                       beqi    %2, 3f;                 \
+                                       bnei    %2, 3f;                 \
                                2:      swx     %5, %3, r0;             \
                                        addic   %2, r0, 0;              \
                                        bnei    %2, 1b;                 \
index 8cb8a85..2565cb9 100644 (file)
@@ -123,11 +123,11 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
  * inb_p/inw_p/...
  * The macros don't do byte-swapping.
  */
-#define inb(port)              readb((u8 *)((port)))
+#define inb(port)              readb((u8 *)((unsigned long)(port)))
 #define outb(val, port)                writeb((val), (u8 *)((unsigned long)(port)))
-#define inw(port)              readw((u16 *)((port)))
+#define inw(port)              readw((u16 *)((unsigned long)(port)))
 #define outw(val, port)                writew((val), (u16 *)((unsigned long)(port)))
-#define inl(port)              readl((u32 *)((port)))
+#define inl(port)              readl((u32 *)((unsigned long)(port)))
 #define outl(val, port)                writel((val), (u32 *)((unsigned long)(port)))
 
 #define inb_p(port)            inb((port))
index efe59d8..04e4955 100644 (file)
@@ -99,13 +99,13 @@ static inline int access_ok(int type, const void __user *addr,
        if ((get_fs().seg < ((unsigned long)addr)) ||
                        (get_fs().seg < ((unsigned long)addr + size - 1))) {
                pr_debug("ACCESS fail: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
-                       type ? "WRITE" : "READ ", (u32)addr, (u32)size,
+                       type ? "WRITE" : "READ ", (__force u32)addr, (u32)size,
                        (u32)get_fs().seg);
                return 0;
        }
 ok:
        pr_debug("ACCESS OK: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
-                       type ? "WRITE" : "READ ", (u32)addr, (u32)size,
+                       type ? "WRITE" : "READ ", (__force u32)addr, (u32)size,
                        (u32)get_fs().seg);
        return 1;
 }
index 4254514..a6e4441 100644 (file)
@@ -140,7 +140,7 @@ do {                                                                        \
 /* It is used only first parameter for OP - for wic, wdc */
 #define CACHE_RANGE_LOOP_1(start, end, line_length, op)                        \
 do {                                                                   \
-       int volatile temp;                                              \
+       int volatile temp = 0;                                          \
        int align = ~(line_length - 1);                                 \
        end = ((end & align) == end) ? end - line_length : end & align; \
        WARN_ON(end - start < 0);                                       \
index b0baa29..01b1b3f 100644 (file)
@@ -428,13 +428,16 @@ static void octeon_restart(char *command)
  */
 static void octeon_kill_core(void *arg)
 {
-       mb();
-       if (octeon_is_simulation()) {
-               /* The simulator needs the watchdog to stop for dead cores */
-               cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+       if (octeon_is_simulation())
                /* A break instruction causes the simulator stop a core */
-               asm volatile ("sync\nbreak");
-       }
+               asm volatile ("break" ::: "memory");
+
+       local_irq_disable();
+       /* Disable watchdog on this core. */
+       cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+       /* Spin in a low power mode. */
+       while (true)
+               asm volatile ("wait" ::: "memory");
 }
 
 
index 143875c..4d6fa0b 100644 (file)
@@ -496,10 +496,6 @@ struct kvm_mips_callbacks {
                            uint32_t cause);
        int (*irq_clear) (struct kvm_vcpu *vcpu, unsigned int priority,
                          uint32_t cause);
-       int (*vcpu_ioctl_get_regs) (struct kvm_vcpu *vcpu,
-                                   struct kvm_regs *regs);
-       int (*vcpu_ioctl_set_regs) (struct kvm_vcpu *vcpu,
-                                   struct kvm_regs *regs);
 };
 extern struct kvm_mips_callbacks *kvm_mips_callbacks;
 int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks);
index 8201160..516e6e9 100644 (file)
@@ -117,7 +117,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
        if (! ((asid += ASID_INC) & ASID_MASK) ) {
                if (cpu_has_vtag_icache)
                        flush_icache_all();
-#ifdef CONFIG_VIRTUALIZATION
+#ifdef CONFIG_KVM
                kvm_local_flush_tlb_all();      /* start new asid cycle */
 #else
                local_flush_tlb_all();  /* start new asid cycle */
index a3186f2..5e6cd09 100644 (file)
 #include <asm/isadep.h>
 #include <uapi/asm/ptrace.h>
 
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+#ifdef CONFIG_32BIT
+       /* Pad bytes for argument save space on the stack. */
+       unsigned long pad0[6];
+#endif
+
+       /* Saved main processor registers. */
+       unsigned long regs[32];
+
+       /* Saved special registers. */
+       unsigned long cp0_status;
+       unsigned long hi;
+       unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       unsigned long acx;
+#endif
+       unsigned long cp0_badvaddr;
+       unsigned long cp0_cause;
+       unsigned long cp0_epc;
+#ifdef CONFIG_MIPS_MT_SMTC
+       unsigned long cp0_tcstatus;
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+       unsigned long long mpl[3];        /* MTM{0,1,2} */
+       unsigned long long mtp[3];        /* MTP{0,1,2} */
+#endif
+} __aligned(8);
+
 struct task_struct;
 
 extern int ptrace_getregs(struct task_struct *child, __s64 __user *data);
index 85789ea..f09ff5a 100644 (file)
 /*
-* This file is subject to the terms and conditions of the GNU General Public
-* License.  See the file "COPYING" in the main directory of this archive
-* for more details.
-*
-* Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
-* Authors: Sanjay Lal <sanjayl@kymasys.com>
-*/
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Cavium, Inc.
+ * Authors: Sanjay Lal <sanjayl@kymasys.com>
+ */
 
 #ifndef __LINUX_KVM_MIPS_H
 #define __LINUX_KVM_MIPS_H
 
 #include <linux/types.h>
 
-#define __KVM_MIPS
-
-#define N_MIPS_COPROC_REGS      32
-#define N_MIPS_COPROC_SEL      8
+/*
+ * KVM MIPS specific structures and definitions.
+ *
+ * Some parts derived from the x86 version of this file.
+ */
 
-/* for KVM_GET_REGS and KVM_SET_REGS */
+/*
+ * for KVM_GET_REGS and KVM_SET_REGS
+ *
+ * If Config[AT] is zero (32-bit CPU), the register contents are
+ * stored in the lower 32-bits of the struct kvm_regs fields and sign
+ * extended to 64-bits.
+ */
 struct kvm_regs {
-       __u32 gprs[32];
-       __u32 hi;
-       __u32 lo;
-       __u32 pc;
-
-       __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL];
-};
-
-/* for KVM_GET_SREGS and KVM_SET_SREGS */
-struct kvm_sregs {
+       /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
+       __u64 gpr[32];
+       __u64 hi;
+       __u64 lo;
+       __u64 pc;
 };
 
-/* for KVM_GET_FPU and KVM_SET_FPU */
+/*
+ * for KVM_GET_FPU and KVM_SET_FPU
+ *
+ * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs
+ * are zero filled.
+ */
 struct kvm_fpu {
+       __u64 fpr[32];
+       __u32 fir;
+       __u32 fccr;
+       __u32 fexr;
+       __u32 fenr;
+       __u32 fcsr;
+       __u32 pad;
 };
 
+
+/*
+ * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0
+ * registers.  The id field is broken down as follows:
+ *
+ *  bits[2..0]   - Register 'sel' index.
+ *  bits[7..3]   - Register 'rd'  index.
+ *  bits[15..8]  - Must be zero.
+ *  bits[31..16] - 1 -> CP0 registers.
+ *  bits[51..32] - Must be zero.
+ *  bits[63..52] - As per linux/kvm.h
+ *
+ * Other sets registers may be added in the future.  Each set would
+ * have its own identifier in bits[31..16].
+ *
+ * The registers defined in struct kvm_regs are also accessible, the
+ * id values for these are below.
+ */
+
+#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0)
+#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1)
+#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2)
+#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3)
+#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4)
+#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5)
+#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6)
+#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7)
+#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8)
+#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9)
+#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10)
+#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11)
+#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12)
+#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13)
+#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14)
+#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15)
+#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16)
+#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17)
+#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18)
+#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19)
+#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20)
+#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21)
+#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22)
+#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23)
+#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24)
+#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25)
+#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26)
+#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27)
+#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28)
+#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29)
+#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30)
+#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31)
+
+#define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32)
+#define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33)
+#define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34)
+
+/*
+ * KVM MIPS specific structures and definitions
+ *
+ */
 struct kvm_debug_exit_arch {
+       __u64 epc;
 };
 
 /* for KVM_SET_GUEST_DEBUG */
 struct kvm_guest_debug_arch {
 };
 
+/* definition of registers in kvm_run */
+struct kvm_sync_regs {
+};
+
+/* dummy definition */
+struct kvm_sregs {
+};
+
 struct kvm_mips_interrupt {
        /* in */
        __u32 cpu;
        __u32 irq;
 };
 
-/* definition of registers in kvm_run */
-struct kvm_sync_regs {
-};
-
 #endif /* __LINUX_KVM_MIPS_H */
index 4d58d84..b26f7e3 100644 (file)
 #define DSP_CONTROL    77
 #define ACX            78
 
+#ifndef __KERNEL__
 /*
  * This struct defines the way the registers are stored on the stack during a
  * system call/exception. As usual the registers k0/k1 aren't being saved.
  */
 struct pt_regs {
-#ifdef CONFIG_32BIT
-       /* Pad bytes for argument save space on the stack. */
-       unsigned long pad0[6];
-#endif
-
        /* Saved main processor registers. */
        unsigned long regs[32];
 
@@ -39,20 +35,11 @@ struct pt_regs {
        unsigned long cp0_status;
        unsigned long hi;
        unsigned long lo;
-#ifdef CONFIG_CPU_HAS_SMARTMIPS
-       unsigned long acx;
-#endif
        unsigned long cp0_badvaddr;
        unsigned long cp0_cause;
        unsigned long cp0_epc;
-#ifdef CONFIG_MIPS_MT_SMTC
-       unsigned long cp0_tcstatus;
-#endif /* CONFIG_MIPS_MT_SMTC */
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-       unsigned long long mpl[3];        /* MTM{0,1,2} */
-       unsigned long long mtp[3];        /* MTP{0,1,2} */
-#endif
 } __attribute__ ((aligned (8)));
+#endif /* __KERNEL__ */
 
 /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
 #define PTRACE_GETREGS         12
index e06f777..1188e00 100644 (file)
@@ -119,4 +119,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
 #undef TASK_SIZE
 #define TASK_SIZE TASK_SIZE32
 
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
+static __inline__ void
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
+{
+       unsigned long jiffies = cputime_to_jiffies(cputime);
+
+       value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+       value->tv_sec = jiffies / HZ;
+}
+
 #include "../../../fs/binfmt_elf.c"
index 97c5a16..202e581 100644 (file)
@@ -162,4 +162,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
 #undef TASK_SIZE
 #define TASK_SIZE TASK_SIZE32
 
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
+static __inline__ void
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
+{
+       unsigned long jiffies = cputime_to_jiffies(cputime);
+
+       value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+       value->tv_sec = jiffies / HZ;
+}
+
 #include "../../../fs/binfmt_elf.c"
index cf5509f..dba90ec 100644 (file)
 #define MCOUNT_OFFSET_INSNS 4
 #endif
 
+#ifdef CONFIG_DYNAMIC_FTRACE
+
 /* Arch override because MIPS doesn't need to run this from stop_machine() */
 void arch_ftrace_update_code(int command)
 {
        ftrace_modify_all_code(command);
 }
 
+#endif
+
 /*
  * Check if the address is in kernel space
  *
index 3b09b88..0c655de 100644 (file)
@@ -93,26 +93,27 @@ static void rm7k_wait_irqoff(void)
 }
 
 /*
- * The Au1xxx wait is available only if using 32khz counter or
- * external timer source, but specifically not CP0 Counter.
- * alchemy/common/time.c may override cpu_wait!
+ * Au1 'wait' is only useful when the 32kHz counter is used as timer,
+ * since coreclock (and the cp0 counter) stops upon executing it. Only an
+ * interrupt can wake it, so they must be enabled before entering idle modes.
  */
 static void au1k_wait(void)
 {
+       unsigned long c0status = read_c0_status() | 1;  /* irqs on */
+
        __asm__(
        "       .set    mips3                   \n"
        "       cache   0x14, 0(%0)             \n"
        "       cache   0x14, 32(%0)            \n"
        "       sync                            \n"
-       "       nop                             \n"
+       "       mtc0    %1, $12                 \n" /* wr c0status */
        "       wait                            \n"
        "       nop                             \n"
        "       nop                             \n"
        "       nop                             \n"
        "       nop                             \n"
        "       .set    mips0                   \n"
-       : : "r" (au1k_wait));
-       local_irq_enable();
+       : : "r" (au1k_wait), "r" (c0status));
 }
 
 static int __initdata nowait;
index 93c070b..6fa198d 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/processor.h>
 #include <asm/vpe.h>
 #include <asm/rtlx.h>
+#include <asm/setup.h>
 
 static struct rtlx_info *rtlx;
 static int major;
index e3be670..a75ae40 100644 (file)
@@ -897,22 +897,24 @@ out_sigsegv:
 
 asmlinkage void do_tr(struct pt_regs *regs)
 {
-       unsigned int opcode, tcode = 0;
+       u32 opcode, tcode = 0;
        u16 instr[2];
-       unsigned long epc = exception_epc(regs);
+       unsigned long epc = msk_isa16_mode(exception_epc(regs));
 
-       if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) ||
-               (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2))))
+       if (get_isa16_mode(regs->cp0_epc)) {
+               if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
+                   __get_user(instr[1], (u16 __user *)(epc + 2)))
                        goto out_sigsegv;
-       opcode = (instr[0] << 16) | instr[1];
-
-       /* Immediate versions don't provide a code.  */
-       if (!(opcode & OPCODE)) {
-               if (get_isa16_mode(regs->cp0_epc))
-                       /* microMIPS */
-                       tcode = (opcode >> 12) & 0x1f;
-               else
-                       tcode = ((opcode >> 6) & ((1 << 10) - 1));
+               opcode = (instr[0] << 16) | instr[1];
+               /* Immediate versions don't provide a code.  */
+               if (!(opcode & OPCODE))
+                       tcode = (opcode >> 12) & ((1 << 4) - 1);
+       } else {
+               if (__get_user(opcode, (u32 __user *)epc))
+                       goto out_sigsegv;
+               /* Immediate versions don't provide a code.  */
+               if (!(opcode & OPCODE))
+                       tcode = (opcode >> 6) & ((1 << 10) - 1);
        }
 
        do_trap_or_bp(regs, tcode, "Trap");
index e0dad02..dd203e5 100644 (file)
@@ -195,7 +195,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
 long
 kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 void kvm_arch_free_memslot(struct kvm_memory_slot *free,
@@ -401,7 +401,7 @@ int
 kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
                                    struct kvm_guest_debug *dbg)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
@@ -475,14 +475,248 @@ int
 kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
                                struct kvm_mp_state *mp_state)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 int
 kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
                                struct kvm_mp_state *mp_state)
 {
-       return -EINVAL;
+       return -ENOIOCTLCMD;
+}
+
+#define MIPS_CP0_32(_R, _S)                                    \
+       (KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x10000 | (8 * (_R) + (_S)))
+
+#define MIPS_CP0_64(_R, _S)                                    \
+       (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x10000 | (8 * (_R) + (_S)))
+
+#define KVM_REG_MIPS_CP0_INDEX         MIPS_CP0_32(0, 0)
+#define KVM_REG_MIPS_CP0_ENTRYLO0      MIPS_CP0_64(2, 0)
+#define KVM_REG_MIPS_CP0_ENTRYLO1      MIPS_CP0_64(3, 0)
+#define KVM_REG_MIPS_CP0_CONTEXT       MIPS_CP0_64(4, 0)
+#define KVM_REG_MIPS_CP0_USERLOCAL     MIPS_CP0_64(4, 2)
+#define KVM_REG_MIPS_CP0_PAGEMASK      MIPS_CP0_32(5, 0)
+#define KVM_REG_MIPS_CP0_PAGEGRAIN     MIPS_CP0_32(5, 1)
+#define KVM_REG_MIPS_CP0_WIRED         MIPS_CP0_32(6, 0)
+#define KVM_REG_MIPS_CP0_HWRENA                MIPS_CP0_32(7, 0)
+#define KVM_REG_MIPS_CP0_BADVADDR      MIPS_CP0_64(8, 0)
+#define KVM_REG_MIPS_CP0_COUNT         MIPS_CP0_32(9, 0)
+#define KVM_REG_MIPS_CP0_ENTRYHI       MIPS_CP0_64(10, 0)
+#define KVM_REG_MIPS_CP0_COMPARE       MIPS_CP0_32(11, 0)
+#define KVM_REG_MIPS_CP0_STATUS                MIPS_CP0_32(12, 0)
+#define KVM_REG_MIPS_CP0_CAUSE         MIPS_CP0_32(13, 0)
+#define KVM_REG_MIPS_CP0_EBASE         MIPS_CP0_64(15, 1)
+#define KVM_REG_MIPS_CP0_CONFIG                MIPS_CP0_32(16, 0)
+#define KVM_REG_MIPS_CP0_CONFIG1       MIPS_CP0_32(16, 1)
+#define KVM_REG_MIPS_CP0_CONFIG2       MIPS_CP0_32(16, 2)
+#define KVM_REG_MIPS_CP0_CONFIG3       MIPS_CP0_32(16, 3)
+#define KVM_REG_MIPS_CP0_CONFIG7       MIPS_CP0_32(16, 7)
+#define KVM_REG_MIPS_CP0_XCONTEXT      MIPS_CP0_64(20, 0)
+#define KVM_REG_MIPS_CP0_ERROREPC      MIPS_CP0_64(30, 0)
+
+static u64 kvm_mips_get_one_regs[] = {
+       KVM_REG_MIPS_R0,
+       KVM_REG_MIPS_R1,
+       KVM_REG_MIPS_R2,
+       KVM_REG_MIPS_R3,
+       KVM_REG_MIPS_R4,
+       KVM_REG_MIPS_R5,
+       KVM_REG_MIPS_R6,
+       KVM_REG_MIPS_R7,
+       KVM_REG_MIPS_R8,
+       KVM_REG_MIPS_R9,
+       KVM_REG_MIPS_R10,
+       KVM_REG_MIPS_R11,
+       KVM_REG_MIPS_R12,
+       KVM_REG_MIPS_R13,
+       KVM_REG_MIPS_R14,
+       KVM_REG_MIPS_R15,
+       KVM_REG_MIPS_R16,
+       KVM_REG_MIPS_R17,
+       KVM_REG_MIPS_R18,
+       KVM_REG_MIPS_R19,
+       KVM_REG_MIPS_R20,
+       KVM_REG_MIPS_R21,
+       KVM_REG_MIPS_R22,
+       KVM_REG_MIPS_R23,
+       KVM_REG_MIPS_R24,
+       KVM_REG_MIPS_R25,
+       KVM_REG_MIPS_R26,
+       KVM_REG_MIPS_R27,
+       KVM_REG_MIPS_R28,
+       KVM_REG_MIPS_R29,
+       KVM_REG_MIPS_R30,
+       KVM_REG_MIPS_R31,
+
+       KVM_REG_MIPS_HI,
+       KVM_REG_MIPS_LO,
+       KVM_REG_MIPS_PC,
+
+       KVM_REG_MIPS_CP0_INDEX,
+       KVM_REG_MIPS_CP0_CONTEXT,
+       KVM_REG_MIPS_CP0_PAGEMASK,
+       KVM_REG_MIPS_CP0_WIRED,
+       KVM_REG_MIPS_CP0_BADVADDR,
+       KVM_REG_MIPS_CP0_ENTRYHI,
+       KVM_REG_MIPS_CP0_STATUS,
+       KVM_REG_MIPS_CP0_CAUSE,
+       /* EPC set via kvm_regs, et al. */
+       KVM_REG_MIPS_CP0_CONFIG,
+       KVM_REG_MIPS_CP0_CONFIG1,
+       KVM_REG_MIPS_CP0_CONFIG2,
+       KVM_REG_MIPS_CP0_CONFIG3,
+       KVM_REG_MIPS_CP0_CONFIG7,
+       KVM_REG_MIPS_CP0_ERROREPC
+};
+
+static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
+                           const struct kvm_one_reg *reg)
+{
+       struct mips_coproc *cop0 = vcpu->arch.cop0;
+       s64 v;
+
+       switch (reg->id) {
+       case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31:
+               v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0];
+               break;
+       case KVM_REG_MIPS_HI:
+               v = (long)vcpu->arch.hi;
+               break;
+       case KVM_REG_MIPS_LO:
+               v = (long)vcpu->arch.lo;
+               break;
+       case KVM_REG_MIPS_PC:
+               v = (long)vcpu->arch.pc;
+               break;
+
+       case KVM_REG_MIPS_CP0_INDEX:
+               v = (long)kvm_read_c0_guest_index(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONTEXT:
+               v = (long)kvm_read_c0_guest_context(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_PAGEMASK:
+               v = (long)kvm_read_c0_guest_pagemask(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_WIRED:
+               v = (long)kvm_read_c0_guest_wired(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_BADVADDR:
+               v = (long)kvm_read_c0_guest_badvaddr(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_ENTRYHI:
+               v = (long)kvm_read_c0_guest_entryhi(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_STATUS:
+               v = (long)kvm_read_c0_guest_status(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CAUSE:
+               v = (long)kvm_read_c0_guest_cause(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_ERROREPC:
+               v = (long)kvm_read_c0_guest_errorepc(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG:
+               v = (long)kvm_read_c0_guest_config(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG1:
+               v = (long)kvm_read_c0_guest_config1(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG2:
+               v = (long)kvm_read_c0_guest_config2(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG3:
+               v = (long)kvm_read_c0_guest_config3(cop0);
+               break;
+       case KVM_REG_MIPS_CP0_CONFIG7:
+               v = (long)kvm_read_c0_guest_config7(cop0);
+               break;
+       default:
+               return -EINVAL;
+       }
+       if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) {
+               u64 __user *uaddr64 = (u64 __user *)(long)reg->addr;
+               return put_user(v, uaddr64);
+       } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
+               u32 __user *uaddr32 = (u32 __user *)(long)reg->addr;
+               u32 v32 = (u32)v;
+               return put_user(v32, uaddr32);
+       } else {
+               return -EINVAL;
+       }
+}
+
+static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
+                           const struct kvm_one_reg *reg)
+{
+       struct mips_coproc *cop0 = vcpu->arch.cop0;
+       u64 v;
+
+       if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) {
+               u64 __user *uaddr64 = (u64 __user *)(long)reg->addr;
+
+               if (get_user(v, uaddr64) != 0)
+                       return -EFAULT;
+       } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
+               u32 __user *uaddr32 = (u32 __user *)(long)reg->addr;
+               s32 v32;
+
+               if (get_user(v32, uaddr32) != 0)
+                       return -EFAULT;
+               v = (s64)v32;
+       } else {
+               return -EINVAL;
+       }
+
+       switch (reg->id) {
+       case KVM_REG_MIPS_R0:
+               /* Silently ignore requests to set $0 */
+               break;
+       case KVM_REG_MIPS_R1 ... KVM_REG_MIPS_R31:
+               vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0] = v;
+               break;
+       case KVM_REG_MIPS_HI:
+               vcpu->arch.hi = v;
+               break;
+       case KVM_REG_MIPS_LO:
+               vcpu->arch.lo = v;
+               break;
+       case KVM_REG_MIPS_PC:
+               vcpu->arch.pc = v;
+               break;
+
+       case KVM_REG_MIPS_CP0_INDEX:
+               kvm_write_c0_guest_index(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_CONTEXT:
+               kvm_write_c0_guest_context(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_PAGEMASK:
+               kvm_write_c0_guest_pagemask(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_WIRED:
+               kvm_write_c0_guest_wired(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_BADVADDR:
+               kvm_write_c0_guest_badvaddr(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_ENTRYHI:
+               kvm_write_c0_guest_entryhi(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_STATUS:
+               kvm_write_c0_guest_status(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_CAUSE:
+               kvm_write_c0_guest_cause(cop0, v);
+               break;
+       case KVM_REG_MIPS_CP0_ERROREPC:
+               kvm_write_c0_guest_errorepc(cop0, v);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
 }
 
 long
@@ -491,9 +725,38 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
        struct kvm_vcpu *vcpu = filp->private_data;
        void __user *argp = (void __user *)arg;
        long r;
-       int intr;
 
        switch (ioctl) {
+       case KVM_SET_ONE_REG:
+       case KVM_GET_ONE_REG: {
+               struct kvm_one_reg reg;
+               if (copy_from_user(&reg, argp, sizeof(reg)))
+                       return -EFAULT;
+               if (ioctl == KVM_SET_ONE_REG)
+                       return kvm_mips_set_reg(vcpu, &reg);
+               else
+                       return kvm_mips_get_reg(vcpu, &reg);
+       }
+       case KVM_GET_REG_LIST: {
+               struct kvm_reg_list __user *user_list = argp;
+               u64 __user *reg_dest;
+               struct kvm_reg_list reg_list;
+               unsigned n;
+
+               if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
+                       return -EFAULT;
+               n = reg_list.n;
+               reg_list.n = ARRAY_SIZE(kvm_mips_get_one_regs);
+               if (copy_to_user(user_list, &reg_list, sizeof(reg_list)))
+                       return -EFAULT;
+               if (n < reg_list.n)
+                       return -E2BIG;
+               reg_dest = user_list->reg;
+               if (copy_to_user(reg_dest, kvm_mips_get_one_regs,
+                                sizeof(kvm_mips_get_one_regs)))
+                       return -EFAULT;
+               return 0;
+       }
        case KVM_NMI:
                /* Treat the NMI as a CPU reset */
                r = kvm_mips_reset_vcpu(vcpu);
@@ -505,8 +768,6 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
                        if (copy_from_user(&irq, argp, sizeof(irq)))
                                goto out;
 
-                       intr = (int)irq.irq;
-
                        kvm_debug("[%d] %s: irq: %d\n", vcpu->vcpu_id, __func__,
                                  irq.irq);
 
@@ -514,7 +775,7 @@ kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
                        break;
                }
        default:
-               r = -EINVAL;
+               r = -ENOIOCTLCMD;
        }
 
 out:
@@ -565,7 +826,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
 
        switch (ioctl) {
        default:
-               r = -EINVAL;
+               r = -ENOIOCTLCMD;
        }
 
        return r;
@@ -593,13 +854,13 @@ void kvm_arch_exit(void)
 int
 kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int
 kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
@@ -609,12 +870,12 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
-       return -ENOTSUPP;
+       return -ENOIOCTLCMD;
 }
 
 int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
@@ -627,6 +888,9 @@ int kvm_dev_ioctl_check_extension(long ext)
        int r;
 
        switch (ext) {
+       case KVM_CAP_ONE_REG:
+               r = 1;
+               break;
        case KVM_CAP_COALESCED_MMIO:
                r = KVM_COALESCED_MMIO_PAGE_OFFSET;
                break;
@@ -635,7 +899,6 @@ int kvm_dev_ioctl_check_extension(long ext)
                break;
        }
        return r;
-
 }
 
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -677,28 +940,28 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
        int i;
 
-       for (i = 0; i < 32; i++)
-               vcpu->arch.gprs[i] = regs->gprs[i];
-
+       for (i = 1; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
+               vcpu->arch.gprs[i] = regs->gpr[i];
+       vcpu->arch.gprs[0] = 0; /* zero is special, and cannot be set. */
        vcpu->arch.hi = regs->hi;
        vcpu->arch.lo = regs->lo;
        vcpu->arch.pc = regs->pc;
 
-       return kvm_mips_callbacks->vcpu_ioctl_set_regs(vcpu, regs);
+       return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
        int i;
 
-       for (i = 0; i < 32; i++)
-               regs->gprs[i] = vcpu->arch.gprs[i];
+       for (i = 0; i < ARRAY_SIZE(vcpu->arch.gprs); i++)
+               regs->gpr[i] = vcpu->arch.gprs[i];
 
        regs->hi = vcpu->arch.hi;
        regs->lo = vcpu->arch.lo;
        regs->pc = vcpu->arch.pc;
 
-       return kvm_mips_callbacks->vcpu_ioctl_get_regs(vcpu, regs);
+       return 0;
 }
 
 void kvm_mips_comparecount_func(unsigned long data)
index 466aeef..30d7253 100644 (file)
@@ -345,54 +345,6 @@ static int kvm_trap_emul_handle_break(struct kvm_vcpu *vcpu)
        return ret;
 }
 
-static int
-kvm_trap_emul_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-       struct mips_coproc *cop0 = vcpu->arch.cop0;
-
-       kvm_write_c0_guest_index(cop0, regs->cp0reg[MIPS_CP0_TLB_INDEX][0]);
-       kvm_write_c0_guest_context(cop0, regs->cp0reg[MIPS_CP0_TLB_CONTEXT][0]);
-       kvm_write_c0_guest_badvaddr(cop0, regs->cp0reg[MIPS_CP0_BAD_VADDR][0]);
-       kvm_write_c0_guest_entryhi(cop0, regs->cp0reg[MIPS_CP0_TLB_HI][0]);
-       kvm_write_c0_guest_epc(cop0, regs->cp0reg[MIPS_CP0_EXC_PC][0]);
-
-       kvm_write_c0_guest_status(cop0, regs->cp0reg[MIPS_CP0_STATUS][0]);
-       kvm_write_c0_guest_cause(cop0, regs->cp0reg[MIPS_CP0_CAUSE][0]);
-       kvm_write_c0_guest_pagemask(cop0,
-                                   regs->cp0reg[MIPS_CP0_TLB_PG_MASK][0]);
-       kvm_write_c0_guest_wired(cop0, regs->cp0reg[MIPS_CP0_TLB_WIRED][0]);
-       kvm_write_c0_guest_errorepc(cop0, regs->cp0reg[MIPS_CP0_ERROR_PC][0]);
-
-       return 0;
-}
-
-static int
-kvm_trap_emul_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-       struct mips_coproc *cop0 = vcpu->arch.cop0;
-
-       regs->cp0reg[MIPS_CP0_TLB_INDEX][0] = kvm_read_c0_guest_index(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_CONTEXT][0] = kvm_read_c0_guest_context(cop0);
-       regs->cp0reg[MIPS_CP0_BAD_VADDR][0] = kvm_read_c0_guest_badvaddr(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_HI][0] = kvm_read_c0_guest_entryhi(cop0);
-       regs->cp0reg[MIPS_CP0_EXC_PC][0] = kvm_read_c0_guest_epc(cop0);
-
-       regs->cp0reg[MIPS_CP0_STATUS][0] = kvm_read_c0_guest_status(cop0);
-       regs->cp0reg[MIPS_CP0_CAUSE][0] = kvm_read_c0_guest_cause(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_PG_MASK][0] =
-           kvm_read_c0_guest_pagemask(cop0);
-       regs->cp0reg[MIPS_CP0_TLB_WIRED][0] = kvm_read_c0_guest_wired(cop0);
-       regs->cp0reg[MIPS_CP0_ERROR_PC][0] = kvm_read_c0_guest_errorepc(cop0);
-
-       regs->cp0reg[MIPS_CP0_CONFIG][0] = kvm_read_c0_guest_config(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][1] = kvm_read_c0_guest_config1(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][2] = kvm_read_c0_guest_config2(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][3] = kvm_read_c0_guest_config3(cop0);
-       regs->cp0reg[MIPS_CP0_CONFIG][7] = kvm_read_c0_guest_config7(cop0);
-
-       return 0;
-}
-
 static int kvm_trap_emul_vm_init(struct kvm *kvm)
 {
        return 0;
@@ -471,8 +423,6 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
        .dequeue_io_int = kvm_mips_dequeue_io_int_cb,
        .irq_deliver = kvm_mips_irq_deliver_cb,
        .irq_clear = kvm_mips_irq_clear_cb,
-       .vcpu_ioctl_get_regs = kvm_trap_emul_ioctl_get_regs,
-       .vcpu_ioctl_set_regs = kvm_trap_emul_ioctl_set_regs,
 };
 
 int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks)
index ce9818e..afeef93 100644 (file)
@@ -301,10 +301,6 @@ static u32 tlb_handler[128] __cpuinitdata;
 static struct uasm_label labels[128] __cpuinitdata;
 static struct uasm_reloc relocs[128] __cpuinitdata;
 
-#ifdef CONFIG_64BIT
-static int check_for_high_segbits __cpuinitdata;
-#endif
-
 static int check_for_high_segbits __cpuinitdata;
 
 static unsigned int kscratch_used_mask __cpuinitdata;
index fb15695..6b5f340 100644 (file)
@@ -88,7 +88,7 @@ void __init plat_mem_setup(void)
        __dt_setup_arch(&__dtb_start);
 
        if (soc_info.mem_size)
-               add_memory_region(soc_info.mem_base, soc_info.mem_size,
+               add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
                                  BOOT_MEM_RAM);
        else
                detect_memory_region(soc_info.mem_base,
index 8137c25..6f31cc0 100644 (file)
@@ -103,4 +103,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
        return channel ? 15 : 14;
 }
 
+#include <asm-generic/pci_iomap.h>
+
 #endif /* _ASM_PCI_H */
index 68fcab8..222152a 100644 (file)
@@ -60,6 +60,7 @@ ENTRY(ret_from_kernel_thread)
        mov     (REG_D0,fp),d0
        mov     (REG_A0,fp),a0
        calls   (a0)
+       GET_THREAD_INFO a2              # A2 must be set on return from sys_exit()
        clr     d0
        mov     d0,(REG_D0,fp)
        jmp     syscall_exit
@@ -107,10 +108,10 @@ syscall_exit_work:
        and     EPSW_nSL,d0
        beq     resume_kernel           # returning to supervisor mode
 
-       btst    _TIF_SYSCALL_TRACE,d2
-       beq     work_pending
        LOCAL_IRQ_ENABLE                # could let syscall_trace_exit() call
                                        # schedule() instead
+       btst    _TIF_SYSCALL_TRACE,d2
+       beq     work_pending
        mov     fp,d0
        call    syscall_trace_exit[],0  # do_syscall_trace(regs)
        jmp     resume_userspace
@@ -123,6 +124,7 @@ work_pending:
 work_resched:
        call    schedule[],0
 
+resume_userspace:
        # make sure we don't miss an interrupt setting need_resched or
        # sigpending between sampling and the rti
        LOCAL_IRQ_DISABLE
@@ -131,6 +133,8 @@ work_resched:
        mov     (TI_flags,a2),d2
        btst    _TIF_WORK_MASK,d2
        beq     restore_all
+
+       LOCAL_IRQ_ENABLE
        btst    _TIF_NEED_RESCHED,d2
        bne     work_resched
 
@@ -169,17 +173,6 @@ ret_from_intr:
        and     EPSW_nSL,d0
        beq     resume_kernel           # returning to supervisor mode
 
-ENTRY(resume_userspace)
-       # make sure we don't miss an interrupt setting need_resched or
-       # sigpending between sampling and the rti
-       LOCAL_IRQ_DISABLE
-
-       # is there any work to be done on int/exception return?
-       mov     (TI_flags,a2),d2
-       btst    _TIF_WORK_MASK,d2
-       bne     work_pending
-       jmp     restore_all
-
 #ifdef CONFIG_PREEMPT
 ENTRY(resume_kernel)
        LOCAL_IRQ_DISABLE
index 1adcf02..e37fac0 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include "pci-asb2305.h"
 
 unsigned int pci_probe = 1;
index 1976900..96ec398 100644 (file)
@@ -66,7 +66,7 @@ KBUILD_CFLAGS_KERNEL += -mlong-calls
 endif
 
 # select which processor to optimise for
-cflags-$(CONFIG_PA7100)                += -march=1.1 -mschedule=7100
+cflags-$(CONFIG_PA7000)                += -march=1.1 -mschedule=7100
 cflags-$(CONFIG_PA7200)                += -march=1.1 -mschedule=7200
 cflags-$(CONFIG_PA7100LC)      += -march=1.1 -mschedule=7100LC
 cflags-$(CONFIG_PA7300LC)      += -march=1.1 -mschedule=7300
index 0e625ab..cc50d33 100644 (file)
@@ -39,17 +39,14 @@ extern unsigned char pfnnid_map[PFNNID_MAP_MAX];
 static inline int pfn_to_nid(unsigned long pfn)
 {
        unsigned int i;
-       unsigned char r;
 
        if (unlikely(pfn_is_io(pfn)))
                return 0;
 
        i = pfn >> PFNNID_SHIFT;
        BUG_ON(i >= ARRAY_SIZE(pfnnid_map));
-       r = pfnnid_map[i];
-       BUG_ON(r == 0xff);
 
-       return (int)r;
+       return (int)pfnnid_map[i];
 }
 
 static inline int pfn_valid(int pfn)
index 5709c5e..14285ca 100644 (file)
@@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath);
 static void setup_bus_id(struct parisc_device *padev)
 {
        struct hardware_path path;
-       char name[20];
+       char name[28];
        char *output = name;
        int i;
 
index 76b63e7..1e95b20 100644 (file)
@@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline_p)
                /* called from hpux boot loader */
                boot_command_line[0] = '\0';
        } else {
-               strcpy(boot_command_line, (char *)__va(boot_args[1]));
+               strlcpy(boot_command_line, (char *)__va(boot_args[1]),
+                       COMMAND_LINE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
                if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
index 26807e5..6f3887d 100644 (file)
@@ -176,6 +176,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_CFAR                   LONG_ASM_CONST(0x0100000000000000)
 #define        CPU_FTR_HAS_PPR                 LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_DAWR                   LONG_ASM_CONST(0x0400000000000000)
+#define CPU_FTR_DABRX                  LONG_ASM_CONST(0x0800000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -394,19 +395,20 @@ extern const char *powerpc_base_platform;
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
            CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \
-           CPU_FTR_HVMODE)
+           CPU_FTR_HVMODE | CPU_FTR_DABRX)
 #define CPU_FTRS_POWER5        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \
-           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
+           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_DABRX)
 #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | \
            CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
            CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
-           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR)
+           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR | \
+           CPU_FTR_DABRX)
 #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -415,7 +417,7 @@ extern const char *powerpc_base_platform;
            CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
            CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
            CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \
-           CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR)
+           CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX)
 #define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -430,14 +432,15 @@ extern const char *powerpc_base_platform;
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_PAUSE_ZERO  | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
-           CPU_FTR_UNALIGNED_LD_STD)
+           CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_DABRX)
 #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \
-           CPU_FTR_PURR | CPU_FTR_REAL_LE)
+           CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX)
 #define CPU_FTRS_COMPATIBLE    (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
 
 #define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \
-                    CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | CPU_FTR_ICSWX)
+                    CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \
+                    CPU_FTR_ICSWX | CPU_FTR_DABRX )
 
 #ifdef __powerpc64__
 #ifdef CONFIG_PPC_BOOK3E
index 8e5fae8..46793b5 100644 (file)
@@ -513,7 +513,7 @@ label##_common:                                                     \
  */
 #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr)            \
        EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \
-                        FINISH_NAP;RUNLATCH_ON;DISABLE_INTS)
+                        FINISH_NAP;DISABLE_INTS;RUNLATCH_ON)
 
 /*
  * When the idle code in power4_idle puts the CPU into NAP mode,
index cf4df8e..0c7f2bf 100644 (file)
 #define H_GET_MPP              0x2D4
 #define H_HOME_NODE_ASSOCIATIVITY 0x2EC
 #define H_BEST_ENERGY          0x2F4
+#define H_XIRR_X               0x2FC
 #define H_RANDOM               0x300
 #define H_COP                  0x304
 #define H_GET_MPP_X            0x314
index b9dd382..851bac7 100644 (file)
 #define BOOKE_INTERRUPT_DEBUG 15
 
 /* E500 */
-#define BOOKE_INTERRUPT_SPE_UNAVAIL 32
-#define BOOKE_INTERRUPT_SPE_FP_DATA 33
+#define BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL 32
+#define BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST 33
+/*
+ * TODO: Unify 32-bit and 64-bit kernel exception handlers to use same defines
+ */
+#define BOOKE_INTERRUPT_SPE_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL
+#define BOOKE_INTERRUPT_SPE_FP_DATA BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST
+#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL
+#define BOOKE_INTERRUPT_ALTIVEC_ASSIST \
+                               BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST
 #define BOOKE_INTERRUPT_SPE_FP_ROUND 34
 #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
 #define BOOKE_INTERRUPT_DOORBELL 36
 #define BOOKE_INTERRUPT_HV_SYSCALL 40
 #define BOOKE_INTERRUPT_HV_PRIV 41
 
-/* altivec */
-#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42
-#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43
-
 /* book3s */
 
 #define BOOK3S_INTERRUPT_SYSTEM_RESET  0x100
index cea8496..2f1b6c5 100644 (file)
@@ -523,6 +523,17 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946)
 #define PPC440EP_ERR42
 #endif
 
+/* The following stops all load and store data streams associated with stream
+ * ID (ie. streams created explicitly).  The embedded and server mnemonics for
+ * dcbt are different so we use machine "power4" here explicitly.
+ */
+#define DCBT_STOP_ALL_STREAM_IDS(scratch)      \
+.machine push ;                                        \
+.machine "power4" ;                            \
+       lis     scratch,0x60000000@h;           \
+       dcbt    r0,scratch,0b01010;             \
+.machine pop
+
 /*
  * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them
  * keep the address intact to be compatible with code shared with
index 594db6b..14a6583 100644 (file)
@@ -409,21 +409,16 @@ static inline void prefetchw(const void *x)
 #endif
 
 #ifdef CONFIG_PPC64
-static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
+static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
 {
-       unsigned long sp;
-
        if (is_32)
-               sp = regs->gpr[1] & 0x0ffffffffUL;
-       else
-               sp = regs->gpr[1];
-
+               return sp & 0x0ffffffffUL;
        return sp;
 }
 #else
-static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
+static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
 {
-       return regs->gpr[1];
+       return sp;
 }
 #endif
 
index a613651..4a9e408 100644 (file)
 #define MSR_TM_TRANSACTIONAL(x)        (((x) & MSR_TS_MASK) == MSR_TS_T)
 #define MSR_TM_SUSPENDED(x)    (((x) & MSR_TS_MASK) == MSR_TS_S)
 
-/* Reason codes describing kernel causes for transaction aborts.  By
-   convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if
-   the failure is persistent.
-*/
-#define TM_CAUSE_RESCHED       0xfe
-#define TM_CAUSE_TLBI          0xfc
-#define TM_CAUSE_FAC_UNAV      0xfa
-#define TM_CAUSE_SYSCALL       0xf9 /* Persistent */
-#define TM_CAUSE_MISC          0xf6
-#define TM_CAUSE_SIGNAL                0xf4
-
 #if defined(CONFIG_PPC_BOOK3S_64)
 #define MSR_64BIT      MSR_SF
 
index fbe66c4..9322c28 100644 (file)
@@ -3,5 +3,8 @@
 
 #define __ARCH_HAS_SA_RESTORER
 #include <uapi/asm/signal.h>
+#include <uapi/asm/ptrace.h>
+
+extern unsigned long get_tm_stackpointer(struct pt_regs *regs);
 
 #endif /* _ASM_POWERPC_SIGNAL_H */
index 4b4449a..9dfbc34 100644 (file)
@@ -5,6 +5,8 @@
  * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation.
  */
 
+#include <uapi/asm/tm.h>
+
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 extern void do_load_up_transact_fpu(struct thread_struct *thread);
 extern void do_load_up_transact_altivec(struct thread_struct *thread);
index f7bca63..5182c86 100644 (file)
@@ -40,6 +40,7 @@ header-y += statfs.h
 header-y += swab.h
 header-y += termbits.h
 header-y += termios.h
+header-y += tm.h
 header-y += types.h
 header-y += ucontext.h
 header-y += unistd.h
diff --git a/arch/powerpc/include/uapi/asm/tm.h b/arch/powerpc/include/uapi/asm/tm.h
new file mode 100644 (file)
index 0000000..85059a0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _ASM_POWERPC_TM_H
+#define _ASM_POWERPC_TM_H
+
+/* Reason codes describing kernel causes for transaction aborts.  By
+ * convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if
+ * the failure is persistent.  PAPR saves 0xff-0xe0 for the hypervisor.
+ */
+#define TM_CAUSE_PERSISTENT    0x01
+#define TM_CAUSE_RESCHED       0xde
+#define TM_CAUSE_TLBI          0xdc
+#define TM_CAUSE_FAC_UNAV      0xda
+#define TM_CAUSE_SYSCALL       0xd8  /* future use */
+#define TM_CAUSE_MISC          0xd6  /* future use */
+#define TM_CAUSE_SIGNAL                0xd4
+#define TM_CAUSE_ALIGNMENT     0xd2
+#define TM_CAUSE_EMULATE       0xd0
+
+#endif
index c60bbec..2a45d0f 100644 (file)
@@ -452,7 +452,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .mmu_features           = MMU_FTRS_POWER8,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
-               .oprofile_type          = PPC_OPROFILE_POWER4,
+               .oprofile_type          = PPC_OPROFILE_INVALID,
                .oprofile_cpu_type      = "ppc64/ibm-compat-v1",
                .cpu_setup              = __setup_cpu_power8,
                .cpu_restore            = __restore_cpu_power8,
@@ -482,7 +482,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_name               = "POWER7+ (raw)",
                .cpu_features           = CPU_FTRS_POWER7,
                .cpu_user_features      = COMMON_USER_POWER7,
-               .cpu_user_features      = COMMON_USER2_POWER7,
+               .cpu_user_features2     = COMMON_USER2_POWER7,
                .mmu_features           = MMU_FTRS_POWER7,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
@@ -507,7 +507,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .num_pmcs               = 6,
                .pmc_type               = PPC_PMC_IBM,
                .oprofile_cpu_type      = "ppc64/power8",
-               .oprofile_type          = PPC_OPROFILE_POWER4,
+               .oprofile_type          = PPC_OPROFILE_INVALID,
                .cpu_setup              = __setup_cpu_power8,
                .cpu_restore            = __restore_cpu_power8,
                .platform               = "power8",
index d22e73e..22b45a4 100644 (file)
@@ -849,7 +849,7 @@ resume_kernel:
        /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
        CURRENT_THREAD_INFO(r9, r1)
        lwz     r8,TI_FLAGS(r9)
-       andis.  r8,r8,_TIF_EMULATE_STACK_STORE@h
+       andis.  r0,r8,_TIF_EMULATE_STACK_STORE@h
        beq+    1f
 
        addi    r8,r1,INT_FRAME_SIZE    /* Get the kprobed function entry */
index 0e9095e..8741c85 100644 (file)
@@ -465,20 +465,6 @@ BEGIN_FTR_SECTION
        std     r0, THREAD_EBBHR(r3)
        mfspr   r0, SPRN_EBBRR
        std     r0, THREAD_EBBRR(r3)
-
-       /* PMU registers made user read/(write) by EBB */
-       mfspr   r0, SPRN_SIAR
-       std     r0, THREAD_SIAR(r3)
-       mfspr   r0, SPRN_SDAR
-       std     r0, THREAD_SDAR(r3)
-       mfspr   r0, SPRN_SIER
-       std     r0, THREAD_SIER(r3)
-       mfspr   r0, SPRN_MMCR0
-       std     r0, THREAD_MMCR0(r3)
-       mfspr   r0, SPRN_MMCR2
-       std     r0, THREAD_MMCR2(r3)
-       mfspr   r0, SPRN_MMCRA
-       std     r0, THREAD_MMCRA(r3)
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 #endif
 
@@ -501,6 +487,13 @@ BEGIN_FTR_SECTION
        ldarx   r6,0,r1
 END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS)
 
+#ifdef CONFIG_PPC_BOOK3S
+/* Cancel all explict user streams as they will have no use after context
+ * switch and will stop the HW from creating streams itself
+ */
+       DCBT_STOP_ALL_STREAM_IDS(r6)
+#endif
+
        addi    r6,r4,-THREAD   /* Convert THREAD to 'current' */
        std     r6,PACACURRENT(r13)     /* Set new 'current' */
 
@@ -574,20 +567,6 @@ BEGIN_FTR_SECTION
        ld      r0, THREAD_EBBRR(r4)
        mtspr   SPRN_EBBRR, r0
 
-       /* PMU registers made user read/(write) by EBB */
-       ld      r0, THREAD_SIAR(r4)
-       mtspr   SPRN_SIAR, r0
-       ld      r0, THREAD_SDAR(r4)
-       mtspr   SPRN_SDAR, r0
-       ld      r0, THREAD_SIER(r4)
-       mtspr   SPRN_SIER, r0
-       ld      r0, THREAD_MMCR0(r4)
-       mtspr   SPRN_MMCR0, r0
-       ld      r0, THREAD_MMCR2(r4)
-       mtspr   SPRN_MMCR2, r0
-       ld      r0, THREAD_MMCRA(r4)
-       mtspr   SPRN_MMCRA, r0
-
        ld      r0,THREAD_TAR(r4)
        mtspr   SPRN_TAR,r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
index e6eba1b..40e4a17 100644 (file)
@@ -454,38 +454,14 @@ BEGIN_FTR_SECTION
        xori    r10,r10,(MSR_FE0|MSR_FE1)
        mtmsrd  r10
        sync
-       fmr     0,0
-       fmr     1,1
-       fmr     2,2
-       fmr     3,3
-       fmr     4,4
-       fmr     5,5
-       fmr     6,6
-       fmr     7,7
-       fmr     8,8
-       fmr     9,9
-       fmr     10,10
-       fmr     11,11
-       fmr     12,12
-       fmr     13,13
-       fmr     14,14
-       fmr     15,15
-       fmr     16,16
-       fmr     17,17
-       fmr     18,18
-       fmr     19,19
-       fmr     20,20
-       fmr     21,21
-       fmr     22,22
-       fmr     23,23
-       fmr     24,24
-       fmr     25,25
-       fmr     26,26
-       fmr     27,27
-       fmr     28,28
-       fmr     29,29
-       fmr     30,30
-       fmr     31,31
+
+#define FMR2(n)  fmr (n), (n) ; fmr n+1, n+1
+#define FMR4(n)  FMR2(n) ; FMR2(n+2)
+#define FMR8(n)  FMR4(n) ; FMR4(n+4)
+#define FMR16(n) FMR8(n) ; FMR8(n+8)
+#define FMR32(n) FMR16(n) ; FMR16(n+16)
+       FMR32(0)
+
 FTR_SECTION_ELSE
 /*
  * To denormalise we need to move a copy of the register to itself.
@@ -495,39 +471,25 @@ FTR_SECTION_ELSE
        oris    r10,r10,MSR_VSX@h
        mtmsrd  r10
        sync
-       XVCPSGNDP(0,0,0)
-       XVCPSGNDP(1,1,1)
-       XVCPSGNDP(2,2,2)
-       XVCPSGNDP(3,3,3)
-       XVCPSGNDP(4,4,4)
-       XVCPSGNDP(5,5,5)
-       XVCPSGNDP(6,6,6)
-       XVCPSGNDP(7,7,7)
-       XVCPSGNDP(8,8,8)
-       XVCPSGNDP(9,9,9)
-       XVCPSGNDP(10,10,10)
-       XVCPSGNDP(11,11,11)
-       XVCPSGNDP(12,12,12)
-       XVCPSGNDP(13,13,13)
-       XVCPSGNDP(14,14,14)
-       XVCPSGNDP(15,15,15)
-       XVCPSGNDP(16,16,16)
-       XVCPSGNDP(17,17,17)
-       XVCPSGNDP(18,18,18)
-       XVCPSGNDP(19,19,19)
-       XVCPSGNDP(20,20,20)
-       XVCPSGNDP(21,21,21)
-       XVCPSGNDP(22,22,22)
-       XVCPSGNDP(23,23,23)
-       XVCPSGNDP(24,24,24)
-       XVCPSGNDP(25,25,25)
-       XVCPSGNDP(26,26,26)
-       XVCPSGNDP(27,27,27)
-       XVCPSGNDP(28,28,28)
-       XVCPSGNDP(29,29,29)
-       XVCPSGNDP(30,30,30)
-       XVCPSGNDP(31,31,31)
+
+#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1)
+#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2)
+#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4)
+#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8)
+#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16)
+       XVCPSGNDP32(0)
+
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
+
+BEGIN_FTR_SECTION
+       b       denorm_done
+END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
+/*
+ * To denormalise we need to move a copy of the register to itself.
+ * For POWER8 we need to do that for all 64 VSX registers
+ */
+       XVCPSGNDP32(32)
+denorm_done:
        mtspr   SPRN_HSRR0,r11
        mtcrf   0x80,r9
        ld      r9,PACA_EXGEN+EX_R9(r13)
@@ -721,7 +683,7 @@ machine_check_common:
        STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
        STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
        STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
-       STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
+       STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt)
        STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 #ifdef CONFIG_PPC_DOORBELL
        STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception)
index 5cbcf4d..ea185e0 100644 (file)
@@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay(void)
         * in case we also had a rollover while hard disabled
         */
        local_paca->irq_happened &= ~PACA_IRQ_DEC;
-       if (decrementer_check_overflow())
+       if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
                return 0x900;
 
        /* Finally check if an external interrupt happened */
index e9acf50..eabeec9 100644 (file)
@@ -657,15 +657,6 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
  *     ranges. However, some machines (thanks Apple !) tend to split their
  *     space into lots of small contiguous ranges. So we have to coalesce.
  *
- *   - We can only cope with all memory ranges having the same offset
- *     between CPU addresses and PCI addresses. Unfortunately, some bridges
- *     are setup for a large 1:1 mapping along with a small "window" which
- *     maps PCI address 0 to some arbitrary high address of the CPU space in
- *     order to give access to the ISA memory hole.
- *     The way out of here that I've chosen for now is to always set the
- *     offset based on the first resource found, then override it if we
- *     have a different offset and the previous was set by an ISA hole.
- *
  *   - Some busses have IO space not starting at 0, which causes trouble with
  *     the way we do our IO resource renumbering. The code somewhat deals with
  *     it for 64 bits but I would expect problems on 32 bits.
@@ -680,10 +671,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
        int rlen;
        int pna = of_n_addr_cells(dev);
        int np = pna + 5;
-       int memno = 0, isa_hole = -1;
+       int memno = 0;
        u32 pci_space;
        unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
-       unsigned long long isa_mb = 0;
        struct resource *res;
 
        printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
@@ -777,8 +767,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
                        }
                        /* Handles ISA memory hole space here */
                        if (pci_addr == 0) {
-                               isa_mb = cpu_addr;
-                               isa_hole = memno;
                                if (primary || isa_mem_base == 0)
                                        isa_mem_base = cpu_addr;
                                hose->isa_mem_phys = cpu_addr;
@@ -839,6 +827,7 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
        }
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                struct resource *res = dev->resource + i;
+               struct pci_bus_region reg;
                if (!res->flags)
                        continue;
 
@@ -847,8 +836,9 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
                 * at 0 as unset as well, except if PCI_PROBE_ONLY is also set
                 * since in that case, we don't want to re-assign anything
                 */
+               pcibios_resource_to_bus(dev, &reg, res);
                if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) ||
-                   (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
+                   (reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
                        /* Only print message if not re-assigning */
                        if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC))
                                pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] "
index a902723..076d124 100644 (file)
@@ -399,7 +399,8 @@ static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
 static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
 {
        mtspr(SPRN_DABR, dabr);
-       mtspr(SPRN_DABRX, dabrx);
+       if (cpu_has_feature(CPU_FTR_DABRX))
+               mtspr(SPRN_DABRX, dabrx);
        return 0;
 }
 #else
@@ -1368,7 +1369,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
 
 #ifdef CONFIG_PPC64
 /* Called with hard IRQs off */
-void __ppc64_runlatch_on(void)
+void notrace __ppc64_runlatch_on(void)
 {
        struct thread_info *ti = current_thread_info();
        unsigned long ctrl;
@@ -1381,7 +1382,7 @@ void __ppc64_runlatch_on(void)
 }
 
 /* Called with hard IRQs off */
-void __ppc64_runlatch_off(void)
+void notrace __ppc64_runlatch_off(void)
 {
        struct thread_info *ti = current_thread_info();
        unsigned long ctrl;
index 577a8aa..457e97a 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/debug.h>
+#include <asm/tm.h>
 
 #include "signal.h"
 
@@ -30,13 +31,13 @@ int show_unhandled_signals = 1;
 /*
  * Allocate space for the signal frame
  */
-void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
                           size_t frame_size, int is_32)
 {
         unsigned long oldsp, newsp;
 
         /* Default to using normal stack */
-        oldsp = get_clean_sp(regs, is_32);
+        oldsp = get_clean_sp(sp, is_32);
 
        /* Check for alt stack */
        if ((ka->sa.sa_flags & SA_ONSTACK) &&
@@ -175,3 +176,38 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
 
        user_enter();
 }
+
+unsigned long get_tm_stackpointer(struct pt_regs *regs)
+{
+       /* When in an active transaction that takes a signal, we need to be
+        * careful with the stack.  It's possible that the stack has moved back
+        * up after the tbegin.  The obvious case here is when the tbegin is
+        * called inside a function that returns before a tend.  In this case,
+        * the stack is part of the checkpointed transactional memory state.
+        * If we write over this non transactionally or in suspend, we are in
+        * trouble because if we get a tm abort, the program counter and stack
+        * pointer will be back at the tbegin but our in memory stack won't be
+        * valid anymore.
+        *
+        * To avoid this, when taking a signal in an active transaction, we
+        * need to use the stack pointer from the checkpointed state, rather
+        * than the speculated state.  This ensures that the signal context
+        * (written tm suspended) will be written below the stack required for
+        * the rollback.  The transaction is aborted becuase of the treclaim,
+        * so any memory written between the tbegin and the signal will be
+        * rolled back anyway.
+        *
+        * For signals taken in non-TM or suspended mode, we use the
+        * normal/non-checkpointed stack pointer.
+        */
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       if (MSR_TM_ACTIVE(regs->msr)) {
+               tm_enable();
+               tm_reclaim(&current->thread, regs->msr, TM_CAUSE_SIGNAL);
+               if (MSR_TM_TRANSACTIONAL(regs->msr))
+                       return current->thread.ckpt_regs.gpr[1];
+       }
+#endif
+       return regs->gpr[1];
+}
index ec84c90..c69b9ae 100644 (file)
@@ -12,7 +12,7 @@
 
 extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags);
 
-extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
                                  size_t frame_size, int is_32);
 
 extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
index 95068bf..201385c 100644 (file)
@@ -503,12 +503,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
 {
        unsigned long msr = regs->msr;
 
-       /* tm_reclaim rolls back all reg states, updating thread.ckpt_regs,
-        * thread.transact_fpr[], thread.transact_vr[], etc.
-        */
-       tm_enable();
-       tm_reclaim(&current->thread, msr, TM_CAUSE_SIGNAL);
-
        /* Make sure floating point registers are stored in regs */
        flush_fp_to_thread(current);
 
@@ -965,7 +959,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
 
        /* Set up Signal Frame */
        /* Put a Real Time Context onto stack */
-       rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1);
+       rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
        addr = rt_sf;
        if (unlikely(rt_sf == NULL))
                goto badframe;
@@ -1403,7 +1397,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
        unsigned long tramp;
 
        /* Set up Signal Frame */
-       frame = get_sigframe(ka, regs, sizeof(*frame), 1);
+       frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1);
        if (unlikely(frame == NULL))
                goto badframe;
        sc = (struct sigcontext __user *) &frame->sctx;
index c179428..3459473 100644 (file)
@@ -154,11 +154,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
  * As above, but Transactional Memory is in use, so deliver sigcontexts
  * containing checkpointed and transactional register states.
  *
- * To do this, we treclaim to gather both sets of registers and set up the
- * 'normal' sigcontext registers with rolled-back register values such that a
- * simple signal handler sees a correct checkpointed register state.
- * If interested, a TM-aware sighandler can examine the transactional registers
- * in the 2nd sigcontext to determine the real origin of the signal.
+ * To do this, we treclaim (done before entering here) to gather both sets of
+ * registers and set up the 'normal' sigcontext registers with rolled-back
+ * register values such that a simple signal handler sees a correct
+ * checkpointed register state.  If interested, a TM-aware sighandler can
+ * examine the transactional registers in the 2nd sigcontext to determine the
+ * real origin of the signal.
  */
 static long setup_tm_sigcontexts(struct sigcontext __user *sc,
                                 struct sigcontext __user *tm_sc,
@@ -184,16 +185,6 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
 
        BUG_ON(!MSR_TM_ACTIVE(regs->msr));
 
-       /* tm_reclaim rolls back all reg states, saving checkpointed (older)
-        * GPRs to thread.ckpt_regs and (if used) FPRs to (newer)
-        * thread.transact_fp and/or VRs to (newer) thread.transact_vr.
-        * THEN we save out FP/VRs, if necessary, to the checkpointed (older)
-        * thread.fr[]/vr[]s.  The transactional (newer) GPRs are on the
-        * stack, in *regs.
-        */
-       tm_enable();
-       tm_reclaim(&current->thread, msr, TM_CAUSE_SIGNAL);
-
        flush_fp_to_thread(current);
 
 #ifdef CONFIG_ALTIVEC
@@ -711,7 +702,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
        unsigned long newsp = 0;
        long err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame), 0);
+       frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0);
        if (unlikely(frame == NULL))
                goto badframe;
 
index a7a648f..c0e5caf 100644 (file)
@@ -53,6 +53,7 @@
 #ifdef CONFIG_PPC64
 #include <asm/firmware.h>
 #include <asm/processor.h>
+#include <asm/tm.h>
 #endif
 #include <asm/kexec.h>
 #include <asm/ppc-opcode.h>
@@ -932,6 +933,28 @@ static int emulate_isel(struct pt_regs *regs, u32 instword)
        return 0;
 }
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+static inline bool tm_abort_check(struct pt_regs *regs, int cause)
+{
+        /* If we're emulating a load/store in an active transaction, we cannot
+         * emulate it as the kernel operates in transaction suspended context.
+         * We need to abort the transaction.  This creates a persistent TM
+         * abort so tell the user what caused it with a new code.
+        */
+       if (MSR_TM_TRANSACTIONAL(regs->msr)) {
+               tm_enable();
+               tm_abort(cause);
+               return true;
+       }
+       return false;
+}
+#else
+static inline bool tm_abort_check(struct pt_regs *regs, int reason)
+{
+       return false;
+}
+#endif
+
 static int emulate_instruction(struct pt_regs *regs)
 {
        u32 instword;
@@ -971,6 +994,9 @@ static int emulate_instruction(struct pt_regs *regs)
 
        /* Emulate load/store string insn. */
        if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
+               if (tm_abort_check(regs,
+                                  TM_CAUSE_EMULATE | TM_CAUSE_PERSISTENT))
+                       return -EINVAL;
                PPC_WARN_EMULATED(string, regs);
                return emulate_string_inst(regs, instword);
        }
@@ -1139,6 +1165,16 @@ bail:
        exception_exit(prev_state);
 }
 
+/*
+ * This occurs when running in hypervisor mode on POWER6 or later
+ * and an illegal instruction is encountered.
+ */
+void __kprobes emulation_assist_interrupt(struct pt_regs *regs)
+{
+       regs->msr |= REASON_ILLEGAL;
+       program_check_exception(regs);
+}
+
 void alignment_exception(struct pt_regs *regs)
 {
        enum ctx_state prev_state = exception_enter();
@@ -1148,6 +1184,9 @@ void alignment_exception(struct pt_regs *regs)
        if (!arch_irq_disabled_regs(regs))
                local_irq_enable();
 
+       if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT))
+               goto bail;
+
        /* we don't implement logging of alignment exceptions */
        if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
                fixed = fix_alignment(regs);
index 5dd3ab4..ed03854 100644 (file)
@@ -441,6 +441,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
        struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
        struct kvmppc_44x_tlbe *tlbe;
        unsigned int gtlb_index;
+       int idx;
 
        gtlb_index = kvmppc_get_gpr(vcpu, ra);
        if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) {
@@ -473,6 +474,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
                return EMULATE_FAIL;
        }
 
+       idx = srcu_read_lock(&vcpu->kvm->srcu);
+
        if (tlbe_is_host_safe(vcpu, tlbe)) {
                gva_t eaddr;
                gpa_t gpaddr;
@@ -489,6 +492,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
                kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
        }
 
+       srcu_read_unlock(&vcpu->kvm->srcu, idx);
+
        trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1,
                             tlbe->word2);
 
index 9de24f8..550f592 100644 (file)
@@ -562,6 +562,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
        case H_CPPR:
        case H_EOI:
        case H_IPI:
+       case H_IPOLL:
+       case H_XIRR_X:
                if (kvmppc_xics_enabled(vcpu)) {
                        ret = kvmppc_xics_hcall(vcpu, req);
                        break;
index b24309c..da0e0bc 100644 (file)
@@ -257,6 +257,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
        case H_CPPR:
        case H_EOI:
        case H_IPI:
+       case H_IPOLL:
+       case H_XIRR_X:
                if (kvmppc_xics_enabled(vcpu))
                        return kvmppc_h_pr_xics_hcall(vcpu, cmd);
                break;
index f7a1037..94c1dd4 100644 (file)
@@ -650,6 +650,23 @@ static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
        return H_SUCCESS;
 }
 
+static int kvmppc_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server)
+{
+       union kvmppc_icp_state state;
+       struct kvmppc_icp *icp;
+
+       icp = vcpu->arch.icp;
+       if (icp->server_num != server) {
+               icp = kvmppc_xics_find_server(vcpu->kvm, server);
+               if (!icp)
+                       return H_PARAMETER;
+       }
+       state = ACCESS_ONCE(icp->state);
+       kvmppc_set_gpr(vcpu, 4, ((u32)state.cppr << 24) | state.xisr);
+       kvmppc_set_gpr(vcpu, 5, state.mfrr);
+       return H_SUCCESS;
+}
+
 static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
 {
        union kvmppc_icp_state old_state, new_state;
@@ -787,6 +804,18 @@ int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req)
        if (!xics || !vcpu->arch.icp)
                return H_HARDWARE;
 
+       /* These requests don't have real-mode implementations at present */
+       switch (req) {
+       case H_XIRR_X:
+               res = kvmppc_h_xirr(vcpu);
+               kvmppc_set_gpr(vcpu, 4, res);
+               kvmppc_set_gpr(vcpu, 5, get_tb());
+               return rc;
+       case H_IPOLL:
+               rc = kvmppc_h_ipoll(vcpu, kvmppc_get_gpr(vcpu, 4));
+               return rc;
+       }
+
        /* Check for real mode returning too hard */
        if (xics->real_mode)
                return kvmppc_xics_rm_complete(vcpu, req);
index 1020119..5cd7ad0 100644 (file)
@@ -832,6 +832,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 {
        int r = RESUME_HOST;
        int s;
+       int idx;
+
+#ifdef CONFIG_PPC64
+       WARN_ON(local_paca->irq_happened != 0);
+#endif
+
+       /*
+        * We enter with interrupts disabled in hardware, but
+        * we need to call hard_irq_disable anyway to ensure that
+        * the software state is kept in sync.
+        */
+       hard_irq_disable();
 
        /* update before a new last_exit_type is rewritten */
        kvmppc_update_timing_stats(vcpu);
@@ -1053,6 +1065,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        break;
                }
 
+               idx = srcu_read_lock(&vcpu->kvm->srcu);
+
                gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
                gfn = gpaddr >> PAGE_SHIFT;
 
@@ -1075,6 +1089,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        kvmppc_account_exit(vcpu, MMIO_EXITS);
                }
 
+               srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
        }
 
@@ -1098,6 +1113,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 
                kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS);
 
+               idx = srcu_read_lock(&vcpu->kvm->srcu);
+
                gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
                gfn = gpaddr >> PAGE_SHIFT;
 
@@ -1114,6 +1131,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK);
                }
 
+               srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
        }
 
index c41a5a9..6d6f153 100644 (file)
@@ -396,6 +396,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
        struct kvm_book3e_206_tlb_entry *gtlbe;
        int tlbsel, esel;
        int recal = 0;
+       int idx;
 
        tlbsel = get_tlb_tlbsel(vcpu);
        esel = get_tlb_esel(vcpu, tlbsel);
@@ -430,6 +431,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
                        kvmppc_set_tlb1map_range(vcpu, gtlbe);
        }
 
+       idx = srcu_read_lock(&vcpu->kvm->srcu);
+
        /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
        if (tlbe_is_host_safe(vcpu, gtlbe)) {
                u64 eaddr = get_tlb_eaddr(gtlbe);
@@ -444,6 +447,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
                kvmppc_mmu_map(vcpu, eaddr, raddr, index_of(tlbsel, esel));
        }
 
+       srcu_read_unlock(&vcpu->kvm->srcu, idx);
+
        kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
        return EMULATE_DONE;
 }
index 753cc99..19c8379 100644 (file)
@@ -177,8 +177,6 @@ int kvmppc_core_check_processor_compat(void)
                r = 0;
        else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
                r = 0;
-       else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0)
-               r = 0;
        else
                r = -ENOTSUPP;
 
index 0ef75bf..395c594 100644 (file)
@@ -28,13 +28,14 @@ _GLOBAL(copypage_power7)
         * aligned we don't need to clear the bottom 7 bits of either
         * address.
         */
-       ori     r9,r3,1         /* stream=1 */
+       ori     r9,r3,1         /* stream=1 => to */
 
 #ifdef CONFIG_PPC_64K_PAGES
-       lis     r7,0x0E01       /* depth=7, units=512 */
+       lis     r7,0x0E01       /* depth=7
+                                * units/cachelines=512 */
 #else
        lis     r7,0x0E00       /* depth=7 */
-       ori     r7,r7,0x1000    /* units=32 */
+       ori     r7,r7,0x1000    /* units/cachelines=32 */
 #endif
        ori     r10,r7,1        /* stream=1 */
 
@@ -43,12 +44,14 @@ _GLOBAL(copypage_power7)
 
 .machine push
 .machine "power4"
-       dcbt    r0,r4,0b01000
-       dcbt    r0,r7,0b01010
-       dcbtst  r0,r9,0b01000
-       dcbtst  r0,r10,0b01010
+       /* setup read stream 0  */
+       dcbt    r0,r4,0b01000   /* addr from */
+       dcbt    r0,r7,0b01010   /* length and depth from */
+       /* setup write stream 1 */
+       dcbtst  r0,r9,0b01000   /* addr to */
+       dcbtst  r0,r10,0b01010  /* length and depth to */
        eieio
-       dcbt    r0,r8,0b01010   /* GO */
+       dcbt    r0,r8,0b01010   /* all streams GO */
 .machine pop
 
 #ifdef CONFIG_ALTIVEC
index 0d24ff1..d1f1179 100644 (file)
@@ -318,12 +318,14 @@ err1;     stb     r0,0(r3)
 
 .machine push
 .machine "power4"
-       dcbt    r0,r6,0b01000
-       dcbt    r0,r7,0b01010
-       dcbtst  r0,r9,0b01000
-       dcbtst  r0,r10,0b01010
+       /* setup read stream 0 */
+       dcbt    r0,r6,0b01000   /* addr from */
+       dcbt    r0,r7,0b01010   /* length and depth from */
+       /* setup write stream 1 */
+       dcbtst  r0,r9,0b01000   /* addr to */
+       dcbtst  r0,r10,0b01010  /* length and depth to */
        eieio
-       dcbt    r0,r8,0b01010   /* GO */
+       dcbt    r0,r8,0b01010   /* all streams GO */
 .machine pop
 
        beq     cr1,.Lunwind_stack_nonvmx_copy
index 6a2aead..4c122c3 100644 (file)
@@ -336,11 +336,18 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 
        hpte_v = hptep->v;
        actual_psize = hpte_actual_psize(hptep, psize);
+       /*
+        * We need to invalidate the TLB always because hpte_remove doesn't do
+        * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less
+        * random entry from it. When we do that we don't invalidate the TLB
+        * (hpte_remove) because we assume the old translation is still
+        * technically "valid".
+        */
        if (actual_psize < 0) {
-               native_unlock_hpte(hptep);
-               return -1;
+               actual_psize = psize;
+               ret = -1;
+               goto err_out;
        }
-       /* Even if we miss, we need to invalidate the TLB */
        if (!HPTE_V_COMPARE(hpte_v, want_v)) {
                DBG_LOW(" -> miss\n");
                ret = -1;
@@ -350,6 +357,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
                hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
                        (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
        }
+err_out:
        native_unlock_hpte(hptep);
 
        /* Ensure it is out of the tlb too. */
@@ -409,7 +417,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
        hptep = htab_address + slot;
        actual_psize = hpte_actual_psize(hptep, psize);
        if (actual_psize < 0)
-               return;
+               actual_psize = psize;
 
        /* Update the HPTE */
        hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
@@ -437,21 +445,27 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
        hpte_v = hptep->v;
 
        actual_psize = hpte_actual_psize(hptep, psize);
+       /*
+        * We need to invalidate the TLB always because hpte_remove doesn't do
+        * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less
+        * random entry from it. When we do that we don't invalidate the TLB
+        * (hpte_remove) because we assume the old translation is still
+        * technically "valid".
+        */
        if (actual_psize < 0) {
+               actual_psize = psize;
                native_unlock_hpte(hptep);
-               local_irq_restore(flags);
-               return;
+               goto err_out;
        }
-       /* Even if we miss, we need to invalidate the TLB */
        if (!HPTE_V_COMPARE(hpte_v, want_v))
                native_unlock_hpte(hptep);
        else
                /* Invalidate the hpte. NOTE: this also unlocks it */
                hptep->v = 0;
 
+err_out:
        /* Invalidate the TLB */
        tlbie(vpn, psize, actual_psize, ssize, local);
-
        local_irq_restore(flags);
 }
 
index 426180b..29c6482 100644 (file)
@@ -110,7 +110,7 @@ static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
 
 static bool regs_use_siar(struct pt_regs *regs)
 {
-       return !!(regs->result & 1);
+       return !!regs->result;
 }
 
 /*
@@ -136,22 +136,30 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
  * If we're not doing instruction sampling, give them the SDAR
  * (sampled data address).  If we are doing instruction sampling, then
  * only give them the SDAR if it corresponds to the instruction
- * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC or
- * the [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA.
+ * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC, the
+ * [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA, or the SDAR_VALID bit in SIER.
  */
 static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
 {
        unsigned long mmcra = regs->dsisr;
-       unsigned long sdsync;
+       bool sdar_valid;
 
-       if (ppmu->flags & PPMU_SIAR_VALID)
-               sdsync = POWER7P_MMCRA_SDAR_VALID;
-       else if (ppmu->flags & PPMU_ALT_SIPR)
-               sdsync = POWER6_MMCRA_SDSYNC;
-       else
-               sdsync = MMCRA_SDSYNC;
+       if (ppmu->flags & PPMU_HAS_SIER)
+               sdar_valid = regs->dar & SIER_SDAR_VALID;
+       else {
+               unsigned long sdsync;
+
+               if (ppmu->flags & PPMU_SIAR_VALID)
+                       sdsync = POWER7P_MMCRA_SDAR_VALID;
+               else if (ppmu->flags & PPMU_ALT_SIPR)
+                       sdsync = POWER6_MMCRA_SDSYNC;
+               else
+                       sdsync = MMCRA_SDSYNC;
+
+               sdar_valid = mmcra & sdsync;
+       }
 
-       if (!(mmcra & MMCRA_SAMPLE_ENABLE) || (mmcra & sdsync))
+       if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
                *addrp = mfspr(SPRN_SDAR);
 }
 
@@ -181,11 +189,6 @@ static bool regs_sipr(struct pt_regs *regs)
        return !!(regs->dsisr & sipr);
 }
 
-static bool regs_no_sipr(struct pt_regs *regs)
-{
-       return !!(regs->result & 2);
-}
-
 static inline u32 perf_flags_from_msr(struct pt_regs *regs)
 {
        if (regs->msr & MSR_PR)
@@ -208,7 +211,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
         * SIAR which should give slightly more reliable
         * results
         */
-       if (regs_no_sipr(regs)) {
+       if (ppmu->flags & PPMU_NO_SIPR) {
                unsigned long siar = mfspr(SPRN_SIAR);
                if (siar >= PAGE_OFFSET)
                        return PERF_RECORD_MISC_KERNEL;
@@ -239,22 +242,9 @@ static inline void perf_read_regs(struct pt_regs *regs)
        int use_siar;
 
        regs->dsisr = mmcra;
-       regs->result = 0;
-
-       if (ppmu->flags & PPMU_NO_SIPR)
-               regs->result |= 2;
-
-       /*
-        * On power8 if we're in random sampling mode, the SIER is updated.
-        * If we're in continuous sampling mode, we don't have SIPR.
-        */
-       if (ppmu->flags & PPMU_HAS_SIER) {
-               if (marked)
-                       regs->dar = mfspr(SPRN_SIER);
-               else
-                       regs->result |= 2;
-       }
 
+       if (ppmu->flags & PPMU_HAS_SIER)
+               regs->dar = mfspr(SPRN_SIER);
 
        /*
         * If this isn't a PMU exception (eg a software event) the SIAR is
@@ -279,12 +269,12 @@ static inline void perf_read_regs(struct pt_regs *regs)
                use_siar = 1;
        else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING))
                use_siar = 0;
-       else if (!regs_no_sipr(regs) && regs_sipr(regs))
+       else if (!(ppmu->flags & PPMU_NO_SIPR) && regs_sipr(regs))
                use_siar = 0;
        else
                use_siar = 1;
 
-       regs->result |= use_siar;
+       regs->result = use_siar;
 }
 
 /*
@@ -308,8 +298,13 @@ static inline int siar_valid(struct pt_regs *regs)
        unsigned long mmcra = regs->dsisr;
        int marked = mmcra & MMCRA_SAMPLE_ENABLE;
 
-       if ((ppmu->flags & PPMU_SIAR_VALID) && marked)
-               return mmcra & POWER7P_MMCRA_SIAR_VALID;
+       if (marked) {
+               if (ppmu->flags & PPMU_HAS_SIER)
+                       return regs->dar & SIER_SIAR_VALID;
+
+               if (ppmu->flags & PPMU_SIAR_VALID)
+                       return mmcra & POWER7P_MMCRA_SIAR_VALID;
+       }
 
        return 1;
 }
@@ -1763,7 +1758,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
                        }
                }
        }
-       if ((!found) && printk_ratelimit())
+       if (!found && !nmi && printk_ratelimit())
                printk(KERN_WARNING "Can't find PMC that caused IRQ\n");
 
        /*
index 023b288..4459eff 100644 (file)
@@ -19,6 +19,8 @@ config PPC_PSERIES
        select ZLIB_DEFLATE
        select PPC_DOORBELL
        select HAVE_CONTEXT_TRACKING
+       select HOTPLUG if SMP
+       select HOTPLUG_CPU if SMP
        default y
 
 config PPC_SPLPAR
index 19506f9..b456b15 100644 (file)
@@ -83,7 +83,11 @@ static int pseries_eeh_init(void)
        ibm_configure_pe                = rtas_token("ibm,configure-pe");
        ibm_configure_bridge            = rtas_token("ibm,configure-bridge");
 
-       /* necessary sanity check */
+       /*
+        * Necessary sanity check. We needn't check "get-config-addr-info"
+        * and its variant since the old firmware probably support address
+        * of domain/bus/slot/function for EEH RTAS operations.
+        */
        if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) {
                pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n",
                        __func__);
@@ -102,12 +106,6 @@ static int pseries_eeh_init(void)
                pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n",
                        __func__);
                return -EINVAL;
-       } else if (ibm_get_config_addr_info2 == RTAS_UNKNOWN_SERVICE &&
-                  ibm_get_config_addr_info == RTAS_UNKNOWN_SERVICE) {
-               pr_warning("%s: RTAS service <ibm,get-config-addr-info2> and "
-                       "<ibm,get-config-addr-info> invalid\n",
-                       __func__);
-               return -EINVAL;
        } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE &&
                   ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) {
                pr_warning("%s: RTAS service <ibm,configure-pe> and "
index 0a13ecb..3cc2f91 100644 (file)
@@ -54,7 +54,7 @@ static DEFINE_RAW_SPINLOCK(mpic_lock);
 
 #ifdef CONFIG_PPC32    /* XXX for now */
 #ifdef CONFIG_IRQ_ALL_CPUS
-#define distribute_irqs        (!(mpic->flags & MPIC_SINGLE_DEST_CPU))
+#define distribute_irqs        (1)
 #else
 #define distribute_irqs        (0)
 #endif
@@ -1703,7 +1703,7 @@ void mpic_setup_this_cpu(void)
         * it differently, then we should make sure we also change the default
         * values of irq_desc[].affinity in irq.c.
         */
-       if (distribute_irqs) {
+       if (distribute_irqs && !(mpic->flags & MPIC_SINGLE_DEST_CPU)) {
                for (i = 0; i < mpic->num_sources ; i++)
                        mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
                                mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
index bae0f40..87a2209 100644 (file)
@@ -212,7 +212,9 @@ appldata_timer_handler(ctl_table *ctl, int write,
                return 0;
        }
        if (!write) {
-               len = sprintf(buf, appldata_timer_active ? "1\n" : "0\n");
+               strncpy(buf, appldata_timer_active ? "1\n" : "0\n",
+                       ARRAY_SIZE(buf));
+               len = strnlen(buf, ARRAY_SIZE(buf));
                if (len > *lenp)
                        len = *lenp;
                if (copy_to_user(buffer, buf, len))
@@ -317,7 +319,8 @@ appldata_generic_handler(ctl_table *ctl, int write,
                return 0;
        }
        if (!write) {
-               len = sprintf(buf, ops->active ? "1\n" : "0\n");
+               strncpy(buf, ops->active ? "1\n" : "0\n", ARRAY_SIZE(buf));
+               len = strnlen(buf, ARRAY_SIZE(buf));
                if (len > *lenp)
                        len = *lenp;
                if (copy_to_user(buffer, buf, len)) {
index 9411db6..886ac7d 100644 (file)
@@ -71,8 +71,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 {
        struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
-       dma_ops->free(dev, size, cpu_addr, dma_handle, NULL);
        debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+       dma_ops->free(dev, size, cpu_addr, dma_handle, NULL);
 }
 
 #endif /* _ASM_S390_DMA_MAPPING_H */
index 379d96e..fd9be01 100644 (file)
@@ -36,6 +36,7 @@ static inline void * phys_to_virt(unsigned long address)
 }
 
 void *xlate_dev_mem_ptr(unsigned long phys);
+#define xlate_dev_mem_ptr xlate_dev_mem_ptr
 void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
 
 /*
index 0f0de30..e8b6e5b 100644 (file)
@@ -623,7 +623,7 @@ static inline pgste_t pgste_get_lock(pte_t *ptep)
                "       csg     %0,%1,%2\n"
                "       jl      0b\n"
                : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
-               : "Q" (ptep[PTRS_PER_PTE]) : "cc");
+               : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory");
 #endif
        return __pgste(new);
 }
@@ -635,18 +635,26 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
                "       nihh    %1,0xff7f\n"    /* clear RCP_PCL_BIT */
                "       stg     %1,%0\n"
                : "=Q" (ptep[PTRS_PER_PTE])
-               : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc");
+               : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
+               : "cc", "memory");
        preempt_enable();
 #endif
 }
 
+static inline void pgste_set(pte_t *ptep, pgste_t pgste)
+{
+#ifdef CONFIG_PGSTE
+       *(pgste_t *)(ptep + PTRS_PER_PTE) = pgste;
+#endif
+}
+
 static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
        unsigned long address, bits;
        unsigned char skey;
 
-       if (!pte_present(*ptep))
+       if (pte_val(*ptep) & _PAGE_INVALID)
                return pgste;
        address = pte_val(*ptep) & PAGE_MASK;
        skey = page_get_storage_key(address);
@@ -680,7 +688,7 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
 #ifdef CONFIG_PGSTE
        int young;
 
-       if (!pte_present(*ptep))
+       if (pte_val(*ptep) & _PAGE_INVALID)
                return pgste;
        /* Get referenced bit from storage key */
        young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
@@ -704,17 +712,19 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry)
 {
 #ifdef CONFIG_PGSTE
        unsigned long address;
-       unsigned long okey, nkey;
+       unsigned long nkey;
 
-       if (!pte_present(entry))
+       if (pte_val(entry) & _PAGE_INVALID)
                return;
+       VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID));
        address = pte_val(entry) & PAGE_MASK;
-       okey = nkey = page_get_storage_key(address);
-       nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
-       /* Set page access key and fetch protection bit from pgste */
-       nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
-       if (okey != nkey)
-               page_set_storage_key(address, nkey, 0);
+       /*
+        * Set page access key and fetch protection bit from pgste.
+        * The guest C/R information is still in the PGSTE, set real
+        * key C/R to 0.
+        */
+       nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
+       page_set_storage_key(address, nkey, 0);
 #endif
 }
 
@@ -1098,6 +1108,11 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
        pte = *ptep;
        if (!mm_exclusive(mm))
                __ptep_ipte(address, ptep);
+
+       if (mm_has_pgste(mm)) {
+               pgste = pgste_update_all(&pte, pgste);
+               pgste_set(ptep, pgste);
+       }
        return pte;
 }
 
@@ -1105,9 +1120,13 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm,
                                           unsigned long address,
                                           pte_t *ptep, pte_t pte)
 {
+       pgste_t pgste;
+
        if (mm_has_pgste(mm)) {
+               pgste = *(pgste_t *)(ptep + PTRS_PER_PTE);
+               pgste_set_key(ptep, pgste, pte);
                pgste_set_pte(ptep, pte);
-               pgste_set_unlock(ptep, *(pgste_t *)(ptep + PTRS_PER_PTE));
+               pgste_set_unlock(ptep, pgste);
        } else
                *ptep = pte;
 }
index 2982974..87acc38 100644 (file)
@@ -74,6 +74,8 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high)
 
 static void show_trace(struct task_struct *task, unsigned long *stack)
 {
+       const unsigned long frame_size =
+               STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
        register unsigned long __r15 asm ("15");
        unsigned long sp;
 
@@ -82,11 +84,13 @@ static void show_trace(struct task_struct *task, unsigned long *stack)
                sp = task ? task->thread.ksp : __r15;
        printk("Call Trace:\n");
 #ifdef CONFIG_CHECK_STACK
-       sp = __show_trace(sp, S390_lowcore.panic_stack - 4096,
-                         S390_lowcore.panic_stack);
+       sp = __show_trace(sp,
+                         S390_lowcore.panic_stack + frame_size - 4096,
+                         S390_lowcore.panic_stack + frame_size);
 #endif
-       sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE,
-                         S390_lowcore.async_stack);
+       sp = __show_trace(sp,
+                         S390_lowcore.async_stack + frame_size - ASYNC_SIZE,
+                         S390_lowcore.async_stack + frame_size);
        if (task)
                __show_trace(sp, (unsigned long) task_stack_page(task),
                             (unsigned long) task_stack_page(task) + THREAD_SIZE);
index f7fb589..408e866 100644 (file)
@@ -311,3 +311,67 @@ void measurement_alert_subclass_unregister(void)
        spin_unlock(&ma_subclass_lock);
 }
 EXPORT_SYMBOL(measurement_alert_subclass_unregister);
+
+void synchronize_irq(unsigned int irq)
+{
+       /*
+        * Not needed, the handler is protected by a lock and IRQs that occur
+        * after the handler is deleted are just NOPs.
+        */
+}
+EXPORT_SYMBOL_GPL(synchronize_irq);
+
+#ifndef CONFIG_PCI
+
+/* Only PCI devices have dynamically-defined IRQ handlers */
+
+int request_irq(unsigned int irq, irq_handler_t handler,
+               unsigned long irqflags, const char *devname, void *dev_id)
+{
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(request_irq);
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+       WARN_ON(1);
+}
+EXPORT_SYMBOL_GPL(free_irq);
+
+void enable_irq(unsigned int irq)
+{
+       WARN_ON(1);
+}
+EXPORT_SYMBOL_GPL(enable_irq);
+
+void disable_irq(unsigned int irq)
+{
+       WARN_ON(1);
+}
+EXPORT_SYMBOL_GPL(disable_irq);
+
+#endif /* !CONFIG_PCI */
+
+void disable_irq_nosync(unsigned int irq)
+{
+       disable_irq(irq);
+}
+EXPORT_SYMBOL_GPL(disable_irq_nosync);
+
+unsigned long probe_irq_on(void)
+{
+       return 0;
+}
+EXPORT_SYMBOL_GPL(probe_irq_on);
+
+int probe_irq_off(unsigned long val)
+{
+       return 0;
+}
+EXPORT_SYMBOL_GPL(probe_irq_off);
+
+unsigned int probe_irq_mask(unsigned long val)
+{
+       return val;
+}
+EXPORT_SYMBOL_GPL(probe_irq_mask);
index b6506ee..29bd7be 100644 (file)
@@ -225,7 +225,7 @@ _sclp_print:
        ahi     %r2,1
        ltr     %r0,%r0                         # end of string?
        jz      .LfinalizemtoS4
-       chi     %r0,0x15                        # end of line (NL)?
+       chi     %r0,0x0a                        # end of line (NL)?
        jz      .LfinalizemtoS4
        stc     %r0,0(%r6,%r7)                  # copy to mto
        la      %r11,0(%r6,%r7)
index 05674b6..4f977d0 100644 (file)
@@ -428,34 +428,27 @@ void smp_stop_cpu(void)
  * This is the main routine where commands issued by other
  * cpus are handled.
  */
-static void do_ext_call_interrupt(struct ext_code ext_code,
-                                 unsigned int param32, unsigned long param64)
+static void smp_handle_ext_call(void)
 {
        unsigned long bits;
-       int cpu;
-
-       cpu = smp_processor_id();
-       if (ext_code.code == 0x1202)
-               inc_irq_stat(IRQEXT_EXC);
-       else
-               inc_irq_stat(IRQEXT_EMS);
-       /*
-        * handle bit signal external calls
-        */
-       bits = xchg(&pcpu_devices[cpu].ec_mask, 0);
 
+       /* handle bit signal external calls */
+       bits = xchg(&pcpu_devices[smp_processor_id()].ec_mask, 0);
        if (test_bit(ec_stop_cpu, &bits))
                smp_stop_cpu();
-
        if (test_bit(ec_schedule, &bits))
                scheduler_ipi();
-
        if (test_bit(ec_call_function, &bits))
                generic_smp_call_function_interrupt();
-
        if (test_bit(ec_call_function_single, &bits))
                generic_smp_call_function_single_interrupt();
+}
 
+static void do_ext_call_interrupt(struct ext_code ext_code,
+                                 unsigned int param32, unsigned long param64)
+{
+       inc_irq_stat(ext_code.code == 0x1202 ? IRQEXT_EXC : IRQEXT_EMS);
+       smp_handle_ext_call();
 }
 
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
@@ -760,6 +753,8 @@ int __cpu_disable(void)
 {
        unsigned long cregs[16];
 
+       /* Handle possible pending IPIs */
+       smp_handle_ext_call();
        set_cpu_online(smp_processor_id(), false);
        /* Disable pseudo page faults on this cpu. */
        pfault_fini();
index 18dc417..a938b54 100644 (file)
@@ -492,7 +492,7 @@ static int gmap_connect_pgtable(unsigned long address, unsigned long segment,
        mp = (struct gmap_pgtable *) page->index;
        rmap->gmap = gmap;
        rmap->entry = segment_ptr;
-       rmap->vmaddr = address;
+       rmap->vmaddr = address & PMD_MASK;
        spin_lock(&mm->page_table_lock);
        if (*segment_ptr == segment) {
                list_add(&rmap->list, &mp->mapper);
index e6f15b5..f1e5be8 100644 (file)
@@ -302,15 +302,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
        return rc;
 }
 
-void synchronize_irq(unsigned int irq)
-{
-       /*
-        * Not needed, the handler is protected by a lock and IRQs that occur
-        * after the handler is deleted are just NOPs.
-        */
-}
-EXPORT_SYMBOL_GPL(synchronize_irq);
-
 void enable_irq(unsigned int irq)
 {
        struct msi_desc *msi = irq_get_msi_desc(irq);
@@ -327,30 +318,6 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(disable_irq);
 
-void disable_irq_nosync(unsigned int irq)
-{
-       disable_irq(irq);
-}
-EXPORT_SYMBOL_GPL(disable_irq_nosync);
-
-unsigned long probe_irq_on(void)
-{
-       return 0;
-}
-EXPORT_SYMBOL_GPL(probe_irq_on);
-
-int probe_irq_off(unsigned long val)
-{
-       return 0;
-}
-EXPORT_SYMBOL_GPL(probe_irq_off);
-
-unsigned int probe_irq_mask(unsigned long val)
-{
-       return val;
-}
-EXPORT_SYMBOL_GPL(probe_irq_mask);
-
 void pcibios_fixup_bus(struct pci_bus *bus)
 {
 }
index 9f20566..79cc0d1 100644 (file)
@@ -54,6 +54,7 @@ EXPORT_SYMBOL(of_set_property_mutex);
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
        struct property **prevp;
+       unsigned long flags;
        void *new_val;
        int err;
 
@@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
        err = -ENODEV;
 
        mutex_lock(&of_set_property_mutex);
-       raw_spin_lock(&devtree_lock);
+       raw_spin_lock_irqsave(&devtree_lock, flags);
        prevp = &dp->properties;
        while (*prevp) {
                struct property *prop = *prevp;
@@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
                }
                prevp = &(*prevp)->next;
        }
-       raw_spin_unlock(&devtree_lock);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
        mutex_unlock(&of_set_property_mutex);
 
        /* XXX Upate procfs if necessary... */
index 35ee62f..c205035 100644 (file)
@@ -251,51 +251,6 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
        *size = len;
 }
 
-static efi_status_t setup_efi_vars(struct boot_params *params)
-{
-       struct setup_data *data;
-       struct efi_var_bootdata *efidata;
-       u64 store_size, remaining_size, var_size;
-       efi_status_t status;
-
-       if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION)
-               return EFI_UNSUPPORTED;
-
-       data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
-
-       while (data && data->next)
-               data = (struct setup_data *)(unsigned long)data->next;
-
-       status = efi_call_phys4((void *)sys_table->runtime->query_variable_info,
-                               EFI_VARIABLE_NON_VOLATILE |
-                               EFI_VARIABLE_BOOTSERVICE_ACCESS |
-                               EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
-                               &remaining_size, &var_size);
-
-       if (status != EFI_SUCCESS)
-               return status;
-
-       status = efi_call_phys3(sys_table->boottime->allocate_pool,
-                               EFI_LOADER_DATA, sizeof(*efidata), &efidata);
-
-       if (status != EFI_SUCCESS)
-               return status;
-
-       efidata->data.type = SETUP_EFI_VARS;
-       efidata->data.len = sizeof(struct efi_var_bootdata) -
-               sizeof(struct setup_data);
-       efidata->data.next = 0;
-       efidata->store_size = store_size;
-       efidata->remaining_size = remaining_size;
-       efidata->max_var_size = var_size;
-
-       if (data)
-               data->next = (unsigned long)efidata;
-       else
-               params->hdr.setup_data = (unsigned long)efidata;
-
-}
-
 static efi_status_t setup_efi_pci(struct boot_params *params)
 {
        efi_pci_io_protocol *pci;
@@ -1202,8 +1157,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
 
        setup_graphics(boot_params);
 
-       setup_efi_vars(boot_params);
-
        setup_efi_pci(boot_params);
 
        status = efi_call_phys3(sys_table->boottime->allocate_pool,
index 94c27df..f247304 100644 (file)
@@ -240,7 +240,7 @@ fold_64:
        pand    %xmm3, %xmm1
        PCLMULQDQ 0x00, CONSTANT, %xmm1
        pxor    %xmm2, %xmm1
-       pextrd  $0x01, %xmm1, %eax
+       PEXTRD  0x01, %xmm1, %eax
 
        ret
 ENDPROC(crc32_pclmul_le_16)
index 56610c4..642f156 100644 (file)
@@ -118,7 +118,7 @@ y2 = %r15d
 
 _INP_END_SIZE = 8
 _INP_SIZE = 8
-_XFER_SIZE = 8
+_XFER_SIZE = 16
 _XMM_SAVE_SIZE = 0
 
 _INP_END = 0
index 98d3c39..f833b74 100644 (file)
@@ -111,7 +111,7 @@ y2 = %r15d
 
 _INP_END_SIZE = 8
 _INP_SIZE = 8
-_XFER_SIZE = 8
+_XFER_SIZE = 16
 _XMM_SAVE_SIZE = 0
 
 _INP_END = 0
index 2fb5d58..60c89f3 100644 (file)
@@ -102,13 +102,6 @@ extern void efi_call_phys_epilog(void);
 extern void efi_unmap_memmap(void);
 extern void efi_memory_uc(u64 addr, unsigned long size);
 
-struct efi_var_bootdata {
-       struct setup_data data;
-       u64 store_size;
-       u64 remaining_size;
-       u64 max_var_size;
-};
-
 #ifdef CONFIG_EFI
 
 static inline bool efi_is_native(void)
index 280bf7f..3e11527 100644 (file)
@@ -9,12 +9,68 @@
 
 #define REG_NUM_INVALID                100
 
-#define REG_TYPE_R64           0
-#define REG_TYPE_XMM           1
+#define REG_TYPE_R32           0
+#define REG_TYPE_R64           1
+#define REG_TYPE_XMM           2
 #define REG_TYPE_INVALID       100
 
+       .macro R32_NUM opd r32
+       \opd = REG_NUM_INVALID
+       .ifc \r32,%eax
+       \opd = 0
+       .endif
+       .ifc \r32,%ecx
+       \opd = 1
+       .endif
+       .ifc \r32,%edx
+       \opd = 2
+       .endif
+       .ifc \r32,%ebx
+       \opd = 3
+       .endif
+       .ifc \r32,%esp
+       \opd = 4
+       .endif
+       .ifc \r32,%ebp
+       \opd = 5
+       .endif
+       .ifc \r32,%esi
+       \opd = 6
+       .endif
+       .ifc \r32,%edi
+       \opd = 7
+       .endif
+#ifdef CONFIG_X86_64
+       .ifc \r32,%r8d
+       \opd = 8
+       .endif
+       .ifc \r32,%r9d
+       \opd = 9
+       .endif
+       .ifc \r32,%r10d
+       \opd = 10
+       .endif
+       .ifc \r32,%r11d
+       \opd = 11
+       .endif
+       .ifc \r32,%r12d
+       \opd = 12
+       .endif
+       .ifc \r32,%r13d
+       \opd = 13
+       .endif
+       .ifc \r32,%r14d
+       \opd = 14
+       .endif
+       .ifc \r32,%r15d
+       \opd = 15
+       .endif
+#endif
+       .endm
+
        .macro R64_NUM opd r64
        \opd = REG_NUM_INVALID
+#ifdef CONFIG_X86_64
        .ifc \r64,%rax
        \opd = 0
        .endif
        .ifc \r64,%r15
        \opd = 15
        .endif
+#endif
        .endm
 
        .macro XMM_NUM opd xmm
        .endm
 
        .macro REG_TYPE type reg
+       R32_NUM reg_type_r32 \reg
        R64_NUM reg_type_r64 \reg
        XMM_NUM reg_type_xmm \reg
        .if reg_type_r64 <> REG_NUM_INVALID
        \type = REG_TYPE_R64
+       .elseif reg_type_r32 <> REG_NUM_INVALID
+       \type = REG_TYPE_R32
        .elseif reg_type_xmm <> REG_NUM_INVALID
        \type = REG_TYPE_XMM
        .else
        .byte \imm8
        .endm
 
+       .macro PEXTRD imm8 xmm gpr
+       R32_NUM extrd_opd1 \gpr
+       XMM_NUM extrd_opd2 \xmm
+       PFX_OPD_SIZE
+       PFX_REX extrd_opd1 extrd_opd2
+       .byte 0x0f, 0x3a, 0x16
+       MODRM 0xc0 extrd_opd1 extrd_opd2
+       .byte \imm8
+       .endm
+
        .macro AESKEYGENASSIST rcon xmm1 xmm2
        XMM_NUM aeskeygen_opd1 \xmm1
        XMM_NUM aeskeygen_opd2 \xmm2
index 0874424..c15ddaf 100644 (file)
@@ -6,7 +6,6 @@
 #define SETUP_E820_EXT                 1
 #define SETUP_DTB                      2
 #define SETUP_PCI                      3
-#define SETUP_EFI_VARS                 4
 
 /* ram_size flags */
 #define RAMDISK_IMAGE_START_MASK       0x07FF
index 08f7e80..321d65e 100644 (file)
@@ -115,8 +115,10 @@ startup_64:
        movq    %rdi, %rax
        shrq    $PUD_SHIFT, %rax
        andl    $(PTRS_PER_PUD-1), %eax
-       movq    %rdx, (4096+0)(%rbx,%rax,8)
-       movq    %rdx, (4096+8)(%rbx,%rax,8)
+       movq    %rdx, 4096(%rbx,%rax,8)
+       incl    %eax
+       andl    $(PTRS_PER_PUD-1), %eax
+       movq    %rdx, 4096(%rbx,%rax,8)
 
        addq    $8192, %rbx
        movq    %rdi, %rax
index 245a71d..cb33909 100644 (file)
 /*
  * Were we in an interrupt that interrupted kernel mode?
  *
- * For now, with eagerfpu we will return interrupted kernel FPU
- * state as not-idle. TBD: Ideally we can change the return value
- * to something like __thread_has_fpu(current). But we need to
- * be careful of doing __thread_clear_has_fpu() before saving
- * the FPU etc for supporting nested uses etc. For now, take
- * the simple route!
- *
  * On others, we can do a kernel_fpu_begin/end() pair *ONLY* if that
  * pair does nothing at all: the thread must not have fpu (so
  * that we don't try to save the FPU state), and TS must
  * be set (so that the clts/stts pair does nothing that is
  * visible in the interrupted kernel thread).
+ *
+ * Except for the eagerfpu case when we return 1 unless we've already
+ * been eager and saved the state in kernel_fpu_begin().
  */
 static inline bool interrupted_kernel_fpu_idle(void)
 {
        if (use_eager_fpu())
-               return 0;
+               return __thread_has_fpu(current);
 
        return !__thread_has_fpu(current) &&
                (read_cr0() & X86_CR0_TS);
@@ -78,8 +74,8 @@ void __kernel_fpu_begin(void)
        struct task_struct *me = current;
 
        if (__thread_has_fpu(me)) {
-               __save_init_fpu(me);
                __thread_clear_has_fpu(me);
+               __save_init_fpu(me);
                /* We do 'stts()' in __kernel_fpu_end() */
        } else if (!use_eager_fpu()) {
                this_cpu_write(fpu_owner_task, NULL);
index 7a6f3b3..f2bb9c9 100644 (file)
@@ -160,7 +160,7 @@ identity_mapped:
        xorq    %rbp, %rbp
        xorq    %r8,  %r8
        xorq    %r9,  %r9
-       xorq    %r10, %r9
+       xorq    %r10, %r10
        xorq    %r11, %r11
        xorq    %r12, %r12
        xorq    %r13, %r13
index 8db0010..5953dce 100644 (file)
@@ -1240,9 +1240,12 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
        ctxt->modrm_seg = VCPU_SREG_DS;
 
        if (ctxt->modrm_mod == 3) {
+               int highbyte_regs = ctxt->rex_prefix == 0;
+
                op->type = OP_REG;
                op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
-               op->addr.reg = decode_register(ctxt, ctxt->modrm_rm, ctxt->d & ByteOp);
+               op->addr.reg = decode_register(ctxt, ctxt->modrm_rm,
+                                              highbyte_regs && (ctxt->d & ByteOp));
                if (ctxt->d & Sse) {
                        op->type = OP_XMM;
                        op->bytes = 16;
@@ -3997,7 +4000,8 @@ static const struct opcode twobyte_table[256] = {
        DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
        N, D(ImplicitOps | ModRM), N, N,
        /* 0x10 - 0x1F */
-       N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
+       N, N, N, N, N, N, N, N,
+       D(ImplicitOps | ModRM), N, N, N, N, N, N, D(ImplicitOps | ModRM),
        /* 0x20 - 0x2F */
        DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read),
        DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read),
@@ -4836,6 +4840,7 @@ twobyte_insn:
        case 0x08:              /* invd */
        case 0x0d:              /* GrpP (prefetch) */
        case 0x18:              /* Grp16 (prefetch/nop) */
+       case 0x1f:              /* nop */
                break;
        case 0x20: /* mov cr, reg */
                ctxt->dst.val = ops->get_cr(ctxt, ctxt->modrm_reg);
index e1adbb4..0eee2c8 100644 (file)
@@ -1861,11 +1861,14 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
 {
        struct kvm_lapic *apic = vcpu->arch.apic;
        unsigned int sipi_vector;
+       unsigned long pe;
 
-       if (!kvm_vcpu_has_lapic(vcpu))
+       if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events)
                return;
 
-       if (test_and_clear_bit(KVM_APIC_INIT, &apic->pending_events)) {
+       pe = xchg(&apic->pending_events, 0);
+
+       if (test_bit(KVM_APIC_INIT, &pe)) {
                kvm_lapic_reset(vcpu);
                kvm_vcpu_reset(vcpu);
                if (kvm_vcpu_is_bsp(apic->vcpu))
@@ -1873,7 +1876,7 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
                else
                        vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
        }
-       if (test_and_clear_bit(KVM_APIC_SIPI, &apic->pending_events) &&
+       if (test_bit(KVM_APIC_SIPI, &pe) &&
            vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
                /* evaluate pending_events before reading the vector */
                smp_rmb();
index eaac174..1f34e92 100644 (file)
@@ -277,6 +277,9 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
        end_pfn = limit_pfn;
        nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
 
+       if (!after_bootmem)
+               adjust_range_page_size_mask(mr, nr_range);
+
        /* try to merge same page size and continuous */
        for (i = 0; nr_range > 1 && i < nr_range - 1; i++) {
                unsigned long old_start;
@@ -291,9 +294,6 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
                nr_range--;
        }
 
-       if (!after_bootmem)
-               adjust_range_page_size_mask(mr, nr_range);
-
        for (i = 0; i < nr_range; i++)
                printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
                                mr[i].start, mr[i].end - 1,
index 305c68b..981c2db 100644 (file)
@@ -628,7 +628,9 @@ int pcibios_add_device(struct pci_dev *dev)
 
        pa_data = boot_params.hdr.setup_data;
        while (pa_data) {
-               data = phys_to_virt(pa_data);
+               data = ioremap(pa_data, sizeof(*rom));
+               if (!data)
+                       return -ENOMEM;
 
                if (data->type == SETUP_PCI) {
                        rom = (struct pci_setup_rom *)data;
@@ -645,6 +647,7 @@ int pcibios_add_device(struct pci_dev *dev)
                        }
                }
                pa_data = data->next;
+               iounmap(data);
        }
        return 0;
 }
index 55856b2..5ae2eb0 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/io.h>
 #include <linux/reboot.h>
 #include <linux/bcd.h>
-#include <linux/ucs2_string.h>
 
 #include <asm/setup.h>
 #include <asm/efi.h>
 
 #define EFI_DEBUG      1
 
-/*
- * There's some additional metadata associated with each
- * variable. Intel's reference implementation is 60 bytes - bump that
- * to account for potential alignment constraints
- */
-#define VAR_METADATA_SIZE 64
+#define EFI_MIN_RESERVE 5120
+
+#define EFI_DUMMY_GUID \
+       EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9)
+
+static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
 
 struct efi __read_mostly efi = {
        .mps        = EFI_INVALID_TABLE_ADDR,
@@ -79,13 +78,6 @@ struct efi_memory_map memmap;
 static struct efi efi_phys __initdata;
 static efi_system_table_t efi_systab __initdata;
 
-static u64 efi_var_store_size;
-static u64 efi_var_remaining_size;
-static u64 efi_var_max_var_size;
-static u64 boot_used_size;
-static u64 boot_var_size;
-static u64 active_size;
-
 unsigned long x86_efi_facility;
 
 /*
@@ -188,53 +180,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
                                               efi_char16_t *name,
                                               efi_guid_t *vendor)
 {
-       efi_status_t status;
-       static bool finished = false;
-       static u64 var_size;
-
-       status = efi_call_virt3(get_next_variable,
-                               name_size, name, vendor);
-
-       if (status == EFI_NOT_FOUND) {
-               finished = true;
-               if (var_size < boot_used_size) {
-                       boot_var_size = boot_used_size - var_size;
-                       active_size += boot_var_size;
-               } else {
-                       printk(KERN_WARNING FW_BUG  "efi: Inconsistent initial sizes\n");
-               }
-       }
-
-       if (boot_used_size && !finished) {
-               unsigned long size;
-               u32 attr;
-               efi_status_t s;
-               void *tmp;
-
-               s = virt_efi_get_variable(name, vendor, &attr, &size, NULL);
-
-               if (s != EFI_BUFFER_TOO_SMALL || !size)
-                       return status;
-
-               tmp = kmalloc(size, GFP_ATOMIC);
-
-               if (!tmp)
-                       return status;
-
-               s = virt_efi_get_variable(name, vendor, &attr, &size, tmp);
-
-               if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) {
-                       var_size += size;
-                       var_size += ucs2_strsize(name, 1024);
-                       active_size += size;
-                       active_size += VAR_METADATA_SIZE;
-                       active_size += ucs2_strsize(name, 1024);
-               }
-
-               kfree(tmp);
-       }
-
-       return status;
+       return efi_call_virt3(get_next_variable,
+                             name_size, name, vendor);
 }
 
 static efi_status_t virt_efi_set_variable(efi_char16_t *name,
@@ -243,34 +190,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
                                          unsigned long data_size,
                                          void *data)
 {
-       efi_status_t status;
-       u32 orig_attr = 0;
-       unsigned long orig_size = 0;
-
-       status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size,
-                                      NULL);
-
-       if (status != EFI_BUFFER_TOO_SMALL)
-               orig_size = 0;
-
-       status = efi_call_virt5(set_variable,
-                               name, vendor, attr,
-                               data_size, data);
-
-       if (status == EFI_SUCCESS) {
-               if (orig_size) {
-                       active_size -= orig_size;
-                       active_size -= ucs2_strsize(name, 1024);
-                       active_size -= VAR_METADATA_SIZE;
-               }
-               if (data_size) {
-                       active_size += data_size;
-                       active_size += ucs2_strsize(name, 1024);
-                       active_size += VAR_METADATA_SIZE;
-               }
-       }
-
-       return status;
+       return efi_call_virt5(set_variable,
+                             name, vendor, attr,
+                             data_size, data);
 }
 
 static efi_status_t virt_efi_query_variable_info(u32 attr,
@@ -786,9 +708,6 @@ void __init efi_init(void)
        char vendor[100] = "unknown";
        int i = 0;
        void *tmp;
-       struct setup_data *data;
-       struct efi_var_bootdata *efi_var_data;
-       u64 pa_data;
 
 #ifdef CONFIG_X86_32
        if (boot_params.efi_info.efi_systab_hi ||
@@ -806,22 +725,6 @@ void __init efi_init(void)
        if (efi_systab_init(efi_phys.systab))
                return;
 
-       pa_data = boot_params.hdr.setup_data;
-       while (pa_data) {
-               data = early_ioremap(pa_data, sizeof(*efi_var_data));
-               if (data->type == SETUP_EFI_VARS) {
-                       efi_var_data = (struct efi_var_bootdata *)data;
-
-                       efi_var_store_size = efi_var_data->store_size;
-                       efi_var_remaining_size = efi_var_data->remaining_size;
-                       efi_var_max_var_size = efi_var_data->max_var_size;
-               }
-               pa_data = data->next;
-               early_iounmap(data, sizeof(*efi_var_data));
-       }
-
-       boot_used_size = efi_var_store_size - efi_var_remaining_size;
-
        set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
 
        /*
@@ -1085,6 +988,13 @@ void __init efi_enter_virtual_mode(void)
                runtime_code_page_mkexec();
 
        kfree(new_memmap);
+
+       /* clean DUMMY object */
+       efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
+                        EFI_VARIABLE_NON_VOLATILE |
+                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                        EFI_VARIABLE_RUNTIME_ACCESS,
+                        0, NULL);
 }
 
 /*
@@ -1136,33 +1046,65 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
        efi_status_t status;
        u64 storage_size, remaining_size, max_size;
 
+       if (!(attributes & EFI_VARIABLE_NON_VOLATILE))
+               return 0;
+
        status = efi.query_variable_info(attributes, &storage_size,
                                         &remaining_size, &max_size);
        if (status != EFI_SUCCESS)
                return status;
 
-       if (!max_size && remaining_size > size)
-               printk_once(KERN_ERR FW_BUG "Broken EFI implementation"
-                           " is returning MaxVariableSize=0\n");
        /*
         * Some firmware implementations refuse to boot if there's insufficient
         * space in the variable store. We account for that by refusing the
         * write if permitting it would reduce the available space to under
-        * 50%. However, some firmware won't reclaim variable space until
-        * after the used (not merely the actively used) space drops below
-        * a threshold. We can approximate that case with the value calculated
-        * above. If both the firmware and our calculations indicate that the
-        * available space would drop below 50%, refuse the write.
+        * 5KB. This figure was provided by Samsung, so should be safe.
         */
+       if ((remaining_size - size < EFI_MIN_RESERVE) &&
+               !efi_no_storage_paranoia) {
+
+               /*
+                * Triggering garbage collection may require that the firmware
+                * generate a real EFI_OUT_OF_RESOURCES error. We can force
+                * that by attempting to use more space than is available.
+                */
+               unsigned long dummy_size = remaining_size + 1024;
+               void *dummy = kmalloc(dummy_size, GFP_ATOMIC);
+
+               status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
+                                         EFI_VARIABLE_NON_VOLATILE |
+                                         EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                         EFI_VARIABLE_RUNTIME_ACCESS,
+                                         dummy_size, dummy);
+
+               if (status == EFI_SUCCESS) {
+                       /*
+                        * This should have failed, so if it didn't make sure
+                        * that we delete it...
+                        */
+                       efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
+                                        EFI_VARIABLE_NON_VOLATILE |
+                                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                        EFI_VARIABLE_RUNTIME_ACCESS,
+                                        0, dummy);
+               }
 
-       if (!storage_size || size > remaining_size ||
-           (max_size && size > max_size))
-               return EFI_OUT_OF_RESOURCES;
+               /*
+                * The runtime code may now have triggered a garbage collection
+                * run, so check the variable info again
+                */
+               status = efi.query_variable_info(attributes, &storage_size,
+                                                &remaining_size, &max_size);
 
-       if (!efi_no_storage_paranoia &&
-           ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) &&
-            (remaining_size - size < storage_size / 2)))
-               return EFI_OUT_OF_RESOURCES;
+               if (status != EFI_SUCCESS)
+                       return status;
+
+               /*
+                * There still isn't enough room, so return an error
+                */
+               if (remaining_size - size < EFI_MIN_RESERVE)
+                       return EFI_OUT_OF_RESOURCES;
+       }
 
        return EFI_SUCCESS;
 }
index 590be10..f7bab68 100644 (file)
@@ -42,9 +42,6 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
        "^(xen_irq_disable_direct_reloc$|"
        "xen_save_fl_direct_reloc$|"
        "VDSO|"
-#if ELF_BITS == 64
-       "__vvar_page|"
-#endif
        "__crc_)",
 
 /*
@@ -72,6 +69,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
        "__per_cpu_load|"
        "init_per_cpu__.*|"
        "__end_rodata_hpage_align|"
+       "__vvar_page|"
 #endif
        "_end)$"
 };
index 8ff3799..d99cae8 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/irq_work.h>
+#include <linux/tick.h>
 
 #include <asm/paravirt.h>
 #include <asm/desc.h>
@@ -447,6 +448,13 @@ static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
        play_dead_common();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
        cpu_bringup();
+       /*
+        * commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down)
+        * clears certain data that the cpu_idle loop (which called us
+        * and that we return from) expects. The only way to get that
+        * data back is to call:
+        */
+       tick_nohz_idle_enter();
 }
 
 #else /* !CONFIG_HOTPLUG_CPU */
@@ -576,24 +584,22 @@ void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
 {
        unsigned cpu;
        unsigned int this_cpu = smp_processor_id();
+       int xen_vector = xen_map_vector(vector);
 
-       if (!(num_online_cpus() > 1))
+       if (!(num_online_cpus() > 1) || (xen_vector < 0))
                return;
 
        for_each_cpu_and(cpu, mask, cpu_online_mask) {
                if (this_cpu == cpu)
                        continue;
 
-               xen_smp_send_call_function_single_ipi(cpu);
+               xen_send_IPI_one(cpu, xen_vector);
        }
 }
 
 void xen_send_IPI_allbutself(int vector)
 {
-       int xen_vector = xen_map_vector(vector);
-
-       if (xen_vector >= 0)
-               xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
+       xen_send_IPI_mask_allbutself(cpu_online_mask, vector);
 }
 
 static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
index 8981a76..c7c2d89 100644 (file)
@@ -5,7 +5,6 @@ extern void xen_send_IPI_mask(const struct cpumask *mask,
 extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
                                int vector);
 extern void xen_send_IPI_allbutself(int vector);
-extern void physflat_send_IPI_allbutself(int vector);
 extern void xen_send_IPI_all(int vector);
 extern void xen_send_IPI_self(int vector);
 
index 33c33bc..d5745b5 100644 (file)
@@ -3164,7 +3164,7 @@ void blk_post_runtime_resume(struct request_queue *q, int err)
                q->rpm_status = RPM_ACTIVE;
                __blk_run_queue(q);
                pm_runtime_mark_last_busy(q->dev);
-               pm_runtime_autosuspend(q->dev);
+               pm_request_autosuspend(q->dev);
        } else {
                q->rpm_status = RPM_SUSPENDED;
        }
index 622d8a4..bf8148e 100644 (file)
@@ -823,6 +823,7 @@ config CRYPTO_BLOWFISH_X86_64
 config CRYPTO_BLOWFISH_AVX2_X86_64
        tristate "Blowfish cipher algorithm (x86_64/AVX2)"
        depends on X86 && 64BIT
+       depends on BROKEN
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
        select CRYPTO_ABLK_HELPER_X86
@@ -1299,6 +1300,7 @@ config CRYPTO_TWOFISH_AVX_X86_64
 config CRYPTO_TWOFISH_AVX2_X86_64
        tristate "Twofish cipher algorithm (x86_64/AVX2)"
        depends on X86 && 64BIT
+       depends on BROKEN
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
        select CRYPTO_ABLK_HELPER_X86
index fefc2ca..33dc6a0 100644 (file)
@@ -250,10 +250,6 @@ static const char *cper_pcie_port_type_strs[] = {
 static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
                            const struct acpi_hest_generic_data *gdata)
 {
-#ifdef CONFIG_ACPI_APEI_PCIEAER
-       struct pci_dev *dev;
-#endif
-
        if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
                printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
                       pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
@@ -285,20 +281,6 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
                printk(
        "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
        pfx, pcie->bridge.secondary_status, pcie->bridge.control);
-#ifdef CONFIG_ACPI_APEI_PCIEAER
-       dev = pci_get_domain_bus_and_slot(pcie->device_id.segment,
-                       pcie->device_id.bus, pcie->device_id.function);
-       if (!dev) {
-               pr_err("PCI AER Cannot get PCI device %04x:%02x:%02x.%d\n",
-                       pcie->device_id.segment, pcie->device_id.bus,
-                       pcie->device_id.slot, pcie->device_id.function);
-               return;
-       }
-       if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO)
-               cper_print_aer(pfx, dev, gdata->error_severity,
-                               (struct aer_capability_regs *) pcie->aer_info);
-       pci_dev_put(dev);
-#endif
 }
 
 static const char *apei_estatus_section_flag_strs[] = {
index d668a8a..fcd7d91 100644 (file)
@@ -454,7 +454,9 @@ static void ghes_do_proc(struct ghes *ghes,
                                aer_severity = cper_severity_to_aer(sev);
                                aer_recover_queue(pcie_err->device_id.segment,
                                                  pcie_err->device_id.bus,
-                                                 devfn, aer_severity);
+                                                 devfn, aer_severity,
+                                                 (struct aer_capability_regs *)
+                                                 pcie_err->aer_info);
                        }
 
                }
@@ -917,13 +919,14 @@ static int ghes_probe(struct platform_device *ghes_dev)
                break;
        case ACPI_HEST_NOTIFY_EXTERNAL:
                /* External interrupt vector is GSI */
-               if (acpi_gsi_to_irq(generic->notify.vector, &ghes->irq)) {
+               rc = acpi_gsi_to_irq(generic->notify.vector, &ghes->irq);
+               if (rc) {
                        pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n",
                               generic->header.source_id);
                        goto err_edac_unreg;
                }
-               if (request_irq(ghes->irq, ghes_irq_func,
-                               0, "GHES IRQ", ghes)) {
+               rc = request_irq(ghes->irq, ghes_irq_func, 0, "GHES IRQ", ghes);
+               if (rc) {
                        pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n",
                               generic->header.source_id);
                        goto err_edac_unreg;
index bc493aa..318fa32 100644 (file)
@@ -278,11 +278,13 @@ int acpi_bus_init_power(struct acpi_device *device)
                if (result)
                        return result;
        } else if (state == ACPI_STATE_UNKNOWN) {
-               /* No power resources and missing _PSC? Try to force D0. */
+               /*
+                * No power resources and missing _PSC?  Cross fingers and make
+                * it D0 in hope that this is what the BIOS put the device into.
+                * [We tried to force D0 here by executing _PS0, but that broke
+                * Toshiba P870-303 in a nasty way.]
+                */
                state = ACPI_STATE_D0;
-               result = acpi_dev_pm_explicit_set(device, state);
-               if (result)
-                       return result;
        }
        device->power.state = state;
        return 0;
index 44225cb..b14ac46 100644 (file)
@@ -1017,11 +1017,8 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
                return -ENOSYS;
 
        result = driver->ops.add(device);
-       if (result) {
-               device->driver = NULL;
-               device->driver_data = NULL;
+       if (result)
                return result;
-       }
 
        device->driver = driver;
 
index 5b32e15..440eadf 100644 (file)
@@ -458,12 +458,28 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
        },
        {
         .callback = video_ignore_initial_backlight,
+        .ident = "HP Pavilion g6 Notebook PC",
+        .matches = {
+                DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+                DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"),
+               },
+       },
+       {
+        .callback = video_ignore_initial_backlight,
         .ident = "HP 1000 Notebook PC",
         .matches = {
                DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
                DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"),
                },
        },
+       {
+        .callback = video_ignore_initial_backlight,
+        .ident = "HP Pavilion m4",
+        .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"),
+               },
+       },
        {}
 };
 
@@ -1706,6 +1722,9 @@ static int acpi_video_bus_add(struct acpi_device *device)
        int error;
        acpi_status status;
 
+       if (device->handler)
+               return -EINVAL;
+
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
                                device->parent->handle, 1,
                                acpi_video_bus_match, NULL,
index 4e94ba2..9d0cf01 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *  acard-ahci.c - ACard AHCI SATA support
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 251e57d..2b50dfd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ahci.c - AHCI SATA support
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
@@ -423,6 +423,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          .driver_data = board_ahci_yes_fbs },                  /* 88se9125 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
+         .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 on some Gigabyte */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
index b830e6c..10b14d4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  ahci.h - Common AHCI SATA definitions and declarations
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 2f48123..9a8a674 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *    ata_piix.c - Intel PATA/SATA controllers
  *
- *    Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *    Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
@@ -151,6 +151,7 @@ enum piix_controller_ids {
        piix_pata_vmw,                  /* PIIX4 for VMware, spurious DMA_ERR */
        ich8_sata_snb,
        ich8_2port_sata_snb,
+       ich8_2port_sata_byt,
 };
 
 struct piix_map_db {
@@ -334,6 +335,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
        /* SATA Controller IDE (Wellsburg) */
        { 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (BayTrail) */
+       { 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
+       { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
 
        { }     /* terminate list */
 };
@@ -441,6 +445,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
        [tolapai_sata]          = &tolapai_map_db,
        [ich8_sata_snb]         = &ich8_map_db,
        [ich8_2port_sata_snb]   = &ich8_2port_map_db,
+       [ich8_2port_sata_byt]   = &ich8_2port_map_db,
 };
 
 static struct pci_bits piix_enable_bits[] = {
@@ -1254,6 +1259,16 @@ static struct ata_port_info piix_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &piix_sata_ops,
        },
+
+       [ich8_2port_sata_byt] =
+       {
+               .flags          = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16,
+               .pio_mask       = ATA_PIO4,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &piix_sata_ops,
+       },
+
 };
 
 #define AHCI_PCI_BAR 5
index 34c8216..a70ff15 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libahci.c - Common AHCI SATA low-level routines
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 63c743b..f218427 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-core.c - helper library for ATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
@@ -1602,6 +1602,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        qc->tf = *tf;
        if (cdb)
                memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
+
+       /* some SATA bridges need us to indicate data xfer direction */
+       if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) &&
+           dma_dir == DMA_FROM_DEVICE)
+               qc->tf.feature |= ATAPI_DMADIR;
+
        qc->flags |= ATA_QCFLAG_RESULT_TF;
        qc->dma_dir = dma_dir;
        if (dma_dir != DMA_NONE) {
index f9476fb..c69fcce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-eh.c - libata error handling
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index dd310b2..0101af5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-scsi.c - helper library for ATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index d8af325..b603720 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  libata-sff.c - helper library for PCI IDE BMDMA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 5053333..8ea6e6a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  pdc_adma.c - Pacific Digital Corporation ADMA
  *
- *  Maintained by:  Mark Lord <mlord@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *
  *  Copyright 2005 Mark Lord
  *
index fb0dd87..958ba2a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_promise.c - Promise SATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Mikael Pettersson <mikpe@it.uu.se>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
index 4799868..249c8a2 100644 (file)
@@ -549,6 +549,7 @@ static void sata_rcar_bmdma_start(struct ata_queued_cmd *qc)
 
        /* start host DMA transaction */
        dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG);
+       dmactl &= ~ATAPI_CONTROL1_STOP;
        dmactl |= ATAPI_CONTROL1_START;
        iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG);
 }
@@ -618,17 +619,16 @@ static struct ata_port_operations sata_rcar_port_ops = {
        .bmdma_status           = sata_rcar_bmdma_status,
 };
 
-static int sata_rcar_serr_interrupt(struct ata_port *ap)
+static void sata_rcar_serr_interrupt(struct ata_port *ap)
 {
        struct sata_rcar_priv *priv = ap->host->private_data;
        struct ata_eh_info *ehi = &ap->link.eh_info;
        int freeze = 0;
-       int handled = 0;
        u32 serror;
 
        serror = ioread32(priv->base + SCRSERR_REG);
        if (!serror)
-               return 0;
+               return;
 
        DPRINTK("SError @host_intr: 0x%x\n", serror);
 
@@ -641,7 +641,6 @@ static int sata_rcar_serr_interrupt(struct ata_port *ap)
                ata_ehi_push_desc(ehi, "%s", "hotplug");
 
                freeze = serror & SERR_COMM_WAKE ? 0 : 1;
-               handled = 1;
        }
 
        /* freeze or abort */
@@ -649,11 +648,9 @@ static int sata_rcar_serr_interrupt(struct ata_port *ap)
                ata_port_freeze(ap);
        else
                ata_port_abort(ap);
-
-       return handled;
 }
 
-static int sata_rcar_ata_interrupt(struct ata_port *ap)
+static void sata_rcar_ata_interrupt(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc;
        int handled = 0;
@@ -662,7 +659,9 @@ static int sata_rcar_ata_interrupt(struct ata_port *ap)
        if (qc)
                handled |= ata_bmdma_port_intr(ap, qc);
 
-       return handled;
+       /* be sure to clear ATA interrupt */
+       if (!handled)
+               sata_rcar_check_status(ap);
 }
 
 static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
@@ -677,20 +676,21 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
        spin_lock_irqsave(&host->lock, flags);
 
        sataintstat = ioread32(priv->base + SATAINTSTAT_REG);
+       sataintstat &= SATA_RCAR_INT_MASK;
        if (!sataintstat)
                goto done;
        /* ack */
-       iowrite32(sataintstat & ~SATA_RCAR_INT_MASK,
-                priv->base + SATAINTSTAT_REG);
+       iowrite32(~sataintstat & 0x7ff, priv->base + SATAINTSTAT_REG);
 
        ap = host->ports[0];
 
        if (sataintstat & SATAINTSTAT_ATA)
-               handled |= sata_rcar_ata_interrupt(ap);
+               sata_rcar_ata_interrupt(ap);
 
        if (sataintstat & SATAINTSTAT_SERR)
-               handled |= sata_rcar_serr_interrupt(ap);
+               sata_rcar_serr_interrupt(ap);
 
+       handled = 1;
 done:
        spin_unlock_irqrestore(&host->lock, flags);
 
index a7b3167..0ae3ca4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_sil.c - Silicon Image SATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 7b7127a..9947010 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_sx4.c - Promise SATA
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
index 5913ea9..87f056e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  sata_via.c - VIA Serial ATA controllers
  *
- *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *  Maintained by:  Tejun Heo <tj@kernel.org>
  *                Please ALWAYS copy linux-ide@vger.kernel.org
  *                on emails.
  *
index aa0875f..02f490b 100644 (file)
@@ -143,7 +143,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
        int registers = 0;
        int this_registers, average;
 
-       map->lock(map);
+       map->lock(map->lock_arg);
 
        mem_size = sizeof(*rbtree_ctx);
        mem_size += BITS_TO_LONGS(map->cache_present_nbits) * sizeof(long);
@@ -170,7 +170,7 @@ static int rbtree_show(struct seq_file *s, void *ignored)
        seq_printf(s, "%d nodes, %d registers, average %d registers, used %zu bytes\n",
                   nodes, registers, average, mem_size);
 
-       map->unlock(map);
+       map->unlock(map->lock_arg);
 
        return 0;
 }
@@ -391,8 +391,6 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min,
        for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
                rbnode = rb_entry(node, struct regcache_rbtree_node, node);
 
-               if (rbnode->base_reg < min)
-                       continue;
                if (rbnode->base_reg > max)
                        break;
                if (rbnode->base_reg + rbnode->blklen < min)
index 75923f2..507ee2d 100644 (file)
@@ -270,7 +270,7 @@ int regcache_sync(struct regmap *map)
 
        BUG_ON(!map->cache_ops || !map->cache_ops->sync);
 
-       map->lock(map);
+       map->lock(map->lock_arg);
        /* Remember the initial bypass state */
        bypass = map->cache_bypass;
        dev_dbg(map->dev, "Syncing %s cache\n",
@@ -306,7 +306,7 @@ out:
        trace_regcache_sync(map->dev, name, "stop");
        /* Restore the bypass state */
        map->cache_bypass = bypass;
-       map->unlock(map);
+       map->unlock(map->lock_arg);
 
        return ret;
 }
@@ -333,7 +333,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
 
        BUG_ON(!map->cache_ops || !map->cache_ops->sync);
 
-       map->lock(map);
+       map->lock(map->lock_arg);
 
        /* Remember the initial bypass state */
        bypass = map->cache_bypass;
@@ -352,7 +352,7 @@ out:
        trace_regcache_sync(map->dev, name, "stop region");
        /* Restore the bypass state */
        map->cache_bypass = bypass;
-       map->unlock(map);
+       map->unlock(map->lock_arg);
 
        return ret;
 }
@@ -372,11 +372,11 @@ EXPORT_SYMBOL_GPL(regcache_sync_region);
  */
 void regcache_cache_only(struct regmap *map, bool enable)
 {
-       map->lock(map);
+       map->lock(map->lock_arg);
        WARN_ON(map->cache_bypass && enable);
        map->cache_only = enable;
        trace_regmap_cache_only(map->dev, enable);
-       map->unlock(map);
+       map->unlock(map->lock_arg);
 }
 EXPORT_SYMBOL_GPL(regcache_cache_only);
 
@@ -391,9 +391,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only);
  */
 void regcache_mark_dirty(struct regmap *map)
 {
-       map->lock(map);
+       map->lock(map->lock_arg);
        map->cache_dirty = true;
-       map->unlock(map);
+       map->unlock(map->lock_arg);
 }
 EXPORT_SYMBOL_GPL(regcache_mark_dirty);
 
@@ -410,11 +410,11 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty);
  */
 void regcache_cache_bypass(struct regmap *map, bool enable)
 {
-       map->lock(map);
+       map->lock(map->lock_arg);
        WARN_ON(map->cache_only && enable);
        map->cache_bypass = enable;
        trace_regmap_cache_bypass(map->dev, enable);
-       map->unlock(map);
+       map->unlock(map->lock_arg);
 }
 EXPORT_SYMBOL_GPL(regcache_cache_bypass);
 
index 23b701f..975719b 100644 (file)
@@ -265,6 +265,7 @@ static ssize_t regmap_map_write_file(struct file *file,
        char *start = buf;
        unsigned long reg, value;
        struct regmap *map = file->private_data;
+       int ret;
 
        buf_size = min(count, (sizeof(buf)-1));
        if (copy_from_user(buf, user_buf, buf_size))
@@ -282,7 +283,9 @@ static ssize_t regmap_map_write_file(struct file *file,
        /* Userspace has been fiddling around behind the kernel's back */
        add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
 
-       regmap_write(map, reg, value);
+       ret = regmap_write(map, reg, value);
+       if (ret < 0)
+               return ret;
        return buf_size;
 }
 #else
index 6374dc1..62b6c2c 100644 (file)
@@ -168,8 +168,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id);
 static int cciss_open(struct block_device *bdev, fmode_t mode);
 static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode);
 static void cciss_release(struct gendisk *disk, fmode_t mode);
-static int do_ioctl(struct block_device *bdev, fmode_t mode,
-                   unsigned int cmd, unsigned long arg);
 static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned int cmd, unsigned long arg);
 static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
@@ -235,7 +233,7 @@ static const struct block_device_operations cciss_fops = {
        .owner = THIS_MODULE,
        .open = cciss_unlocked_open,
        .release = cciss_release,
-       .ioctl = do_ioctl,
+       .ioctl = cciss_ioctl,
        .getgeo = cciss_getgeo,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = cciss_compat_ioctl,
@@ -1143,16 +1141,6 @@ static void cciss_release(struct gendisk *disk, fmode_t mode)
        mutex_unlock(&cciss_mutex);
 }
 
-static int do_ioctl(struct block_device *bdev, fmode_t mode,
-                   unsigned cmd, unsigned long arg)
-{
-       int ret;
-       mutex_lock(&cciss_mutex);
-       ret = cciss_ioctl(bdev, mode, cmd, arg);
-       mutex_unlock(&cciss_mutex);
-       return ret;
-}
-
 #ifdef CONFIG_COMPAT
 
 static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
@@ -1179,7 +1167,7 @@ static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode,
        case CCISS_REGNEWD:
        case CCISS_RESCANDISK:
        case CCISS_GETLUNINFO:
-               return do_ioctl(bdev, mode, cmd, arg);
+               return cciss_ioctl(bdev, mode, cmd, arg);
 
        case CCISS_PASSTHRU32:
                return cciss_ioctl32_passthru(bdev, mode, cmd, arg);
@@ -1219,7 +1207,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
        if (err)
                return -EFAULT;
 
-       err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
+       err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p);
        if (err)
                return err;
        err |=
@@ -1261,7 +1249,7 @@ static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode,
        if (err)
                return -EFAULT;
 
-       err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
+       err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p);
        if (err)
                return err;
        err |=
@@ -1311,11 +1299,14 @@ static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
 static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
 {
        cciss_coalint_struct intinfo;
+       unsigned long flags;
 
        if (!argp)
                return -EINVAL;
+       spin_lock_irqsave(&h->lock, flags);
        intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
        intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
+       spin_unlock_irqrestore(&h->lock, flags);
        if (copy_to_user
            (argp, &intinfo, sizeof(cciss_coalint_struct)))
                return -EFAULT;
@@ -1356,12 +1347,15 @@ static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
 static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
 {
        NodeName_type NodeName;
+       unsigned long flags;
        int i;
 
        if (!argp)
                return -EINVAL;
+       spin_lock_irqsave(&h->lock, flags);
        for (i = 0; i < 16; i++)
                NodeName[i] = readb(&h->cfgtable->ServerName[i]);
+       spin_unlock_irqrestore(&h->lock, flags);
        if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
                return -EFAULT;
        return 0;
@@ -1398,10 +1392,13 @@ static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
 static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
 {
        Heartbeat_type heartbeat;
+       unsigned long flags;
 
        if (!argp)
                return -EINVAL;
+       spin_lock_irqsave(&h->lock, flags);
        heartbeat = readl(&h->cfgtable->HeartBeat);
+       spin_unlock_irqrestore(&h->lock, flags);
        if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
                return -EFAULT;
        return 0;
@@ -1410,10 +1407,13 @@ static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
 static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
 {
        BusTypes_type BusTypes;
+       unsigned long flags;
 
        if (!argp)
                return -EINVAL;
+       spin_lock_irqsave(&h->lock, flags);
        BusTypes = readl(&h->cfgtable->BusTypes);
+       spin_unlock_irqrestore(&h->lock, flags);
        if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
                return -EFAULT;
        return 0;
index 847107e..20dd52a 100644 (file)
@@ -3002,7 +3002,8 @@ static int mtip_hw_debugfs_init(struct driver_data *dd)
 
 static void mtip_hw_debugfs_exit(struct driver_data *dd)
 {
-       debugfs_remove_recursive(dd->dfs_node);
+       if (dd->dfs_node)
+               debugfs_remove_recursive(dd->dfs_node);
 }
 
 
@@ -3863,7 +3864,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
        struct driver_data *dd = queue->queuedata;
        struct scatterlist *sg;
        struct bio_vec *bvec;
-       int nents = 0;
+       int i, nents = 0;
        int tag = 0, unaligned = 0;
 
        if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
@@ -3921,11 +3922,12 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
                }
 
                /* Create the scatter list for this bio. */
-               bio_for_each_segment(bvec, bio, nents) {
+               bio_for_each_segment(bvec, bio, i) {
                        sg_set_page(&sg[nents],
                                        bvec->bv_page,
                                        bvec->bv_len,
                                        bvec->bv_offset);
+                       nents++;
                }
 
                /* Issue the read/write. */
index 8efdfaa..ce79a59 100644 (file)
@@ -629,7 +629,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,
        struct nvme_command *cmnd;
        struct nvme_iod *iod;
        enum dma_data_direction dma_dir;
-       int cmdid, length, result = -ENOMEM;
+       int cmdid, length, result;
        u16 control;
        u32 dsmgmt;
        int psegs = bio_phys_segments(ns->queue, bio);
@@ -640,6 +640,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns,
                        return result;
        }
 
+       result = -ENOMEM;
        iod = nvme_alloc_iod(psegs, bio->bi_size, GFP_ATOMIC);
        if (!iod)
                goto nomem;
@@ -977,6 +978,8 @@ static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout)
 
                if (timeout && !time_after(now, info[cmdid].timeout))
                        continue;
+               if (info[cmdid].ctx == CMD_CTX_CANCELLED)
+                       continue;
                dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d\n", cmdid);
                ctx = cancel_cmdid(nvmeq, cmdid, &fn);
                fn(nvmeq->dev, ctx, &cqe);
@@ -1206,7 +1209,7 @@ struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write,
 
        if (addr & 3)
                return ERR_PTR(-EINVAL);
-       if (!length)
+       if (!length || length > INT_MAX - PAGE_SIZE)
                return ERR_PTR(-EINVAL);
 
        offset = offset_in_page(addr);
@@ -1227,7 +1230,8 @@ struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write,
        sg_init_table(sg, count);
        for (i = 0; i < count; i++) {
                sg_set_page(&sg[i], pages[i],
-                               min_t(int, length, PAGE_SIZE - offset), offset);
+                           min_t(unsigned, length, PAGE_SIZE - offset),
+                           offset);
                length -= (PAGE_SIZE - offset);
                offset = 0;
        }
@@ -1435,7 +1439,7 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev,
                nvme_free_iod(dev, iod);
        }
 
-       if (!status && copy_to_user(&ucmd->result, &cmd.result,
+       if ((status >= 0) && copy_to_user(&ucmd->result, &cmd.result,
                                                        sizeof(cmd.result)))
                status = -EFAULT;
 
@@ -1633,7 +1637,8 @@ static int set_queue_count(struct nvme_dev *dev, int count)
 
 static int nvme_setup_io_queues(struct nvme_dev *dev)
 {
-       int result, cpu, i, nr_io_queues, db_bar_size, q_depth;
+       struct pci_dev *pdev = dev->pci_dev;
+       int result, cpu, i, nr_io_queues, db_bar_size, q_depth, q_count;
 
        nr_io_queues = num_online_cpus();
        result = set_queue_count(dev, nr_io_queues);
@@ -1642,14 +1647,14 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        if (result < nr_io_queues)
                nr_io_queues = result;
 
+       q_count = nr_io_queues;
        /* Deregister the admin queue's interrupt */
        free_irq(dev->entry[0].vector, dev->queues[0]);
 
        db_bar_size = 4096 + ((nr_io_queues + 1) << (dev->db_stride + 3));
        if (db_bar_size > 8192) {
                iounmap(dev->bar);
-               dev->bar = ioremap(pci_resource_start(dev->pci_dev, 0),
-                                                               db_bar_size);
+               dev->bar = ioremap(pci_resource_start(pdev, 0), db_bar_size);
                dev->dbs = ((void __iomem *)dev->bar) + 4096;
                dev->queues[0]->q_db = dev->dbs;
        }
@@ -1657,19 +1662,36 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        for (i = 0; i < nr_io_queues; i++)
                dev->entry[i].entry = i;
        for (;;) {
-               result = pci_enable_msix(dev->pci_dev, dev->entry,
-                                                               nr_io_queues);
+               result = pci_enable_msix(pdev, dev->entry, nr_io_queues);
                if (result == 0) {
                        break;
                } else if (result > 0) {
                        nr_io_queues = result;
                        continue;
                } else {
-                       nr_io_queues = 1;
+                       nr_io_queues = 0;
                        break;
                }
        }
 
+       if (nr_io_queues == 0) {
+               nr_io_queues = q_count;
+               for (;;) {
+                       result = pci_enable_msi_block(pdev, nr_io_queues);
+                       if (result == 0) {
+                               for (i = 0; i < nr_io_queues; i++)
+                                       dev->entry[i].vector = i + pdev->irq;
+                               break;
+                       } else if (result > 0) {
+                               nr_io_queues = result;
+                               continue;
+                       } else {
+                               nr_io_queues = 1;
+                               break;
+                       }
+               }
+       }
+
        result = queue_request_irq(dev, dev->queues[0], "nvme admin");
        /* XXX: handle failure here */
 
@@ -1850,7 +1872,10 @@ static void nvme_free_dev(struct kref *kref)
 {
        struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref);
        nvme_dev_remove(dev);
-       pci_disable_msix(dev->pci_dev);
+       if (dev->pci_dev->msi_enabled)
+               pci_disable_msi(dev->pci_dev);
+       else if (dev->pci_dev->msix_enabled)
+               pci_disable_msix(dev->pci_dev);
        iounmap(dev->bar);
        nvme_release_instance(dev);
        nvme_release_prp_pools(dev);
@@ -1923,8 +1948,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        INIT_LIST_HEAD(&dev->namespaces);
        dev->pci_dev = pdev;
        pci_set_drvdata(pdev, dev);
-       dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
-       dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+
+       if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)))
+               dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+       else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)))
+               dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+       else
+               goto disable;
+
        result = nvme_set_instance(dev);
        if (result)
                goto disable;
@@ -1977,7 +2008,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  unmap:
        iounmap(dev->bar);
  disable_msix:
-       pci_disable_msix(pdev);
+       if (dev->pci_dev->msi_enabled)
+               pci_disable_msi(dev->pci_dev);
+       else if (dev->pci_dev->msix_enabled)
+               pci_disable_msix(dev->pci_dev);
        nvme_release_instance(dev);
        nvme_release_prp_pools(dev);
  disable:
index fed54b0..102de2f 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <scsi/sg.h>
 #include <scsi/scsi.h>
 
@@ -1654,7 +1653,7 @@ static void nvme_trans_modesel_save_bd(struct nvme_ns *ns, u8 *parm_list,
        }
 }
 
-static u16 nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr,
+static int nvme_trans_modesel_get_mp(struct nvme_ns *ns, struct sg_io_hdr *hdr,
                                        u8 *mode_page, u8 page_code)
 {
        int res = SNTI_TRANSLATION_SUCCESS;
index 3c08983..f5d0ea1 100644 (file)
@@ -83,7 +83,8 @@
 
 #define MAX_SPEED 0xffff
 
-#define ZONE(sector, pd) (((sector) + (pd)->offset) & ~((pd)->settings.size - 1))
+#define ZONE(sector, pd) (((sector) + (pd)->offset) & \
+                       ~(sector_t)((pd)->settings.size - 1))
 
 static DEFINE_MUTEX(pktcdvd_mutex);
 static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
index d6d3140..3063452 100644 (file)
@@ -519,8 +519,8 @@ static const struct block_device_operations rbd_bd_ops = {
 };
 
 /*
- * Initialize an rbd client instance.
- * We own *ceph_opts.
+ * Initialize an rbd client instance.  Success or not, this function
+ * consumes ceph_opts.
  */
 static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts)
 {
@@ -675,7 +675,8 @@ static int parse_rbd_opts_token(char *c, void *private)
 
 /*
  * Get a ceph client with specific addr and configuration, if one does
- * not exist create it.
+ * not exist create it.  Either way, ceph_opts is consumed by this
+ * function.
  */
 static struct rbd_client *rbd_get_client(struct ceph_options *ceph_opts)
 {
@@ -4697,8 +4698,10 @@ out:
        return ret;
 }
 
-/* Undo whatever state changes are made by v1 or v2 image probe */
-
+/*
+ * Undo whatever state changes are made by v1 or v2 header info
+ * call.
+ */
 static void rbd_dev_unprobe(struct rbd_device *rbd_dev)
 {
        struct rbd_image_header *header;
@@ -4902,9 +4905,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping)
        int tmp;
 
        /*
-        * Get the id from the image id object.  If it's not a
-        * format 2 image, we'll get ENOENT back, and we'll assume
-        * it's a format 1 image.
+        * Get the id from the image id object.  Unless there's an
+        * error, rbd_dev->spec->image_id will be filled in with
+        * a dynamically-allocated string, and rbd_dev->image_format
+        * will be set to either 1 or 2.
         */
        ret = rbd_dev_image_id(rbd_dev);
        if (ret)
@@ -4992,7 +4996,6 @@ static ssize_t rbd_add(struct bus_type *bus,
                rc = PTR_ERR(rbdc);
                goto err_out_args;
        }
-       ceph_opts = NULL;       /* rbd_dev client now owns this */
 
        /* pick the pool */
        osdc = &rbdc->client->osdc;
@@ -5027,18 +5030,18 @@ static ssize_t rbd_add(struct bus_type *bus,
        rbd_dev->mapping.read_only = read_only;
 
        rc = rbd_dev_device_setup(rbd_dev);
-       if (!rc)
-               return count;
+       if (rc) {
+               rbd_dev_image_release(rbd_dev);
+               goto err_out_module;
+       }
+
+       return count;
 
-       rbd_dev_image_release(rbd_dev);
 err_out_rbd_dev:
        rbd_dev_destroy(rbd_dev);
 err_out_client:
        rbd_put_client(rbdc);
 err_out_args:
-       if (ceph_opts)
-               ceph_destroy_options(ceph_opts);
-       kfree(rbd_opts);
        rbd_spec_put(spec);
 err_out_module:
        module_put(THIS_MODULE);
index fdfd61a..11a6104 100644 (file)
@@ -201,7 +201,7 @@ config BT_MRVL
          The core driver to support Marvell Bluetooth devices.
 
          This driver is required if you want to support
-         Marvell Bluetooth devices, such as 8688/8787/8797.
+         Marvell Bluetooth devices, such as 8688/8787/8797/8897.
 
          Say Y here to compile Marvell Bluetooth driver
          into the kernel or say M to compile it as module.
@@ -214,7 +214,7 @@ config BT_MRVL_SDIO
          The driver for Marvell Bluetooth chipsets with SDIO interface.
 
          This driver is required if you want to use Marvell Bluetooth
-         devices with SDIO interface. Currently SD8688/SD8787/SD8797
+         devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897
          chipsets are supported.
 
          Say Y here to compile support for Marvell BT-over-SDIO driver
index c63488c..13693b7 100644 (file)
@@ -82,6 +82,23 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
        .io_port_2 = 0x7a,
 };
 
+static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
+       .cfg = 0x00,
+       .host_int_mask = 0x02,
+       .host_intstatus = 0x03,
+       .card_status = 0x50,
+       .sq_read_base_addr_a0 = 0x60,
+       .sq_read_base_addr_a1 = 0x61,
+       .card_revision = 0xbc,
+       .card_fw_status0 = 0xc0,
+       .card_fw_status1 = 0xc1,
+       .card_rx_len = 0xc2,
+       .card_rx_unit = 0xc3,
+       .io_port_0 = 0xd8,
+       .io_port_1 = 0xd9,
+       .io_port_2 = 0xda,
+};
+
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
        .helper         = "mrvl/sd8688_helper.bin",
        .firmware       = "mrvl/sd8688.bin",
@@ -103,6 +120,13 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
        .sd_blksz_fw_dl = 256,
 };
 
+static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
+       .helper         = NULL,
+       .firmware       = "mrvl/sd8897_uapsta.bin",
+       .reg            = &btmrvl_reg_88xx,
+       .sd_blksz_fw_dl = 256,
+};
+
 static const struct sdio_device_id btmrvl_sdio_ids[] = {
        /* Marvell SD8688 Bluetooth device */
        { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
@@ -116,6 +140,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
        /* Marvell SD8797 Bluetooth device */
        { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
                        .driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
+       /* Marvell SD8897 Bluetooth device */
+       { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
+                       .driver_data = (unsigned long) &btmrvl_sdio_sd8897 },
 
        { }     /* Terminating entry */
 };
@@ -1194,3 +1221,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
 MODULE_FIRMWARE("mrvl/sd8688.bin");
 MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
+MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
index 8927284..24f5536 100644 (file)
@@ -932,7 +932,7 @@ static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
        unsigned char reg;
        unsigned char rdiv;
 
-       if (hwdata->num > 5)
+       if (hwdata->num <= 5)
                reg = si5351_msynth_params_address(hwdata->num) + 2;
        else
                reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
@@ -1477,6 +1477,16 @@ static int si5351_i2c_probe(struct i2c_client *client,
                        return -EINVAL;
                }
                drvdata->onecell.clks[n] = clk;
+
+               /* set initial clkout rate */
+               if (pdata->clkout[n].rate != 0) {
+                       int ret;
+                       ret = clk_set_rate(clk, pdata->clkout[n].rate);
+                       if (ret != 0) {
+                               dev_err(&client->dev, "Cannot set rate : %d\n",
+                                       ret);
+                       }
+               }
        }
 
        ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
index debf688..553ac35 100644 (file)
@@ -183,7 +183,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
        writel(divisor, cdev->div_reg);
        vt8500_pmc_wait_busy();
 
-       spin_lock_irqsave(cdev->lock, flags);
+       spin_unlock_irqrestore(cdev->lock, flags);
 
        return 0;
 }
index d0e5eed..4faf0af 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk/mxs.h>
 #include <linux/clkdev.h>
 #include <linux/err.h>
 #include <linux/init.h>
index d0940e6..3c1f888 100644 (file)
@@ -791,7 +791,8 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
        GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0),
        GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0),
        GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0),
-       GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0),
+       GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0,
+                       CLK_IGNORE_UNUSED, 0),
        GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0),
        GATE(smmu_rotator, "smmu_rotator", "aclk200",
                        E4210_GATE_IP_IMAGE, 4, 0, 0),
@@ -819,7 +820,8 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
        GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0),
        GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0),
        GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0),
-       GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, 0, 0),
+       GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1,
+                       CLK_IGNORE_UNUSED, 0),
        GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0),
        GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0",
                        SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0),
index bc7e9bd..e364c9d 100644 (file)
@@ -145,7 +145,13 @@ static struct clk *clk_reg_sysctrl(struct device *dev,
                return ERR_PTR(-ENOMEM);
        }
 
-       for (i = 0; i < num_parents; i++) {
+       /* set main clock registers */
+       clk->reg_sel[0] = reg_sel[0];
+       clk->reg_bits[0] = reg_bits[0];
+       clk->reg_mask[0] = reg_mask[0];
+
+       /* handle clocks with more than one parent */
+       for (i = 1; i < num_parents; i++) {
                clk->reg_sel[i] = reg_sel[i];
                clk->reg_bits[i] = reg_bits[i];
                clk->reg_mask[i] = reg_mask[i];
index 0b4f35a..80069c3 100644 (file)
@@ -325,7 +325,7 @@ void u8500_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
        clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base,
                                BIT(0), 0);
        clk_register_clkdev(clk, "fsmc", NULL);
-       clk_register_clkdev(clk, NULL, "smsc911x");
+       clk_register_clkdev(clk, NULL, "smsc911x.0");
 
        clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base,
                                BIT(1), 0);
index 11b8b4b..edc089e 100644 (file)
@@ -347,11 +347,11 @@ static u32 get_cur_val(const struct cpumask *mask)
        switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {
        case SYSTEM_INTEL_MSR_CAPABLE:
                cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
-               cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
+               cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
                break;
        case SYSTEM_AMD_MSR_CAPABLE:
                cmd.type = SYSTEM_AMD_MSR_CAPABLE;
-               cmd.addr.msr.reg = MSR_AMD_PERF_STATUS;
+               cmd.addr.msr.reg = MSR_AMD_PERF_CTL;
                break;
        case SYSTEM_IO_CAPABLE:
                cmd.type = SYSTEM_IO_CAPABLE;
index a64eb8b..ad1fde2 100644 (file)
@@ -45,7 +45,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
        struct cpufreq_freqs freqs;
        struct opp *opp;
        unsigned long volt = 0, volt_old = 0, tol = 0;
-       long freq_Hz;
+       long freq_Hz, freq_exact;
        unsigned int index;
        int ret;
 
@@ -60,6 +60,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
        freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
        if (freq_Hz < 0)
                freq_Hz = freq_table[index].frequency * 1000;
+       freq_exact = freq_Hz;
        freqs.new = freq_Hz / 1000;
        freqs.old = clk_get_rate(cpu_clk) / 1000;
 
@@ -98,7 +99,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
                }
        }
 
-       ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+       ret = clk_set_rate(cpu_clk, freq_exact);
        if (ret) {
                pr_err("failed to set clock rate: %d\n", ret);
                if (cpu_reg)
index 5af40ad..dc9b72e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/tick.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
+#include <linux/cpu.h>
 
 #include "cpufreq_governor.h"
 
@@ -180,8 +181,10 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
        if (!all_cpus) {
                __gov_queue_work(smp_processor_id(), dbs_data, delay);
        } else {
+               get_online_cpus();
                for_each_cpu(i, policy->cpus)
                        __gov_queue_work(i, dbs_data, delay);
+               put_online_cpus();
        }
 }
 EXPORT_SYMBOL_GPL(gov_queue_work);
index 765fdf5..bf416a8 100644 (file)
@@ -1154,7 +1154,7 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
                dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
 
        sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
-                                DMA_BIDIRECTIONAL, assoc_chained);
+                                DMA_TO_DEVICE, assoc_chained);
        if (likely(req->src == req->dst)) {
                sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
                                         DMA_BIDIRECTIONAL, src_chained);
@@ -1336,7 +1336,7 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
                dst_nents = sg_count(req->dst, req->cryptlen, &dst_chained);
 
        sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
-                                DMA_BIDIRECTIONAL, assoc_chained);
+                                DMA_TO_DEVICE, assoc_chained);
        if (likely(req->src == req->dst)) {
                sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
                                         DMA_BIDIRECTIONAL, src_chained);
index a97bb6c..c3dc1c0 100644 (file)
@@ -863,7 +863,7 @@ static struct of_device_id sahara_dt_ids[] = {
        { .compatible = "fsl,imx27-sahara" },
        { /* sentinel */ }
 };
-MODULE_DEVICE_TABLE(platform, sahara_dt_ids);
+MODULE_DEVICE_TABLE(of, sahara_dt_ids);
 
 static int sahara_probe(struct platform_device *pdev)
 {
index d8ce4ec..e88ded2 100644 (file)
@@ -716,8 +716,7 @@ static int dmatest_func(void *data)
                }
                dma_async_issue_pending(chan);
 
-               wait_event_freezable_timeout(done_wait,
-                                            done.done || kthread_should_stop(),
+               wait_event_freezable_timeout(done_wait, done.done,
                                             msecs_to_jiffies(params->timeout));
 
                status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
@@ -997,7 +996,6 @@ static void stop_threaded_test(struct dmatest_info *info)
 static int __restart_threaded_test(struct dmatest_info *info, bool run)
 {
        struct dmatest_params *params = &info->params;
-       int ret;
 
        /* Stop any running test first */
        __stop_threaded_test(info);
@@ -1012,13 +1010,23 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run)
        memcpy(params, &info->dbgfs_params, sizeof(*params));
 
        /* Run test with new parameters */
-       ret = __run_threaded_test(info);
-       if (ret) {
-               __stop_threaded_test(info);
-               pr_err("dmatest: Can't run test\n");
+       return __run_threaded_test(info);
+}
+
+static bool __is_threaded_test_run(struct dmatest_info *info)
+{
+       struct dmatest_chan *dtc;
+
+       list_for_each_entry(dtc, &info->channels, node) {
+               struct dmatest_thread *thread;
+
+               list_for_each_entry(thread, &dtc->threads, node) {
+                       if (!thread->done)
+                               return true;
+               }
        }
 
-       return ret;
+       return false;
 }
 
 static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
@@ -1091,22 +1099,10 @@ static ssize_t dtf_read_run(struct file *file, char __user *user_buf,
 {
        struct dmatest_info *info = file->private_data;
        char buf[3];
-       struct dmatest_chan *dtc;
-       bool alive = false;
 
        mutex_lock(&info->lock);
-       list_for_each_entry(dtc, &info->channels, node) {
-               struct dmatest_thread *thread;
-
-               list_for_each_entry(thread, &dtc->threads, node) {
-                       if (!thread->done) {
-                               alive = true;
-                               break;
-                       }
-               }
-       }
 
-       if (alive) {
+       if (__is_threaded_test_run(info)) {
                buf[0] = 'Y';
        } else {
                __stop_threaded_test(info);
@@ -1132,7 +1128,12 @@ static ssize_t dtf_write_run(struct file *file, const char __user *user_buf,
 
        if (strtobool(buf, &bv) == 0) {
                mutex_lock(&info->lock);
-               ret = __restart_threaded_test(info, bv);
+
+               if (__is_threaded_test_run(info))
+                       ret = -EBUSY;
+               else
+                       ret = __restart_threaded_test(info, bv);
+
                mutex_unlock(&info->lock);
        }
 
index 1734fee..71bf4ec 100644 (file)
@@ -1566,10 +1566,12 @@ static void dma_tc_handle(struct d40_chan *d40c)
                        return;
                }
 
-               if (d40_queue_start(d40c) == NULL)
+               if (d40_queue_start(d40c) == NULL) {
                        d40c->busy = false;
-               pm_runtime_mark_last_busy(d40c->base->dev);
-               pm_runtime_put_autosuspend(d40c->base->dev);
+
+                       pm_runtime_mark_last_busy(d40c->base->dev);
+                       pm_runtime_put_autosuspend(d40c->base->dev);
+               }
 
                d40_desc_remove(d40d);
                d40_desc_done(d40c, d40d);
index b623c59..8bd1bb6 100644 (file)
@@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
        struct efivar_entry *entry;
        int err;
 
-       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-       if (!entry)
-               return;
-
        /* Add new sysfs entries */
        while (1) {
-               memset(entry, 0, sizeof(*entry));
+               entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+               if (!entry)
+                       return;
 
                err = efivar_init(efivar_update_sysfs_entry, entry,
                                  true, false, &efivar_sysfs_list);
index a6a8643..8bcce78 100644 (file)
@@ -1054,7 +1054,7 @@ EXPORT_SYMBOL(drm_vblank_off);
  */
 void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
 {
-       /* vblank is not initialized (IRQ not installed ?) */
+       /* vblank is not initialized (IRQ not installed ?), or has been freed */
        if (!dev->num_crtcs)
                return;
        /*
@@ -1076,6 +1076,10 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
 {
        unsigned long irqflags;
 
+       /* vblank is not initialized (IRQ not installed ?), or has been freed */
+       if (!dev->num_crtcs)
+               return;
+
        if (dev->vblank_inmodeset[crtc]) {
                spin_lock_irqsave(&dev->vbl_lock, irqflags);
                dev->vblank_disable_allowed = 1;
index e8894bc..c200e4d 100644 (file)
@@ -48,6 +48,8 @@ struct exynos_drm_crtc {
        unsigned int                    pipe;
        unsigned int                    dpms;
        enum exynos_crtc_mode           mode;
+       wait_queue_head_t               pending_flip_queue;
+       atomic_t                        pending_flip;
 };
 
 static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -61,6 +63,13 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
                return;
        }
 
+       if (mode > DRM_MODE_DPMS_ON) {
+               /* wait for the completion of page flip. */
+               wait_event(exynos_crtc->pending_flip_queue,
+                               atomic_read(&exynos_crtc->pending_flip) == 0);
+               drm_vblank_off(crtc->dev, exynos_crtc->pipe);
+       }
+
        exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
        exynos_crtc->dpms = mode;
 }
@@ -217,7 +226,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                ret = drm_vblank_get(dev, exynos_crtc->pipe);
                if (ret) {
                        DRM_DEBUG("failed to acquire vblank counter\n");
-                       list_del(&event->base.link);
 
                        goto out;
                }
@@ -225,6 +233,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                spin_lock_irq(&dev->event_lock);
                list_add_tail(&event->base.link,
                                &dev_priv->pageflip_event_list);
+               atomic_set(&exynos_crtc->pending_flip, 1);
                spin_unlock_irq(&dev->event_lock);
 
                crtc->fb = fb;
@@ -344,6 +353,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
 
        exynos_crtc->pipe = nr;
        exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
+       init_waitqueue_head(&exynos_crtc->pending_flip_queue);
+       atomic_set(&exynos_crtc->pending_flip, 0);
        exynos_crtc->plane = exynos_plane_init(dev, 1 << nr, true);
        if (!exynos_crtc->plane) {
                kfree(exynos_crtc);
@@ -398,7 +409,8 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = dev->dev_private;
        struct drm_pending_vblank_event *e, *t;
-       struct timeval now;
+       struct drm_crtc *drm_crtc = dev_priv->crtc[crtc];
+       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(drm_crtc);
        unsigned long flags;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -411,14 +423,11 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
                if (crtc != e->pipe)
                        continue;
 
-               do_gettimeofday(&now);
-               e->event.sequence = 0;
-               e->event.tv_sec = now.tv_sec;
-               e->event.tv_usec = now.tv_usec;
-
-               list_move_tail(&e->base.link, &e->base.file_priv->event_list);
-               wake_up_interruptible(&e->base.file_priv->event_wait);
+               list_del(&e->base.link);
+               drm_send_vblank_event(dev, -1, e);
                drm_vblank_put(dev, crtc);
+               atomic_set(&exynos_crtc->pending_flip, 0);
+               wake_up(&exynos_crtc->pending_flip_queue);
        }
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
index 68f0045..8f007aa 100644 (file)
@@ -182,7 +182,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 
        helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd,
                        &exynos_gem_obj->base);
-       if (IS_ERR_OR_NULL(helper->fb)) {
+       if (IS_ERR(helper->fb)) {
                DRM_ERROR("failed to create drm framebuffer.\n");
                ret = PTR_ERR(helper->fb);
                goto err_destroy_gem;
index 773f583..4a1616a 100644 (file)
@@ -12,9 +12,9 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
@@ -1845,7 +1845,7 @@ static int fimc_probe(struct platform_device *pdev)
        }
 
        ctx->irq = res->start;
-       ret = request_threaded_irq(ctx->irq, NULL, fimc_irq_handler,
+       ret = devm_request_threaded_irq(dev, ctx->irq, NULL, fimc_irq_handler,
                IRQF_ONESHOT, "drm_fimc", ctx);
        if (ret < 0) {
                dev_err(dev, "failed to request irq.\n");
@@ -1854,7 +1854,7 @@ static int fimc_probe(struct platform_device *pdev)
 
        ret = fimc_setup_clocks(ctx);
        if (ret < 0)
-               goto err_free_irq;
+               return ret;
 
        ippdrv = &ctx->ippdrv;
        ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &fimc_src_ops;
@@ -1884,7 +1884,7 @@ static int fimc_probe(struct platform_device *pdev)
                goto err_pm_dis;
        }
 
-       dev_info(&pdev->dev, "drm fimc registered successfully.\n");
+       dev_info(dev, "drm fimc registered successfully.\n");
 
        return 0;
 
@@ -1892,8 +1892,6 @@ err_pm_dis:
        pm_runtime_disable(dev);
 err_put_clk:
        fimc_put_clocks(ctx);
-err_free_irq:
-       free_irq(ctx->irq, ctx);
 
        return ret;
 }
@@ -1911,8 +1909,6 @@ static int fimc_remove(struct platform_device *pdev)
        pm_runtime_set_suspended(dev);
        pm_runtime_disable(dev);
 
-       free_irq(ctx->irq, ctx);
-
        return 0;
 }
 
index 746b282..97c61db 100644 (file)
@@ -885,7 +885,7 @@ static int fimd_probe(struct platform_device *pdev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (pdev->dev.of_node) {
+       if (dev->of_node) {
                pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
                if (!pdata) {
                        DRM_ERROR("memory allocation for pdata failed\n");
@@ -899,7 +899,7 @@ static int fimd_probe(struct platform_device *pdev)
                        return ret;
                }
        } else {
-               pdata = pdev->dev.platform_data;
+               pdata = dev->platform_data;
                if (!pdata) {
                        DRM_ERROR("no platform data specified\n");
                        return -EINVAL;
@@ -912,7 +912,7 @@ static int fimd_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
 
@@ -930,7 +930,7 @@ static int fimd_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       ctx->regs = devm_ioremap_resource(&pdev->dev, res);
+       ctx->regs = devm_ioremap_resource(dev, res);
        if (IS_ERR(ctx->regs))
                return PTR_ERR(ctx->regs);
 
@@ -942,7 +942,7 @@ static int fimd_probe(struct platform_device *pdev)
 
        ctx->irq = res->start;
 
-       ret = devm_request_irq(&pdev->dev, ctx->irq, fimd_irq_handler,
+       ret = devm_request_irq(dev, ctx->irq, fimd_irq_handler,
                                                        0, "drm_fimd", ctx);
        if (ret) {
                dev_err(dev, "irq request failed.\n");
index 47a493c..af75434 100644 (file)
@@ -1379,7 +1379,7 @@ static int g2d_probe(struct platform_device *pdev)
        struct exynos_drm_subdrv *subdrv;
        int ret;
 
-       g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL);
+       g2d = devm_kzalloc(dev, sizeof(*g2d), GFP_KERNEL);
        if (!g2d) {
                dev_err(dev, "failed to allocate driver data\n");
                return -ENOMEM;
@@ -1417,7 +1417,7 @@ static int g2d_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-       g2d->regs = devm_ioremap_resource(&pdev->dev, res);
+       g2d->regs = devm_ioremap_resource(dev, res);
        if (IS_ERR(g2d->regs)) {
                ret = PTR_ERR(g2d->regs);
                goto err_put_clk;
@@ -1430,7 +1430,7 @@ static int g2d_probe(struct platform_device *pdev)
                goto err_put_clk;
        }
 
-       ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0,
+       ret = devm_request_irq(dev, g2d->irq, g2d_irq_handler, 0,
                                                                "drm_g2d", g2d);
        if (ret < 0) {
                dev_err(dev, "irq request failed\n");
index 7841c3b..762f40d 100644 (file)
@@ -1704,7 +1704,7 @@ static int gsc_probe(struct platform_device *pdev)
        }
 
        ctx->irq = res->start;
-       ret = request_threaded_irq(ctx->irq, NULL, gsc_irq_handler,
+       ret = devm_request_threaded_irq(dev, ctx->irq, NULL, gsc_irq_handler,
                IRQF_ONESHOT, "drm_gsc", ctx);
        if (ret < 0) {
                dev_err(dev, "failed to request irq.\n");
@@ -1725,7 +1725,7 @@ static int gsc_probe(struct platform_device *pdev)
        ret = gsc_init_prop_list(ippdrv);
        if (ret < 0) {
                dev_err(dev, "failed to init property list.\n");
-               goto err_get_irq;
+               return ret;
        }
 
        DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
@@ -1743,15 +1743,12 @@ static int gsc_probe(struct platform_device *pdev)
                goto err_ippdrv_register;
        }
 
-       dev_info(&pdev->dev, "drm gsc registered successfully.\n");
+       dev_info(dev, "drm gsc registered successfully.\n");
 
        return 0;
 
 err_ippdrv_register:
-       devm_kfree(dev, ippdrv->prop_list);
        pm_runtime_disable(dev);
-err_get_irq:
-       free_irq(ctx->irq, ctx);
        return ret;
 }
 
@@ -1761,15 +1758,12 @@ static int gsc_remove(struct platform_device *pdev)
        struct gsc_context *ctx = get_gsc_context(dev);
        struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 
-       devm_kfree(dev, ippdrv->prop_list);
        exynos_drm_ippdrv_unregister(ippdrv);
        mutex_destroy(&ctx->lock);
 
        pm_runtime_set_suspended(dev);
        pm_runtime_disable(dev);
 
-       free_irq(ctx->irq, ctx);
-
        return 0;
 }
 
index ba2f0f1..437fb94 100644 (file)
@@ -442,7 +442,7 @@ static int exynos_drm_hdmi_probe(struct platform_device *pdev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx) {
                DRM_LOG_KMS("failed to alloc common hdmi context.\n");
                return -ENOMEM;
index 29d2ad3..be1e884 100644 (file)
@@ -222,7 +222,7 @@ static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
                /* find ipp driver using idr */
                ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock,
                        ipp_id);
-               if (IS_ERR_OR_NULL(ippdrv)) {
+               if (IS_ERR(ippdrv)) {
                        DRM_ERROR("not found ipp%d driver.\n", ipp_id);
                        return ippdrv;
                }
@@ -388,7 +388,7 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property)
        DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, prop_id);
 
        ippdrv = ipp_find_drv_by_handle(prop_id);
-       if (IS_ERR_OR_NULL(ippdrv)) {
+       if (IS_ERR(ippdrv)) {
                DRM_ERROR("failed to get ipp driver.\n");
                return -EINVAL;
        }
@@ -492,7 +492,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
 
        /* find ipp driver using ipp id */
        ippdrv = ipp_find_driver(ctx, property);
-       if (IS_ERR_OR_NULL(ippdrv)) {
+       if (IS_ERR(ippdrv)) {
                DRM_ERROR("failed to get ipp driver.\n");
                return -EINVAL;
        }
@@ -521,19 +521,19 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
        c_node->state = IPP_STATE_IDLE;
 
        c_node->start_work = ipp_create_cmd_work();
-       if (IS_ERR_OR_NULL(c_node->start_work)) {
+       if (IS_ERR(c_node->start_work)) {
                DRM_ERROR("failed to create start work.\n");
                goto err_clear;
        }
 
        c_node->stop_work = ipp_create_cmd_work();
-       if (IS_ERR_OR_NULL(c_node->stop_work)) {
+       if (IS_ERR(c_node->stop_work)) {
                DRM_ERROR("failed to create stop work.\n");
                goto err_free_start;
        }
 
        c_node->event_work = ipp_create_event_work();
-       if (IS_ERR_OR_NULL(c_node->event_work)) {
+       if (IS_ERR(c_node->event_work)) {
                DRM_ERROR("failed to create event work.\n");
                goto err_free_stop;
        }
@@ -915,7 +915,7 @@ static int ipp_queue_buf_with_run(struct device *dev,
        DRM_DEBUG_KMS("%s\n", __func__);
 
        ippdrv = ipp_find_drv_by_handle(qbuf->prop_id);
-       if (IS_ERR_OR_NULL(ippdrv)) {
+       if (IS_ERR(ippdrv)) {
                DRM_ERROR("failed to get ipp driver.\n");
                return -EFAULT;
        }
@@ -1909,7 +1909,7 @@ static int ipp_probe(struct platform_device *pdev)
        struct exynos_drm_subdrv *subdrv;
        int ret;
 
-       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
 
@@ -1963,7 +1963,7 @@ static int ipp_probe(struct platform_device *pdev)
                goto err_cmd_workq;
        }
 
-       dev_info(&pdev->dev, "drm ipp registered successfully.\n");
+       dev_info(dev, "drm ipp registered successfully.\n");
 
        return 0;
 
index 947f09f..9b6c709 100644 (file)
@@ -666,8 +666,8 @@ static int rotator_probe(struct platform_device *pdev)
                return rot->irq;
        }
 
-       ret = request_threaded_irq(rot->irq, NULL, rotator_irq_handler,
-                       IRQF_ONESHOT, "drm_rotator", rot);
+       ret = devm_request_threaded_irq(dev, rot->irq, NULL,
+                       rotator_irq_handler, IRQF_ONESHOT, "drm_rotator", rot);
        if (ret < 0) {
                dev_err(dev, "failed to request irq\n");
                return ret;
@@ -676,8 +676,7 @@ static int rotator_probe(struct platform_device *pdev)
        rot->clock = devm_clk_get(dev, "rotator");
        if (IS_ERR(rot->clock)) {
                dev_err(dev, "failed to get clock\n");
-               ret = PTR_ERR(rot->clock);
-               goto err_clk_get;
+               return PTR_ERR(rot->clock);
        }
 
        pm_runtime_enable(dev);
@@ -709,10 +708,7 @@ static int rotator_probe(struct platform_device *pdev)
        return 0;
 
 err_ippdrv_register:
-       devm_kfree(dev, ippdrv->prop_list);
        pm_runtime_disable(dev);
-err_clk_get:
-       free_irq(rot->irq, rot);
        return ret;
 }
 
@@ -722,13 +718,10 @@ static int rotator_remove(struct platform_device *pdev)
        struct rot_context *rot = dev_get_drvdata(dev);
        struct exynos_drm_ippdrv *ippdrv = &rot->ippdrv;
 
-       devm_kfree(dev, ippdrv->prop_list);
        exynos_drm_ippdrv_unregister(ippdrv);
 
        pm_runtime_disable(dev);
 
-       free_irq(rot->irq, rot);
-
        return 0;
 }
 
index 9504b0c..24376c1 100644 (file)
@@ -594,7 +594,7 @@ static int vidi_probe(struct platform_device *pdev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
 
@@ -612,7 +612,7 @@ static int vidi_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, ctx);
 
-       ret = device_create_file(&pdev->dev, &dev_attr_connection);
+       ret = device_create_file(dev, &dev_attr_connection);
        if (ret < 0)
                DRM_INFO("failed to create connection sysfs.\n");
 
index 6652597..fd1426d 100644 (file)
@@ -1946,14 +1946,14 @@ static int hdmi_probe(struct platform_device *pdev)
 
        DRM_DEBUG_KMS("[%d]\n", __LINE__);
 
-       if (pdev->dev.of_node) {
+       if (dev->of_node) {
                pdata = drm_hdmi_dt_parse_pdata(dev);
                if (IS_ERR(pdata)) {
                        DRM_ERROR("failed to parse dt\n");
                        return PTR_ERR(pdata);
                }
        } else {
-               pdata = pdev->dev.platform_data;
+               pdata = dev->platform_data;
        }
 
        if (!pdata) {
@@ -1961,14 +1961,14 @@ static int hdmi_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
+       drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
                                                                GFP_KERNEL);
        if (!drm_hdmi_ctx) {
                DRM_ERROR("failed to allocate common hdmi context.\n");
                return -ENOMEM;
        }
 
-       hdata = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_context),
+       hdata = devm_kzalloc(dev, sizeof(struct hdmi_context),
                                                                GFP_KERNEL);
        if (!hdata) {
                DRM_ERROR("out of memory\n");
@@ -1985,7 +1985,7 @@ static int hdmi_probe(struct platform_device *pdev)
        if (dev->of_node) {
                const struct of_device_id *match;
                match = of_match_node(of_match_ptr(hdmi_match_types),
-                                       pdev->dev.of_node);
+                                       dev->of_node);
                if (match == NULL)
                        return -ENODEV;
                hdata->type = (enum hdmi_type)match->data;
@@ -2005,11 +2005,11 @@ static int hdmi_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hdata->regs = devm_ioremap_resource(&pdev->dev, res);
+       hdata->regs = devm_ioremap_resource(dev, res);
        if (IS_ERR(hdata->regs))
                return PTR_ERR(hdata->regs);
 
-       ret = devm_gpio_request(&pdev->dev, hdata->hpd_gpio, "HPD");
+       ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
        if (ret) {
                DRM_ERROR("failed to request HPD gpio\n");
                return ret;
@@ -2041,7 +2041,7 @@ static int hdmi_probe(struct platform_device *pdev)
 
        hdata->hpd = gpio_get_value(hdata->hpd_gpio);
 
-       ret = request_threaded_irq(hdata->irq, NULL,
+       ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
                        hdmi_irq_thread, IRQF_TRIGGER_RISING |
                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                        "hdmi", drm_hdmi_ctx);
@@ -2070,16 +2070,11 @@ err_ddc:
 static int hdmi_remove(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
-       struct hdmi_context *hdata = ctx->ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
        pm_runtime_disable(dev);
 
-       free_irq(hdata->irq, hdata);
-
-
        /* hdmiphy i2c driver */
        i2c_del_driver(&hdmiphy_driver);
        /* DDC i2c driver */
index ec3e376..7c197d3 100644 (file)
@@ -1061,7 +1061,7 @@ static int mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                return -ENXIO;
        }
 
-       mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
+       mixer_res->mixer_regs = devm_ioremap(dev, res->start,
                                                        resource_size(res));
        if (mixer_res->mixer_regs == NULL) {
                dev_err(dev, "register mapping failed.\n");
@@ -1074,7 +1074,7 @@ static int mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                return -ENXIO;
        }
 
-       ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
+       ret = devm_request_irq(dev, res->start, mixer_irq_handler,
                                                        0, "drm_mixer", ctx);
        if (ret) {
                dev_err(dev, "request interrupt failed.\n");
@@ -1118,7 +1118,7 @@ static int vp_resources_init(struct exynos_drm_hdmi_context *ctx,
                return -ENXIO;
        }
 
-       mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
+       mixer_res->vp_regs = devm_ioremap(dev, res->start,
                                                        resource_size(res));
        if (mixer_res->vp_regs == NULL) {
                dev_err(dev, "register mapping failed.\n");
@@ -1169,14 +1169,14 @@ static int mixer_probe(struct platform_device *pdev)
 
        dev_info(dev, "probe start\n");
 
-       drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
+       drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
                                                                GFP_KERNEL);
        if (!drm_hdmi_ctx) {
                DRM_ERROR("failed to allocate common hdmi context.\n");
                return -ENOMEM;
        }
 
-       ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
        if (!ctx) {
                DRM_ERROR("failed to alloc mixer context.\n");
                return -ENOMEM;
@@ -1187,14 +1187,14 @@ static int mixer_probe(struct platform_device *pdev)
        if (dev->of_node) {
                const struct of_device_id *match;
                match = of_match_node(of_match_ptr(mixer_match_types),
-                                                         pdev->dev.of_node);
+                                                         dev->of_node);
                drv = (struct mixer_drv_data *)match->data;
        } else {
                drv = (struct mixer_drv_data *)
                        platform_get_device_id(pdev)->driver_data;
        }
 
-       ctx->dev = &pdev->dev;
+       ctx->dev = dev;
        ctx->parent_ctx = (void *)drm_hdmi_ctx;
        drm_hdmi_ctx->ctx = (void *)ctx;
        ctx->vp_enabled = drv->is_vp_enabled;
index 3cfd093..82430ad 100644 (file)
@@ -1462,7 +1462,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
        size_t addr = 0;
        struct gtt_range *gt;
        struct drm_gem_object *obj;
-       int ret;
+       int ret = 0;
 
        /* if we want to turn of the cursor ignore width and height */
        if (!handle) {
@@ -1499,7 +1499,8 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
        if (obj->size < width * height * 4) {
                dev_dbg(dev->dev, "buffer is to small\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto unref_cursor;
        }
 
        gt = container_of(obj, struct gtt_range, gem);
@@ -1508,7 +1509,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
        ret = psb_gtt_pin(gt);
        if (ret) {
                dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-               return ret;
+               goto unref_cursor;
        }
 
        addr = gt->offset;      /* Or resource.start ??? */
@@ -1532,9 +1533,14 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
                                                        struct gtt_range, gem);
                psb_gtt_unpin(gt);
                drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = obj;
        }
-       return 0;
+
+       psb_intel_crtc->cursor_obj = obj;
+       return ret;
+
+unref_cursor:
+       drm_gem_object_unreference(obj);
+       return ret;
 }
 
 static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
@@ -1750,6 +1756,19 @@ static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
        kfree(psb_intel_crtc);
 }
 
+static void cdv_intel_crtc_disable(struct drm_crtc *crtc)
+{
+       struct gtt_range *gt;
+       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+       if (crtc->fb) {
+               gt = to_psb_fb(crtc->fb)->gtt;
+               psb_gtt_unpin(gt);
+       }
+}
+
 const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
        .dpms = cdv_intel_crtc_dpms,
        .mode_fixup = cdv_intel_crtc_mode_fixup,
@@ -1757,6 +1776,7 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
        .mode_set_base = cdv_intel_pipe_set_base,
        .prepare = cdv_intel_crtc_prepare,
        .commit = cdv_intel_crtc_commit,
+       .disable = cdv_intel_crtc_disable,
 };
 
 const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
index 1534e22..8b1b6d9 100644 (file)
@@ -121,8 +121,8 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        unsigned long address;
        int ret;
        unsigned long pfn;
-       /* FIXME: assumes fb at stolen base which may not be true */
-       unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
+       unsigned long phys_addr = (unsigned long)dev_priv->stolen_base +
+                                 psbfb->gtt->offset;
 
        page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT);
index 6e8f42b..6666493 100644 (file)
@@ -843,7 +843,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
        struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt;
        struct drm_gem_object *obj;
        void *tmp_dst, *tmp_src;
-       int ret, i, cursor_pages;
+       int ret = 0, i, cursor_pages;
 
        /* if we want to turn of the cursor ignore width and height */
        if (!handle) {
@@ -880,7 +880,8 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
        if (obj->size < width * height * 4) {
                dev_dbg(dev->dev, "buffer is to small\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto unref_cursor;
        }
 
        gt = container_of(obj, struct gtt_range, gem);
@@ -889,13 +890,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
        ret = psb_gtt_pin(gt);
        if (ret) {
                dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-               return ret;
+               goto unref_cursor;
        }
 
        if (dev_priv->ops->cursor_needs_phys) {
                if (cursor_gt == NULL) {
                        dev_err(dev->dev, "No hardware cursor mem available");
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto unref_cursor;
                }
 
                /* Prevent overflow */
@@ -936,9 +938,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
                                                        struct gtt_range, gem);
                psb_gtt_unpin(gt);
                drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-               psb_intel_crtc->cursor_obj = obj;
        }
-       return 0;
+
+       psb_intel_crtc->cursor_obj = obj;
+       return ret;
+
+unref_cursor:
+       drm_gem_object_unreference(obj);
+       return ret;
 }
 
 static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
@@ -1150,6 +1157,19 @@ static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
        kfree(psb_intel_crtc);
 }
 
+static void psb_intel_crtc_disable(struct drm_crtc *crtc)
+{
+       struct gtt_range *gt;
+       struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+       crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+
+       if (crtc->fb) {
+               gt = to_psb_fb(crtc->fb)->gtt;
+               psb_gtt_unpin(gt);
+       }
+}
+
 const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
        .dpms = psb_intel_crtc_dpms,
        .mode_fixup = psb_intel_crtc_mode_fixup,
@@ -1157,6 +1177,7 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
        .mode_set_base = psb_intel_pipe_set_base,
        .prepare = psb_intel_crtc_prepare,
        .commit = psb_intel_crtc_commit,
+       .disable = psb_intel_crtc_disable,
 };
 
 const struct drm_crtc_funcs psb_intel_crtc_funcs = {
index 9ebe895..a2e4953 100644 (file)
@@ -364,40 +364,64 @@ static const struct pci_device_id pciidlist[] = {         /* aka */
        INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */
        INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */
        INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */
-       INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */
+       INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT3 desktop */
        INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */
        INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */
-       INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */
+       INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT3 server */
        INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */
        INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */
        INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */
+       INTEL_VGA_DEVICE(0x040B, &intel_haswell_d_info), /* GT1 reserved */
+       INTEL_VGA_DEVICE(0x041B, &intel_haswell_d_info), /* GT2 reserved */
+       INTEL_VGA_DEVICE(0x042B, &intel_haswell_d_info), /* GT3 reserved */
+       INTEL_VGA_DEVICE(0x040E, &intel_haswell_d_info), /* GT1 reserved */
+       INTEL_VGA_DEVICE(0x041E, &intel_haswell_d_info), /* GT2 reserved */
+       INTEL_VGA_DEVICE(0x042E, &intel_haswell_d_info), /* GT3 reserved */
        INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */
        INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */
-       INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */
+       INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT3 desktop */
        INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */
        INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */
-       INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */
+       INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT3 server */
        INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */
        INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */
-       INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */
+       INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT3 mobile */
+       INTEL_VGA_DEVICE(0x0C0B, &intel_haswell_d_info), /* SDV GT1 reserved */
+       INTEL_VGA_DEVICE(0x0C1B, &intel_haswell_d_info), /* SDV GT2 reserved */
+       INTEL_VGA_DEVICE(0x0C2B, &intel_haswell_d_info), /* SDV GT3 reserved */
+       INTEL_VGA_DEVICE(0x0C0E, &intel_haswell_d_info), /* SDV GT1 reserved */
+       INTEL_VGA_DEVICE(0x0C1E, &intel_haswell_d_info), /* SDV GT2 reserved */
+       INTEL_VGA_DEVICE(0x0C2E, &intel_haswell_d_info), /* SDV GT3 reserved */
        INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */
        INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */
-       INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */
+       INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT3 desktop */
        INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */
        INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */
-       INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */
+       INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT3 server */
        INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
        INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
-       INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
+       INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT3 mobile */
+       INTEL_VGA_DEVICE(0x0A0B, &intel_haswell_d_info), /* ULT GT1 reserved */
+       INTEL_VGA_DEVICE(0x0A1B, &intel_haswell_d_info), /* ULT GT2 reserved */
+       INTEL_VGA_DEVICE(0x0A2B, &intel_haswell_d_info), /* ULT GT3 reserved */
+       INTEL_VGA_DEVICE(0x0A0E, &intel_haswell_m_info), /* ULT GT1 reserved */
+       INTEL_VGA_DEVICE(0x0A1E, &intel_haswell_m_info), /* ULT GT2 reserved */
+       INTEL_VGA_DEVICE(0x0A2E, &intel_haswell_m_info), /* ULT GT3 reserved */
        INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
        INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
-       INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
+       INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT3 desktop */
        INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
        INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
-       INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
+       INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT3 server */
        INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
        INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
-       INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
+       INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT3 mobile */
+       INTEL_VGA_DEVICE(0x0D0B, &intel_haswell_d_info), /* CRW GT1 reserved */
+       INTEL_VGA_DEVICE(0x0D1B, &intel_haswell_d_info), /* CRW GT2 reserved */
+       INTEL_VGA_DEVICE(0x0D2B, &intel_haswell_d_info), /* CRW GT3 reserved */
+       INTEL_VGA_DEVICE(0x0D0E, &intel_haswell_d_info), /* CRW GT1 reserved */
+       INTEL_VGA_DEVICE(0x0D1E, &intel_haswell_d_info), /* CRW GT2 reserved */
+       INTEL_VGA_DEVICE(0x0D2E, &intel_haswell_d_info), /* CRW GT3 reserved */
        INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0f31, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0f32, &intel_valleyview_m_info),
index d5dcf7f..b9d00dc 100644 (file)
@@ -1943,4 +1943,19 @@ static inline void __user *to_user_ptr(u64 address)
        return (void __user *)(uintptr_t)address;
 }
 
+static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
+{
+       unsigned long j = msecs_to_jiffies(m);
+
+       return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
+}
+
+static inline unsigned long
+timespec_to_jiffies_timeout(const struct timespec *value)
+{
+       unsigned long j = timespec_to_jiffies(value);
+
+       return min_t(unsigned long, MAX_JIFFY_OFFSET, j + 1);
+}
+
 #endif
index 6165535..970ad17 100644 (file)
@@ -91,14 +91,11 @@ i915_gem_wait_for_error(struct i915_gpu_error *error)
 {
        int ret;
 
-#define EXIT_COND (!i915_reset_in_progress(error))
+#define EXIT_COND (!i915_reset_in_progress(error) || \
+                  i915_terminally_wedged(error))
        if (EXIT_COND)
                return 0;
 
-       /* GPU is already declared terminally dead, give up. */
-       if (i915_terminally_wedged(error))
-               return -EIO;
-
        /*
         * Only wait 10 seconds for the gpu reset to complete to avoid hanging
         * userspace. If it takes that long something really bad is going on and
@@ -1003,7 +1000,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
                wait_forever = false;
        }
 
-       timeout_jiffies = timespec_to_jiffies(&wait_time);
+       timeout_jiffies = timespec_to_jiffies_timeout(&wait_time);
 
        if (WARN_ON(!ring->irq_get(ring)))
                return -ENODEV;
index efe8299..56746dc 100644 (file)
@@ -7937,6 +7937,11 @@ intel_modeset_check_state(struct drm_device *dev)
                memset(&pipe_config, 0, sizeof(pipe_config));
                active = dev_priv->display.get_pipe_config(crtc,
                                                           &pipe_config);
+
+               /* hw state is inconsistent with the pipe A quirk */
+               if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
+                       active = crtc->active;
+
                WARN(crtc->active != active,
                     "crtc active state doesn't match with hw state "
                     "(expected %i, found %i)\n", crtc->active, active);
@@ -8140,6 +8145,21 @@ static void intel_set_config_restore_state(struct drm_device *dev,
        }
 }
 
+static bool
+is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors,
+                     int num_connectors)
+{
+       int i;
+
+       for (i = 0; i < num_connectors; i++)
+               if (connectors[i].encoder &&
+                   connectors[i].encoder->crtc == crtc &&
+                   connectors[i].dpms != DRM_MODE_DPMS_ON)
+                       return true;
+
+       return false;
+}
+
 static void
 intel_set_config_compute_mode_changes(struct drm_mode_set *set,
                                      struct intel_set_config *config)
@@ -8147,7 +8167,11 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
 
        /* We should be able to check here if the fb has the same properties
         * and then just flip_or_move it */
-       if (set->crtc->fb != set->fb) {
+       if (set->connectors != NULL &&
+           is_crtc_connector_off(set->crtc, *set->connectors,
+                                 set->num_connectors)) {
+                       config->mode_changed = true;
+       } else if (set->crtc->fb != set->fb) {
                /* If we have no fb then treat it as a full mode set */
                if (set->crtc->fb == NULL) {
                        DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
@@ -8157,8 +8181,9 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
                } else if (set->fb->pixel_format !=
                           set->crtc->fb->pixel_format) {
                        config->mode_changed = true;
-               } else
+               } else {
                        config->fb_changed = true;
+               }
        }
 
        if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y))
@@ -8332,11 +8357,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 
                ret = intel_set_mode(set->crtc, set->mode,
                                     set->x, set->y, set->fb);
-               if (ret) {
-                       DRM_ERROR("failed to set mode on [CRTC:%d], err = %d\n",
-                                 set->crtc->base.id, ret);
-                       goto fail;
-               }
        } else if (config->fb_changed) {
                intel_crtc_wait_for_pending_flips(set->crtc);
 
@@ -8344,18 +8364,18 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
                                          set->x, set->y, set->fb);
        }
 
-       intel_set_config_free(config);
-
-       return 0;
-
+       if (ret) {
+               DRM_ERROR("failed to set mode on [CRTC:%d], err = %d\n",
+                         set->crtc->base.id, ret);
 fail:
-       intel_set_config_restore_state(dev, config);
+               intel_set_config_restore_state(dev, config);
 
-       /* Try to restore the config */
-       if (config->mode_changed &&
-           intel_set_mode(save_set.crtc, save_set.mode,
-                          save_set.x, save_set.y, save_set.fb))
-               DRM_ERROR("failed to restore config after modeset failure\n");
+               /* Try to restore the config */
+               if (config->mode_changed &&
+                   intel_set_mode(save_set.crtc, save_set.mode,
+                                  save_set.x, save_set.y, save_set.fb))
+                       DRM_ERROR("failed to restore config after modeset failure\n");
+       }
 
 out_config:
        intel_set_config_free(config);
index 3d704b7..70789b1 100644 (file)
@@ -303,7 +303,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
 #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
        if (has_aux_irq)
                done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
-                                         msecs_to_jiffies(10));
+                                         msecs_to_jiffies_timeout(10));
        else
                done = wait_for_atomic(C, 10) == 0;
        if (!done)
index 5d24503..639fe19 100644 (file)
@@ -228,7 +228,7 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
         * need to wake up periodically and check that ourselves. */
        I915_WRITE(GMBUS4 + reg_offset, gmbus4_irq_en);
 
-       for (i = 0; i < msecs_to_jiffies(50) + 1; i++) {
+       for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
                prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
                                TASK_UNINTERRUPTIBLE);
 
@@ -263,7 +263,8 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
        /* Important: The hw handles only the first bit, so set only one! */
        I915_WRITE(GMBUS4 + reg_offset, GMBUS_IDLE_EN);
 
-       ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10);
+       ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
+                                msecs_to_jiffies_timeout(10));
 
        I915_WRITE(GMBUS4 + reg_offset, 0);
 
index f36f1ba..29412cc 100644 (file)
@@ -815,10 +815,10 @@ static const struct dmi_system_id intel_no_lvds[] = {
        },
        {
                .callback = intel_no_lvds_dmi_callback,
-               .ident = "Hewlett-Packard HP t5740e Thin Client",
+               .ident = "Hewlett-Packard HP t5740",
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
                },
        },
        {
index d154284..d4ea6c2 100644 (file)
@@ -1776,11 +1776,14 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
         * Assume that the preferred modes are
         * arranged in priority order.
         */
-       intel_ddc_get_modes(connector, intel_sdvo->i2c);
-       if (list_empty(&connector->probed_modes) == false)
-               goto end;
+       intel_ddc_get_modes(connector, &intel_sdvo->ddc);
 
-       /* Fetch modes from VBT */
+       /*
+        * Fetch modes from VBT. For SDVO prefer the VBT mode since some
+        * SDVO->LVDS transcoders can't cope with the EDID mode. Since
+        * drm_mode_probed_add adds the mode at the head of the list we add it
+        * last.
+        */
        if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
                newmode = drm_mode_duplicate(connector->dev,
                                             dev_priv->sdvo_lvds_vbt_mode);
@@ -1792,7 +1795,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
                }
        }
 
-end:
        list_for_each_entry(newmode, &connector->probed_modes, head) {
                if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
                        intel_sdvo->sdvo_lvds_fixed_mode =
@@ -2790,12 +2792,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
                        SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
        }
 
-       /* Only enable the hotplug irq if we need it, to work around noisy
-        * hotplug lines.
-        */
-       if (intel_sdvo->hotplug_active)
-               intel_encoder->hpd_pin = HPD_SDVO_B ? HPD_SDVO_B : HPD_SDVO_C;
-
        intel_encoder->compute_config = intel_sdvo_compute_config;
        intel_encoder->disable = intel_disable_sdvo;
        intel_encoder->mode_set = intel_sdvo_mode_set;
@@ -2814,6 +2810,14 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
                goto err_output;
        }
 
+       /* Only enable the hotplug irq if we need it, to work around noisy
+        * hotplug lines.
+        */
+       if (intel_sdvo->hotplug_active) {
+               intel_encoder->hpd_pin =
+                       intel_sdvo->is_sdvob ?  HPD_SDVO_B : HPD_SDVO_C;
+       }
+
        /*
         * Cloning SDVO with anything is often impossible, since the SDVO
         * encoder can request a special input timing mode. And even if that's
index 77b8a45..ee66bad 100644 (file)
@@ -1034,13 +1034,14 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
                        else
                                hi_pri_lvl = 5;
 
-                       WREG8(0x1fde, 0x06);
-                       WREG8(0x1fdf, hi_pri_lvl);
+                       WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
+                       WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
                } else {
+                       WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
                        if (mdev->reg_1e24 >= 0x01)
-                               WREG8(0x1fdf, 0x03);
+                               WREG8(MGAREG_CRTCEXT_DATA, 0x03);
                        else
-                               WREG8(0x1fdf, 0x04);
+                               WREG8(MGAREG_CRTCEXT_DATA, 0x04);
                }
        }
        return 0;
index d0817d9..f02fd9f 100644 (file)
@@ -50,11 +50,16 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
 {
        const u32 doff = (or * 0x800);
        int load = -EINVAL;
+       nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000);
+       nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
        nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval);
-       udelay(9500);
+       mdelay(9);
+       udelay(500);
        nv_wr32(priv, 0x61a00c + doff, 0x80000000);
        load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27;
        nv_wr32(priv, 0x61a00c + doff, 0x00000000);
+       nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000);
+       nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
        return load;
 }
 
index 0d36bdc..7fdade6 100644 (file)
@@ -55,6 +55,10 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
        nv_wr32(priv, 0x616510 + hoff, 0x00000000);
        nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000001);
 
+       nv_mask(priv, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
+       nv_mask(priv, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
+       nv_mask(priv, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
+
        /* ??? */
        nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
        nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
index 89bf459..e9b8217 100644 (file)
  * FIFO channel objects
  ******************************************************************************/
 
-void
-nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
+static void
+nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv)
 {
        struct nouveau_bar *bar = nouveau_bar(priv);
        struct nouveau_gpuobj *cur;
        int i, p;
 
-       mutex_lock(&nv_subdev(priv)->mutex);
        cur = priv->playlist[priv->cur_playlist];
        priv->cur_playlist = !priv->cur_playlist;
 
@@ -61,6 +60,13 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
        nv_wr32(priv, 0x0032f4, cur->addr >> 12);
        nv_wr32(priv, 0x0032ec, p);
        nv_wr32(priv, 0x002500, 0x00000101);
+}
+
+void
+nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
+{
+       mutex_lock(&nv_subdev(priv)->mutex);
+       nv50_fifo_playlist_update_locked(priv);
        mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
@@ -489,7 +495,7 @@ nv50_fifo_init(struct nouveau_object *object)
 
        for (i = 0; i < 128; i++)
                nv_wr32(priv, 0x002600 + (i * 4), 0x00000000);
-       nv50_fifo_playlist_update(priv);
+       nv50_fifo_playlist_update_locked(priv);
 
        nv_wr32(priv, 0x003200, 0x00000001);
        nv_wr32(priv, 0x003250, 0x00000001);
index 0a393f7..5a5961b 100644 (file)
@@ -218,7 +218,7 @@ struct nv04_display_class {
 #define NV50_DISP_DAC_PWR_STATE                                      0x00000040
 #define NV50_DISP_DAC_PWR_STATE_ON                                   0x00000000
 #define NV50_DISP_DAC_PWR_STATE_OFF                                  0x00000040
-#define NV50_DISP_DAC_LOAD                                           0x0002000c
+#define NV50_DISP_DAC_LOAD                                           0x00020100
 #define NV50_DISP_DAC_LOAD_VALUE                                     0x00000007
 
 #define NV50_DISP_PIOR_MTHD                                          0x00030000
index 7bf22d4..f17dc2a 100644 (file)
@@ -638,17 +638,8 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
        }
 
        s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
-       if (s->event) {
-               struct drm_pending_vblank_event *e = s->event;
-               struct timeval now;
-
-               do_gettimeofday(&now);
-               e->event.sequence = 0;
-               e->event.tv_sec = now.tv_sec;
-               e->event.tv_usec = now.tv_usec;
-               list_add_tail(&e->base.link, &e->base.file_priv->event_list);
-               wake_up_interruptible(&e->base.file_priv->event_wait);
-       }
+       if (s->event)
+               drm_send_vblank_event(dev, -1, s->event);
 
        list_del(&s->head);
        if (ps)
index ebf0a68..dd5e01f 100644 (file)
@@ -1554,7 +1554,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
        struct nv50_disp *disp = nv50_disp(encoder->dev);
        int ret, or = nouveau_encoder(encoder)->or;
-       u32 load = 0;
+       u32 load = nouveau_drm(encoder->dev)->vbios.dactestval;
+       if (load == 0)
+               load = 340;
 
        ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load));
        if (ret || load != 7)
index 9c53c25..826586f 100644 (file)
@@ -649,6 +649,9 @@ static void pdev_shutdown(struct platform_device *device)
 
 static int pdev_probe(struct platform_device *device)
 {
+       if (omapdss_is_initialized() == false)
+               return -EPROBE_DEFER;
+
        DBG("%s", device->name);
        return drm_platform_init(&omap_drm_driver, device);
 }
index 2f1a57e..d6c1279 100644 (file)
@@ -4,6 +4,7 @@ config DRM_QXL
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
+       select FB_DEFERRED_IO
         select DRM_KMS_HELPER
         select DRM_TTM
        help
index 6db7370..a4b71b2 100644 (file)
@@ -151,7 +151,7 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
                struct qxl_bo *cmd_bo;
                int release_type;
                struct drm_qxl_command *commands =
-                       (struct drm_qxl_command *)execbuffer->commands;
+                       (struct drm_qxl_command *)(uintptr_t)execbuffer->commands;
 
                if (DRM_COPY_FROM_USER(&user_cmd, &commands[cmd_num],
                                       sizeof(user_cmd)))
@@ -193,7 +193,7 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
 
                for (i = 0 ; i < user_cmd.relocs_num; ++i) {
                        if (DRM_COPY_FROM_USER(&reloc,
-                                              &((struct drm_qxl_reloc *)user_cmd.relocs)[i],
+                                              &((struct drm_qxl_reloc *)(uintptr_t)user_cmd.relocs)[i],
                                               sizeof(reloc))) {
                                qxl_bo_list_unreserve(&reloc_list, true);
                                qxl_release_unreserve(qdev, release);
index 85127ed..e27ce2a 100644 (file)
@@ -128,12 +128,13 @@ int qxl_device_init(struct qxl_device *qdev,
 
        qdev->vram_mapping = io_mapping_create_wc(qdev->vram_base, pci_resource_len(pdev, 0));
        qdev->surface_mapping = io_mapping_create_wc(qdev->surfaceram_base, qdev->surfaceram_size);
-       DRM_DEBUG_KMS("qxl: vram %p-%p(%dM %dk), surface %p-%p(%dM %dk)\n",
-                (void *)qdev->vram_base, (void *)pci_resource_end(pdev, 0),
+       DRM_DEBUG_KMS("qxl: vram %llx-%llx(%dM %dk), surface %llx-%llx(%dM %dk)\n",
+                (unsigned long long)qdev->vram_base,
+                (unsigned long long)pci_resource_end(pdev, 0),
                 (int)pci_resource_len(pdev, 0) / 1024 / 1024,
                 (int)pci_resource_len(pdev, 0) / 1024,
-                (void *)qdev->surfaceram_base,
-                (void *)pci_resource_end(pdev, 1),
+                (unsigned long long)qdev->surfaceram_base,
+                (unsigned long long)pci_resource_end(pdev, 1),
                 (int)qdev->surfaceram_size / 1024 / 1024,
                 (int)qdev->surfaceram_size / 1024);
 
index 44a7da6..8406c82 100644 (file)
@@ -667,6 +667,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
 int
 atombios_get_encoder_mode(struct drm_encoder *encoder)
 {
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct drm_connector *connector;
        struct radeon_connector *radeon_connector;
@@ -693,7 +695,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
                if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
-                   radeon_audio)
+                   radeon_audio &&
+                   !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
                        return ATOM_ENCODER_MODE_HDMI;
                else if (radeon_connector->use_digital)
                        return ATOM_ENCODER_MODE_DVI;
@@ -704,7 +707,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        case DRM_MODE_CONNECTOR_HDMIA:
        default:
                if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
-                   radeon_audio)
+                   radeon_audio &&
+                   !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
                        return ATOM_ENCODER_MODE_HDMI;
                else
                        return ATOM_ENCODER_MODE_DVI;
@@ -718,7 +722,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
                    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
                        return ATOM_ENCODER_MODE_DP;
                else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
-                        radeon_audio)
+                        radeon_audio &&
+                        !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
                        return ATOM_ENCODER_MODE_HDMI;
                else
                        return ATOM_ENCODER_MODE_DVI;
index 8f9e2d3..0f89ce3 100644 (file)
@@ -4754,6 +4754,12 @@ static int evergreen_startup(struct radeon_device *rdev)
                rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -4923,10 +4929,6 @@ int evergreen_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
@@ -4999,8 +5001,7 @@ void evergreen_fini(struct radeon_device *rdev)
 
 void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
 {
-       u32 link_width_cntl, speed_cntl, mask;
-       int ret;
+       u32 link_width_cntl, speed_cntl;
 
        if (radeon_pcie_gen2 == 0)
                return;
@@ -5015,11 +5016,8 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
        if (ASIC_IS_X2(rdev))
                return;
 
-       ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
-       if (ret != 0)
-               return;
-
-       if (!(mask & DRM_PCIE_SPEED_50))
+       if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
+               (rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
                return;
 
        speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
index 7969c0c..8458330 100644 (file)
@@ -2025,6 +2025,12 @@ static int cayman_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -2190,10 +2196,6 @@ int cayman_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 1024 * 1024);
 
index 4973bff..d0314ec 100644 (file)
@@ -3869,6 +3869,12 @@ static int r100_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -4024,9 +4030,6 @@ int r100_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index c60350e..b9b776f 100644 (file)
@@ -1382,6 +1382,12 @@ static int r300_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -1516,9 +1522,6 @@ int r300_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index 6fce2eb..4e796ec 100644 (file)
@@ -265,6 +265,12 @@ static int r420_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -411,10 +417,6 @@ int r420_init(struct radeon_device *rdev)
        if (r) {
                return r;
        }
-       r = radeon_irq_kms_init(rdev);
-       if (r) {
-               return r;
-       }
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r) {
index f795a4e..e1aece7 100644 (file)
@@ -194,6 +194,12 @@ static int r520_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -297,9 +303,6 @@ int r520_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index 1a08008..0e53416 100644 (file)
@@ -1046,6 +1046,24 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
        return -1;
 }
 
+uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg)
+{
+       uint32_t r;
+
+       WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg));
+       r = RREG32(R_0028FC_MC_DATA);
+       WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR);
+       return r;
+}
+
+void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+{
+       WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) |
+               S_0028F8_MC_IND_WR_EN(1));
+       WREG32(R_0028FC_MC_DATA, v);
+       WREG32(R_0028F8_MC_INDEX, 0x7F);
+}
+
 static void r600_mc_program(struct radeon_device *rdev)
 {
        struct rv515_mc_save save;
@@ -1181,6 +1199,8 @@ static int r600_mc_init(struct radeon_device *rdev)
 {
        u32 tmp;
        int chansize, numchan;
+       uint32_t h_addr, l_addr;
+       unsigned long long k8_addr;
 
        /* Get VRAM informations */
        rdev->mc.vram_is_ddr = true;
@@ -1221,7 +1241,30 @@ static int r600_mc_init(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_IGP) {
                rs690_pm_info(rdev);
                rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
+
+               if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
+                       /* Use K8 direct mapping for fast fb access. */
+                       rdev->fastfb_working = false;
+                       h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL));
+                       l_addr = RREG32_MC(R_000011_K8_FB_LOCATION);
+                       k8_addr = ((unsigned long long)h_addr) << 32 | l_addr;
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
+                       if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL)
+#endif
+                       {
+                               /* FastFB shall be used with UMA memory. Here it is simply disabled when sideport
+                               * memory is present.
+                               */
+                               if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) {
+                                       DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n",
+                                               (unsigned long long)rdev->mc.aper_base, k8_addr);
+                                       rdev->mc.aper_base = (resource_size_t)k8_addr;
+                                       rdev->fastfb_working = true;
+                               }
+                       }
+               }
        }
+
        radeon_update_bandwidth_info(rdev);
        return 0;
 }
@@ -3202,6 +3245,12 @@ static int r600_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -3356,10 +3405,6 @@ int r600_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
@@ -4631,8 +4676,6 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
 {
        u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp;
        u16 link_cntl2;
-       u32 mask;
-       int ret;
 
        if (radeon_pcie_gen2 == 0)
                return;
@@ -4651,11 +4694,8 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
        if (rdev->family <= CHIP_R600)
                return;
 
-       ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
-       if (ret != 0)
-               return;
-
-       if (!(mask & DRM_PCIE_SPEED_50))
+       if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
+               (rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
                return;
 
        speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
index acb146c..79df558 100644 (file)
 #define        PACKET3_STRMOUT_BASE_UPDATE                     0x72 /* r7xx */
 #define        PACKET3_SURFACE_BASE_UPDATE                     0x73
 
+#define R_000011_K8_FB_LOCATION                 0x11
+#define R_000012_MC_MISC_UMA_CNTL               0x12
+#define   G_000012_K8_ADDR_EXT(x)               (((x) >> 0) & 0xFF)
+#define R_0028F8_MC_INDEX                      0x28F8
+#define        S_0028F8_MC_IND_ADDR(x)                 (((x) & 0x1FF) << 0)
+#define        C_0028F8_MC_IND_ADDR                    0xFFFFFE00
+#define        S_0028F8_MC_IND_WR_EN(x)                (((x) & 0x1) << 9)
+#define R_0028FC_MC_DATA                        0x28FC
 
 #define        R_008020_GRBM_SOFT_RESET                0x8020
 #define                S_008020_SOFT_RESET_CP(x)               (((x) & 1) << 0)
index 06b8c19..a2802b4 100644 (file)
@@ -122,6 +122,10 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
                rdev->mc_rreg = &rs600_mc_rreg;
                rdev->mc_wreg = &rs600_mc_wreg;
        }
+       if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
+               rdev->mc_rreg = &rs780_mc_rreg;
+               rdev->mc_wreg = &rs780_mc_wreg;
+       }
        if (rdev->family >= CHIP_R600) {
                rdev->pciep_rreg = &r600_pciep_rreg;
                rdev->pciep_wreg = &r600_pciep_wreg;
index 2c87365..a72759e 100644 (file)
@@ -347,6 +347,8 @@ extern bool r600_gui_idle(struct radeon_device *rdev);
 extern void r600_pm_misc(struct radeon_device *rdev);
 extern void r600_pm_init_profile(struct radeon_device *rdev);
 extern void rs780_pm_init_profile(struct radeon_device *rdev);
+extern uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg);
+extern void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
 extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
 extern int r600_get_pcie_lanes(struct radeon_device *rdev);
index c2c59fb..1899738 100644 (file)
@@ -467,23 +467,27 @@ bool radeon_card_posted(struct radeon_device *rdev)
 {
        uint32_t reg;
 
+       /* required for EFI mode on macbook2,1 which uses an r5xx asic */
        if (efi_enabled(EFI_BOOT) &&
-           rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE)
+           (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+           (rdev->family < CHIP_R600))
                return false;
 
+       if (ASIC_IS_NODCE(rdev))
+               goto check_memsize;
+
        /* first check CRTCs */
-       if (ASIC_IS_DCE41(rdev)) {
+       if (ASIC_IS_DCE4(rdev)) {
                reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
                        RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
-               if (reg & EVERGREEN_CRTC_MASTER_EN)
-                       return true;
-       } else if (ASIC_IS_DCE4(rdev)) {
-               reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
-                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
-                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
-                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) |
-                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
-                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+                       if (rdev->num_crtc >= 4) {
+                               reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
+                                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+                       }
+                       if (rdev->num_crtc >= 6) {
+                               reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) |
+                                       RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+                       }
                if (reg & EVERGREEN_CRTC_MASTER_EN)
                        return true;
        } else if (ASIC_IS_AVIVO(rdev)) {
@@ -500,6 +504,7 @@ bool radeon_card_posted(struct radeon_device *rdev)
                }
        }
 
+check_memsize:
        /* then check MEM_SIZE, in case the crtcs are off */
        if (rdev->family >= CHIP_R600)
                reg = RREG32(R600_CONFIG_MEMSIZE);
index e38fd55..eb18bb7 100644 (file)
@@ -271,8 +271,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        struct radeon_unpin_work *work;
-       struct drm_pending_vblank_event *e;
-       struct timeval now;
        unsigned long flags;
        u32 update_pending;
        int vpos, hpos;
@@ -328,14 +326,9 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
        radeon_crtc->unpin_work = NULL;
 
        /* wakeup userspace */
-       if (work->event) {
-               e = work->event;
-               e->event.sequence = drm_vblank_count_and_time(rdev->ddev, crtc_id, &now);
-               e->event.tv_sec = now.tv_sec;
-               e->event.tv_usec = now.tv_usec;
-               list_add_tail(&e->base.link, &e->base.file_priv->event_list);
-               wake_up_interruptible(&e->base.file_priv->event_wait);
-       }
+       if (work->event)
+               drm_send_vblank_event(rdev->ddev, crtc_id, work->event);
+
        spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
 
        drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
index 73051ce..233a9b9 100644 (file)
@@ -417,6 +417,12 @@ static int rs400_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r100_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -535,9 +541,6 @@ int rs400_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index 46fa1b0..670b555 100644 (file)
@@ -923,6 +923,12 @@ static int rs600_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -1047,9 +1053,6 @@ int rs600_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index ab4c86c..55880d5 100644 (file)
@@ -651,6 +651,12 @@ static int rs690_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -776,9 +782,6 @@ int rs690_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index ffcba73..21c7d7b 100644 (file)
@@ -532,6 +532,12 @@ static int rv515_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        rs600_irq_set(rdev);
        rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
        /* 1M ring buffer */
@@ -662,9 +668,6 @@ int rv515_init(struct radeon_device *rdev)
        r = radeon_fence_driver_init(rdev);
        if (r)
                return r;
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
        /* Memory manager */
        r = radeon_bo_init(rdev);
        if (r)
index 83f612a..4a62ad2 100644 (file)
@@ -862,10 +862,8 @@ int rv770_uvd_resume(struct radeon_device *rdev)
                chip_id = 0x0100000b;
                break;
        case CHIP_SUMO:
-               chip_id = 0x0100000c;
-               break;
        case CHIP_SUMO2:
-               chip_id = 0x0100000d;
+               chip_id = 0x0100000c;
                break;
        case CHIP_PALM:
                chip_id = 0x0100000e;
@@ -1889,6 +1887,12 @@ static int rv770_startup(struct radeon_device *rdev)
                rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = r600_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -2047,10 +2051,6 @@ int rv770_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
        r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
@@ -2113,8 +2113,6 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
 {
        u32 link_width_cntl, lanes, speed_cntl, tmp;
        u16 link_cntl2;
-       u32 mask;
-       int ret;
 
        if (radeon_pcie_gen2 == 0)
                return;
@@ -2129,11 +2127,8 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
        if (ASIC_IS_X2(rdev))
                return;
 
-       ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
-       if (ret != 0)
-               return;
-
-       if (!(mask & DRM_PCIE_SPEED_50))
+       if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
+               (rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
                return;
 
        DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
index 5ffade6..a1b0da6 100644 (file)
@@ -2616,7 +2616,7 @@ static void si_gpu_init(struct radeon_device *rdev)
        default:
                rdev->config.si.max_shader_engines = 1;
                rdev->config.si.max_tile_pipes = 4;
-               rdev->config.si.max_cu_per_sh = 2;
+               rdev->config.si.max_cu_per_sh = 5;
                rdev->config.si.max_sh_per_se = 2;
                rdev->config.si.max_backends_per_se = 4;
                rdev->config.si.max_texture_channel_caches = 4;
@@ -5350,6 +5350,12 @@ static int si_startup(struct radeon_device *rdev)
        }
 
        /* Enable IRQ */
+       if (!rdev->irq.installed) {
+               r = radeon_irq_kms_init(rdev);
+               if (r)
+                       return r;
+       }
+
        r = si_irq_init(rdev);
        if (r) {
                DRM_ERROR("radeon: IH init failed (%d).\n", r);
@@ -5533,10 +5539,6 @@ int si_init(struct radeon_device *rdev)
        if (r)
                return r;
 
-       r = radeon_irq_kms_init(rdev);
-       if (r)
-               return r;
-
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        ring->ring_obj = NULL;
        r600_ring_init(rdev, ring, 1024 * 1024);
index 7dff49e..99e2034 100644 (file)
@@ -451,27 +451,16 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
 {
        struct drm_pending_vblank_event *event;
        struct drm_device *dev = scrtc->crtc.dev;
-       struct timeval vblanktime;
        unsigned long flags;
 
        spin_lock_irqsave(&dev->event_lock, flags);
        event = scrtc->event;
        scrtc->event = NULL;
+       if (event) {
+               drm_send_vblank_event(dev, 0, event);
+               drm_vblank_put(dev, 0);
+       }
        spin_unlock_irqrestore(&dev->event_lock, flags);
-
-       if (event == NULL)
-               return;
-
-       event->event.sequence = drm_vblank_count_and_time(dev, 0, &vblanktime);
-       event->event.tv_sec = vblanktime.tv_sec;
-       event->event.tv_usec = vblanktime.tv_usec;
-
-       spin_lock_irqsave(&dev->event_lock, flags);
-       list_add_tail(&event->base.link, &event->base.file_priv->event_list);
-       wake_up_interruptible(&event->base.file_priv->event_wait);
-       spin_unlock_irqrestore(&dev->event_lock, flags);
-
-       drm_vblank_put(dev, 0);
 }
 
 static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
index e461e99..7a4d101 100644 (file)
@@ -6,6 +6,7 @@ config DRM_TILCDC
        select DRM_GEM_CMA_HELPER
        select VIDEOMODE_HELPERS
        select BACKLIGHT_CLASS_DEVICE
+       select BACKLIGHT_LCD_SUPPORT
        help
          Choose this option if you have an TI SoC with LCDC display
          controller, for example AM33xx in beagle-bone, DA8xx, or
index dc3ae5c..d39a5ce 100644 (file)
@@ -264,9 +264,12 @@ static struct mt_class mt_classes[] = {
 static void mt_free_input_name(struct hid_input *hi)
 {
        struct hid_device *hdev = hi->report->device;
+       const char *name = hi->input->name;
 
-       if (hi->input->name != hdev->name)
-               kfree(hi->input->name);
+       if (name != hdev->name) {
+               hi->input->name = hdev->name;
+               kfree(name);
+       }
 }
 
 static ssize_t mt_show_quirks(struct device *dev,
@@ -1040,11 +1043,11 @@ static void mt_remove(struct hid_device *hdev)
        struct hid_input *hi;
 
        sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
-       hid_hw_stop(hdev);
-
        list_for_each_entry(hi, &hdev->inputs, list)
                mt_free_input_name(hi);
 
+       hid_hw_stop(hdev);
+
        kfree(td);
        hid_set_drvdata(hdev, NULL);
 }
index 7e76922..f920619 100644 (file)
@@ -331,26 +331,68 @@ static int adm1021_detect(struct i2c_client *client,
        man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
        dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID);
 
+       if (man_id < 0 || dev_id < 0)
+               return -ENODEV;
+
        if (man_id == 0x4d && dev_id == 0x01)
                type_name = "max1617a";
        else if (man_id == 0x41) {
                if ((dev_id & 0xF0) == 0x30)
                        type_name = "adm1023";
-               else
+               else if ((dev_id & 0xF0) == 0x00)
                        type_name = "adm1021";
+               else
+                       return -ENODEV;
        } else if (man_id == 0x49)
                type_name = "thmc10";
        else if (man_id == 0x23)
                type_name = "gl523sm";
        else if (man_id == 0x54)
                type_name = "mc1066";
-       /* LM84 Mfr ID in a different place, and it has more unused bits */
-       else if (conv_rate == 0x00
-                && (config & 0x7F) == 0x00
-                && (status & 0xAB) == 0x00)
-               type_name = "lm84";
-       else
-               type_name = "max1617";
+       else {
+               int lte, rte, lhi, rhi, llo, rlo;
+
+               /* extra checks for LM84 and MAX1617 to avoid misdetections */
+
+               llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0));
+               rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1));
+
+               /* fail if any of the additional register reads failed */
+               if (llo < 0 || rlo < 0)
+                       return -ENODEV;
+
+               lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0));
+               rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1));
+               lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0));
+               rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1));
+
+               /*
+                * Fail for negative temperatures and negative high limits.
+                * This check also catches read errors on the tested registers.
+                */
+               if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0)
+                       return -ENODEV;
+
+               /* fail if all registers hold the same value */
+               if (lte == rte && lte == lhi && lte == rhi && lte == llo
+                   && lte == rlo)
+                       return -ENODEV;
+
+               /*
+                * LM84 Mfr ID is in a different place,
+                * and it has more unused bits.
+                */
+               if (conv_rate == 0x00
+                   && (config & 0x7F) == 0x00
+                   && (status & 0xAB) == 0x00) {
+                       type_name = "lm84";
+               } else {
+                       /* fail if low limits are larger than high limits */
+                       if ((s8)llo > lhi || (s8)rlo > rhi)
+                               return -ENODEV;
+                       type_name = "max1617";
+               }
+       }
 
        pr_debug("Detected chip %s at adapter %d, address 0x%02x.\n",
                 type_name, i2c_adapter_id(adapter), client->addr);
index 9201022..9d19ba7 100644 (file)
@@ -64,7 +64,7 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
        while (chan->indio_dev) {
                if (chan->indio_dev != indio_dev) {
                        ret = -EINVAL;
-                       goto error_release_channels;
+                       goto error_free_scan_mask;
                }
                set_bit(chan->channel->scan_index,
                        cb_buff->buffer.scan_mask);
@@ -73,6 +73,8 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
 
        return cb_buff;
 
+error_free_scan_mask:
+       kfree(cb_buff->buffer.scan_mask);
 error_release_channels:
        iio_channel_release_all(cb_buff->channels);
 error_free_cb_buff:
@@ -100,6 +102,7 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
 
 void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
 {
+       kfree(cb_buff->buffer.scan_mask);
        iio_channel_release_all(cb_buff->channels);
        kfree(cb_buff);
 }
index a884252..e76d4ac 100644 (file)
@@ -212,7 +212,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
                (pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS |
                ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N |
                ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) |
-               ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9)));
+               ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x3)));
 
        st->regs[ADF4350_REG3] = pdata->r3_user_settings &
                                 (ADF4350_REG3_12BIT_CLKDIV(0xFFF) |
index 795d100..98ddc32 100644 (file)
@@ -124,7 +124,7 @@ static int __of_iio_channel_get(struct iio_channel *channel,
        channel->indio_dev = indio_dev;
        index = iiospec.args_count ? iiospec.args[0] : 0;
        if (index >= indio_dev->num_channels) {
-               return -EINVAL;
+               err = -EINVAL;
                goto err_put;
        }
        channel->channel = &indio_dev->channels[index];
@@ -450,7 +450,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
        s64 raw64 = raw;
        int ret;
 
-       ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_SCALE);
+       ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
        if (ret == 0)
                raw64 += offset;
 
index 81c7b73..3b9afcc 100644 (file)
@@ -61,7 +61,7 @@ int qib_alloc_lkey(struct qib_mregion *mr, int dma_region)
        if (dma_region) {
                struct qib_mregion *tmr;
 
-               tmr = rcu_dereference(dev->dma_mr);
+               tmr = rcu_access_pointer(dev->dma_mr);
                if (!tmr) {
                        qib_get_mr(mr);
                        rcu_assign_pointer(dev->dma_mr, mr);
index f19b099..2e84ef8 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2004 Alex Aizman
  * Copyright (C) 2005 Mike Christie
  * Copyright (c) 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. All rights reserved.
  * maintained by openib-general@openib.org
  *
  * This software is available to you under a choice of one of two
index 06f578c..4f069c0 100644 (file)
@@ -8,6 +8,7 @@
  *
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. 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
index a00ccd1..b6d81a8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. 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
index 68ebb7f..7827baf 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. 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
index 5278916..2c4941d 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2013 Mellanox Technologies. 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
@@ -292,10 +293,10 @@ out_err:
 }
 
 /**
- * releases the FMR pool, QP and CMA ID objects, returns 0 on success,
+ * releases the FMR pool and QP objects, returns 0 on success,
  * -1 on failure
  */
-static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
+static int iser_free_ib_conn_res(struct iser_conn *ib_conn)
 {
        int cq_index;
        BUG_ON(ib_conn == NULL);
@@ -314,13 +315,9 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
 
                rdma_destroy_qp(ib_conn->cma_id);
        }
-       /* if cma handler context, the caller acts s.t the cma destroy the id */
-       if (ib_conn->cma_id != NULL && can_destroy_id)
-               rdma_destroy_id(ib_conn->cma_id);
 
        ib_conn->fmr_pool = NULL;
        ib_conn->qp       = NULL;
-       ib_conn->cma_id   = NULL;
        kfree(ib_conn->page_vec);
 
        if (ib_conn->login_buf) {
@@ -415,11 +412,16 @@ static void iser_conn_release(struct iser_conn *ib_conn, int can_destroy_id)
        list_del(&ib_conn->conn_list);
        mutex_unlock(&ig.connlist_mutex);
        iser_free_rx_descriptors(ib_conn);
-       iser_free_ib_conn_res(ib_conn, can_destroy_id);
+       iser_free_ib_conn_res(ib_conn);
        ib_conn->device = NULL;
        /* on EVENT_ADDR_ERROR there's no device yet for this conn */
        if (device != NULL)
                iser_device_try_release(device);
+       /* if cma handler context, the caller actually destroy the id */
+       if (ib_conn->cma_id != NULL && can_destroy_id) {
+               rdma_destroy_id(ib_conn->cma_id);
+               ib_conn->cma_id = NULL;
+       }
        iscsi_destroy_endpoint(ib_conn->ep);
 }
 
index b08ca7a..3f3f041 100644 (file)
@@ -2227,6 +2227,27 @@ static void srpt_close_ch(struct srpt_rdma_ch *ch)
 }
 
 /**
+ * srpt_shutdown_session() - Whether or not a session may be shut down.
+ */
+static int srpt_shutdown_session(struct se_session *se_sess)
+{
+       struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ch->spinlock, flags);
+       if (ch->in_shutdown) {
+               spin_unlock_irqrestore(&ch->spinlock, flags);
+               return true;
+       }
+
+       ch->in_shutdown = true;
+       target_sess_cmd_list_set_waiting(se_sess);
+       spin_unlock_irqrestore(&ch->spinlock, flags);
+
+       return true;
+}
+
+/**
  * srpt_drain_channel() - Drain a channel by resetting the IB queue pair.
  * @cm_id: Pointer to the CM ID of the channel to be drained.
  *
@@ -2264,6 +2285,9 @@ static void srpt_drain_channel(struct ib_cm_id *cm_id)
        spin_unlock_irq(&sdev->spinlock);
 
        if (do_reset) {
+               if (ch->sess)
+                       srpt_shutdown_session(ch->sess);
+
                ret = srpt_ch_qp_err(ch);
                if (ret < 0)
                        printk(KERN_ERR "Setting queue pair in error state"
@@ -2328,7 +2352,7 @@ static void srpt_release_channel_work(struct work_struct *w)
        se_sess = ch->sess;
        BUG_ON(!se_sess);
 
-       target_wait_for_sess_cmds(se_sess, 0);
+       target_wait_for_sess_cmds(se_sess);
 
        transport_deregister_session_configfs(se_sess);
        transport_deregister_session(se_sess);
@@ -3467,14 +3491,6 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
 }
 
 /**
- * srpt_shutdown_session() - Whether or not a session may be shut down.
- */
-static int srpt_shutdown_session(struct se_session *se_sess)
-{
-       return true;
-}
-
-/**
  * srpt_close_session() - Forcibly close a session.
  *
  * Callback function invoked by the TCM core to clean up sessions associated
index 4caf55c..3dae156 100644 (file)
@@ -325,6 +325,7 @@ struct srpt_rdma_ch {
        u8                      sess_name[36];
        struct work_struct      release_work;
        struct completion       *release_done;
+       bool                    in_shutdown;
 };
 
 /**
index 2f78538..b2420ae 100644 (file)
@@ -1379,6 +1379,7 @@ static int synaptics_reconnect(struct psmouse *psmouse)
 {
        struct synaptics_data *priv = psmouse->private;
        struct synaptics_data old_priv = *priv;
+       unsigned char param[2];
        int retry = 0;
        int error;
 
@@ -1394,6 +1395,7 @@ static int synaptics_reconnect(struct psmouse *psmouse)
                         */
                        ssleep(1);
                }
+               ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETID);
                error = synaptics_detect(psmouse, 0);
        } while (error && ++retry < 3);
 
index 5c68e44..518282d 100644 (file)
@@ -1966,7 +1966,8 @@ static const struct wacom_features wacom_features_0xF4 =
          63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0xF8 =
        { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, /* Pen */
-         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
+         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+         .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
 static const struct wacom_features wacom_features_0xF6 =
        { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
          .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
@@ -2009,7 +2010,8 @@ static const struct wacom_features wacom_features_0xFA =
          63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
 static const struct wacom_features wacom_features_0x5B =
        { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS,      95840, 54260, 2047,
-         63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
+         63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+         .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
 static const struct wacom_features wacom_features_0x5E =
        { "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
          .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10 };
@@ -2042,7 +2044,7 @@ static const struct wacom_features wacom_features_0xE5 =
 static const struct wacom_features wacom_features_0xE6 =
        { "Wacom ISDv4 E6",       WACOM_PKGLEN_TPC2FG,    27760, 15694,  255,
          0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
-       .touch_max = 2 };
+         .touch_max = 2 };
 static const struct wacom_features wacom_features_0xEC =
        { "Wacom ISDv4 EC",       WACOM_PKGLEN_GRAPHIRE,  25710, 14500,  255,
          0, TABLETPC,    WACOM_INTUOS_RES, WACOM_INTUOS_RES };
index 29889bb..63b3d4e 100644 (file)
@@ -76,16 +76,10 @@ asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
 {
        u32 irqnr;
 
-       do {
-               irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
-               if (irqnr != 0x7f) {
-                       __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
-                       irqnr = irq_find_mapping(icoll_domain, irqnr);
-                       handle_IRQ(irqnr, regs);
-                       continue;
-               }
-               break;
-       } while (1);
+       irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
+       __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
+       irqnr = irq_find_mapping(icoll_domain, irqnr);
+       handle_IRQ(irqnr, regs);
 }
 
 static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
index 065b7a3..47a52ab 100644 (file)
@@ -119,7 +119,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
 
        /* Skip invalid IRQs, only register handlers for the real ones */
        if (!(f->valid & BIT(hwirq)))
-               return -ENOTSUPP;
+               return -EPERM;
        irq_set_chip_data(irq, f);
        irq_set_chip_and_handler(irq, &f->chip,
                                handle_level_irq);
index 884d11c..2bbb004 100644 (file)
@@ -197,7 +197,7 @@ static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq,
 
        /* Skip invalid IRQs, only register handlers for the real ones */
        if (!(v->valid_sources & (1 << hwirq)))
-               return -ENOTSUPP;
+               return -EPERM;
        irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq);
        irq_set_chip_data(irq, v->base);
        set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
index 05c220d..f950c9d 100644 (file)
@@ -1,7 +1,6 @@
 
 config BCACHE
        tristate "Block device as cache"
-       select CLOSURES
        ---help---
        Allows a block device to be used as cache for other devices; uses
        a btree for indexing and the layout is optimized for SSDs.
index 340146d..d3e15b4 100644 (file)
@@ -1241,7 +1241,7 @@ void bch_cache_set_stop(struct cache_set *);
 struct cache_set *bch_cache_set_alloc(struct cache_sb *);
 void bch_btree_cache_free(struct cache_set *);
 int bch_btree_cache_alloc(struct cache_set *);
-void bch_writeback_init_cached_dev(struct cached_dev *);
+void bch_cached_dev_writeback_init(struct cached_dev *);
 void bch_moving_init_cache_set(struct cache_set *);
 
 void bch_cache_allocator_exit(struct cache *ca);
index 64e6794..b8730e7 100644 (file)
@@ -93,24 +93,6 @@ static struct attribute *bch_stats_files[] = {
 };
 static KTYPE(bch_stats);
 
-static void scale_accounting(unsigned long data);
-
-void bch_cache_accounting_init(struct cache_accounting *acc,
-                              struct closure *parent)
-{
-       kobject_init(&acc->total.kobj,          &bch_stats_ktype);
-       kobject_init(&acc->five_minute.kobj,    &bch_stats_ktype);
-       kobject_init(&acc->hour.kobj,           &bch_stats_ktype);
-       kobject_init(&acc->day.kobj,            &bch_stats_ktype);
-
-       closure_init(&acc->cl, parent);
-       init_timer(&acc->timer);
-       acc->timer.expires      = jiffies + accounting_delay;
-       acc->timer.data         = (unsigned long) acc;
-       acc->timer.function     = scale_accounting;
-       add_timer(&acc->timer);
-}
-
 int bch_cache_accounting_add_kobjs(struct cache_accounting *acc,
                                   struct kobject *parent)
 {
@@ -244,3 +226,19 @@ void bch_mark_sectors_bypassed(struct search *s, int sectors)
        atomic_add(sectors, &dc->accounting.collector.sectors_bypassed);
        atomic_add(sectors, &s->op.c->accounting.collector.sectors_bypassed);
 }
+
+void bch_cache_accounting_init(struct cache_accounting *acc,
+                              struct closure *parent)
+{
+       kobject_init(&acc->total.kobj,          &bch_stats_ktype);
+       kobject_init(&acc->five_minute.kobj,    &bch_stats_ktype);
+       kobject_init(&acc->hour.kobj,           &bch_stats_ktype);
+       kobject_init(&acc->day.kobj,            &bch_stats_ktype);
+
+       closure_init(&acc->cl, parent);
+       init_timer(&acc->timer);
+       acc->timer.expires      = jiffies + accounting_delay;
+       acc->timer.data         = (unsigned long) acc;
+       acc->timer.function     = scale_accounting;
+       add_timer(&acc->timer);
+}
index c8046bc..f88e2b6 100644 (file)
@@ -634,11 +634,10 @@ static int open_dev(struct block_device *b, fmode_t mode)
        return 0;
 }
 
-static int release_dev(struct gendisk *b, fmode_t mode)
+static void release_dev(struct gendisk *b, fmode_t mode)
 {
        struct bcache_device *d = b->private_data;
        closure_put(&d->cl);
-       return 0;
 }
 
 static int ioctl_dev(struct block_device *b, fmode_t mode,
@@ -732,8 +731,7 @@ static void bcache_device_free(struct bcache_device *d)
 
        if (d->c)
                bcache_device_detach(d);
-
-       if (d->disk)
+       if (d->disk && d->disk->flags & GENHD_FL_UP)
                del_gendisk(d->disk);
        if (d->disk && d->disk->queue)
                blk_cleanup_queue(d->disk->queue);
@@ -756,12 +754,9 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size)
        if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio))) ||
            !(d->unaligned_bvec = mempool_create_kmalloc_pool(1,
                                sizeof(struct bio_vec) * BIO_MAX_PAGES)) ||
-           bio_split_pool_init(&d->bio_split_hook))
-
-               return -ENOMEM;
-
-       d->disk = alloc_disk(1);
-       if (!d->disk)
+           bio_split_pool_init(&d->bio_split_hook) ||
+           !(d->disk = alloc_disk(1)) ||
+           !(q = blk_alloc_queue(GFP_KERNEL)))
                return -ENOMEM;
 
        snprintf(d->disk->disk_name, DISK_NAME_LEN, "bcache%i", bcache_minor);
@@ -771,10 +766,6 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size)
        d->disk->fops           = &bcache_ops;
        d->disk->private_data   = d;
 
-       q = blk_alloc_queue(GFP_KERNEL);
-       if (!q)
-               return -ENOMEM;
-
        blk_queue_make_request(q, NULL);
        d->disk->queue                  = q;
        q->queuedata                    = d;
@@ -999,14 +990,17 @@ static void cached_dev_free(struct closure *cl)
 
        mutex_lock(&bch_register_lock);
 
-       bd_unlink_disk_holder(dc->bdev, dc->disk.disk);
+       if (atomic_read(&dc->running))
+               bd_unlink_disk_holder(dc->bdev, dc->disk.disk);
        bcache_device_free(&dc->disk);
        list_del(&dc->list);
 
        mutex_unlock(&bch_register_lock);
 
        if (!IS_ERR_OR_NULL(dc->bdev)) {
-               blk_sync_queue(bdev_get_queue(dc->bdev));
+               if (dc->bdev->bd_disk)
+                       blk_sync_queue(bdev_get_queue(dc->bdev));
+
                blkdev_put(dc->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
        }
 
@@ -1028,73 +1022,67 @@ static void cached_dev_flush(struct closure *cl)
 
 static int cached_dev_init(struct cached_dev *dc, unsigned block_size)
 {
-       int err;
+       int ret;
        struct io *io;
-
-       closure_init(&dc->disk.cl, NULL);
-       set_closure_fn(&dc->disk.cl, cached_dev_flush, system_wq);
+       struct request_queue *q = bdev_get_queue(dc->bdev);
 
        __module_get(THIS_MODULE);
        INIT_LIST_HEAD(&dc->list);
+       closure_init(&dc->disk.cl, NULL);
+       set_closure_fn(&dc->disk.cl, cached_dev_flush, system_wq);
        kobject_init(&dc->disk.kobj, &bch_cached_dev_ktype);
-
-       bch_cache_accounting_init(&dc->accounting, &dc->disk.cl);
-
-       err = bcache_device_init(&dc->disk, block_size);
-       if (err)
-               goto err;
-
-       spin_lock_init(&dc->io_lock);
-       closure_init_unlocked(&dc->sb_write);
        INIT_WORK(&dc->detach, cached_dev_detach_finish);
+       closure_init_unlocked(&dc->sb_write);
+       INIT_LIST_HEAD(&dc->io_lru);
+       spin_lock_init(&dc->io_lock);
+       bch_cache_accounting_init(&dc->accounting, &dc->disk.cl);
 
        dc->sequential_merge            = true;
        dc->sequential_cutoff           = 4 << 20;
 
-       INIT_LIST_HEAD(&dc->io_lru);
-       dc->sb_bio.bi_max_vecs  = 1;
-       dc->sb_bio.bi_io_vec    = dc->sb_bio.bi_inline_vecs;
-
        for (io = dc->io; io < dc->io + RECENT_IO; io++) {
                list_add(&io->lru, &dc->io_lru);
                hlist_add_head(&io->hash, dc->io_hash + RECENT_IO);
        }
 
-       bch_writeback_init_cached_dev(dc);
+       ret = bcache_device_init(&dc->disk, block_size);
+       if (ret)
+               return ret;
+
+       set_capacity(dc->disk.disk,
+                    dc->bdev->bd_part->nr_sects - dc->sb.data_offset);
+
+       dc->disk.disk->queue->backing_dev_info.ra_pages =
+               max(dc->disk.disk->queue->backing_dev_info.ra_pages,
+                   q->backing_dev_info.ra_pages);
+
+       bch_cached_dev_request_init(dc);
+       bch_cached_dev_writeback_init(dc);
        return 0;
-err:
-       bcache_device_stop(&dc->disk);
-       return err;
 }
 
 /* Cached device - bcache superblock */
 
-static const char *register_bdev(struct cache_sb *sb, struct page *sb_page,
+static void register_bdev(struct cache_sb *sb, struct page *sb_page,
                                 struct block_device *bdev,
                                 struct cached_dev *dc)
 {
        char name[BDEVNAME_SIZE];
        const char *err = "cannot allocate memory";
-       struct gendisk *g;
        struct cache_set *c;
 
-       if (!dc || cached_dev_init(dc, sb->block_size << 9) != 0)
-               return err;
-
        memcpy(&dc->sb, sb, sizeof(struct cache_sb));
-       dc->sb_bio.bi_io_vec[0].bv_page = sb_page;
        dc->bdev = bdev;
        dc->bdev->bd_holder = dc;
 
-       g = dc->disk.disk;
-
-       set_capacity(g, dc->bdev->bd_part->nr_sects - dc->sb.data_offset);
-
-       g->queue->backing_dev_info.ra_pages =
-               max(g->queue->backing_dev_info.ra_pages,
-                   bdev->bd_queue->backing_dev_info.ra_pages);
+       bio_init(&dc->sb_bio);
+       dc->sb_bio.bi_max_vecs  = 1;
+       dc->sb_bio.bi_io_vec    = dc->sb_bio.bi_inline_vecs;
+       dc->sb_bio.bi_io_vec[0].bv_page = sb_page;
+       get_page(sb_page);
 
-       bch_cached_dev_request_init(dc);
+       if (cached_dev_init(dc, sb->block_size << 9))
+               goto err;
 
        err = "error creating kobject";
        if (kobject_add(&dc->disk.kobj, &part_to_dev(bdev->bd_part)->kobj,
@@ -1103,6 +1091,8 @@ static const char *register_bdev(struct cache_sb *sb, struct page *sb_page,
        if (bch_cache_accounting_add_kobjs(&dc->accounting, &dc->disk.kobj))
                goto err;
 
+       pr_info("registered backing device %s", bdevname(bdev, name));
+
        list_add(&dc->list, &uncached_devices);
        list_for_each_entry(c, &bch_cache_sets, list)
                bch_cached_dev_attach(dc, c);
@@ -1111,15 +1101,10 @@ static const char *register_bdev(struct cache_sb *sb, struct page *sb_page,
            BDEV_STATE(&dc->sb) == BDEV_STATE_STALE)
                bch_cached_dev_run(dc);
 
-       return NULL;
+       return;
 err:
-       kobject_put(&dc->disk.kobj);
        pr_notice("error opening %s: %s", bdevname(bdev, name), err);
-       /*
-        * Return NULL instead of an error because kobject_put() cleans
-        * everything up
-        */
-       return NULL;
+       bcache_device_stop(&dc->disk);
 }
 
 /* Flash only volumes */
@@ -1717,20 +1702,11 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca)
        size_t free;
        struct bucket *b;
 
-       if (!ca)
-               return -ENOMEM;
-
        __module_get(THIS_MODULE);
        kobject_init(&ca->kobj, &bch_cache_ktype);
 
-       memcpy(&ca->sb, sb, sizeof(struct cache_sb));
-
        INIT_LIST_HEAD(&ca->discards);
 
-       bio_init(&ca->sb_bio);
-       ca->sb_bio.bi_max_vecs  = 1;
-       ca->sb_bio.bi_io_vec    = ca->sb_bio.bi_inline_vecs;
-
        bio_init(&ca->journal.bio);
        ca->journal.bio.bi_max_vecs = 8;
        ca->journal.bio.bi_io_vec = ca->journal.bio.bi_inline_vecs;
@@ -1742,18 +1718,17 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca)
            !init_fifo(&ca->free_inc,   free << 2, GFP_KERNEL) ||
            !init_fifo(&ca->unused,     free << 2, GFP_KERNEL) ||
            !init_heap(&ca->heap,       free << 3, GFP_KERNEL) ||
-           !(ca->buckets       = vmalloc(sizeof(struct bucket) *
+           !(ca->buckets       = vzalloc(sizeof(struct bucket) *
                                          ca->sb.nbuckets)) ||
            !(ca->prio_buckets  = kzalloc(sizeof(uint64_t) * prio_buckets(ca) *
                                          2, GFP_KERNEL)) ||
            !(ca->disk_buckets  = alloc_bucket_pages(GFP_KERNEL, ca)) ||
            !(ca->alloc_workqueue = alloc_workqueue("bch_allocator", 0, 1)) ||
            bio_split_pool_init(&ca->bio_split_hook))
-               goto err;
+               return -ENOMEM;
 
        ca->prio_last_buckets = ca->prio_buckets + prio_buckets(ca);
 
-       memset(ca->buckets, 0, ca->sb.nbuckets * sizeof(struct bucket));
        for_each_bucket(b, ca)
                atomic_set(&b->pin, 0);
 
@@ -1766,22 +1741,28 @@ err:
        return -ENOMEM;
 }
 
-static const char *register_cache(struct cache_sb *sb, struct page *sb_page,
+static void register_cache(struct cache_sb *sb, struct page *sb_page,
                                  struct block_device *bdev, struct cache *ca)
 {
        char name[BDEVNAME_SIZE];
        const char *err = "cannot allocate memory";
 
-       if (cache_alloc(sb, ca) != 0)
-               return err;
-
-       ca->sb_bio.bi_io_vec[0].bv_page = sb_page;
+       memcpy(&ca->sb, sb, sizeof(struct cache_sb));
        ca->bdev = bdev;
        ca->bdev->bd_holder = ca;
 
+       bio_init(&ca->sb_bio);
+       ca->sb_bio.bi_max_vecs  = 1;
+       ca->sb_bio.bi_io_vec    = ca->sb_bio.bi_inline_vecs;
+       ca->sb_bio.bi_io_vec[0].bv_page = sb_page;
+       get_page(sb_page);
+
        if (blk_queue_discard(bdev_get_queue(ca->bdev)))
                ca->discard = CACHE_DISCARD(&ca->sb);
 
+       if (cache_alloc(sb, ca) != 0)
+               goto err;
+
        err = "error creating kobject";
        if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache"))
                goto err;
@@ -1791,15 +1772,10 @@ static const char *register_cache(struct cache_sb *sb, struct page *sb_page,
                goto err;
 
        pr_info("registered cache device %s", bdevname(bdev, name));
-
-       return NULL;
+       return;
 err:
+       pr_notice("error opening %s: %s", bdevname(bdev, name), err);
        kobject_put(&ca->kobj);
-       pr_info("error opening %s: %s", bdevname(bdev, name), err);
-       /* Return NULL instead of an error because kobject_put() cleans
-        * everything up
-        */
-       return NULL;
 }
 
 /* Global interfaces/init */
@@ -1833,12 +1809,15 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
        bdev = blkdev_get_by_path(strim(path),
                                  FMODE_READ|FMODE_WRITE|FMODE_EXCL,
                                  sb);
-       if (bdev == ERR_PTR(-EBUSY))
-               err = "device busy";
-
-       if (IS_ERR(bdev) ||
-           set_blocksize(bdev, 4096))
+       if (IS_ERR(bdev)) {
+               if (bdev == ERR_PTR(-EBUSY))
+                       err = "device busy";
                goto err;
+       }
+
+       err = "failed to set blocksize";
+       if (set_blocksize(bdev, 4096))
+               goto err_close;
 
        err = read_super(sb, bdev, &sb_page);
        if (err)
@@ -1846,33 +1825,33 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 
        if (SB_IS_BDEV(sb)) {
                struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
+               if (!dc)
+                       goto err_close;
 
-               err = register_bdev(sb, sb_page, bdev, dc);
+               register_bdev(sb, sb_page, bdev, dc);
        } else {
                struct cache *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
+               if (!ca)
+                       goto err_close;
 
-               err = register_cache(sb, sb_page, bdev, ca);
+               register_cache(sb, sb_page, bdev, ca);
        }
-
-       if (err) {
-               /* register_(bdev|cache) will only return an error if they
-                * didn't get far enough to create the kobject - if they did,
-                * the kobject destructor will do this cleanup.
-                */
+out:
+       if (sb_page)
                put_page(sb_page);
-err_close:
-               blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
-err:
-               if (attr != &ksysfs_register_quiet)
-                       pr_info("error opening %s: %s", path, err);
-               ret = -EINVAL;
-       }
-
        kfree(sb);
        kfree(path);
        mutex_unlock(&bch_register_lock);
        module_put(THIS_MODULE);
        return ret;
+
+err_close:
+       blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
+err:
+       if (attr != &ksysfs_register_quiet)
+               pr_info("error opening %s: %s", path, err);
+       ret = -EINVAL;
+       goto out;
 }
 
 static int bcache_reboot(struct notifier_block *n, unsigned long code, void *x)
index 93e7e31..2714ed3 100644 (file)
@@ -375,7 +375,7 @@ err:
        refill_dirty(cl);
 }
 
-void bch_writeback_init_cached_dev(struct cached_dev *dc)
+void bch_cached_dev_writeback_init(struct cached_dev *dc)
 {
        closure_init_unlocked(&dc->writeback);
        init_rwsem(&dc->writeback_lock);
index 681d109..9b82377 100644 (file)
@@ -5268,8 +5268,8 @@ static void md_clean(struct mddev *mddev)
 
 static void __md_stop_writes(struct mddev *mddev)
 {
+       set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
        if (mddev->sync_thread) {
-               set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
                set_bit(MD_RECOVERY_INTR, &mddev->recovery);
                md_reap_sync_thread(mddev);
        }
index 5595118..6e17f81 100644 (file)
@@ -417,7 +417,17 @@ static void raid1_end_write_request(struct bio *bio, int error)
 
                r1_bio->bios[mirror] = NULL;
                to_put = bio;
-               set_bit(R1BIO_Uptodate, &r1_bio->state);
+               /*
+                * Do not set R1BIO_Uptodate if the current device is
+                * rebuilding or Faulty. This is because we cannot use
+                * such device for properly reading the data back (we could
+                * potentially use it, if the current write would have felt
+                * before rdev->recovery_offset, but for simplicity we don't
+                * check this here.
+                */
+               if (test_bit(In_sync, &conf->mirrors[mirror].rdev->flags) &&
+                   !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags))
+                       set_bit(R1BIO_Uptodate, &r1_bio->state);
 
                /* Maybe we can clear some bad blocks. */
                if (is_badblock(conf->mirrors[mirror].rdev,
@@ -870,17 +880,17 @@ static void allow_barrier(struct r1conf *conf)
        wake_up(&conf->wait_barrier);
 }
 
-static void freeze_array(struct r1conf *conf)
+static void freeze_array(struct r1conf *conf, int extra)
 {
        /* stop syncio and normal IO and wait for everything to
         * go quite.
         * We increment barrier and nr_waiting, and then
-        * wait until nr_pending match nr_queued+1
+        * wait until nr_pending match nr_queued+extra
         * This is called in the context of one normal IO request
         * that has failed. Thus any sync request that might be pending
         * will be blocked by nr_pending, and we need to wait for
         * pending IO requests to complete or be queued for re-try.
-        * Thus the number queued (nr_queued) plus this request (1)
+        * Thus the number queued (nr_queued) plus this request (extra)
         * must match the number of pending IOs (nr_pending) before
         * we continue.
         */
@@ -888,7 +898,7 @@ static void freeze_array(struct r1conf *conf)
        conf->barrier++;
        conf->nr_waiting++;
        wait_event_lock_irq_cmd(conf->wait_barrier,
-                               conf->nr_pending == conf->nr_queued+1,
+                               conf->nr_pending == conf->nr_queued+extra,
                                conf->resync_lock,
                                flush_pending_writes(conf));
        spin_unlock_irq(&conf->resync_lock);
@@ -1544,8 +1554,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
                 * we wait for all outstanding requests to complete.
                 */
                synchronize_sched();
-               raise_barrier(conf);
-               lower_barrier(conf);
+               freeze_array(conf, 0);
+               unfreeze_array(conf);
                clear_bit(Unmerged, &rdev->flags);
        }
        md_integrity_add_rdev(rdev, mddev);
@@ -1595,11 +1605,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
                         */
                        struct md_rdev *repl =
                                conf->mirrors[conf->raid_disks + number].rdev;
-                       raise_barrier(conf);
+                       freeze_array(conf, 0);
                        clear_bit(Replacement, &repl->flags);
                        p->rdev = repl;
                        conf->mirrors[conf->raid_disks + number].rdev = NULL;
-                       lower_barrier(conf);
+                       unfreeze_array(conf);
                        clear_bit(WantReplacement, &rdev->flags);
                } else
                        clear_bit(WantReplacement, &rdev->flags);
@@ -2195,7 +2205,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio)
         * frozen
         */
        if (mddev->ro == 0) {
-               freeze_array(conf);
+               freeze_array(conf, 1);
                fix_read_error(conf, r1_bio->read_disk,
                               r1_bio->sector, r1_bio->sectors);
                unfreeze_array(conf);
@@ -2780,8 +2790,8 @@ static int run(struct mddev *mddev)
                return PTR_ERR(conf);
 
        if (mddev->queue)
-               blk_queue_max_write_same_sectors(mddev->queue,
-                                                mddev->chunk_sectors);
+               blk_queue_max_write_same_sectors(mddev->queue, 0);
+
        rdev_for_each(rdev, mddev) {
                if (!mddev->gendisk)
                        continue;
@@ -2963,7 +2973,7 @@ static int raid1_reshape(struct mddev *mddev)
                return -ENOMEM;
        }
 
-       raise_barrier(conf);
+       freeze_array(conf, 0);
 
        /* ok, everything is stopped */
        oldpool = conf->r1bio_pool;
@@ -2994,7 +3004,7 @@ static int raid1_reshape(struct mddev *mddev)
        conf->raid_disks = mddev->raid_disks = raid_disks;
        mddev->delta_disks = 0;
 
-       lower_barrier(conf);
+       unfreeze_array(conf);
 
        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        md_wakeup_thread(mddev->thread);
index 59d4daa..6ddae25 100644 (file)
@@ -490,7 +490,17 @@ static void raid10_end_write_request(struct bio *bio, int error)
                sector_t first_bad;
                int bad_sectors;
 
-               set_bit(R10BIO_Uptodate, &r10_bio->state);
+               /*
+                * Do not set R10BIO_Uptodate if the current device is
+                * rebuilding or Faulty. This is because we cannot use
+                * such device for properly reading the data back (we could
+                * potentially use it, if the current write would have felt
+                * before rdev->recovery_offset, but for simplicity we don't
+                * check this here.
+                */
+               if (test_bit(In_sync, &rdev->flags) &&
+                   !test_bit(Faulty, &rdev->flags))
+                       set_bit(R10BIO_Uptodate, &r10_bio->state);
 
                /* Maybe we can clear some bad blocks. */
                if (is_badblock(rdev,
@@ -1055,17 +1065,17 @@ static void allow_barrier(struct r10conf *conf)
        wake_up(&conf->wait_barrier);
 }
 
-static void freeze_array(struct r10conf *conf)
+static void freeze_array(struct r10conf *conf, int extra)
 {
        /* stop syncio and normal IO and wait for everything to
         * go quiet.
         * We increment barrier and nr_waiting, and then
-        * wait until nr_pending match nr_queued+1
+        * wait until nr_pending match nr_queued+extra
         * This is called in the context of one normal IO request
         * that has failed. Thus any sync request that might be pending
         * will be blocked by nr_pending, and we need to wait for
         * pending IO requests to complete or be queued for re-try.
-        * Thus the number queued (nr_queued) plus this request (1)
+        * Thus the number queued (nr_queued) plus this request (extra)
         * must match the number of pending IOs (nr_pending) before
         * we continue.
         */
@@ -1073,7 +1083,7 @@ static void freeze_array(struct r10conf *conf)
        conf->barrier++;
        conf->nr_waiting++;
        wait_event_lock_irq_cmd(conf->wait_barrier,
-                               conf->nr_pending == conf->nr_queued+1,
+                               conf->nr_pending == conf->nr_queued+extra,
                                conf->resync_lock,
                                flush_pending_writes(conf));
 
@@ -1837,8 +1847,8 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
                 * we wait for all outstanding requests to complete.
                 */
                synchronize_sched();
-               raise_barrier(conf, 0);
-               lower_barrier(conf);
+               freeze_array(conf, 0);
+               unfreeze_array(conf);
                clear_bit(Unmerged, &rdev->flags);
        }
        md_integrity_add_rdev(rdev, mddev);
@@ -2612,7 +2622,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
        r10_bio->devs[slot].bio = NULL;
 
        if (mddev->ro == 0) {
-               freeze_array(conf);
+               freeze_array(conf, 1);
                fix_read_error(conf, mddev, r10_bio);
                unfreeze_array(conf);
        } else
@@ -3609,8 +3619,7 @@ static int run(struct mddev *mddev)
        if (mddev->queue) {
                blk_queue_max_discard_sectors(mddev->queue,
                                              mddev->chunk_sectors);
-               blk_queue_max_write_same_sectors(mddev->queue,
-                                                mddev->chunk_sectors);
+               blk_queue_max_write_same_sectors(mddev->queue, 0);
                blk_queue_io_min(mddev->queue, chunk_size);
                if (conf->geo.raid_disks % conf->geo.near_copies)
                        blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks);
index 9359828..05e4a10 100644 (file)
@@ -664,6 +664,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                        if (test_bit(R5_ReadNoMerge, &sh->dev[i].flags))
                                bi->bi_rw |= REQ_FLUSH;
 
+                       bi->bi_vcnt = 1;
                        bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
                        bi->bi_io_vec[0].bv_offset = 0;
                        bi->bi_size = STRIPE_SIZE;
@@ -701,6 +702,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
                        else
                                rbi->bi_sector = (sh->sector
                                                  + rrdev->data_offset);
+                       rbi->bi_vcnt = 1;
                        rbi->bi_io_vec[0].bv_len = STRIPE_SIZE;
                        rbi->bi_io_vec[0].bv_offset = 0;
                        rbi->bi_size = STRIPE_SIZE;
@@ -5464,7 +5466,7 @@ static int run(struct mddev *mddev)
                if (mddev->major_version == 0 &&
                    mddev->minor_version > 90)
                        rdev->recovery_offset = reshape_offset;
-                       
+
                if (rdev->recovery_offset < reshape_offset) {
                        /* We need to check old and new layout */
                        if (!only_parity(rdev->raid_disk,
@@ -5587,6 +5589,8 @@ static int run(struct mddev *mddev)
                 */
                mddev->queue->limits.discard_zeroes_data = 0;
 
+               blk_queue_max_write_same_sectors(mddev->queue, 0);
+
                rdev_for_each(rdev, mddev) {
                        disk_stack_limits(mddev->gendisk, rdev->bdev,
                                          rdev->data_offset << 9);
index ca2754a..5e04008 100644 (file)
@@ -176,7 +176,7 @@ struct zoran_fh;
 
 struct zoran_mapping {
        struct zoran_fh *fh;
-       int count;
+       atomic_t count;
 };
 
 struct zoran_buffer {
index 1168a84..d133c30 100644 (file)
@@ -2803,8 +2803,7 @@ static void
 zoran_vm_open (struct vm_area_struct *vma)
 {
        struct zoran_mapping *map = vma->vm_private_data;
-
-       map->count++;
+       atomic_inc(&map->count);
 }
 
 static void
@@ -2815,7 +2814,7 @@ zoran_vm_close (struct vm_area_struct *vma)
        struct zoran *zr = fh->zr;
        int i;
 
-       if (--map->count > 0)
+       if (!atomic_dec_and_mutex_lock(&map->count, &zr->resource_lock))
                return;
 
        dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
@@ -2828,14 +2827,16 @@ zoran_vm_close (struct vm_area_struct *vma)
        kfree(map);
 
        /* Any buffers still mapped? */
-       for (i = 0; i < fh->buffers.num_buffers; i++)
-               if (fh->buffers.buffer[i].map)
+       for (i = 0; i < fh->buffers.num_buffers; i++) {
+               if (fh->buffers.buffer[i].map) {
+                       mutex_unlock(&zr->resource_lock);
                        return;
+               }
+       }
 
        dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
                __func__, mode_name(fh->map_mode));
 
-       mutex_lock(&zr->resource_lock);
 
        if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
                if (fh->buffers.active != ZORAN_FREE) {
@@ -2939,7 +2940,7 @@ zoran_mmap (struct file           *file,
                goto mmap_unlock_and_return;
        }
        map->fh = fh;
-       map->count = 1;
+       atomic_set(&map->count, 1);
 
        vma->vm_ops = &zoran_vm_ops;
        vma->vm_flags |= VM_DONTEXPAND;
index 477268a..d338b19 100644 (file)
@@ -2150,6 +2150,9 @@ static int __init omap_vout_probe(struct platform_device *pdev)
        struct omap_dss_device *def_display;
        struct omap2video_device *vid_dev = NULL;
 
+       if (omapdss_is_initialized() == false)
+               return -EPROBE_DEFER;
+
        ret = omapdss_compat_init();
        if (ret) {
                dev_err(&pdev->dev, "failed to init dss\n");
index 6ab0304..74b4481 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
 #include <linux/slab.h>
 
 #include <linux/mfd/arizona/core.h>
@@ -344,6 +348,17 @@ static int arizona_runtime_resume(struct device *dev)
 
        switch (arizona->type) {
        case WM5102:
+               if (arizona->external_dcvdd) {
+                       ret = regmap_update_bits(arizona->regmap,
+                                                ARIZONA_ISOLATION_CONTROL,
+                                                ARIZONA_ISOLATE_DCVDD1, 0);
+                       if (ret != 0) {
+                               dev_err(arizona->dev,
+                                       "Failed to connect DCVDD: %d\n", ret);
+                               goto err;
+                       }
+               }
+
                ret = wm5102_patch(arizona);
                if (ret != 0) {
                        dev_err(arizona->dev, "Failed to apply patch: %d\n",
@@ -365,6 +380,28 @@ static int arizona_runtime_resume(struct device *dev)
                        goto err;
                }
 
+               if (arizona->external_dcvdd) {
+                       ret = regmap_update_bits(arizona->regmap,
+                                                ARIZONA_ISOLATION_CONTROL,
+                                                ARIZONA_ISOLATE_DCVDD1, 0);
+                       if (ret != 0) {
+                               dev_err(arizona->dev,
+                                       "Failed to connect DCVDD: %d\n", ret);
+                               goto err;
+                       }
+               }
+               break;
+       }
+
+       switch (arizona->type) {
+       case WM5102:
+               ret = wm5102_patch(arizona);
+               if (ret != 0) {
+                       dev_err(arizona->dev, "Failed to apply patch: %d\n",
+                               ret);
+                       goto err;
+               }
+       default:
                break;
        }
 
@@ -385,9 +422,22 @@ err:
 static int arizona_runtime_suspend(struct device *dev)
 {
        struct arizona *arizona = dev_get_drvdata(dev);
+       int ret;
 
        dev_dbg(arizona->dev, "Entering AoD mode\n");
 
+       if (arizona->external_dcvdd) {
+               ret = regmap_update_bits(arizona->regmap,
+                                        ARIZONA_ISOLATION_CONTROL,
+                                        ARIZONA_ISOLATE_DCVDD1,
+                                        ARIZONA_ISOLATE_DCVDD1);
+               if (ret != 0) {
+                       dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
        regulator_disable(arizona->dcvdd);
        regcache_cache_only(arizona->regmap, true);
        regcache_mark_dirty(arizona->regmap);
@@ -397,6 +447,26 @@ static int arizona_runtime_suspend(struct device *dev)
 #endif
 
 #ifdef CONFIG_PM_SLEEP
+static int arizona_suspend(struct device *dev)
+{
+       struct arizona *arizona = dev_get_drvdata(dev);
+
+       dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
+       disable_irq(arizona->irq);
+
+       return 0;
+}
+
+static int arizona_suspend_late(struct device *dev)
+{
+       struct arizona *arizona = dev_get_drvdata(dev);
+
+       dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
+       enable_irq(arizona->irq);
+
+       return 0;
+}
+
 static int arizona_resume_noirq(struct device *dev)
 {
        struct arizona *arizona = dev_get_drvdata(dev);
@@ -422,13 +492,78 @@ const struct dev_pm_ops arizona_pm_ops = {
        SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
                           arizona_runtime_resume,
                           NULL)
-       SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume)
+       SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
 #ifdef CONFIG_PM_SLEEP
+       .suspend_late = arizona_suspend_late,
        .resume_noirq = arizona_resume_noirq,
 #endif
 };
 EXPORT_SYMBOL_GPL(arizona_pm_ops);
 
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev)
+{
+       const struct of_device_id *id = of_match_device(arizona_of_match, dev);
+
+       if (id)
+               return (int)id->data;
+       else
+               return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_of_get_type);
+
+static int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+       int ret, i;
+
+       arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
+                                                "wlf,reset", 0);
+       if (arizona->pdata.reset < 0)
+               arizona->pdata.reset = 0;
+
+       arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
+                                                 "wlf,ldoena", 0);
+       if (arizona->pdata.ldoena < 0)
+               arizona->pdata.ldoena = 0;
+
+       ret = of_property_read_u32_array(arizona->dev->of_node,
+                                        "wlf,gpio-defaults",
+                                        arizona->pdata.gpio_defaults,
+                                        ARRAY_SIZE(arizona->pdata.gpio_defaults));
+       if (ret >= 0) {
+               /*
+                * All values are literal except out of range values
+                * which are chip default, translate into platform
+                * data which uses 0 as chip default and out of range
+                * as zero.
+                */
+               for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
+                       if (arizona->pdata.gpio_defaults[i] > 0xffff)
+                               arizona->pdata.gpio_defaults[i] = 0;
+                       if (arizona->pdata.gpio_defaults[i] == 0)
+                               arizona->pdata.gpio_defaults[i] = 0x10000;
+               }
+       } else {
+               dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
+                       ret);
+       }
+
+       return 0;
+}
+
+const struct of_device_id arizona_of_match[] = {
+       { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
+       { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
+       {},
+};
+EXPORT_SYMBOL_GPL(arizona_of_match);
+#else
+static inline int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+       return 0;
+}
+#endif
+
 static struct mfd_cell early_devs[] = {
        { .name = "arizona-ldo1" },
 };
@@ -462,6 +597,8 @@ int arizona_dev_init(struct arizona *arizona)
        dev_set_drvdata(arizona->dev, arizona);
        mutex_init(&arizona->clk_lock);
 
+       arizona_of_get_core_pdata(arizona);
+
        if (dev_get_platdata(arizona->dev))
                memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
                       sizeof(arizona->pdata));
@@ -536,51 +673,22 @@ int arizona_dev_init(struct arizona *arizona)
 
        regcache_cache_only(arizona->regmap, false);
 
+       /* Verify that this is a chip we know about */
        ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
        if (ret != 0) {
                dev_err(dev, "Failed to read ID register: %d\n", ret);
                goto err_reset;
        }
 
-       ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
-                         &arizona->rev);
-       if (ret != 0) {
-               dev_err(dev, "Failed to read revision register: %d\n", ret);
-               goto err_reset;
-       }
-       arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
-
        switch (reg) {
-#ifdef CONFIG_MFD_WM5102
        case 0x5102:
-               type_name = "WM5102";
-               if (arizona->type != WM5102) {
-                       dev_err(arizona->dev, "WM5102 registered as %d\n",
-                               arizona->type);
-                       arizona->type = WM5102;
-               }
-               apply_patch = wm5102_patch;
-               arizona->rev &= 0x7;
-               break;
-#endif
-#ifdef CONFIG_MFD_WM5110
        case 0x5110:
-               type_name = "WM5110";
-               if (arizona->type != WM5110) {
-                       dev_err(arizona->dev, "WM5110 registered as %d\n",
-                               arizona->type);
-                       arizona->type = WM5110;
-               }
-               apply_patch = wm5110_patch;
                break;
-#endif
        default:
-               dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+               dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
                goto err_reset;
        }
 
-       dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
-
        /* If we have a /RESET GPIO we'll already be reset */
        if (!arizona->pdata.reset) {
                regcache_mark_dirty(arizona->regmap);
@@ -600,6 +708,7 @@ int arizona_dev_init(struct arizona *arizona)
                }
        }
 
+       /* Ensure device startup is complete */
        switch (arizona->type) {
        case WM5102:
                ret = regmap_read(arizona->regmap, 0x19, &val);
@@ -620,6 +729,52 @@ int arizona_dev_init(struct arizona *arizona)
                break;
        }
 
+       /* Read the device ID information & do device specific stuff */
+       ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
+       if (ret != 0) {
+               dev_err(dev, "Failed to read ID register: %d\n", ret);
+               goto err_reset;
+       }
+
+       ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
+                         &arizona->rev);
+       if (ret != 0) {
+               dev_err(dev, "Failed to read revision register: %d\n", ret);
+               goto err_reset;
+       }
+       arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
+
+       switch (reg) {
+#ifdef CONFIG_MFD_WM5102
+       case 0x5102:
+               type_name = "WM5102";
+               if (arizona->type != WM5102) {
+                       dev_err(arizona->dev, "WM5102 registered as %d\n",
+                               arizona->type);
+                       arizona->type = WM5102;
+               }
+               apply_patch = wm5102_patch;
+               arizona->rev &= 0x7;
+               break;
+#endif
+#ifdef CONFIG_MFD_WM5110
+       case 0x5110:
+               type_name = "WM5110";
+               if (arizona->type != WM5110) {
+                       dev_err(arizona->dev, "WM5110 registered as %d\n",
+                               arizona->type);
+                       arizona->type = WM5110;
+               }
+               apply_patch = wm5110_patch;
+               break;
+#endif
+       default:
+               dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+               goto err_reset;
+       }
+
+       dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
+
        if (apply_patch) {
                ret = apply_patch(arizona);
                if (ret != 0) {
@@ -651,6 +806,14 @@ int arizona_dev_init(struct arizona *arizona)
                             arizona->pdata.gpio_defaults[i]);
        }
 
+       /*
+        * LDO1 can only be used to supply DCVDD so if it has no
+        * consumers then DCVDD is supplied externally.
+        */
+       if (arizona->pdata.ldo1 &&
+           arizona->pdata.ldo1->num_consumer_supplies == 0)
+               arizona->external_dcvdd = true;
+
        pm_runtime_set_autosuspend_delay(arizona->dev, 100);
        pm_runtime_use_autosuspend(arizona->dev);
        pm_runtime_enable(arizona->dev);
@@ -697,7 +860,7 @@ int arizona_dev_init(struct arizona *arizona)
                if (arizona->pdata.micbias[i].discharge)
                        val |= ARIZONA_MICB1_DISCH;
 
-               if (arizona->pdata.micbias[i].fast_start)
+               if (arizona->pdata.micbias[i].soft_start)
                        val |= ARIZONA_MICB1_RATE;
 
                if (arizona->pdata.micbias[i].bypass)
@@ -809,6 +972,11 @@ int arizona_dev_exit(struct arizona *arizona)
        arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
        pm_runtime_disable(arizona->dev);
        arizona_irq_exit(arizona);
+       if (arizona->pdata.reset)
+               gpio_set_value_cansleep(arizona->pdata.reset, 0);
+       regulator_disable(arizona->dcvdd);
+       regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
+                              arizona->core_supplies);
        return 0;
 }
 EXPORT_SYMBOL_GPL(arizona_dev_exit);
index 44a1bb9..deb267e 100644 (file)
@@ -27,9 +27,14 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
 {
        struct arizona *arizona;
        const struct regmap_config *regmap_config;
-       int ret;
+       int ret, type;
 
-       switch (id->driver_data) {
+       if (i2c->dev.of_node)
+               type = arizona_of_get_type(&i2c->dev);
+       else
+               type = id->driver_data;
+
+       switch (type) {
 #ifdef CONFIG_MFD_WM5102
        case WM5102:
                regmap_config = &wm5102_i2c_regmap;
@@ -84,6 +89,7 @@ static struct i2c_driver arizona_i2c_driver = {
                .name   = "arizona",
                .owner  = THIS_MODULE,
                .pm     = &arizona_pm_ops,
+               .of_match_table = of_match_ptr(arizona_of_match),
        },
        .probe          = arizona_i2c_probe,
        .remove         = arizona_i2c_remove,
index b57e642..47be7b3 100644 (file)
@@ -27,9 +27,14 @@ static int arizona_spi_probe(struct spi_device *spi)
        const struct spi_device_id *id = spi_get_device_id(spi);
        struct arizona *arizona;
        const struct regmap_config *regmap_config;
-       int ret;
+       int ret, type;
 
-       switch (id->driver_data) {
+       if (spi->dev.of_node)
+               type = arizona_of_get_type(&spi->dev);
+       else
+               type = id->driver_data;
+
+       switch (type) {
 #ifdef CONFIG_MFD_WM5102
        case WM5102:
                regmap_config = &wm5102_spi_regmap;
@@ -84,6 +89,7 @@ static struct spi_driver arizona_spi_driver = {
                .name   = "arizona",
                .owner  = THIS_MODULE,
                .pm     = &arizona_pm_ops,
+               .of_match_table = of_match_ptr(arizona_of_match),
        },
        .probe          = arizona_spi_probe,
        .remove         = arizona_spi_remove,
index 9798ae5..db55d98 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef _WM5102_H
 #define _WM5102_H
 
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/pm.h>
 
@@ -26,6 +27,8 @@ extern const struct regmap_config wm5110_spi_regmap;
 
 extern const struct dev_pm_ops arizona_pm_ops;
 
+extern const struct of_device_id arizona_of_match[];
+
 extern const struct regmap_irq_chip wm5102_aod;
 extern const struct regmap_irq_chip wm5102_irq;
 
@@ -37,4 +40,13 @@ int arizona_dev_exit(struct arizona *arizona);
 int arizona_irq_init(struct arizona *arizona);
 int arizona_irq_exit(struct arizona *arizona);
 
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev);
+#else
+static inline int arizona_of_get_type(struct device *dev)
+{
+       return 0;
+}
+#endif
+
 #endif
index 155c4a1..802dd3c 100644 (file)
@@ -65,7 +65,8 @@ static const struct reg_default wm5102_revb_patch[] = {
        { 0x418, 0xa080 },
        { 0x420, 0xa080 },
        { 0x428, 0xe000 },
-       { 0x443, 0xDC1A },
+       { 0x442, 0x3F0A },
+       { 0x443, 0xDC1F },
        { 0x4B0, 0x0066 },
        { 0x458, 0x000b },
        { 0x212, 0x0000 },
@@ -424,6 +425,9 @@ static const struct reg_default wm5102_reg_default[] = {
        { 0x00000435, 0x0180 },   /* R1077  - DAC Digital Volume 5R */ 
        { 0x00000436, 0x0081 },   /* R1078  - DAC Volume Limit 5R */
        { 0x00000437, 0x0200 },   /* R1079  - Noise Gate Select 5R */
+       { 0x00000440, 0x8FFF },   /* R1088  - DRE Enable */
+       { 0x00000442, 0x3F0A },   /* R1090  - DRE Control 2 */
+       { 0x00000443, 0xDC1F },   /* R1090  - DRE Control 3 */
        { 0x00000450, 0x0000 },   /* R1104  - DAC AEC Control 1 */ 
        { 0x00000458, 0x000B },   /* R1112  - Noise Gate Control */
        { 0x00000490, 0x0069 },   /* R1168  - PDM SPK1 CTRL 1 */ 
@@ -1197,6 +1201,9 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DAC_DIGITAL_VOLUME_5R:
        case ARIZONA_DAC_VOLUME_LIMIT_5R:
        case ARIZONA_NOISE_GATE_SELECT_5R:
+       case ARIZONA_DRE_ENABLE:
+       case ARIZONA_DRE_CONTROL_2:
+       case ARIZONA_DRE_CONTROL_3:
        case ARIZONA_DAC_AEC_CONTROL_1:
        case ARIZONA_NOISE_GATE_CONTROL:
        case ARIZONA_PDM_SPK1_CTRL_1:
index c415998..2a79723 100644 (file)
@@ -2273,18 +2273,22 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP1_CLOCKING_1:
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
+       case ARIZONA_DSP1_STATUS_3:
        case ARIZONA_DSP2_CONTROL_1:
        case ARIZONA_DSP2_CLOCKING_1:
        case ARIZONA_DSP2_STATUS_1:
        case ARIZONA_DSP2_STATUS_2:
+       case ARIZONA_DSP2_STATUS_3:
        case ARIZONA_DSP3_CONTROL_1:
        case ARIZONA_DSP3_CLOCKING_1:
        case ARIZONA_DSP3_STATUS_1:
        case ARIZONA_DSP3_STATUS_2:
+       case ARIZONA_DSP3_STATUS_3:
        case ARIZONA_DSP4_CONTROL_1:
        case ARIZONA_DSP4_CLOCKING_1:
        case ARIZONA_DSP4_STATUS_1:
        case ARIZONA_DSP4_STATUS_2:
+       case ARIZONA_DSP4_STATUS_3:
                return true;
        default:
                return false;
@@ -2334,12 +2338,16 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
        case ARIZONA_DSP1_CLOCKING_1:
        case ARIZONA_DSP1_STATUS_1:
        case ARIZONA_DSP1_STATUS_2:
+       case ARIZONA_DSP1_STATUS_3:
        case ARIZONA_DSP2_STATUS_1:
        case ARIZONA_DSP2_STATUS_2:
+       case ARIZONA_DSP2_STATUS_3:
        case ARIZONA_DSP3_STATUS_1:
        case ARIZONA_DSP3_STATUS_2:
+       case ARIZONA_DSP3_STATUS_3:
        case ARIZONA_DSP4_STATUS_1:
        case ARIZONA_DSP4_STATUS_2:
+       case ARIZONA_DSP4_STATUS_3:
                return true;
        default:
                return false;
index 1abd5ad..f7b9066 100644 (file)
@@ -58,7 +58,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
        ssc->user++;
        spin_unlock(&user_lock);
 
-       clk_enable(ssc->clk);
+       clk_prepare_enable(ssc->clk);
 
        return ssc;
 }
@@ -69,7 +69,7 @@ void ssc_free(struct ssc_device *ssc)
        spin_lock(&user_lock);
        if (ssc->user) {
                ssc->user--;
-               clk_disable(ssc->clk);
+               clk_disable_unprepare(ssc->clk);
        } else {
                dev_dbg(&ssc->pdev->dev, "device already free\n");
        }
@@ -167,10 +167,10 @@ static int ssc_probe(struct platform_device *pdev)
        }
 
        /* disable all interrupts */
-       clk_enable(ssc->clk);
+       clk_prepare_enable(ssc->clk);
        ssc_writel(ssc->regs, IDR, -1);
        ssc_readl(ssc->regs, SR);
-       clk_disable(ssc->clk);
+       clk_disable_unprepare(ssc->clk);
 
        ssc->irq = platform_get_irq(pdev, 0);
        if (!ssc->irq) {
index 713d89f..f580d30 100644 (file)
@@ -197,6 +197,8 @@ void mei_stop(struct mei_device *dev)
 {
        dev_dbg(&dev->pdev->dev, "stopping the device.\n");
 
+       flush_scheduled_work();
+
        mutex_lock(&dev->device_lock);
 
        cancel_delayed_work(&dev->timer_work);
@@ -210,8 +212,6 @@ void mei_stop(struct mei_device *dev)
 
        mutex_unlock(&dev->device_lock);
 
-       flush_scheduled_work();
-
        mei_watchdog_unregister(dev);
 }
 EXPORT_SYMBOL_GPL(mei_stop);
index 3adf8a7..d0c6907 100644 (file)
@@ -142,6 +142,8 @@ static void mei_nfc_free(struct mei_nfc_dev *ndev)
                mei_cl_unlink(ndev->cl_info);
                kfree(ndev->cl_info);
        }
+
+       memset(ndev, 0, sizeof(struct mei_nfc_dev));
 }
 
 static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev)
index a727464..0f26832 100644 (file)
@@ -325,6 +325,7 @@ static int mei_me_pci_resume(struct device *device)
 
        mutex_lock(&dev->device_lock);
        dev->dev_state = MEI_DEV_POWER_UP;
+       mei_clear_interrupts(dev);
        mei_reset(dev, 1);
        mutex_unlock(&dev->device_lock);
 
index 44d273c..0535d1e 100644 (file)
@@ -172,6 +172,7 @@ static long gru_get_config_info(unsigned long arg)
                nodesperblade = 2;
        else
                nodesperblade = 1;
+       memset(&info, 0, sizeof(info));
        info.cpus = num_online_cpus();
        info.nodes = num_online_nodes();
        info.blades = info.nodes / nodesperblade;
index e75774f..aca59d9 100644 (file)
@@ -2230,10 +2230,15 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot,
        mmc_free_host(slot->mmc);
 }
 
-static bool atmci_filter(struct dma_chan *chan, void *slave)
+static bool atmci_filter(struct dma_chan *chan, void *pdata)
 {
-       struct mci_dma_data     *sl = slave;
+       struct mci_platform_data *sl_pdata = pdata;
+       struct mci_dma_data *sl;
 
+       if (!sl_pdata)
+               return false;
+
+       sl = sl_pdata->dma_slave;
        if (sl && find_slave_dev(sl) == chan->device->dev) {
                chan->private = slave_data_ptr(sl);
                return true;
@@ -2245,24 +2250,18 @@ static bool atmci_filter(struct dma_chan *chan, void *slave)
 static bool atmci_configure_dma(struct atmel_mci *host)
 {
        struct mci_platform_data        *pdata;
+       dma_cap_mask_t mask;
 
        if (host == NULL)
                return false;
 
        pdata = host->pdev->dev.platform_data;
 
-       if (!pdata)
-               return false;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
 
-       if (pdata->dma_slave && find_slave_dev(pdata->dma_slave)) {
-               dma_cap_mask_t mask;
-
-               /* Try to grab a DMA channel */
-               dma_cap_zero(mask);
-               dma_cap_set(DMA_SLAVE, mask);
-               host->dma.chan =
-                       dma_request_channel(mask, atmci_filter, pdata->dma_slave);
-       }
+       host->dma.chan = dma_request_slave_channel_compat(mask, atmci_filter, pdata,
+                                                         &host->pdev->dev, "rxtx");
        if (!host->dma.chan) {
                dev_warn(&host->pdev->dev, "no DMA channel available\n");
                return false;
index 6e44025..eccedc7 100644 (file)
@@ -161,6 +161,7 @@ struct omap_hsmmc_host {
         */
        struct  regulator       *vcc;
        struct  regulator       *vcc_aux;
+       int                     pbias_disable;
        void    __iomem         *base;
        resource_size_t         mapbase;
        spinlock_t              irq_lock; /* Prevent races with irq handler */
@@ -255,11 +256,11 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on,
        if (!host->vcc)
                return 0;
        /*
-        * With DT, never turn OFF the regulator. This is because
+        * With DT, never turn OFF the regulator for MMC1. This is because
         * the pbias cell programming support is still missing when
         * booting with Device tree
         */
-       if (dev->of_node && !vdd)
+       if (host->pbias_disable && !vdd)
                return 0;
 
        if (mmc_slot(host).before_set_reg)
@@ -1520,10 +1521,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        (ios->vdd == DUAL_VOLT_OCR_BIT) &&
                        /*
                         * With pbias cell programming missing, this
-                        * can't be allowed when booting with device
+                        * can't be allowed on MMC1 when booting with device
                         * tree.
                         */
-                       !host->dev->of_node) {
+                       !host->pbias_disable) {
                                /*
                                 * The mmc_select_voltage fn of the core does
                                 * not seem to set the power_mode to
@@ -1871,6 +1872,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
        omap_hsmmc_context_save(host);
 
+       /* This can be removed once we support PBIAS with DT */
+       if (host->dev->of_node && host->mapbase == 0x4809c000)
+               host->pbias_disable = 1;
+
        host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
        /*
         * MMC can still work without debounce clock.
@@ -1906,33 +1911,41 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
        omap_hsmmc_conf_bus_power(host);
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
-       if (!res) {
-               dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
-               ret = -ENXIO;
-               goto err_irq;
-       }
-       tx_req = res->start;
+       if (!pdev->dev.of_node) {
+               res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+               if (!res) {
+                       dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
+                       ret = -ENXIO;
+                       goto err_irq;
+               }
+               tx_req = res->start;
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
-       if (!res) {
-               dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
-               ret = -ENXIO;
-               goto err_irq;
+               res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+               if (!res) {
+                       dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
+                       ret = -ENXIO;
+                       goto err_irq;
+               }
+               rx_req = res->start;
        }
-       rx_req = res->start;
 
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
-       host->rx_chan = dma_request_channel(mask, omap_dma_filter_fn, &rx_req);
+       host->rx_chan =
+               dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+                                                &rx_req, &pdev->dev, "rx");
+
        if (!host->rx_chan) {
                dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req);
                ret = -ENXIO;
                goto err_irq;
        }
 
-       host->tx_chan = dma_request_channel(mask, omap_dma_filter_fn, &tx_req);
+       host->tx_chan =
+               dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+                                                &tx_req, &pdev->dev, "tx");
+
        if (!host->tx_chan) {
                dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req);
                ret = -ENXIO;
index 7bcf74b..706d9cb 100644 (file)
@@ -87,6 +87,12 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = {
        .enable_dma = sdhci_acpi_enable_dma,
 };
 
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
+       .caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+       .caps2   = MMC_CAP2_HC_ERASE_SZ,
+       .flags   = SDHCI_ACPI_RUNTIME_PM,
+};
+
 static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
        .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
        .caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD,
@@ -94,23 +100,67 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
        .pm_caps = MMC_PM_KEEP_POWER,
 };
 
+static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
+};
+
+struct sdhci_acpi_uid_slot {
+       const char *hid;
+       const char *uid;
+       const struct sdhci_acpi_slot *slot;
+};
+
+static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
+       { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc },
+       { "80860F14" , "3" , &sdhci_acpi_slot_int_sd   },
+       { "INT33BB"  , "2" , &sdhci_acpi_slot_int_sdio },
+       { "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
+       { "PNP0D40"  },
+       { },
+};
+
 static const struct acpi_device_id sdhci_acpi_ids[] = {
-       { "INT33C6", (kernel_ulong_t)&sdhci_acpi_slot_int_sdio },
-       { "PNP0D40" },
+       { "80860F14" },
+       { "INT33BB"  },
+       { "INT33C6"  },
+       { "PNP0D40"  },
        { },
 };
 MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids);
 
-static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid)
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot_by_ids(const char *hid,
+                                                               const char *uid)
 {
-       const struct acpi_device_id *id;
-
-       for (id = sdhci_acpi_ids; id->id[0]; id++)
-               if (!strcmp(id->id, hid))
-                       return (const struct sdhci_acpi_slot *)id->driver_data;
+       const struct sdhci_acpi_uid_slot *u;
+
+       for (u = sdhci_acpi_uids; u->hid; u++) {
+               if (strcmp(u->hid, hid))
+                       continue;
+               if (!u->uid)
+                       return u->slot;
+               if (uid && !strcmp(u->uid, uid))
+                       return u->slot;
+       }
        return NULL;
 }
 
+static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle,
+                                                        const char *hid)
+{
+       const struct sdhci_acpi_slot *slot;
+       struct acpi_device_info *info;
+       const char *uid = NULL;
+       acpi_status status;
+
+       status = acpi_get_object_info(handle, &info);
+       if (!ACPI_FAILURE(status) && (info->valid & ACPI_VALID_UID))
+               uid = info->unique_id.string;
+
+       slot = sdhci_acpi_get_slot_by_ids(hid, uid);
+
+       kfree(info);
+       return slot;
+}
+
 static int sdhci_acpi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -148,7 +198,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
 
        c = sdhci_priv(host);
        c->host = host;
-       c->slot = sdhci_acpi_get_slot(hid);
+       c->slot = sdhci_acpi_get_slot(handle, hid);
        c->pdev = pdev;
        c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM);
 
@@ -202,6 +252,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
                goto err_free;
 
        if (c->use_runtime_pm) {
+               pm_runtime_set_active(dev);
                pm_suspend_ignore_children(dev, 1);
                pm_runtime_set_autosuspend_delay(dev, 50);
                pm_runtime_use_autosuspend(dev);
index 67d6dde..d5f0d59 100644 (file)
@@ -85,6 +85,12 @@ struct pltfm_imx_data {
        struct clk *clk_ipg;
        struct clk *clk_ahb;
        struct clk *clk_per;
+       enum {
+               NO_CMD_PENDING,      /* no multiblock command pending*/
+               MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
+               WAIT_FOR_INT,        /* sent CMD12, waiting for response INT */
+       } multiblock_status;
+
 };
 
 static struct platform_device_id imx_esdhc_devtype[] = {
@@ -154,6 +160,8 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
 
 static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 {
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct pltfm_imx_data *imx_data = pltfm_host->priv;
        u32 val = readl(host->ioaddr + reg);
 
        if (unlikely(reg == SDHCI_CAPABILITIES)) {
@@ -175,6 +183,18 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
                        val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR;
                        val |= SDHCI_INT_ADMA_ERROR;
                }
+
+               /*
+                * mask off the interrupt we get in response to the manually
+                * sent CMD12
+                */
+               if ((imx_data->multiblock_status == WAIT_FOR_INT) &&
+                   ((val & SDHCI_INT_RESPONSE) == SDHCI_INT_RESPONSE)) {
+                       val &= ~SDHCI_INT_RESPONSE;
+                       writel(SDHCI_INT_RESPONSE, host->ioaddr +
+                                                  SDHCI_INT_STATUS);
+                       imx_data->multiblock_status = NO_CMD_PENDING;
+               }
        }
 
        return val;
@@ -211,6 +231,15 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
                        v = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
                        v &= ~ESDHC_VENDOR_SPEC_SDIO_QUIRK;
                        writel(v, host->ioaddr + ESDHC_VENDOR_SPEC);
+
+                       if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS)
+                       {
+                               /* send a manual CMD12 with RESPTYP=none */
+                               data = MMC_STOP_TRANSMISSION << 24 |
+                                      SDHCI_CMD_ABORTCMD << 16;
+                               writel(data, host->ioaddr + SDHCI_TRANSFER_MODE);
+                               imx_data->multiblock_status = WAIT_FOR_INT;
+                       }
        }
 
        if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
@@ -277,11 +306,13 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
                }
                return;
        case SDHCI_COMMAND:
-               if ((host->cmd->opcode == MMC_STOP_TRANSMISSION ||
-                    host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
-                   (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+               if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
                        val |= SDHCI_CMD_ABORTCMD;
 
+               if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
+                   (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+                       imx_data->multiblock_status = MULTIBLK_IN_PROCESS;
+
                if (is_imx6q_usdhc(imx_data))
                        writel(val << 16,
                               host->ioaddr + SDHCI_TRANSFER_MODE);
@@ -324,8 +355,10 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
                /*
                 * Do not touch buswidth bits here. This is done in
                 * esdhc_pltfm_bus_width.
+                * Do not touch the D3CD bit either which is used for the
+                * SDIO interrupt errata workaround.
                 */
-               mask = 0xffff & ~ESDHC_CTRL_BUSWIDTH_MASK;
+               mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD);
 
                esdhc_clrset_le(host, mask, new_val, reg);
                return;
index 0012d3f..701d06d 100644 (file)
@@ -33,6 +33,9 @@
  */
 #define PCI_DEVICE_ID_INTEL_PCH_SDIO0  0x8809
 #define PCI_DEVICE_ID_INTEL_PCH_SDIO1  0x880a
+#define PCI_DEVICE_ID_INTEL_BYT_EMMC   0x0f14
+#define PCI_DEVICE_ID_INTEL_BYT_SDIO   0x0f15
+#define PCI_DEVICE_ID_INTEL_BYT_SD     0x0f16
 
 /*
  * PCI registers
@@ -304,6 +307,33 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = {
        .probe_slot     = pch_hc_probe_slot,
 };
 
+static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+{
+       slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
+       slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
+       return 0;
+}
+
+static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+{
+       slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
+       return 0;
+}
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
+       .allow_runtime_pm = true,
+       .probe_slot     = byt_emmc_probe_slot,
+};
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
+       .quirks2        = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+       .allow_runtime_pm = true,
+       .probe_slot     = byt_sdio_probe_slot,
+};
+
+static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
+};
+
 /* O2Micro extra registers */
 #define O2_SD_LOCK_WP          0xD3
 #define O2_SD_MULTI_VCC3V      0xEE
@@ -856,6 +886,30 @@ static const struct pci_device_id pci_ids[] = {
        },
 
        {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_EMMC,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_emmc,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_SDIO,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sdio,
+       },
+
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BYT_SD,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .driver_data    = (kernel_ulong_t)&sdhci_intel_byt_sd,
+       },
+
+       {
                .vendor         = PCI_VENDOR_ID_O2,
                .device         = PCI_DEVICE_ID_O2_8120,
                .subvendor      = PCI_ANY_ID,
index 29b846c..02d9ae7 100644 (file)
@@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
        struct net_device *bond_dev, *vlan_dev, *upper_dev;
        struct vlan_entry *vlan;
 
-       rcu_read_lock();
        read_lock(&bond->lock);
+       rcu_read_lock();
 
        bond_dev = bond->dev;
 
@@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
                if (vlan_dev)
                        __bond_resend_igmp_join_requests(vlan_dev);
        }
+       rcu_read_unlock();
 
-       if (--bond->igmp_retrans > 0)
+       /* We use curr_slave_lock to protect against concurrent access to
+        * igmp_retrans from multiple running instances of this function and
+        * bond_change_active_slave
+        */
+       write_lock_bh(&bond->curr_slave_lock);
+       if (bond->igmp_retrans > 1) {
+               bond->igmp_retrans--;
                queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
-
+       }
+       write_unlock_bh(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
-       rcu_read_unlock();
 }
 
 static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
@@ -1957,6 +1964,10 @@ err_free:
 
 err_undo_flags:
        bond_compute_features(bond);
+       /* Enslave of first slave has failed and we need to fix master's mac */
+       if (bond->slave_cnt == 0 &&
+           ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr))
+               eth_hw_addr_random(bond_dev);
 
        return res;
 }
index 2baec24..f989e15 100644 (file)
@@ -225,7 +225,7 @@ struct bonding {
        rwlock_t curr_slave_lock;
        u8       send_peer_notif;
        s8       setup_by_slave;
-       s8       igmp_retrans;
+       u8       igmp_retrans;
 #ifdef CONFIG_PROC_FS
        struct   proc_dir_entry *proc_entry;
        char     proc_file_name[IFNAMSIZ];
index 9b74d1e..6aa7b32 100644 (file)
@@ -612,9 +612,15 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv)
 {
        struct esd_usb2 *dev = priv->usb2;
        struct net_device *netdev = priv->netdev;
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
        int err, i;
 
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg) {
+               err = -ENOMEM;
+               goto out;
+       }
+
        /*
         * Enable all IDs
         * The IDADD message takes up to 64 32 bit bitmasks (2048 bits).
@@ -628,33 +634,32 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv)
         * the number of the starting bitmask (0..64) to the filter.option
         * field followed by only some bitmasks.
         */
-       msg.msg.hdr.cmd = CMD_IDADD;
-       msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
-       msg.msg.filter.net = priv->index;
-       msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+       msg->msg.hdr.cmd = CMD_IDADD;
+       msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+       msg->msg.filter.net = priv->index;
+       msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
        for (i = 0; i < ESD_MAX_ID_SEGMENT; i++)
-               msg.msg.filter.mask[i] = cpu_to_le32(0xffffffff);
+               msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff);
        /* enable 29bit extended IDs */
-       msg.msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
+       msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
 
-       err = esd_usb2_send_msg(dev, &msg);
+       err = esd_usb2_send_msg(dev, msg);
        if (err)
-               goto failed;
+               goto out;
 
        err = esd_usb2_setup_rx_urbs(dev);
        if (err)
-               goto failed;
+               goto out;
 
        priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
-       return 0;
-
-failed:
+out:
        if (err == -ENODEV)
                netif_device_detach(netdev);
+       if (err)
+               netdev_err(netdev, "couldn't start device: %d\n", err);
 
-       netdev_err(netdev, "couldn't start device: %d\n", err);
-
+       kfree(msg);
        return err;
 }
 
@@ -833,26 +838,30 @@ nourbmem:
 static int esd_usb2_close(struct net_device *netdev)
 {
        struct esd_usb2_net_priv *priv = netdev_priv(netdev);
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
        int i;
 
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
        /* Disable all IDs (see esd_usb2_start()) */
-       msg.msg.hdr.cmd = CMD_IDADD;
-       msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
-       msg.msg.filter.net = priv->index;
-       msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+       msg->msg.hdr.cmd = CMD_IDADD;
+       msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+       msg->msg.filter.net = priv->index;
+       msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
        for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
-               msg.msg.filter.mask[i] = 0;
-       if (esd_usb2_send_msg(priv->usb2, &msg) < 0)
+               msg->msg.filter.mask[i] = 0;
+       if (esd_usb2_send_msg(priv->usb2, msg) < 0)
                netdev_err(netdev, "sending idadd message failed\n");
 
        /* set CAN controller to reset mode */
-       msg.msg.hdr.len = 2;
-       msg.msg.hdr.cmd = CMD_SETBAUD;
-       msg.msg.setbaud.net = priv->index;
-       msg.msg.setbaud.rsvd = 0;
-       msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
-       if (esd_usb2_send_msg(priv->usb2, &msg) < 0)
+       msg->msg.hdr.len = 2;
+       msg->msg.hdr.cmd = CMD_SETBAUD;
+       msg->msg.setbaud.net = priv->index;
+       msg->msg.setbaud.rsvd = 0;
+       msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
+       if (esd_usb2_send_msg(priv->usb2, msg) < 0)
                netdev_err(netdev, "sending setbaud message failed\n");
 
        priv->can.state = CAN_STATE_STOPPED;
@@ -861,6 +870,8 @@ static int esd_usb2_close(struct net_device *netdev)
 
        close_candev(netdev);
 
+       kfree(msg);
+
        return 0;
 }
 
@@ -886,7 +897,8 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
 {
        struct esd_usb2_net_priv *priv = netdev_priv(netdev);
        struct can_bittiming *bt = &priv->can.bittiming;
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
+       int err;
        u32 canbtr;
        int sjw_shift;
 
@@ -912,15 +924,22 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
        if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
                canbtr |= ESD_USB2_3_SAMPLES;
 
-       msg.msg.hdr.len = 2;
-       msg.msg.hdr.cmd = CMD_SETBAUD;
-       msg.msg.setbaud.net = priv->index;
-       msg.msg.setbaud.rsvd = 0;
-       msg.msg.setbaud.baud = cpu_to_le32(canbtr);
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       msg->msg.hdr.len = 2;
+       msg->msg.hdr.cmd = CMD_SETBAUD;
+       msg->msg.setbaud.net = priv->index;
+       msg->msg.setbaud.rsvd = 0;
+       msg->msg.setbaud.baud = cpu_to_le32(canbtr);
 
        netdev_info(netdev, "setting BTR=%#x\n", canbtr);
 
-       return esd_usb2_send_msg(priv->usb2, &msg);
+       err = esd_usb2_send_msg(priv->usb2, msg);
+
+       kfree(msg);
+       return err;
 }
 
 static int esd_usb2_get_berr_counter(const struct net_device *netdev,
@@ -1022,7 +1041,7 @@ static int esd_usb2_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
 {
        struct esd_usb2 *dev;
-       struct esd_usb2_msg msg;
+       struct esd_usb2_msg *msg;
        int i, err;
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1037,27 +1056,33 @@ static int esd_usb2_probe(struct usb_interface *intf,
 
        usb_set_intfdata(intf, dev);
 
+       msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+       if (!msg) {
+               err = -ENOMEM;
+               goto free_msg;
+       }
+
        /* query number of CAN interfaces (nets) */
-       msg.msg.hdr.cmd = CMD_VERSION;
-       msg.msg.hdr.len = 2;
-       msg.msg.version.rsvd = 0;
-       msg.msg.version.flags = 0;
-       msg.msg.version.drv_version = 0;
+       msg->msg.hdr.cmd = CMD_VERSION;
+       msg->msg.hdr.len = 2;
+       msg->msg.version.rsvd = 0;
+       msg->msg.version.flags = 0;
+       msg->msg.version.drv_version = 0;
 
-       err = esd_usb2_send_msg(dev, &msg);
+       err = esd_usb2_send_msg(dev, msg);
        if (err < 0) {
                dev_err(&intf->dev, "sending version message failed\n");
-               goto free_dev;
+               goto free_msg;
        }
 
-       err = esd_usb2_wait_msg(dev, &msg);
+       err = esd_usb2_wait_msg(dev, msg);
        if (err < 0) {
                dev_err(&intf->dev, "no version message answer\n");
-               goto free_dev;
+               goto free_msg;
        }
 
-       dev->net_count = (int)msg.msg.version_reply.nets;
-       dev->version = le32_to_cpu(msg.msg.version_reply.version);
+       dev->net_count = (int)msg->msg.version_reply.nets;
+       dev->version = le32_to_cpu(msg->msg.version_reply.version);
 
        if (device_create_file(&intf->dev, &dev_attr_firmware))
                dev_err(&intf->dev,
@@ -1075,10 +1100,10 @@ static int esd_usb2_probe(struct usb_interface *intf,
        for (i = 0; i < dev->net_count; i++)
                esd_usb2_probe_one_net(intf, i);
 
-       return 0;
-
-free_dev:
-       kfree(dev);
+free_msg:
+       kfree(msg);
+       if (err)
+               kfree(dev);
 done:
        return err;
 }
index 45cb9f3..3b95465 100644 (file)
 #define KVASER_CTRL_MODE_SELFRECEPTION 3
 #define KVASER_CTRL_MODE_OFF           4
 
+/* log message */
+#define KVASER_EXTENDED_FRAME          BIT(31)
+
 struct kvaser_msg_simple {
        u8 tid;
        u8 channel;
@@ -817,8 +820,13 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
        priv = dev->nets[channel];
        stats = &priv->netdev->stats;
 
-       if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | MSG_FLAG_NERR |
-                                 MSG_FLAG_OVERRUN)) {
+       if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) &&
+           (msg->id == CMD_LOG_MESSAGE)) {
+               kvaser_usb_rx_error(dev, msg);
+               return;
+       } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
+                                        MSG_FLAG_NERR |
+                                        MSG_FLAG_OVERRUN)) {
                kvaser_usb_rx_can_err(priv, msg);
                return;
        } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) {
@@ -834,22 +842,40 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
                return;
        }
 
-       cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
-                    (msg->u.rx_can.msg[1] & 0x3f);
-       cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);
+       if (msg->id == CMD_LOG_MESSAGE) {
+               cf->can_id = le32_to_cpu(msg->u.log_message.id);
+               if (cf->can_id & KVASER_EXTENDED_FRAME)
+                       cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG;
+               else
+                       cf->can_id &= CAN_SFF_MASK;
 
-       if (msg->id == CMD_RX_EXT_MESSAGE) {
-               cf->can_id <<= 18;
-               cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
-                             ((msg->u.rx_can.msg[3] & 0xff) << 6) |
-                             (msg->u.rx_can.msg[4] & 0x3f);
-               cf->can_id |= CAN_EFF_FLAG;
-       }
+               cf->can_dlc = get_can_dlc(msg->u.log_message.dlc);
 
-       if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
-               cf->can_id |= CAN_RTR_FLAG;
-       else
-               memcpy(cf->data, &msg->u.rx_can.msg[6], cf->can_dlc);
+               if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME)
+                       cf->can_id |= CAN_RTR_FLAG;
+               else
+                       memcpy(cf->data, &msg->u.log_message.data,
+                              cf->can_dlc);
+       } else {
+               cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
+                            (msg->u.rx_can.msg[1] & 0x3f);
+
+               if (msg->id == CMD_RX_EXT_MESSAGE) {
+                       cf->can_id <<= 18;
+                       cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
+                                     ((msg->u.rx_can.msg[3] & 0xff) << 6) |
+                                     (msg->u.rx_can.msg[4] & 0x3f);
+                       cf->can_id |= CAN_EFF_FLAG;
+               }
+
+               cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);
+
+               if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
+                       cf->can_id |= CAN_RTR_FLAG;
+               else
+                       memcpy(cf->data, &msg->u.rx_can.msg[6],
+                              cf->can_dlc);
+       }
 
        netif_rx(skb);
 
@@ -911,6 +937,7 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
 
        case CMD_RX_STD_MESSAGE:
        case CMD_RX_EXT_MESSAGE:
+       case CMD_LOG_MESSAGE:
                kvaser_usb_rx_can_msg(dev, msg);
                break;
 
@@ -919,11 +946,6 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
                kvaser_usb_rx_error(dev, msg);
                break;
 
-       case CMD_LOG_MESSAGE:
-               if (msg->u.log_message.flags & MSG_FLAG_ERROR_FRAME)
-                       kvaser_usb_rx_error(dev, msg);
-               break;
-
        case CMD_TX_ACKNOWLEDGE:
                kvaser_usb_tx_acknowledge(dev, msg);
                break;
index 30d79bf..8ee9d15 100644 (file)
@@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev,
        return usb_submit_urb(urb, GFP_ATOMIC);
 }
 
-static void pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
+static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
 {
-       u8 buffer[16];
+       u8 *buffer;
+       int err;
+
+       buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
 
        buffer[0] = 0;
        buffer[1] = !!loaded;
 
-       pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
-                             PCAN_USBPRO_FCT_DRVLD, buffer, sizeof(buffer));
+       err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
+                                   PCAN_USBPRO_FCT_DRVLD, buffer,
+                                   PCAN_USBPRO_FCT_DRVLD_REQ_LEN);
+       kfree(buffer);
+
+       return err;
 }
 
 static inline
@@ -851,21 +860,24 @@ static int pcan_usb_pro_stop(struct peak_usb_device *dev)
  */
 static int pcan_usb_pro_init(struct peak_usb_device *dev)
 {
-       struct pcan_usb_pro_interface *usb_if;
        struct pcan_usb_pro_device *pdev =
                        container_of(dev, struct pcan_usb_pro_device, dev);
+       struct pcan_usb_pro_interface *usb_if = NULL;
+       struct pcan_usb_pro_fwinfo *fi = NULL;
+       struct pcan_usb_pro_blinfo *bi = NULL;
+       int err;
 
        /* do this for 1st channel only */
        if (!dev->prev_siblings) {
-               struct pcan_usb_pro_fwinfo fi;
-               struct pcan_usb_pro_blinfo bi;
-               int err;
-
                /* allocate netdevices common structure attached to first one */
                usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface),
                                 GFP_KERNEL);
-               if (!usb_if)
-                       return -ENOMEM;
+               fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL);
+               bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL);
+               if (!usb_if || !fi || !bi) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
 
                /* number of ts msgs to ignore before taking one into account */
                usb_if->cm_ignore_count = 5;
@@ -877,34 +889,34 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
                 */
                err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
                                            PCAN_USBPRO_INFO_FW,
-                                           &fi, sizeof(fi));
+                                           fi, sizeof(*fi));
                if (err) {
-                       kfree(usb_if);
                        dev_err(dev->netdev->dev.parent,
                                "unable to read %s firmware info (err %d)\n",
                                pcan_usb_pro.name, err);
-                       return err;
+                       goto err_out;
                }
 
                err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
                                            PCAN_USBPRO_INFO_BL,
-                                           &bi, sizeof(bi));
+                                           bi, sizeof(*bi));
                if (err) {
-                       kfree(usb_if);
                        dev_err(dev->netdev->dev.parent,
                                "unable to read %s bootloader info (err %d)\n",
                                pcan_usb_pro.name, err);
-                       return err;
+                       goto err_out;
                }
 
+               /* tell the device the can driver is running */
+               err = pcan_usb_pro_drv_loaded(dev, 1);
+               if (err)
+                       goto err_out;
+
                dev_info(dev->netdev->dev.parent,
                     "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n",
                     pcan_usb_pro.name,
-                    bi.hw_rev, bi.serial_num_hi, bi.serial_num_lo,
+                    bi->hw_rev, bi->serial_num_hi, bi->serial_num_lo,
                     pcan_usb_pro.ctrl_count);
-
-               /* tell the device the can driver is running */
-               pcan_usb_pro_drv_loaded(dev, 1);
        } else {
                usb_if = pcan_usb_pro_dev_if(dev->prev_siblings);
        }
@@ -916,6 +928,13 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
        pcan_usb_pro_set_led(dev, 0, 1);
 
        return 0;
+
+ err_out:
+       kfree(bi);
+       kfree(fi);
+       kfree(usb_if);
+
+       return err;
 }
 
 static void pcan_usb_pro_exit(struct peak_usb_device *dev)
index a869918..32275af 100644 (file)
@@ -29,6 +29,7 @@
 
 /* Vendor Request value for XXX_FCT */
 #define PCAN_USBPRO_FCT_DRVLD          5 /* tell device driver is loaded */
+#define PCAN_USBPRO_FCT_DRVLD_REQ_LEN  16
 
 /* PCAN_USBPRO_INFO_BL vendor request record type */
 struct __packed pcan_usb_pro_blinfo {
index be59ec4..638e554 100644 (file)
@@ -3192,11 +3192,11 @@ static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
                rc |= XMIT_CSUM_TCP;
 
        if (skb_is_gso_v6(skb)) {
-               rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6);
+               rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP);
                if (rc & XMIT_CSUM_ENC)
                        rc |= XMIT_GSO_ENC_V6;
        } else if (skb_is_gso(skb)) {
-               rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP);
+               rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP);
                if (rc & XMIT_CSUM_ENC)
                        rc |= XMIT_GSO_ENC_V4;
        }
@@ -3483,19 +3483,18 @@ static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
 {
        u16 hlen_w = 0;
        u8 outerip_off, outerip_len = 0;
+
        /* from outer IP to transport */
        hlen_w = (skb_inner_transport_header(skb) -
                  skb_network_header(skb)) >> 1;
 
        /* transport len */
-       if (xmit_type & XMIT_CSUM_TCP)
-               hlen_w += inner_tcp_hdrlen(skb) >> 1;
-       else
-               hlen_w += sizeof(struct udphdr) >> 1;
+       hlen_w += inner_tcp_hdrlen(skb) >> 1;
 
        pbd2->fw_ip_hdr_to_payload_w = hlen_w;
 
-       if (xmit_type & XMIT_CSUM_ENC_V4) {
+       /* outer IP header info */
+       if (xmit_type & XMIT_CSUM_V4) {
                struct iphdr *iph = ip_hdr(skb);
                pbd2->fw_ip_csum_wo_len_flags_frag =
                        bswab16(csum_fold((~iph->check) -
@@ -3818,8 +3817,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
                                             xmit_type);
                else
-                       bnx2x_set_pbd_gso(skb, pbd_e1x, tx_start_bd,
-                                         xmit_type);
+                       bnx2x_set_pbd_gso(skb, pbd_e1x, first_bd, xmit_type);
        }
 
        /* Set the PBD's parsing_data field if not zero
index 1f2dd92..c777b90 100644 (file)
@@ -1800,6 +1800,9 @@ static int tg3_poll_fw(struct tg3 *tp)
        int i;
        u32 val;
 
+       if (tg3_flag(tp, NO_FWARE_REPORTED))
+               return 0;
+
        if (tg3_flag(tp, IS_SSB_CORE)) {
                /* We don't use firmware. */
                return 0;
@@ -9468,6 +9471,14 @@ static void tg3_rss_write_indir_tbl(struct tg3 *tp)
        }
 }
 
+static inline u32 tg3_lso_rd_dma_workaround_bit(struct tg3 *tp)
+{
+       if (tg3_asic_rev(tp) == ASIC_REV_5719)
+               return TG3_LSO_RD_DMA_TX_LENGTH_WA_5719;
+       else
+               return TG3_LSO_RD_DMA_TX_LENGTH_WA_5720;
+}
+
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
 {
@@ -10153,16 +10164,17 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
        tw32_f(RDMAC_MODE, rdmac_mode);
        udelay(40);
 
-       if (tg3_asic_rev(tp) == ASIC_REV_5719) {
+       if (tg3_asic_rev(tp) == ASIC_REV_5719 ||
+           tg3_asic_rev(tp) == ASIC_REV_5720) {
                for (i = 0; i < TG3_NUM_RDMA_CHANNELS; i++) {
                        if (tr32(TG3_RDMA_LENGTH + (i << 2)) > TG3_MAX_MTU(tp))
                                break;
                }
                if (i < TG3_NUM_RDMA_CHANNELS) {
                        val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-                       val |= TG3_LSO_RD_DMA_TX_LENGTH_WA;
+                       val |= tg3_lso_rd_dma_workaround_bit(tp);
                        tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
-                       tg3_flag_set(tp, 5719_RDMA_BUG);
+                       tg3_flag_set(tp, 5719_5720_RDMA_BUG);
                }
        }
 
@@ -10395,6 +10407,13 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
  */
 static int tg3_init_hw(struct tg3 *tp, bool reset_phy)
 {
+       /* Chip may have been just powered on. If so, the boot code may still
+        * be running initialization. Wait for it to finish to avoid races in
+        * accessing the hardware.
+        */
+       tg3_enable_register_access(tp);
+       tg3_poll_fw(tp);
+
        tg3_switch_clocks(tp);
 
        tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
@@ -10526,15 +10545,15 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
        TG3_STAT_ADD32(&sp->tx_ucast_packets, MAC_TX_STATS_UCAST);
        TG3_STAT_ADD32(&sp->tx_mcast_packets, MAC_TX_STATS_MCAST);
        TG3_STAT_ADD32(&sp->tx_bcast_packets, MAC_TX_STATS_BCAST);
-       if (unlikely(tg3_flag(tp, 5719_RDMA_BUG) &&
+       if (unlikely(tg3_flag(tp, 5719_5720_RDMA_BUG) &&
                     (sp->tx_ucast_packets.low + sp->tx_mcast_packets.low +
                      sp->tx_bcast_packets.low) > TG3_NUM_RDMA_CHANNELS)) {
                u32 val;
 
                val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
-               val &= ~TG3_LSO_RD_DMA_TX_LENGTH_WA;
+               val &= ~tg3_lso_rd_dma_workaround_bit(tp);
                tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val);
-               tg3_flag_clear(tp, 5719_RDMA_BUG);
+               tg3_flag_clear(tp, 5719_5720_RDMA_BUG);
        }
 
        TG3_STAT_ADD32(&sp->rx_octets, MAC_RX_STATS_OCTETS);
index 9b2d3ac..ff6e30e 100644 (file)
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL     0x00004910
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K   0x00030000
 #define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K  0x000c0000
-#define TG3_LSO_RD_DMA_TX_LENGTH_WA     0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5719        0x02000000
+#define TG3_LSO_RD_DMA_TX_LENGTH_WA_5720        0x00200000
 /* 0x4914 --> 0x4be0 unused */
 
 #define TG3_NUM_RDMA_CHANNELS          4
@@ -3059,7 +3060,7 @@ enum TG3_FLAGS {
        TG3_FLAG_APE_HAS_NCSI,
        TG3_FLAG_TX_TSTAMP_EN,
        TG3_FLAG_4K_FIFO_LIMIT,
-       TG3_FLAG_5719_RDMA_BUG,
+       TG3_FLAG_5719_5720_RDMA_BUG,
        TG3_FLAG_RESET_TASK_PENDING,
        TG3_FLAG_PTP_CAPABLE,
        TG3_FLAG_5705_PLUS,
index 28a5e42..92306b3 100644 (file)
@@ -76,6 +76,12 @@ int tulip_refill_rx(struct net_device *dev)
 
                        mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
                                                 PCI_DMA_FROMDEVICE);
+                       if (dma_mapping_error(&tp->pdev->dev, mapping)) {
+                               dev_kfree_skb(skb);
+                               tp->rx_buffers[entry].skb = NULL;
+                               break;
+                       }
+
                        tp->rx_buffers[entry].mapping = mapping;
 
                        tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
index f544b29..0a51068 100644 (file)
@@ -262,6 +262,7 @@ struct be_rx_compl_info {
        u8 ipv6;
        u8 vtm;
        u8 pkt_type;
+       u8 ip_frag;
 };
 
 struct be_rx_obj {
index a236ecd..1db2df6 100644 (file)
@@ -562,7 +562,7 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
 
        resource_error = lancer_provisioning_error(adapter);
        if (resource_error)
-               return -1;
+               return -EAGAIN;
 
        status = lancer_wait_ready(adapter);
        if (!status) {
@@ -590,8 +590,8 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
         * when PF provisions resources.
         */
        resource_error = lancer_provisioning_error(adapter);
-       if (status == -1 && !resource_error)
-               adapter->eeh_error = true;
+       if (resource_error)
+               status = -EAGAIN;
 
        return status;
 }
index 3c1099b..8780183 100644 (file)
@@ -356,7 +356,7 @@ struct amap_eth_rx_compl_v0 {
        u8 ip_version;          /* dword 1 */
        u8 macdst[6];           /* dword 1 */
        u8 vtp;                 /* dword 1 */
-       u8 rsvd0;               /* dword 1 */
+       u8 ip_frag;             /* dword 1 */
        u8 fragndx[10];         /* dword 1 */
        u8 ct[2];               /* dword 1 */
        u8 sw;                  /* dword 1 */
index ca2967b..a0b4be5 100644 (file)
@@ -1599,6 +1599,8 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
                                               compl);
        }
        rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
+       rxcp->ip_frag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
+                                     ip_frag, compl);
 }
 
 static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -1620,6 +1622,9 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
        else
                be_parse_rx_compl_v0(compl, rxcp);
 
+       if (rxcp->ip_frag)
+               rxcp->l4_csum = 0;
+
        if (rxcp->vlanf) {
                /* vlanf could be wrongly set in some cards.
                 * ignore if vtm is not set */
@@ -2168,7 +2173,7 @@ static irqreturn_t be_msix(int irq, void *dev)
 
 static inline bool do_gro(struct be_rx_compl_info *rxcp)
 {
-       return (rxcp->tcpf && !rxcp->err) ? true : false;
+       return (rxcp->tcpf && !rxcp->err && rxcp->l4_csum) ? true : false;
 }
 
 static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
@@ -4093,6 +4098,7 @@ static int be_get_initial_config(struct be_adapter *adapter)
 
 static int lancer_recover_func(struct be_adapter *adapter)
 {
+       struct device *dev = &adapter->pdev->dev;
        int status;
 
        status = lancer_test_and_set_rdy_state(adapter);
@@ -4104,8 +4110,7 @@ static int lancer_recover_func(struct be_adapter *adapter)
 
        be_clear(adapter);
 
-       adapter->hw_error = false;
-       adapter->fw_timeout = false;
+       be_clear_all_error(adapter);
 
        status = be_setup(adapter);
        if (status)
@@ -4117,13 +4122,13 @@ static int lancer_recover_func(struct be_adapter *adapter)
                        goto err;
        }
 
-       dev_err(&adapter->pdev->dev,
-               "Adapter SLIPORT recovery succeeded\n");
+       dev_err(dev, "Error recovery successful\n");
        return 0;
 err:
-       if (adapter->eeh_error)
-               dev_err(&adapter->pdev->dev,
-                       "Adapter SLIPORT recovery failed\n");
+       if (status == -EAGAIN)
+               dev_err(dev, "Waiting for resource provisioning\n");
+       else
+               dev_err(dev, "Error recovery failed\n");
 
        return status;
 }
@@ -4132,28 +4137,27 @@ static void be_func_recovery_task(struct work_struct *work)
 {
        struct be_adapter *adapter =
                container_of(work, struct be_adapter,  func_recovery_work.work);
-       int status;
+       int status = 0;
 
        be_detect_error(adapter);
 
        if (adapter->hw_error && lancer_chip(adapter)) {
 
-               if (adapter->eeh_error)
-                       goto out;
-
                rtnl_lock();
                netif_device_detach(adapter->netdev);
                rtnl_unlock();
 
                status = lancer_recover_func(adapter);
-
                if (!status)
                        netif_device_attach(adapter->netdev);
        }
 
-out:
-       schedule_delayed_work(&adapter->func_recovery_work,
-                             msecs_to_jiffies(1000));
+       /* In Lancer, for all errors other than provisioning error (-EAGAIN),
+        * no need to attempt further recovery.
+        */
+       if (!status || status == -EAGAIN)
+               schedule_delayed_work(&adapter->func_recovery_work,
+                                     msecs_to_jiffies(1000));
 }
 
 static void be_worker(struct work_struct *work)
@@ -4258,6 +4262,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
                netdev->features |= NETIF_F_HIGHDMA;
        } else {
                status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+               if (!status)
+                       status = dma_set_coherent_mask(&pdev->dev,
+                                                      DMA_BIT_MASK(32));
                if (status) {
                        dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
                        goto free_netdev;
@@ -4436,20 +4443,19 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
 
        dev_err(&adapter->pdev->dev, "EEH error detected\n");
 
-       adapter->eeh_error = true;
+       if (!adapter->eeh_error) {
+               adapter->eeh_error = true;
 
-       cancel_delayed_work_sync(&adapter->func_recovery_work);
-
-       rtnl_lock();
-       netif_device_detach(netdev);
-       rtnl_unlock();
+               cancel_delayed_work_sync(&adapter->func_recovery_work);
 
-       if (netif_running(netdev)) {
                rtnl_lock();
-               be_close(netdev);
+               netif_device_detach(netdev);
+               if (netif_running(netdev))
+                       be_close(netdev);
                rtnl_unlock();
+
+               be_clear(adapter);
        }
-       be_clear(adapter);
 
        if (state == pci_channel_io_perm_failure)
                return PCI_ERS_RESULT_DISCONNECT;
@@ -4474,7 +4480,6 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
        int status;
 
        dev_info(&adapter->pdev->dev, "EEH reset\n");
-       be_clear_all_error(adapter);
 
        status = pci_enable_device(pdev);
        if (status)
@@ -4492,6 +4497,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
                return PCI_ERS_RESULT_DISCONNECT;
 
        pci_cleanup_aer_uncorrect_error_status(pdev);
+       be_clear_all_error(adapter);
        return PCI_ERS_RESULT_RECOVERED;
 }
 
index 85a0603..a667015 100644 (file)
@@ -1038,6 +1038,18 @@ static void fec_get_mac(struct net_device *ndev)
                iap = &tmpaddr[0];
        }
 
+       /*
+        * 5) random mac address
+        */
+       if (!is_valid_ether_addr(iap)) {
+               /* Report it and use a random ethernet address instead */
+               netdev_err(ndev, "Invalid MAC address: %pM\n", iap);
+               eth_hw_addr_random(ndev);
+               netdev_info(ndev, "Using random MAC address: %pM\n",
+                           ndev->dev_addr);
+               return;
+       }
+
        memcpy(ndev->dev_addr, iap, ETH_ALEN);
 
        /* Adjust MAC if using macaddr */
index 1df56cc..0e572a5 100644 (file)
@@ -222,8 +222,6 @@ static int mlx4_comm_cmd_poll(struct mlx4_dev *dev, u8 cmd, u16 param,
                 * FLR process. The only non-zero result in the RESET command
                 * is MLX4_DELAY_RESET_SLAVE*/
                if ((MLX4_COMM_CMD_RESET == cmd)) {
-                       mlx4_warn(dev, "Got slave FLRed from Communication"
-                                 " channel (ret:0x%x)\n", ret_from_pending);
                        err = MLX4_DELAY_RESET_SLAVE;
                } else {
                        mlx4_warn(dev, "Communication channel timed out\n");
index b35f947..89c47ea 100644 (file)
@@ -1323,6 +1323,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
                        priv->last_moder_time[ring] = moder_time;
                        cq = &priv->rx_cq[ring];
                        cq->moder_time = moder_time;
+                       cq->moder_cnt = priv->rx_frames;
                        err = mlx4_en_set_cq_moder(priv, cq);
                        if (err)
                                en_err(priv, "Failed modifying moderation for cq:%d\n",
@@ -2118,6 +2119,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        struct mlx4_en_priv *priv;
        int i;
        int err;
+       u64 mac_u64;
 
        dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv),
                                 MAX_TX_RINGS, MAX_RX_RINGS);
@@ -2191,10 +2193,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        dev->addr_len = ETH_ALEN;
        mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]);
        if (!is_valid_ether_addr(dev->dev_addr)) {
-               en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n",
-                      priv->port, dev->dev_addr);
-               err = -EINVAL;
-               goto out;
+               if (mlx4_is_slave(priv->mdev->dev)) {
+                       eth_hw_addr_random(dev);
+                       en_warn(priv, "Assigned random MAC address %pM\n", dev->dev_addr);
+                       mac_u64 = mlx4_en_mac_to_u64(dev->dev_addr);
+                       mdev->dev->caps.def_mac[priv->port] = mac_u64;
+               } else {
+                       en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n",
+                              priv->port, dev->dev_addr);
+                       err = -EINVAL;
+                       goto out;
+               }
        }
 
        memcpy(priv->prev_mac, dev->dev_addr, sizeof(priv->prev_mac));
index 58a8e53..2c97901 100644 (file)
@@ -840,12 +840,16 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
                           MLX4_CMD_NATIVE);
 
        if (!err && dev->caps.function != slave) {
-               /* set slave default_mac address */
-               MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET);
-               def_mac += slave << 8;
                /* if config MAC in DB use it */
                if (priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac)
                        def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac;
+               else {
+                       /* set slave default_mac address */
+                       MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET);
+                       def_mac += slave << 8;
+                       priv->mfunc.master.vf_admin[slave].vport[vhcr->in_modifier].mac = def_mac;
+               }
+
                MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET);
 
                /* get port type - currently only eth is enabled */
index 0d32a82..2f4a260 100644 (file)
@@ -1290,7 +1290,6 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        u64 dma = (u64) priv->mfunc.vhcr_dma;
-       int num_of_reset_retries = NUM_OF_RESET_RETRIES;
        int ret_from_reset = 0;
        u32 slave_read;
        u32 cmd_channel_ver;
@@ -1304,18 +1303,10 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
         * NUM_OF_RESET_RETRIES times before leaving.*/
        if (ret_from_reset) {
                if (MLX4_DELAY_RESET_SLAVE == ret_from_reset) {
-                       msleep(SLEEP_TIME_IN_RESET);
-                       while (ret_from_reset && num_of_reset_retries) {
-                               mlx4_warn(dev, "slave is currently in the"
-                                         "middle of FLR. retrying..."
-                                         "(try num:%d)\n",
-                                         (NUM_OF_RESET_RETRIES -
-                                          num_of_reset_retries  + 1));
-                               ret_from_reset =
-                                       mlx4_comm_cmd(dev, MLX4_COMM_CMD_RESET,
-                                                     0, MLX4_COMM_TIME);
-                               num_of_reset_retries = num_of_reset_retries - 1;
-                       }
+                       mlx4_warn(dev, "slave is currently in the "
+                                 "middle of FLR. Deferring probe.\n");
+                       mutex_unlock(&priv->cmd.slave_cmd_mutex);
+                       return -EPROBE_DEFER;
                } else
                        goto err;
        }
@@ -1526,7 +1517,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
        } else {
                err = mlx4_init_slave(dev);
                if (err) {
-                       mlx4_err(dev, "Failed to initialize slave\n");
+                       if (err != -EPROBE_DEFER)
+                               mlx4_err(dev, "Failed to initialize slave\n");
                        return err;
                }
 
index 50235d2..f87cc21 100644 (file)
@@ -4717,6 +4717,7 @@ static int qlge_probe(struct pci_dev *pdev,
                dev_err(&pdev->dev, "net device registration failed.\n");
                ql_release_all(pdev);
                pci_disable_device(pdev);
+               free_netdev(ndev);
                return err;
        }
        /* Start up the timer to trigger EEH if
index 42e9dd0..5e3982f 100644 (file)
@@ -897,8 +897,8 @@ static int sh_eth_check_reset(struct net_device *ndev)
                mdelay(1);
                cnt--;
        }
-       if (cnt < 0) {
-               pr_err("Device reset fail\n");
+       if (cnt <= 0) {
+               pr_err("Device reset failed\n");
                ret = -ETIMEDOUT;
        }
        return ret;
@@ -1401,16 +1401,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
                desc_status = edmac_to_cpu(mdp, rxdesc->status);
                pkt_len = rxdesc->frame_length;
 
-#if defined(CONFIG_ARCH_R8A7740)
-               desc_status >>= 16;
-#endif
-
                if (--boguscnt < 0)
                        break;
 
                if (!(desc_status & RDFEND))
                        ndev->stats.rx_length_errors++;
 
+#if defined(CONFIG_ARCH_R8A7740)
+               /*
+                * In case of almost all GETHER/ETHERs, the Receive Frame State
+                * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
+                * bit 0. However, in case of the R8A7740's GETHER, the RFS
+                * bits are from bit 25 to bit 16. So, the driver needs right
+                * shifting by 16.
+                */
+               desc_status >>= 16;
+#endif
+
                if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
                                   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
                        ndev->stats.rx_errors++;
index 618446a..ee919ca 100644 (file)
@@ -1899,7 +1899,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
 #ifdef STMMAC_XMIT_DEBUG
        if (netif_msg_pktdata(priv)) {
-               pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d"
+               pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d",
                        __func__, (priv->cur_tx % txsize),
                        (priv->dirty_tx % txsize), entry, first, nfrags);
                if (priv->extend_desc)
index 12aec17..c47f0db 100644 (file)
@@ -449,10 +449,9 @@ static int davinci_mdio_suspend(struct device *dev)
        __raw_writel(ctrl, &data->regs->control);
        wait_for_idle(data);
 
-       pm_runtime_put_sync(data->dev);
-
        data->suspended = true;
        spin_unlock(&data->lock);
+       pm_runtime_put_sync(data->dev);
 
        return 0;
 }
@@ -460,15 +459,12 @@ static int davinci_mdio_suspend(struct device *dev)
 static int davinci_mdio_resume(struct device *dev)
 {
        struct davinci_mdio_data *data = dev_get_drvdata(dev);
-       u32 ctrl;
 
-       spin_lock(&data->lock);
        pm_runtime_get_sync(data->dev);
 
+       spin_lock(&data->lock);
        /* restart the scan state machine */
-       ctrl = __raw_readl(&data->regs->control);
-       ctrl |= CONTROL_ENABLE;
-       __raw_writel(ctrl, &data->regs->control);
+       __davinci_mdio_reset(data);
 
        data->suspended = false;
        spin_unlock(&data->lock);
@@ -477,8 +473,8 @@ static int davinci_mdio_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops davinci_mdio_pm_ops = {
-       .suspend        = davinci_mdio_suspend,
-       .resume         = davinci_mdio_resume,
+       .suspend_late   = davinci_mdio_suspend,
+       .resume_early   = davinci_mdio_resume,
 };
 
 static const struct of_device_id davinci_mdio_of_mtable[] = {
index 919b983..b7268b3 100644 (file)
@@ -946,7 +946,8 @@ static int xemaclite_open(struct net_device *dev)
                phy_write(lp->phy_dev, MII_CTRL1000, 0);
 
                /* Advertise only 10 and 100mbps full/half duplex speeds */
-               phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL);
+               phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL |
+                         ADVERTISE_CSMA);
 
                /* Restart auto negotiation */
                bmcr = phy_read(lp->phy_dev, MII_BMCR);
index 088c554..ab2307b 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/inetdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/if_vlan.h>
 #include <linux/in.h>
 #include <linux/slab.h>
 #include <net/arp.h>
@@ -284,7 +285,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 
        skb->protocol = eth_type_trans(skb, net);
        skb->ip_summed = CHECKSUM_NONE;
-       skb->vlan_tci = packet->vlan_tci;
+       __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), packet->vlan_tci);
 
        net->stats.rx_packets++;
        net->stats.rx_bytes += packet->total_data_buflen;
index 1c502bb..6e91931 100644 (file)
@@ -853,18 +853,24 @@ static int macvlan_changelink(struct net_device *dev,
                struct nlattr *tb[], struct nlattr *data[])
 {
        struct macvlan_dev *vlan = netdev_priv(dev);
-       if (data && data[IFLA_MACVLAN_MODE])
-               vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+
        if (data && data[IFLA_MACVLAN_FLAGS]) {
                __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
                bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC;
-
-               if (promisc && (flags & MACVLAN_FLAG_NOPROMISC))
-                       dev_set_promiscuity(vlan->lowerdev, -1);
-               else if (promisc && !(flags & MACVLAN_FLAG_NOPROMISC))
-                       dev_set_promiscuity(vlan->lowerdev, 1);
+               if (vlan->port->passthru && promisc) {
+                       int err;
+
+                       if (flags & MACVLAN_FLAG_NOPROMISC)
+                               err = dev_set_promiscuity(vlan->lowerdev, -1);
+                       else
+                               err = dev_set_promiscuity(vlan->lowerdev, 1);
+                       if (err < 0)
+                               return err;
+               }
                vlan->flags = flags;
        }
+       if (data && data[IFLA_MACVLAN_MODE])
+               vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
        return 0;
 }
 
index c14f147..38f0b31 100644 (file)
@@ -1044,7 +1044,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
                adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
                lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
                idx = phy_find_setting(phydev->speed, phydev->duplex);
-               if ((lp & adv & settings[idx].setting))
+               if (!(lp & adv & settings[idx].setting))
                        goto eee_exit;
 
                if (clk_stop_enable) {
index 7c43261..b305105 100644 (file)
@@ -1092,8 +1092,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
        }
 
        port->index = -1;
-       team_port_enable(team, port);
        list_add_tail_rcu(&port->list, &team->port_list);
+       team_port_enable(team, port);
        __team_compute_features(team);
        __team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
        __team_options_change_check(team);
@@ -2374,7 +2374,8 @@ static int team_nl_send_port_list_get(struct team *team, u32 portid, u32 seq,
        bool incomplete;
        int i;
 
-       port = list_first_entry(&team->port_list, struct team_port, list);
+       port = list_first_entry_or_null(&team->port_list,
+                                       struct team_port, list);
 
 start_again:
        err = __send_and_alloc_skb(&skb, team, portid, send_func);
@@ -2402,8 +2403,8 @@ start_again:
                err = team_nl_fill_one_port_get(skb, one_port);
                if (err)
                        goto errout;
-       } else {
-               list_for_each_entry(port, &team->port_list, list) {
+       } else if (port) {
+               list_for_each_entry_from(port, &team->port_list, list) {
                        err = team_nl_fill_one_port_get(skb, port);
                        if (err) {
                                if (err == -EMSGSIZE) {
index 5ca14d4..7f032e2 100644 (file)
@@ -28,6 +28,8 @@ static bool rnd_transmit(struct team *team, struct sk_buff *skb)
 
        port_index = random_N(team->en_port_count);
        port = team_get_port_by_index_rcu(team, port_index);
+       if (unlikely(!port))
+               goto drop;
        port = team_get_first_port_txable_rcu(team, port);
        if (unlikely(!port))
                goto drop;
index d268e4d..472623f 100644 (file)
@@ -32,6 +32,8 @@ static bool rr_transmit(struct team *team, struct sk_buff *skb)
 
        port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
        port = team_get_port_by_index_rcu(team, port_index);
+       if (unlikely(!port))
+               goto drop;
        port = team_get_first_port_txable_rcu(team, port);
        if (unlikely(!port))
                goto drop;
index f042b03..bfa9bb4 100644 (file)
@@ -352,7 +352,7 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb)
        u32 numqueues = 0;
 
        rcu_read_lock();
-       numqueues = tun->numqueues;
+       numqueues = ACCESS_ONCE(tun->numqueues);
 
        txq = skb_get_rxhash(skb);
        if (txq) {
@@ -1585,6 +1585,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                else
                        return -EINVAL;
 
+               if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) !=
+                   !!(tun->flags & TUN_TAP_MQ))
+                       return -EINVAL;
+
                if (tun_not_capable(tun))
                        return -EPERM;
                err = security_tun_dev_open(tun->security);
@@ -2155,6 +2159,8 @@ static int tun_chr_open(struct inode *inode, struct file * file)
        set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags);
        INIT_LIST_HEAD(&tfile->next);
 
+       sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
+
        return 0;
 }
 
index 078795f..04ee044 100644 (file)
@@ -627,6 +627,12 @@ static const struct usb_device_id  products [] = {
        .driver_info = 0,
 },
 
+/* Huawei E1820 - handled by qmi_wwan */
+{
+       USB_DEVICE_INTERFACE_NUMBER(HUAWEI_VENDOR_ID, 0x14ac, 1),
+       .driver_info = 0,
+},
+
 /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
 #if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE)
 {
index 86adfa0..d095d0d 100644 (file)
@@ -519,6 +519,7 @@ static const struct usb_device_id products[] = {
        /* 3. Combined interface devices matching on interface number */
        {QMI_FIXED_INTF(0x0408, 0xea42, 4)},    /* Yota / Megafon M100-1 */
        {QMI_FIXED_INTF(0x12d1, 0x140c, 1)},    /* Huawei E173 */
+       {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)},    /* Huawei E1820 */
        {QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
        {QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
        {QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
index f3dc124..3c2cbc9 100644 (file)
@@ -92,13 +92,17 @@ config ATH9K_MAC_DEBUG
          This option enables collection of statistics for Rx/Tx status
          data and some other MAC related statistics
 
-config ATH9K_RATE_CONTROL
+config ATH9K_LEGACY_RATE_CONTROL
        bool "Atheros ath9k rate control"
        depends on ATH9K
-       default y
+       default n
        ---help---
          Say Y, if you want to use the ath9k specific rate control
-         module instead of minstrel_ht.
+         module instead of minstrel_ht. Be warned that there are various
+         issues with the ath9k RC and minstrel is a more robust algorithm.
+         Note that even if this option is selected, "ath9k_rate_control"
+         has to be passed to mac80211 using the module parameter,
+         ieee80211_default_rc_algo.
 
 config ATH9K_HTC
        tristate "Atheros HTC based wireless cards support"
index 2ad8f94..75ee9e7 100644 (file)
@@ -8,7 +8,7 @@ ath9k-y +=      beacon.o \
                antenna.o
 
 ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
-ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
+ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
 ath9k-$(CONFIG_ATH9K_PCI) += pci.o
 ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
index db5ffad..7546b9a 100644 (file)
@@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
        {0x0000a074, 0x00000000},
        {0x0000a078, 0x00000000},
        {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x1a1a1a1a},
-       {0x0000a084, 0x1a1a1a1a},
-       {0x0000a088, 0x1a1a1a1a},
-       {0x0000a08c, 0x1a1a1a1a},
-       {0x0000a090, 0x171a1a1a},
+       {0x0000a080, 0x22222229},
+       {0x0000a084, 0x1d1d1d1d},
+       {0x0000a088, 0x1d1d1d1d},
+       {0x0000a08c, 0x1d1d1d1d},
+       {0x0000a090, 0x171d1d1d},
        {0x0000a094, 0x11111717},
        {0x0000a098, 0x00030311},
        {0x0000a09c, 0x00000000},
index 54ba42f..874f657 100644 (file)
 #define AR9300_BASE_ADDR 0x3ff
 #define AR9300_BASE_ADDR_512 0x1ff
 
-#define AR9300_OTP_BASE                        (AR_SREV_9340(ah) ? 0x30000 : 0x14000)
-#define AR9300_OTP_STATUS              (AR_SREV_9340(ah) ? 0x30018 : 0x15f18)
+#define AR9300_OTP_BASE \
+               ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
+#define AR9300_OTP_STATUS \
+               ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
 #define AR9300_OTP_STATUS_TYPE         0x7
 #define AR9300_OTP_STATUS_VALID                0x4
 #define AR9300_OTP_STATUS_ACCESS_BUSY  0x2
 #define AR9300_OTP_STATUS_SM_BUSY      0x1
-#define AR9300_OTP_READ_DATA           (AR_SREV_9340(ah) ? 0x3001c : 0x15f1c)
+#define AR9300_OTP_READ_DATA \
+               ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
 
 enum targetPowerHTRates {
        HT_TARGET_RATE_0_8_16,
index 2bf6548..e1714d7 100644 (file)
@@ -334,7 +334,8 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
        REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
                      AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
 
-       if (REG_READ_FIELD(ah, AR_PHY_MODE,
+       if (!AR_SREV_9340(ah) &&
+           REG_READ_FIELD(ah, AR_PHY_MODE,
                           AR_PHY_MODE_DYNAMIC) == 0x1)
                REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
                              AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
index 366002f..42b03dc 100644 (file)
@@ -251,10 +251,9 @@ struct ath_atx_tid {
        int tidno;
        int baw_head;   /* first un-acked tx buffer */
        int baw_tail;   /* next unused tx buffer slot */
-       int sched;
-       int paused;
-       u8 state;
-       bool stop_cb;
+       bool sched;
+       bool paused;
+       bool active;
 };
 
 struct ath_node {
@@ -275,10 +274,6 @@ struct ath_node {
 #endif
 };
 
-#define AGGR_CLEANUP         BIT(1)
-#define AGGR_ADDBA_COMPLETE  BIT(2)
-#define AGGR_ADDBA_PROGRESS  BIT(3)
-
 struct ath_tx_control {
        struct ath_txq *txq;
        struct ath_node *an;
@@ -352,8 +347,7 @@ void ath_tx_tasklet(struct ath_softc *sc);
 void ath_tx_edma_tasklet(struct ath_softc *sc);
 int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
                      u16 tid, u16 *ssn);
-bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
-                     bool flush);
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 
 void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
index 7f25da8..15dfefc 100644 (file)
@@ -1172,6 +1172,7 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
 static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
+       int txbuf_size;
 
        ENABLE_REGWRITE_BUFFER(ah);
 
@@ -1225,13 +1226,17 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
                 * So set the usable tx buf size also to half to
                 * avoid data/delimiter underruns
                 */
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
-       } else if (!AR_SREV_9271(ah)) {
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+               txbuf_size = AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE;
+       } else if (AR_SREV_9340_13_OR_LATER(ah)) {
+               /* Uses fewer entries for AR934x v1.3+ to prevent rx overruns */
+               txbuf_size = AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE;
+       } else {
+               txbuf_size = AR_PCU_TXBUF_CTRL_USABLE_SIZE;
        }
 
+       if (!AR_SREV_9271(ah))
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL, txbuf_size);
+
        REGWRITE_BUFFER_FLUSH(ah);
 
        if (AR_SREV_9300_20_OR_LATER(ah))
@@ -1306,9 +1311,13 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
                        AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
        } else {
                tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-               if (tmpReg &
-                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
-                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+               if (AR_SREV_9340(ah))
+                       tmpReg &= AR9340_INTR_SYNC_LOCAL_TIMEOUT;
+               else
+                       tmpReg &= AR_INTR_SYNC_LOCAL_TIMEOUT |
+                                 AR_INTR_SYNC_RADM_CPL_TIMEOUT;
+
+               if (tmpReg) {
                        u32 val;
                        REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
 
index aba4151..2ba4945 100644 (file)
@@ -787,8 +787,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        hw->wiphy->iface_combinations = if_comb;
        hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
 
-       if (AR_SREV_5416(sc->sc_ah))
-               hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+       hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
        hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
        hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
@@ -830,10 +829,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
        sc->ant_rx = hw->wiphy->available_antennas_rx;
        sc->ant_tx = hw->wiphy->available_antennas_tx;
 
-#ifdef CONFIG_ATH9K_RATE_CONTROL
-       hw->rate_control_algorithm = "ath9k_rate_control";
-#endif
-
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
                        &sc->sbands[IEEE80211_BAND_2GHZ];
index 498fee0..566109a 100644 (file)
@@ -410,7 +410,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 
        REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
 
-       if (AR_SREV_9340(ah))
+       if (AR_SREV_9340(ah) && !AR_SREV_9340_13_OR_LATER(ah))
                REG_WRITE(ah, AR_DMISC(q),
                          AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
        else
index 2382d12..5092eca 100644 (file)
@@ -1709,7 +1709,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                flush = true;
        case IEEE80211_AMPDU_TX_STOP_CONT:
                ath9k_ps_wakeup(sc);
-               if (ath_tx_aggr_stop(sc, sta, tid, flush))
+               ath_tx_aggr_stop(sc, sta, tid);
+               if (!flush)
                        ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                ath9k_ps_restore(sc);
                break;
index aa4d368..7eb1f4b 100644 (file)
@@ -1227,10 +1227,7 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
                return false;
 
        txtid = ATH_AN_2_TID(an, tidno);
-
-       if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
-                       return true;
-       return false;
+       return !txtid->active;
 }
 
 
index 267dbfc..b9a8738 100644 (file)
@@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
 }
 #endif
 
-#ifdef CONFIG_ATH9K_RATE_CONTROL
+#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
 int ath_rate_control_register(void);
 void ath_rate_control_unregister(void);
 #else
index 5c4ab50..f7c90cc 100644 (file)
 #define AR_SREV_REVISION_9485_10       0
 #define AR_SREV_REVISION_9485_11        1
 #define AR_SREV_VERSION_9340           0x300
+#define AR_SREV_REVISION_9340_10       0
+#define AR_SREV_REVISION_9340_11       1
+#define AR_SREV_REVISION_9340_12       2
+#define AR_SREV_REVISION_9340_13       3
 #define AR_SREV_VERSION_9580           0x1C0
 #define AR_SREV_REVISION_9580_10       4 /* AR9580 1.0 */
 #define AR_SREV_VERSION_9462           0x280
 #define AR_SREV_9340(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
 
+#define AR_SREV_9340_13_OR_LATER(_ah) \
+       (AR_SREV_9340((_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13))
+
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
      ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
@@ -1007,6 +1015,8 @@ enum {
                                AR_INTR_SYNC_LOCAL_TIMEOUT |
                                AR_INTR_SYNC_MAC_SLEEP_ACCESS),
 
+       AR9340_INTR_SYNC_LOCAL_TIMEOUT = 0x00000010,
+
        AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
 
 };
@@ -1881,6 +1891,7 @@ enum {
 #define AR_PCU_TXBUF_CTRL_SIZE_MASK     0x7FF
 #define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
+#define AR_9340_PCU_TXBUF_CTRL_USABLE_SIZE   0x500
 
 #define AR_PCU_MISC_MODE2               0x8344
 #define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
index 14bb335..1c9b1ba 100644 (file)
@@ -125,24 +125,6 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
        list_add_tail(&ac->list, &txq->axq_acq);
 }
 
-static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = tid->ac->txq;
-
-       WARN_ON(!tid->paused);
-
-       ath_txq_lock(sc, txq);
-       tid->paused = false;
-
-       if (skb_queue_empty(&tid->buf_q))
-               goto unlock;
-
-       ath_tx_queue_tid(txq, tid);
-       ath_txq_schedule(sc, txq);
-unlock:
-       ath_txq_unlock_complete(sc, txq);
-}
-
 static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
 {
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -164,20 +146,7 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
                               ARRAY_SIZE(bf->rates));
 }
 
-static void ath_tx_clear_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       tid->state &= ~AGGR_ADDBA_COMPLETE;
-       tid->state &= ~AGGR_CLEANUP;
-       if (!tid->stop_cb)
-               return;
-
-       ieee80211_start_tx_ba_cb_irqsafe(tid->an->vif, tid->an->sta->addr,
-                                        tid->tidno);
-       tid->stop_cb = false;
-}
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
-                            bool flush_packets)
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
        struct ath_txq *txq = tid->ac->txq;
        struct sk_buff *skb;
@@ -194,15 +163,16 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
        while ((skb = __skb_dequeue(&tid->buf_q))) {
                fi = get_frame_info(skb);
                bf = fi->bf;
-               if (!bf && !flush_packets)
-                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 
                if (!bf) {
-                       ieee80211_free_txskb(sc->hw, skb);
-                       continue;
+                       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
+                       if (!bf) {
+                               ieee80211_free_txskb(sc->hw, skb);
+                               continue;
+                       }
                }
 
-               if (fi->retries || flush_packets) {
+               if (fi->retries) {
                        list_add_tail(&bf->list, &bf_head);
                        ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
                        ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -213,10 +183,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid,
                }
        }
 
-       if (tid->baw_head == tid->baw_tail)
-               ath_tx_clear_tid(sc, tid);
-
-       if (sendbar && !flush_packets) {
+       if (sendbar) {
                ath_txq_unlock(sc, txq);
                ath_send_bar(tid, tid->seq_start);
                ath_txq_lock(sc, txq);
@@ -499,19 +466,19 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                tx_info = IEEE80211_SKB_CB(skb);
                fi = get_frame_info(skb);
 
-               if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
+               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
+                       /*
+                        * Outside of the current BlockAck window,
+                        * maybe part of a previous session
+                        */
+                       txfail = 1;
+               } else if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, seqno))) {
                        /* transmit completion, subframe is
                         * acked by block ack */
                        acked_cnt++;
                } else if (!isaggr && txok) {
                        /* transmit completion */
                        acked_cnt++;
-               } else if (tid->state & AGGR_CLEANUP) {
-                       /*
-                        * cleanup in progress, just fail
-                        * the un-acked sub-frames
-                        */
-                       txfail = 1;
                } else if (flush) {
                        txpending = 1;
                } else if (fi->retries < ATH_MAX_SW_RETRIES) {
@@ -535,7 +502,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                if (bf_next != NULL || !bf_last->bf_stale)
                        list_move_tail(&bf->list, &bf_head);
 
-               if (!txpending || (tid->state & AGGR_CLEANUP)) {
+               if (!txpending) {
                        /*
                         * complete the acked-ones/xretried ones; update
                         * block-ack window
@@ -609,9 +576,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
                ath_txq_lock(sc, txq);
        }
 
-       if (tid->state & AGGR_CLEANUP)
-               ath_tx_flush_tid(sc, tid, false);
-
        rcu_read_unlock();
 
        if (needreset)
@@ -1244,9 +1208,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
        an = (struct ath_node *)sta->drv_priv;
        txtid = ATH_AN_2_TID(an, tid);
 
-       if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
-               return -EAGAIN;
-
        /* update ampdu factor/density, they may have changed. This may happen
         * in HT IBSS when a beacon with HT-info is received after the station
         * has already been added.
@@ -1258,7 +1219,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
                an->mpdudensity = density;
        }
 
-       txtid->state |= AGGR_ADDBA_PROGRESS;
+       txtid->active = true;
        txtid->paused = true;
        *ssn = txtid->seq_start = txtid->seq_next;
        txtid->bar_index = -1;
@@ -1269,45 +1230,17 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
        return 0;
 }
 
-bool ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid,
-                     bool flush)
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
        struct ath_node *an = (struct ath_node *)sta->drv_priv;
        struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
        struct ath_txq *txq = txtid->ac->txq;
-       bool ret = !flush;
-
-       if (flush)
-               txtid->stop_cb = false;
-
-       if (txtid->state & AGGR_CLEANUP)
-               return false;
-
-       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-               txtid->state &= ~AGGR_ADDBA_PROGRESS;
-               return ret;
-       }
 
        ath_txq_lock(sc, txq);
+       txtid->active = false;
        txtid->paused = true;
-
-       /*
-        * If frames are still being transmitted for this TID, they will be
-        * cleaned up during tx completion. To prevent race conditions, this
-        * TID can only be reused after all in-progress subframes have been
-        * completed.
-        */
-       if (txtid->baw_head != txtid->baw_tail) {
-               txtid->state |= AGGR_CLEANUP;
-               ret = false;
-               txtid->stop_cb = !flush;
-       } else {
-               txtid->state &= ~AGGR_ADDBA_COMPLETE;
-       }
-
-       ath_tx_flush_tid(sc, txtid, flush);
+       ath_tx_flush_tid(sc, txtid);
        ath_txq_unlock_complete(sc, txq);
-       return ret;
 }
 
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
@@ -1371,18 +1304,28 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
        }
 }
 
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
+                       u16 tidno)
 {
-       struct ath_atx_tid *txtid;
+       struct ath_atx_tid *tid;
        struct ath_node *an;
+       struct ath_txq *txq;
 
        an = (struct ath_node *)sta->drv_priv;
+       tid = ATH_AN_2_TID(an, tidno);
+       txq = tid->ac->txq;
 
-       txtid = ATH_AN_2_TID(an, tid);
-       txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-       txtid->state |= AGGR_ADDBA_COMPLETE;
-       txtid->state &= ~AGGR_ADDBA_PROGRESS;
-       ath_tx_resume_tid(sc, txtid);
+       ath_txq_lock(sc, txq);
+
+       tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+       tid->paused = false;
+
+       if (!skb_queue_empty(&tid->buf_q)) {
+               ath_tx_queue_tid(txq, tid);
+               ath_txq_schedule(sc, txq);
+       }
+
+       ath_txq_unlock_complete(sc, txq);
 }
 
 /********************/
@@ -2431,13 +2374,10 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
                tid->baw_head  = tid->baw_tail = 0;
                tid->sched     = false;
                tid->paused    = false;
-               tid->state &= ~AGGR_CLEANUP;
+               tid->active        = false;
                __skb_queue_head_init(&tid->buf_q);
                acno = TID_TO_WME_AC(tidno);
                tid->ac = &an->ac[acno];
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
-               tid->state &= ~AGGR_ADDBA_PROGRESS;
-               tid->stop_cb = false;
        }
 
        for (acno = 0, ac = &an->ac[acno];
@@ -2474,7 +2414,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
                }
 
                ath_tid_drain(sc, txq, tid);
-               ath_tx_clear_tid(sc, tid);
+               tid->active = false;
 
                ath_txq_unlock(sc, txq);
        }
index 830bb1d..b827d51 100644 (file)
@@ -1624,7 +1624,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
 
        netif_carrier_off(dev);
 
-       if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv));
+       if (!proc_create_data("driver/atmel", 0, NULL, &atmel_proc_fops, priv))
                printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
 
        printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
index 6dd07e2..a95b77a 100644 (file)
@@ -2458,7 +2458,7 @@ static void b43_request_firmware(struct work_struct *work)
        for (i = 0; i < B43_NR_FWTYPES; i++) {
                errmsg = ctx->errors[i];
                if (strlen(errmsg))
-                       b43err(dev->wl, errmsg);
+                       b43err(dev->wl, "%s", errmsg);
        }
        b43_print_fw_helptext(dev->wl, 1);
        goto out;
index be0787c..9431af2 100644 (file)
@@ -27,7 +27,6 @@
 #include "tracepoint.h"
 
 #define PKTFILTER_BUF_SIZE             128
-#define BRCMF_ARPOL_MODE               0xb     /* agent|snoop|peer_autoreply */
 #define BRCMF_DEFAULT_BCN_TIMEOUT      3
 #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME        40
 #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME        40
@@ -338,23 +337,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
                goto done;
        }
 
-       /* Try to set and enable ARP offload feature, this may fail */
-       err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE);
-       if (err) {
-               brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
-                         BRCMF_ARPOL_MODE, err);
-               err = 0;
-       } else {
-               err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1);
-               if (err) {
-                       brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n",
-                                 err);
-                       err = 0;
-               } else
-                       brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n",
-                                 BRCMF_ARPOL_MODE);
-       }
-
        /* Setup packet filter */
        brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER);
        brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
index 59c2546..b98f223 100644 (file)
@@ -653,10 +653,13 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
 
        brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
 
+       ndev->destructor = free_netdev;
        return 0;
 
 fail:
+       drvr->iflist[ifp->bssidx] = NULL;
        ndev->netdev_ops = NULL;
+       free_netdev(ndev);
        return -EBADE;
 }
 
@@ -720,6 +723,9 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
        return 0;
 
 fail:
+       ifp->drvr->iflist[ifp->bssidx] = NULL;
+       ndev->netdev_ops = NULL;
+       free_netdev(ndev);
        return -EBADE;
 }
 
@@ -788,6 +794,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
        struct brcmf_if *ifp;
 
        ifp = drvr->iflist[bssidx];
+       drvr->iflist[bssidx] = NULL;
        if (!ifp) {
                brcmf_err("Null interface, idx=%d\n", bssidx);
                return;
@@ -808,15 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
                        cancel_work_sync(&ifp->setmacaddr_work);
                        cancel_work_sync(&ifp->multicast_work);
                }
-
+               /* unregister will take care of freeing it */
                unregister_netdev(ifp->ndev);
                if (bssidx == 0)
                        brcmf_cfg80211_detach(drvr->config);
-               free_netdev(ifp->ndev);
        } else {
                kfree(ifp);
        }
-       drvr->iflist[bssidx] = NULL;
 }
 
 int brcmf_attach(uint bus_hdrlen, struct device *dev)
@@ -925,8 +930,6 @@ fail:
                        brcmf_fws_del_interface(ifp);
                        brcmf_fws_deinit(drvr);
                }
-               free_netdev(ifp->ndev);
-               drvr->iflist[0] = NULL;
                if (p2p_ifp) {
                        free_netdev(p2p_ifp->ndev);
                        drvr->iflist[1] = NULL;
@@ -934,7 +937,8 @@ fail:
                return ret;
        }
        if ((brcmf_p2p_enable) && (p2p_ifp))
-               brcmf_net_p2p_attach(p2p_ifp);
+               if (brcmf_net_p2p_attach(p2p_ifp) < 0)
+                       brcmf_p2p_enable = 0;
 
        return 0;
 }
index 5a64280..83ee53a 100644 (file)
@@ -202,7 +202,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
                        return;
                brcmf_fws_add_interface(ifp);
                if (!drvr->fweh.evt_handler[BRCMF_E_IF])
-                       err = brcmf_net_attach(ifp, false);
+                       if (brcmf_net_attach(ifp, false) < 0)
+                               return;
        }
 
        if (ifevent->action == BRCMF_E_IF_CHANGE)
index 0f2c83b..665ef69 100644 (file)
 
 #define BRCMF_FIL_ACTION_FRAME_SIZE    1800
 
+/* ARP Offload feature flags for arp_ol iovar */
+#define BRCMF_ARP_OL_AGENT             0x00000001
+#define BRCMF_ARP_OL_SNOOP             0x00000002
+#define BRCMF_ARP_OL_HOST_AUTO_REPLY   0x00000004
+#define BRCMF_ARP_OL_PEER_AUTO_REPLY   0x00000008
+
 
 enum brcmf_fil_p2p_if_types {
        BRCMF_FIL_P2P_IF_CLIENT,
index e7a1a47..79555f0 100644 (file)
@@ -47,6 +47,7 @@
 #define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
                                         (channel == SOCIAL_CHAN_2) || \
                                         (channel == SOCIAL_CHAN_3))
+#define BRCMF_P2P_TEMP_CHAN    SOCIAL_CHAN_3
 #define SOCIAL_CHAN_CNT                3
 #define AF_PEER_SEARCH_CNT     2
 
@@ -1954,21 +1955,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
                err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
                if (err < 0) {
                        brcmf_err("set p2p_disc error\n");
-                       brcmf_free_vif(p2p_vif);
+                       brcmf_free_vif(cfg, p2p_vif);
                        goto exit;
                }
                /* obtain bsscfg index for P2P discovery */
                err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
                if (err < 0) {
                        brcmf_err("retrieving discover bsscfg index failed\n");
-                       brcmf_free_vif(p2p_vif);
+                       brcmf_free_vif(cfg, p2p_vif);
                        goto exit;
                }
                /* Verify that firmware uses same bssidx as driver !! */
                if (p2p_ifp->bssidx != bssidx) {
                        brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
                                  bssidx, p2p_ifp->bssidx);
-                       brcmf_free_vif(p2p_vif);
+                       brcmf_free_vif(cfg, p2p_vif);
                        goto exit;
                }
 
@@ -1996,7 +1997,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p)
                brcmf_p2p_cancel_remain_on_channel(vif->ifp);
                brcmf_p2p_deinit_discovery(p2p);
                /* remove discovery interface */
-               brcmf_free_vif(vif);
+               brcmf_free_vif(p2p->cfg, vif);
                p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
        }
        /* just set it all to zero */
@@ -2013,17 +2014,30 @@ static void brcmf_p2p_get_current_chanspec(struct brcmf_p2p_info *p2p,
                                           u16 *chanspec)
 {
        struct brcmf_if *ifp;
-       struct brcmf_fil_chan_info_le ci;
+       u8 mac_addr[ETH_ALEN];
        struct brcmu_chan ch;
-       s32 err;
+       struct brcmf_bss_info_le *bi;
+       u8 *buf;
 
        ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
 
-       ch.chnum = 11;
-
-       err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, &ci, sizeof(ci));
-       if (!err)
-               ch.chnum = le32_to_cpu(ci.hw_channel);
+       if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mac_addr,
+                                  ETH_ALEN) == 0) {
+               buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+               if (buf != NULL) {
+                       *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+                       if (brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
+                                                  buf, WL_BSS_INFO_MAX) == 0) {
+                               bi = (struct brcmf_bss_info_le *)(buf + 4);
+                               *chanspec = le16_to_cpu(bi->chanspec);
+                               kfree(buf);
+                               return;
+                       }
+                       kfree(buf);
+               }
+       }
+       /* Use default channel for P2P */
+       ch.chnum = BRCMF_P2P_TEMP_CHAN;
        ch.bw = BRCMU_CHAN_BW_20;
        p2p->cfg->d11inf.encchspec(&ch);
        *chanspec = ch.chspec;
@@ -2208,7 +2222,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
        return &p2p_vif->wdev;
 
 fail:
-       brcmf_free_vif(p2p_vif);
+       brcmf_free_vif(p2p->cfg, p2p_vif);
        return ERR_PTR(err);
 }
 
@@ -2217,13 +2231,31 @@ fail:
  *
  * @vif: virtual interface object to delete.
  */
-static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_vif *vif)
+static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg,
+                                   struct brcmf_cfg80211_vif *vif)
 {
-       struct brcmf_p2p_info *p2p = &vif->ifp->drvr->config->p2p;
-
        cfg80211_unregister_wdev(&vif->wdev);
-       p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
-       brcmf_free_vif(vif);
+       cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
+       brcmf_free_vif(cfg, vif);
+}
+
+/**
+ * brcmf_p2p_free_p2p_if() - free up net device related data.
+ *
+ * @ndev: net device that needs to be freed.
+ */
+static void brcmf_p2p_free_p2p_if(struct net_device *ndev)
+{
+       struct brcmf_cfg80211_info *cfg;
+       struct brcmf_cfg80211_vif *vif;
+       struct brcmf_if *ifp;
+
+       ifp = netdev_priv(ndev);
+       cfg = ifp->drvr->config;
+       vif = ifp->vif;
+
+       brcmf_free_vif(cfg, vif);
+       free_netdev(ifp->ndev);
 }
 
 /**
@@ -2303,6 +2335,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
                brcmf_err("Registering netdevice failed\n");
                goto fail;
        }
+       /* override destructor */
+       ifp->ndev->destructor = brcmf_p2p_free_p2p_if;
+
        cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
        /* Disable firmware roaming for P2P interface  */
        brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
@@ -2314,7 +2349,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
        return &ifp->vif->wdev;
 
 fail:
-       brcmf_free_vif(vif);
+       brcmf_free_vif(cfg, vif);
        return ERR_PTR(err);
 }
 
@@ -2350,7 +2385,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
                break;
 
        case NL80211_IFTYPE_P2P_DEVICE:
-               brcmf_p2p_delete_p2pdev(vif);
+               brcmf_p2p_delete_p2pdev(cfg, vif);
                return 0;
        default:
                return -ENOTSUPP;
@@ -2378,7 +2413,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
                        err = 0;
        }
        brcmf_cfg80211_arm_vif_event(cfg, NULL);
-       brcmf_free_vif(vif);
        p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
 
        return err;
index 761f501..301e572 100644 (file)
@@ -459,6 +459,38 @@ send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
        return err;
 }
 
+static s32
+brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
+{
+       s32 err;
+       u32 mode;
+
+       if (enable)
+               mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
+       else
+               mode = 0;
+
+       /* Try to set and enable ARP offload feature, this may fail, then it  */
+       /* is simply not supported and err 0 will be returned                 */
+       err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
+       if (err) {
+               brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
+                         mode, err);
+               err = 0;
+       } else {
+               err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
+               if (err) {
+                       brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
+                                 enable, err);
+                       err = 0;
+               } else
+                       brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
+                                 enable, mode);
+       }
+
+       return err;
+}
+
 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
                                                     const char *name,
                                                     enum nl80211_iftype type,
@@ -2216,6 +2248,11 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
        }
 
        pm = enabled ? PM_FAST : PM_OFF;
+       /* Do not enable the power save after assoc if it is a p2p interface */
+       if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
+               brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
+               pm = PM_OFF;
+       }
        brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
 
        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
@@ -3640,10 +3677,28 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
 }
 
 static s32
+brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
+                          struct brcmf_if *ifp,
+                          struct ieee80211_channel *channel)
+{
+       u16 chanspec;
+       s32 err;
+
+       brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
+                 channel->center_freq);
+
+       chanspec = channel_to_chanspec(&cfg->d11inf, channel);
+       err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
+
+       return err;
+}
+
+static s32
 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
                        struct cfg80211_ap_settings *settings)
 {
        s32 ie_offset;
+       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
        struct brcmf_if *ifp = netdev_priv(ndev);
        struct brcmf_tlv *ssid_ie;
        struct brcmf_ssid_le ssid_le;
@@ -3683,6 +3738,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
        }
 
        brcmf_set_mpc(ifp, 0);
+       brcmf_configure_arp_offload(ifp, false);
 
        /* find the RSN_IE */
        rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
@@ -3713,6 +3769,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
 
        brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
 
+       err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
+       if (err < 0) {
+               brcmf_err("Set Channel failed, %d\n", err);
+               goto exit;
+       }
+
        if (settings->beacon_interval) {
                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
                                            settings->beacon_interval);
@@ -3789,8 +3851,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
        set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
 exit:
-       if (err)
+       if (err) {
                brcmf_set_mpc(ifp, 1);
+               brcmf_configure_arp_offload(ifp, true);
+       }
        return err;
 }
 
@@ -3831,6 +3895,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
                        brcmf_err("bss_enable config failed %d\n", err);
        }
        brcmf_set_mpc(ifp, 1);
+       brcmf_configure_arp_offload(ifp, true);
        set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
        clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 
@@ -4148,7 +4213,7 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
        {
                 .max_interfaces = BRCMF_IFACE_MAX_CNT,
-                .num_different_channels = 1, /* no multi-channel for now */
+                .num_different_channels = 2,
                 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
                 .limits = brcmf_iface_limits
        }
@@ -4256,20 +4321,16 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
        return vif;
 }
 
-void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
+void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
+                   struct brcmf_cfg80211_vif *vif)
 {
-       struct brcmf_cfg80211_info *cfg;
-       struct wiphy *wiphy;
-
-       wiphy = vif->wdev.wiphy;
-       cfg = wiphy_priv(wiphy);
        list_del(&vif->list);
        cfg->vif_cnt--;
 
        kfree(vif);
        if (!cfg->vif_cnt) {
-               wiphy_unregister(wiphy);
-               wiphy_free(wiphy);
+               wiphy_unregister(cfg->wiphy);
+               wiphy_free(cfg->wiphy);
        }
 }
 
@@ -4646,7 +4707,6 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
                return 0;
 
        case BRCMF_E_IF_DEL:
-               ifp->vif = NULL;
                mutex_unlock(&event->vif_event_lock);
                /* event may not be upon user request */
                if (brcmf_cfg80211_vif_event_armed(cfg))
@@ -4852,8 +4912,7 @@ cfg80211_p2p_attach_out:
        wl_deinit_priv(cfg);
 
 cfg80211_attach_out:
-       brcmf_free_vif(vif);
-       wiphy_free(wiphy);
+       brcmf_free_vif(cfg, vif);
        return NULL;
 }
 
@@ -4865,7 +4924,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
        wl_deinit_priv(cfg);
        brcmf_btcoex_detach(cfg);
        list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
-               brcmf_free_vif(vif);
+               brcmf_free_vif(cfg, vif);
        }
 }
 
@@ -5229,6 +5288,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
        if (err)
                goto default_conf_out;
 
+       brcmf_configure_arp_offload(ifp, true);
+
        cfg->dongle_up = true;
 default_conf_out:
 
index a71cff8..d9bdaf9 100644 (file)
@@ -487,7 +487,8 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
                                           enum nl80211_iftype type,
                                           bool pm_block);
-void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
+void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
+                   struct brcmf_cfg80211_vif *vif);
 
 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
                          const u8 *vndr_ie_buf, u32 vndr_ie_len);
index f8246f2..4caaf52 100644 (file)
@@ -1832,16 +1832,16 @@ u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval);
 __le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
                          u32 beacon_interval);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 extern const struct dev_pm_ops il_pm_ops;
 
 #define IL_LEGACY_PM_OPS       (&il_pm_ops)
 
-#else /* !CONFIG_PM */
+#else /* !CONFIG_PM_SLEEP */
 
 #define IL_LEGACY_PM_OPS       NULL
 
-#endif /* !CONFIG_PM */
+#endif /* !CONFIG_PM_SLEEP */
 
 /*****************************************************
 *  Error Handling Debugging
index db183b4..c3c13ce 100644 (file)
@@ -735,7 +735,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                                        memcpy(&lq, priv->stations[i].lq,
                                               sizeof(struct iwl_link_quality_cmd));
 
-                               if (!memcmp(&lq, &zero_lq, sizeof(lq)))
+                               if (memcmp(&lq, &zero_lq, sizeof(lq)))
                                        send_lq = true;
                        }
                        spin_unlock_bh(&priv->sta_lock);
index 753b568..a5f9875 100644 (file)
 static struct dentry *mwifiex_dfs_dir;
 
 static char *bss_modes[] = {
-       "Unknown",
-       "Ad-hoc",
-       "Managed",
-       "Auto"
+       "UNSPECIFIED",
+       "ADHOC",
+       "STATION",
+       "AP",
+       "AP_VLAN",
+       "WDS",
+       "MONITOR",
+       "MESH_POINT",
+       "P2P_CLIENT",
+       "P2P_GO",
+       "P2P_DEVICE",
 };
 
 /* size/addr for mwifiex_debug_info */
@@ -200,7 +207,12 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
        p += sprintf(p, "driver_version = %s", fmt);
        p += sprintf(p, "\nverext = %s", priv->version_str);
        p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
-       p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
+
+       if (info.bss_mode >= ARRAY_SIZE(bss_modes))
+               p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
+       else
+               p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
+
        p += sprintf(p, "media_state=\"%s\"\n",
                     (!priv->media_connected ? "Disconnected" : "Connected"));
        p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
index 999ffc1..c97e9d3 100644 (file)
@@ -764,6 +764,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                                 "can't alloc skb for rx\n");
                        goto done;
                }
+               kmemleak_not_leak(new_skb);
 
                pci_unmap_single(rtlpci->pdev,
                                 *((dma_addr_t *) skb->cb),
index 3d0498e..189ba12 100644 (file)
@@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
        }
 }
 
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
-                                  struct ieee80211_sta *sta,
-                                  u8 rssi_level)
+static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+                                         struct ieee80211_sta *sta)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-       u32 ratr_value = (u32) mac->basic_rates;
-       u8 *mcsrate = mac->mcs;
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 ratr_value;
        u8 ratr_index = 0;
        u8 nmode = mac->ht_enable;
-       u8 mimo_ps = 1;
-       u16 shortgi_rate = 0;
-       u32 tmp_ratr_value = 0;
+       u8 mimo_ps = IEEE80211_SMPS_OFF;
+       u16 shortgi_rate;
+       u32 tmp_ratr_value;
        u8 curtxbw_40mhz = mac->bw_40;
-       u8 curshortgi_40mhz = mac->sgi_40;
-       u8 curshortgi_20mhz = mac->sgi_20;
+       u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                              1 : 0;
+       u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+                              1 : 0;
        enum wireless_mode wirelessmode = mac->mode;
 
-       ratr_value |= ((*(u16 *) (mcsrate))) << 12;
+       if (rtlhal->current_bandtype == BAND_ON_5G)
+               ratr_value = sta->supp_rates[1] << 4;
+       else
+               ratr_value = sta->supp_rates[0];
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               ratr_value = 0xfff;
+
+       ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+                       sta->ht_cap.mcs.rx_mask[0] << 12);
        switch (wirelessmode) {
        case WIRELESS_MODE_B:
                if (ratr_value & 0x0000000c)
@@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
        case WIRELESS_MODE_N_24G:
        case WIRELESS_MODE_N_5G:
                nmode = 1;
-               if (mimo_ps == 0) {
+               if (mimo_ps == IEEE80211_SMPS_STATIC) {
                        ratr_value &= 0x0007F005;
                } else {
                        u32 ratr_mask;
@@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
                                ratr_mask = 0x000ff005;
                        else
                                ratr_mask = 0x0f0ff005;
-                       if (curtxbw_40mhz)
-                               ratr_mask |= 0x00000010;
+
                        ratr_value &= ratr_mask;
                }
                break;
@@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
                        ratr_value &= 0x000ff0ff;
                else
                        ratr_value &= 0x0f0ff0ff;
+
                break;
        }
+
        ratr_value &= 0x0FFFFFFF;
-       if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
-           (!curtxbw_40mhz && curshortgi_20mhz))) {
+
+       if (nmode && ((curtxbw_40mhz &&
+                        curshortgi_40mhz) || (!curtxbw_40mhz &&
+                                              curshortgi_20mhz))) {
+
                ratr_value |= 0x10000000;
                tmp_ratr_value = (ratr_value >> 12);
+
                for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
                        if ((1 << shortgi_rate) & tmp_ratr_value)
                                break;
                }
+
                shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
-                              (shortgi_rate << 4) | (shortgi_rate);
+                   (shortgi_rate << 4) | (shortgi_rate);
        }
+
        rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+                rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
-void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
+static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
+                                        struct ieee80211_sta *sta,
+                                        u8 rssi_level)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_phy *rtlphy = &(rtlpriv->phy);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-       u32 ratr_bitmap = (u32) mac->basic_rates;
-       u8 *p_mcsrate = mac->mcs;
-       u8 ratr_index = 0;
-       u8 curtxbw_40mhz = mac->bw_40;
-       u8 curshortgi_40mhz = mac->sgi_40;
-       u8 curshortgi_20mhz = mac->sgi_20;
-       enum wireless_mode wirelessmode = mac->mode;
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_sta_info *sta_entry = NULL;
+       u32 ratr_bitmap;
+       u8 ratr_index;
+       u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
+       u8 curshortgi_40mhz = curtxbw_40mhz &&
+                             (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                               1 : 0;
+       u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+                               1 : 0;
+       enum wireless_mode wirelessmode = 0;
        bool shortgi = false;
        u8 rate_mask[5];
        u8 macid = 0;
-       u8 mimops = 1;
-
-       ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
+       u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+       sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+       wirelessmode = sta_entry->wireless_mode;
+       if (mac->opmode == NL80211_IFTYPE_STATION ||
+           mac->opmode == NL80211_IFTYPE_MESH_POINT)
+               curtxbw_40mhz = mac->bw_40;
+       else if (mac->opmode == NL80211_IFTYPE_AP ||
+               mac->opmode == NL80211_IFTYPE_ADHOC)
+               macid = sta->aid + 1;
+
+       if (rtlhal->current_bandtype == BAND_ON_5G)
+               ratr_bitmap = sta->supp_rates[1] << 4;
+       else
+               ratr_bitmap = sta->supp_rates[0];
+       if (mac->opmode == NL80211_IFTYPE_ADHOC)
+               ratr_bitmap = 0xfff;
+       ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+                       sta->ht_cap.mcs.rx_mask[0] << 12);
        switch (wirelessmode) {
        case WIRELESS_MODE_B:
                ratr_index = RATR_INX_WIRELESS_B;
@@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
                break;
        case WIRELESS_MODE_G:
                ratr_index = RATR_INX_WIRELESS_GB;
+
                if (rssi_level == 1)
                        ratr_bitmap &= 0x00000f00;
                else if (rssi_level == 2)
@@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
        case WIRELESS_MODE_N_24G:
        case WIRELESS_MODE_N_5G:
                ratr_index = RATR_INX_WIRELESS_NGB;
-               if (mimops == 0) {
+
+               if (mimo_ps == IEEE80211_SMPS_STATIC) {
                        if (rssi_level == 1)
                                ratr_bitmap &= 0x00070000;
                        else if (rssi_level == 2)
@@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
                                }
                        }
                }
+
                if ((curtxbw_40mhz && curshortgi_40mhz) ||
                    (!curtxbw_40mhz && curshortgi_20mhz)) {
+
                        if (macid == 0)
                                shortgi = true;
                        else if (macid == 1)
@@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
                break;
        default:
                ratr_index = RATR_INX_WIRELESS_NGB;
+
                if (rtlphy->rf_type == RF_1T2R)
                        ratr_bitmap &= 0x000ff0ff;
                else
                        ratr_bitmap &= 0x0f0ff0ff;
                break;
        }
-       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
-                ratr_bitmap);
-       *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
-                                     ratr_index << 28);
+       sta_entry->ratr_index = ratr_index;
+
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+                "ratr_bitmap :%x\n", ratr_bitmap);
+       *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
+                                    (ratr_index << 28);
        rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
                 "Rate_index:%x, ratr_val:%x, %5phC\n",
                 ratr_index, ratr_bitmap, rate_mask);
-       rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
+       memcpy(rtlpriv->rate_mask, rate_mask, 5);
+       /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a
+        * "scheduled while atomic" if called directly */
+       schedule_work(&rtlpriv->works.fill_h2c_cmd);
+
+       if (macid != 0)
+               sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
+                                struct ieee80211_sta *sta,
+                                u8 rssi_level)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->dm.useramask)
+               rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
+       else
+               rtl92cu_update_hal_rate_table(hw, sta);
 }
 
 void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
index f41a3aa..8e3ec1e 100644 (file)
@@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
                                   u32 add_msr, u32 rm_msr);
 void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
 void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
-                                  struct ieee80211_sta *sta,
-                                  u8 rssi_level);
-void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
 
 void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
 bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
index 85b6bdb..da4f587 100644 (file)
@@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
                                macaddr = cam_const_broad;
                                entry_id = key_index;
                        } else {
+                               if (mac->opmode == NL80211_IFTYPE_AP ||
+                                   mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+                                       entry_id = rtl_cam_get_free_entry(hw,
+                                                                p_macaddr);
+                                       if (entry_id >=  TOTAL_CAM_ENTRY) {
+                                               RT_TRACE(rtlpriv, COMP_SEC,
+                                                        DBG_EMERG,
+                                                        "Can not find free hw security cam entry\n");
+                                               return;
+                                       }
+                               } else {
+                                       entry_id = CAM_PAIRWISE_KEY_POSITION;
+                               }
+
                                key_index = PAIRWISE_KEYIDX;
-                               entry_id = CAM_PAIRWISE_KEY_POSITION;
                                is_pairwise = true;
                        }
                }
                if (rtlpriv->sec.key_len[key_index] == 0) {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
                                 "delete one entry\n");
+                       if (mac->opmode == NL80211_IFTYPE_AP ||
+                           mac->opmode == NL80211_IFTYPE_MESH_POINT)
+                               rtl_cam_del_entry(hw, p_macaddr);
                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
                } else {
                        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
index 938b1e6..826f085 100644 (file)
@@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
        .update_interrupt_mask = rtl92cu_update_interrupt_mask,
        .get_hw_reg = rtl92cu_get_hw_reg,
        .set_hw_reg = rtl92cu_set_hw_reg,
-       .update_rate_tbl = rtl92cu_update_hal_rate_table,
-       .update_rate_mask = rtl92cu_update_hal_rate_mask,
+       .update_rate_tbl = rtl92cu_update_hal_rate_tbl,
        .fill_tx_desc = rtl92cu_tx_fill_desc,
        .fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
        .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
@@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
        .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
        .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
        .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
+       .fill_h2c_cmd = rtl92c_fill_h2c_cmd,
 };
 
 static struct rtl_mod_params rtl92cu_mod_params = {
index a1310ab..262e1e4 100644 (file)
@@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
                            enum radio_path rfpath, u32 regaddr, u32 bitmask);
 void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
+                                struct ieee80211_sta *sta,
+                                u8 rssi_level);
 
 #endif
index 76732b0..a3532e0 100644 (file)
@@ -824,6 +824,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
 
        /* should after adapter start and interrupt enable. */
        set_hal_stop(rtlhal);
+       cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
        /* Enable software */
        SET_USB_STOP(rtlusb);
        rtl_usb_deinit(hw);
@@ -1026,6 +1027,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw,
        return false;
 }
 
+static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work)
+{
+       struct rtl_works *rtlworks =
+           container_of(work, struct rtl_works, fill_h2c_cmd);
+       struct ieee80211_hw *hw = rtlworks->hw;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask);
+}
+
 static struct rtl_intf_ops rtl_usb_ops = {
        .adapter_start = rtl_usb_start,
        .adapter_stop = rtl_usb_stop,
@@ -1057,6 +1068,8 @@ int rtl_usb_probe(struct usb_interface *intf,
 
        /* this spin lock must be initialized early */
        spin_lock_init(&rtlpriv->locks.usb_lock);
+       INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
+                 rtl_fill_h2c_cmd_work_callback);
 
        rtlpriv->usb_data_index = 0;
        init_completion(&rtlpriv->firmware_loading_complete);
index 44328ba..cc03e7c 100644 (file)
@@ -1736,6 +1736,8 @@ struct rtl_hal_ops {
        void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
                                             bool mstate);
        void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
+       void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
+                             u32 cmd_len, u8 *p_cmdbuffer);
 };
 
 struct rtl_intf_ops {
@@ -1869,6 +1871,7 @@ struct rtl_works {
        struct delayed_work fwevt_wq;
 
        struct work_struct lps_change_work;
+       struct work_struct fill_h2c_cmd;
 };
 
 struct rtl_debug {
@@ -2048,6 +2051,7 @@ struct rtl_priv {
                };
        };
        bool enter_ps;  /* true when entering PS */
+       u8 rate_mask[5];
 
        /*This must be the last item so
           that it points to the data allocated
index affdb3e..4a0bbb1 100644 (file)
@@ -310,7 +310,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
        memcpy(cmd->channels_2, cmd_channels->channels_2,
               sizeof(cmd->channels_2));
        memcpy(cmd->channels_5, cmd_channels->channels_5,
-              sizeof(cmd->channels_2));
+              sizeof(cmd->channels_5));
        /* channels_4 are not supported, so no need to copy them */
 }
 
index 222d035..9e5484a 100644 (file)
 #define WL127X_IFTYPE_SR_VER   3
 #define WL127X_MAJOR_SR_VER    10
 #define WL127X_SUBTYPE_SR_VER  WLCORE_FW_VER_IGNORE
-#define WL127X_MINOR_SR_VER    115
+#define WL127X_MINOR_SR_VER    133
 /* minimum multi-role FW version for wl127x */
 #define WL127X_IFTYPE_MR_VER   5
 #define WL127X_MAJOR_MR_VER    7
 #define WL127X_SUBTYPE_MR_VER  WLCORE_FW_VER_IGNORE
-#define WL127X_MINOR_MR_VER    115
+#define WL127X_MINOR_MR_VER    42
 
 /* FW chip version for wl128x */
 #define WL128X_CHIP_VER                7
@@ -49,7 +49,7 @@
 #define WL128X_IFTYPE_SR_VER   3
 #define WL128X_MAJOR_SR_VER    10
 #define WL128X_SUBTYPE_SR_VER  WLCORE_FW_VER_IGNORE
-#define WL128X_MINOR_SR_VER    115
+#define WL128X_MINOR_SR_VER    133
 /* minimum multi-role FW version for wl128x */
 #define WL128X_IFTYPE_MR_VER   5
 #define WL128X_MAJOR_MR_VER    7
index 09d9445..2b642f8 100644 (file)
@@ -34,7 +34,7 @@ static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd,
        memcpy(cmd->channels_2, cmd_channels->channels_2,
               sizeof(cmd->channels_2));
        memcpy(cmd->channels_5, cmd_channels->channels_5,
-              sizeof(cmd->channels_2));
+              sizeof(cmd->channels_5));
        /* channels_4 are not supported, so no need to copy them */
 }
 
index 37984e6..8c20935 100644 (file)
@@ -662,7 +662,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
 {
        struct xenvif *vif = NULL, *tmp;
        s8 status;
-       u16 irq, flags;
+       u16 flags;
        struct xen_netif_rx_response *resp;
        struct sk_buff_head rxq;
        struct sk_buff *skb;
@@ -771,13 +771,13 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
                                         sco->meta_slots_used);
 
                RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->rx, ret);
-               irq = vif->irq;
-               if (ret && list_empty(&vif->notify_list))
-                       list_add_tail(&vif->notify_list, &notify);
 
                xenvif_notify_tx_completion(vif);
 
-               xenvif_put(vif);
+               if (ret && list_empty(&vif->notify_list))
+                       list_add_tail(&vif->notify_list, &notify);
+               else
+                       xenvif_put(vif);
                npo.meta_cons += sco->meta_slots_used;
                dev_kfree_skb(skb);
        }
@@ -785,6 +785,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
        list_for_each_entry_safe(vif, tmp, &notify, notify_list) {
                notify_remote_via_irq(vif->irq);
                list_del_init(&vif->notify_list);
+               xenvif_put(vif);
        }
 
        /* More work to do? */
index 4775d4e..74a852e 100644 (file)
@@ -28,7 +28,7 @@ config NFC_WILINK
 
 config NFC_MEI_PHY
        tristate "MEI bus NFC device support"
-       depends on INTEL_MEI_BUS_NFC && NFC_HCI
+       depends on INTEL_MEI && NFC_HCI
        help
          This adds support to use an mei bus nfc device. Select this if you
          will use an HCI NFC driver for an NFC chip connected behind an
index b8f8abc..1201bdb 100644 (file)
@@ -64,6 +64,15 @@ int nfc_mei_phy_enable(void *phy_id)
                 return r;
        }
 
+       r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
+       if (r) {
+               pr_err("MEY_PHY: Event cb registration failed\n");
+               mei_cl_disable_device(phy->device);
+               phy->powered = 0;
+
+               return r;
+       }
+
        phy->powered = 1;
 
        return 0;
index 1ad044d..cdf1bc5 100644 (file)
@@ -43,24 +43,16 @@ static int microread_mei_probe(struct mei_cl_device *device,
                return -ENOMEM;
        }
 
-       r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
-       if (r) {
-               pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n");
-               goto err_out;
-       }
-
        r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
                            MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
                            &phy->hdev);
-       if (r < 0)
-               goto err_out;
-
-       return 0;
+       if (r < 0) {
+               nfc_mei_phy_free(phy);
 
-err_out:
-       nfc_mei_phy_free(phy);
+               return r;
+       }
 
-       return r;
+       return 0;
 }
 
 static int microread_mei_remove(struct mei_cl_device *device)
@@ -71,8 +63,6 @@ static int microread_mei_remove(struct mei_cl_device *device)
 
        microread_remove(phy->hdev);
 
-       nfc_mei_phy_disable(phy);
-
        nfc_mei_phy_free(phy);
 
        return 0;
index 1eb4884..b5d3d18 100644 (file)
@@ -43,24 +43,16 @@ static int pn544_mei_probe(struct mei_cl_device *device,
                return -ENOMEM;
        }
 
-       r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
-       if (r) {
-               pr_err(PN544_DRIVER_NAME ": event cb registration failed\n");
-               goto err_out;
-       }
-
        r = pn544_hci_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
                            MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
                            &phy->hdev);
-       if (r < 0)
-               goto err_out;
-
-       return 0;
+       if (r < 0) {
+               nfc_mei_phy_free(phy);
 
-err_out:
-       nfc_mei_phy_free(phy);
+               return r;
+       }
 
-       return r;
+       return 0;
 }
 
 static int pn544_mei_remove(struct mei_cl_device *device)
@@ -71,8 +63,6 @@ static int pn544_mei_remove(struct mei_cl_device *device)
 
        pn544_hci_remove(phy->hdev);
 
-       nfc_mei_phy_disable(phy);
-
        nfc_mei_phy_free(phy);
 
        return 0;
index f53b992..a6f584a 100644 (file)
@@ -192,14 +192,15 @@ EXPORT_SYMBOL(of_find_property);
 struct device_node *of_find_all_nodes(struct device_node *prev)
 {
        struct device_node *np;
+       unsigned long flags;
 
-       raw_spin_lock(&devtree_lock);
+       raw_spin_lock_irqsave(&devtree_lock, flags);
        np = prev ? prev->allnext : of_allnodes;
        for (; np != NULL; np = np->allnext)
                if (of_node_get(np))
                        break;
        of_node_put(prev);
-       raw_spin_unlock(&devtree_lock);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
        return np;
 }
 EXPORT_SYMBOL(of_find_all_nodes);
@@ -421,8 +422,9 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
        struct device_node *prev)
 {
        struct device_node *next;
+       unsigned long flags;
 
-       raw_spin_lock(&devtree_lock);
+       raw_spin_lock_irqsave(&devtree_lock, flags);
        next = prev ? prev->sibling : node->child;
        for (; next; next = next->sibling) {
                if (!__of_device_is_available(next))
@@ -431,7 +433,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
                        break;
        }
        of_node_put(prev);
-       raw_spin_unlock(&devtree_lock);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
        return next;
 }
 EXPORT_SYMBOL(of_get_next_available_child);
@@ -735,13 +737,14 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
 struct device_node *of_find_node_by_phandle(phandle handle)
 {
        struct device_node *np;
+       unsigned long flags;
 
-       raw_spin_lock(&devtree_lock);
+       raw_spin_lock_irqsave(&devtree_lock, flags);
        for (np = of_allnodes; np; np = np->allnext)
                if (np->phandle == handle)
                        break;
        of_node_get(np);
-       raw_spin_unlock(&devtree_lock);
+       raw_spin_unlock_irqrestore(&devtree_lock, flags);
        return np;
 }
 EXPORT_SYMBOL(of_find_node_by_phandle);
index 2ef7103..1f05913 100644 (file)
@@ -668,7 +668,7 @@ lba_fixup_bus(struct pci_bus *bus)
                        BUG();
                }
 
-               if (ldev->hba.elmmio_space.start) {
+               if (ldev->hba.elmmio_space.flags) {
                        err = request_resource(&iomem_resource,
                                        &(ldev->hba.elmmio_space));
                        if (err < 0) {
@@ -993,7 +993,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
 
                case PAT_LMMIO:
                        /* used to fix up pre-initialized MEM BARs */
-                       if (!lba_dev->hba.lmmio_space.start) {
+                       if (!lba_dev->hba.lmmio_space.flags) {
                                sprintf(lba_dev->hba.lmmio_name,
                                                "PCI%02x LMMIO",
                                                (int)lba_dev->hba.bus_num.start);
@@ -1001,7 +1001,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
                                        io->start;
                                r = &lba_dev->hba.lmmio_space;
                                r->name = lba_dev->hba.lmmio_name;
-                       } else if (!lba_dev->hba.elmmio_space.start) {
+                       } else if (!lba_dev->hba.elmmio_space.flags) {
                                sprintf(lba_dev->hba.elmmio_name,
                                                "PCI%02x ELMMIO",
                                                (int)lba_dev->hba.bus_num.start);
@@ -1096,6 +1096,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
        r->name = "LBA PCI Busses";
        r->start = lba_num & 0xff;
        r->end = (lba_num>>8) & 0xff;
+       r->flags = IORESOURCE_BUS;
 
        /* Set up local PCI Bus resources - we don't need them for
        ** Legacy boxes but it's nice to see in /proc/iomem.
@@ -1494,7 +1495,7 @@ lba_driver_probe(struct parisc_device *dev)
 
        pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
                                HBA_PORT_BASE(lba_dev->hba.hba_num));
-       if (lba_dev->hba.elmmio_space.start)
+       if (lba_dev->hba.elmmio_space.flags)
                pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
                                        lba_dev->hba.lmmio_space_offset);
        if (lba_dev->hba.lmmio_space.flags)
index 24e12d4..a505760 100644 (file)
@@ -71,7 +71,7 @@ config PARPORT_PC_FIFO
 
 config PARPORT_PC_SUPERIO
        bool "SuperIO chipset support"
-       depends on PARPORT_PC
+       depends on PARPORT_PC && !PARISC
        help
          Saying Y here enables some probes for Super-IO chipsets in order to
          find out things like base addresses, IRQ lines and DMA channels.  It
index a5251cb..6e3a60c 100644 (file)
@@ -234,7 +234,7 @@ static int parport_PS2_supported(struct parport *pb)
 
 struct parport *parport_gsc_probe_port(unsigned long base,
                                       unsigned long base_hi, int irq,
-                                      int dma, struct pci_dev *dev)
+                                      int dma, struct parisc_device *padev)
 {
        struct parport_gsc_private *priv;
        struct parport_operations *ops;
@@ -258,7 +258,6 @@ struct parport *parport_gsc_probe_port(unsigned long base,
        priv->ctr_writable = 0xff;
        priv->dma_buf = 0;
        priv->dma_handle = 0;
-       priv->dev = dev;
        p->base = base;
        p->base_hi = base_hi;
        p->irq = irq;
@@ -282,6 +281,7 @@ struct parport *parport_gsc_probe_port(unsigned long base,
                return NULL;
        }
 
+       p->dev = &padev->dev;
        p->base_hi = base_hi;
        p->modes = tmp.modes;
        p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
@@ -373,7 +373,7 @@ static int parport_init_chip(struct parisc_device *dev)
        }
        
        p = parport_gsc_probe_port(port, 0, dev->irq,
-                       /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, NULL);
+                       /* PARPORT_IRQ_NONE */ PARPORT_DMA_NONE, dev);
        if (p)
                parport_count++;
        dev_set_drvdata(&dev->dev, p);
index fc9c37c..8122147 100644 (file)
@@ -217,6 +217,6 @@ extern void parport_gsc_dec_use_count(void);
 extern struct parport *parport_gsc_probe_port(unsigned long base,
                                                unsigned long base_hi,
                                                int irq, int dma,
-                                               struct pci_dev *dev);
+                                               struct parisc_device *padev);
 
 #endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */
index 8ec8b4f..0f4554e 100644 (file)
@@ -580,6 +580,7 @@ struct aer_recover_entry
        u8      devfn;
        u16     domain;
        int     severity;
+       struct aer_capability_regs *regs;
 };
 
 static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry,
@@ -593,7 +594,7 @@ static DEFINE_SPINLOCK(aer_recover_ring_lock);
 static DECLARE_WORK(aer_recover_work, aer_recover_work_func);
 
 void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
-                      int severity)
+                      int severity, struct aer_capability_regs *aer_regs)
 {
        unsigned long flags;
        struct aer_recover_entry entry = {
@@ -601,6 +602,7 @@ void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
                .devfn          = devfn,
                .domain         = domain,
                .severity       = severity,
+               .regs           = aer_regs,
        };
 
        spin_lock_irqsave(&aer_recover_ring_lock, flags);
@@ -627,6 +629,7 @@ static void aer_recover_work_func(struct work_struct *work)
                               PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn));
                        continue;
                }
+               cper_print_aer(pdev, entry.severity, entry.regs);
                do_recovery(pdev, entry.severity);
                pci_dev_put(pdev);
        }
index 5ab1425..2c7c9f5 100644 (file)
@@ -220,7 +220,7 @@ int cper_severity_to_aer(int cper_severity)
 }
 EXPORT_SYMBOL_GPL(cper_severity_to_aer);
 
-void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity,
+void cper_print_aer(struct pci_dev *dev, int cper_severity,
                    struct aer_capability_regs *aer)
 {
        int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0;
@@ -244,7 +244,7 @@ void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity,
        agent = AER_GET_AGENT(aer_severity, status);
        dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n",
               status, mask);
-       cper_print_bits(prefix, status, status_strs, status_strs_size);
+       cper_print_bits("", status, status_strs, status_strs_size);
        dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n",
               aer_error_layer[layer], aer_agent_string[agent]);
        if (aer_severity != AER_CORRECTABLE)
index c67c37e..694c3ac 100644 (file)
@@ -610,7 +610,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d)
        bool found = false;
        unsigned long config;
 
-       mutex_lock(&pctldev->mutex);
+       mutex_lock(&pinctrl_maps_mutex);
 
        /* Parse the pinctrl map and look for the elected pin/state */
        for_each_maps(maps_node, i, map) {
@@ -659,7 +659,7 @@ static int pinconf_dbg_config_print(struct seq_file *s, void *d)
                confops->pin_config_config_dbg_show(pctldev, s, config);
 
 exit:
-       mutex_unlock(&pctldev->mutex);
+       mutex_unlock(&pinctrl_maps_mutex);
 
        return 0;
 }
index a67af41..d6b4174 100644 (file)
@@ -830,7 +830,8 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
        return 0;
 
 err_no_range:
-       err = gpiochip_remove(&gpio->chip);
+       if (gpiochip_remove(&gpio->chip))
+               dev_err(&pdev->dev, "failed to remove gpio chip\n");
 err_no_chip:
 err_no_domain:
 err_no_port:
index ac74281..2d76f66 100644 (file)
@@ -196,6 +196,12 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+struct exynos_eint_gpio_save {
+       u32 eint_con;
+       u32 eint_fltcon0;
+       u32 eint_fltcon1;
+};
+
 /*
  * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
  * @d: driver data of samsung pinctrl driver.
@@ -204,8 +210,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 {
        struct samsung_pin_bank *bank;
        struct device *dev = d->dev;
-       unsigned int ret;
-       unsigned int i;
+       int ret;
+       int i;
 
        if (!d->irq) {
                dev_err(dev, "irq number not available\n");
@@ -227,11 +233,29 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
                                bank->nr_pins, &exynos_gpio_irqd_ops, bank);
                if (!bank->irq_domain) {
                        dev_err(dev, "gpio irq domain add failed\n");
-                       return -ENXIO;
+                       ret = -ENXIO;
+                       goto err_domains;
+               }
+
+               bank->soc_priv = devm_kzalloc(d->dev,
+                       sizeof(struct exynos_eint_gpio_save), GFP_KERNEL);
+               if (!bank->soc_priv) {
+                       irq_domain_remove(bank->irq_domain);
+                       ret = -ENOMEM;
+                       goto err_domains;
                }
        }
 
        return 0;
+
+err_domains:
+       for (--i, --bank; i >= 0; --i, --bank) {
+               if (bank->eint_type != EINT_TYPE_GPIO)
+                       continue;
+               irq_domain_remove(bank->irq_domain);
+       }
+
+       return ret;
 }
 
 static void exynos_wkup_irq_unmask(struct irq_data *irqd)
@@ -326,6 +350,28 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
        return 0;
 }
 
+static u32 exynos_eint_wake_mask = 0xffffffff;
+
+u32 exynos_get_eint_wake_mask(void)
+{
+       return exynos_eint_wake_mask;
+}
+
+static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
+{
+       struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+       unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
+
+       pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq);
+
+       if (!on)
+               exynos_eint_wake_mask |= bit;
+       else
+               exynos_eint_wake_mask &= ~bit;
+
+       return 0;
+}
+
 /*
  * irq_chip for wakeup interrupts
  */
@@ -335,6 +381,7 @@ static struct irq_chip exynos_wkup_irq_chip = {
        .irq_mask       = exynos_wkup_irq_mask,
        .irq_ack        = exynos_wkup_irq_ack,
        .irq_set_type   = exynos_wkup_irq_set_type,
+       .irq_set_wake   = exynos_wkup_irq_set_wake,
 };
 
 /* interrupt handler for wakeup interrupts 0..15 */
@@ -505,6 +552,72 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
        return 0;
 }
 
+static void exynos_pinctrl_suspend_bank(
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               struct samsung_pin_bank *bank)
+{
+       struct exynos_eint_gpio_save *save = bank->soc_priv;
+       void __iomem *regs = drvdata->virt_base;
+
+       save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
+                                               + bank->eint_offset);
+       save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset);
+       save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset + 4);
+
+       pr_debug("%s: save     con %#010x\n", bank->name, save->eint_con);
+       pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
+       pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
+}
+
+static void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
+               if (bank->eint_type == EINT_TYPE_GPIO)
+                       exynos_pinctrl_suspend_bank(drvdata, bank);
+}
+
+static void exynos_pinctrl_resume_bank(
+                               struct samsung_pinctrl_drv_data *drvdata,
+                               struct samsung_pin_bank *bank)
+{
+       struct exynos_eint_gpio_save *save = bank->soc_priv;
+       void __iomem *regs = drvdata->virt_base;
+
+       pr_debug("%s:     con %#010x => %#010x\n", bank->name,
+                       readl(regs + EXYNOS_GPIO_ECON_OFFSET
+                       + bank->eint_offset), save->eint_con);
+       pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
+                       readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                       + 2 * bank->eint_offset), save->eint_fltcon0);
+       pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
+                       readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                       + 2 * bank->eint_offset + 4), save->eint_fltcon1);
+
+       writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
+                                               + bank->eint_offset);
+       writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset);
+       writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
+                                               + 2 * bank->eint_offset + 4);
+}
+
+static void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       struct samsung_pin_bank *bank = ctrl->pin_banks;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; ++i, ++bank)
+               if (bank->eint_type == EINT_TYPE_GPIO)
+                       exynos_pinctrl_resume_bank(drvdata, bank);
+}
+
 /* pin banks of exynos4210 pin-controller 0 */
 static struct samsung_pin_bank exynos4210_pin_banks0[] = {
        EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
@@ -568,6 +681,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos4210-gpio-ctrl0",
        }, {
                /* pin-controller instance 1 data */
@@ -582,6 +697,8 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
                .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos4210-gpio-ctrl1",
        }, {
                /* pin-controller instance 2 data */
@@ -663,6 +780,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos4x12-gpio-ctrl0",
        }, {
                /* pin-controller instance 1 data */
@@ -677,6 +796,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
                .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos4x12-gpio-ctrl1",
        }, {
                /* pin-controller instance 2 data */
@@ -687,6 +808,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos4x12-gpio-ctrl2",
        }, {
                /* pin-controller instance 3 data */
@@ -697,6 +820,8 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos4x12-gpio-ctrl3",
        },
 };
@@ -775,6 +900,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
                .eint_wkup_init = exynos_eint_wkup_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos5250-gpio-ctrl0",
        }, {
                /* pin-controller instance 1 data */
@@ -785,6 +912,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos5250-gpio-ctrl1",
        }, {
                /* pin-controller instance 2 data */
@@ -795,6 +924,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos5250-gpio-ctrl2",
        }, {
                /* pin-controller instance 3 data */
@@ -805,6 +936,8 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
                .geint_pend     = EXYNOS_GPIO_EPEND_OFFSET,
                .svc            = EXYNOS_SVC_OFFSET,
                .eint_gpio_init = exynos_eint_gpio_init,
+               .suspend        = exynos_pinctrl_suspend,
+               .resume         = exynos_pinctrl_resume,
                .label          = "exynos5250-gpio-ctrl3",
        },
 };
index 9b1f77a..3c91c35 100644 (file)
@@ -19,6 +19,7 @@
 
 /* External GPIO and wakeup interrupt related definitions */
 #define EXYNOS_GPIO_ECON_OFFSET                0x700
+#define EXYNOS_GPIO_EFLTCON_OFFSET     0x800
 #define EXYNOS_GPIO_EMASK_OFFSET       0x900
 #define EXYNOS_GPIO_EPEND_OFFSET       0xA00
 #define EXYNOS_WKUP_ECON_OFFSET                0xE00
index 055d016..63ac22e 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/gpio.h>
 #include <linux/irqdomain.h>
 #include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
 
 #include "core.h"
 #include "pinctrl-samsung.h"
@@ -48,6 +49,9 @@ static struct pin_config {
        { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
 };
 
+/* Global list of devices (struct samsung_pinctrl_drv_data) */
+LIST_HEAD(drvdata_list);
+
 static unsigned int pin_base;
 
 static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
@@ -956,9 +960,151 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
                ctrl->eint_wkup_init(drvdata);
 
        platform_set_drvdata(pdev, drvdata);
+
+       /* Add to the global list */
+       list_add_tail(&drvdata->node, &drvdata_list);
+
        return 0;
 }
 
+#ifdef CONFIG_PM
+
+/**
+ * samsung_pinctrl_suspend_dev - save pinctrl state for suspend for a device
+ *
+ * Save data for all banks handled by this device.
+ */
+static void samsung_pinctrl_suspend_dev(
+       struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       void __iomem *virt_base = drvdata->virt_base;
+       int i;
+
+       for (i = 0; i < ctrl->nr_banks; i++) {
+               struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
+               void __iomem *reg = virt_base + bank->pctl_offset;
+
+               u8 *offs = bank->type->reg_offset;
+               u8 *widths = bank->type->fld_width;
+               enum pincfg_type type;
+
+               /* Registers without a powerdown config aren't lost */
+               if (!widths[PINCFG_TYPE_CON_PDN])
+                       continue;
+
+               for (type = 0; type < PINCFG_TYPE_NUM; type++)
+                       if (widths[type])
+                               bank->pm_save[type] = readl(reg + offs[type]);
+
+               if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
+                       /* Some banks have two config registers */
+                       bank->pm_save[PINCFG_TYPE_NUM] =
+                               readl(reg + offs[PINCFG_TYPE_FUNC] + 4);
+                       pr_debug("Save %s @ %p (con %#010x %08x)\n",
+                                bank->name, reg,
+                                bank->pm_save[PINCFG_TYPE_FUNC],
+                                bank->pm_save[PINCFG_TYPE_NUM]);
+               } else {
+                       pr_debug("Save %s @ %p (con %#010x)\n", bank->name,
+                                reg, bank->pm_save[PINCFG_TYPE_FUNC]);
+               }
+       }
+
+       if (ctrl->suspend)
+               ctrl->suspend(drvdata);
+}
+
+/**
+ * samsung_pinctrl_resume_dev - restore pinctrl state from suspend for a device
+ *
+ * Restore one of the banks that was saved during suspend.
+ *
+ * We don't bother doing anything complicated to avoid glitching lines since
+ * we're called before pad retention is turned off.
+ */
+static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata)
+{
+       struct samsung_pin_ctrl *ctrl = drvdata->ctrl;
+       void __iomem *virt_base = drvdata->virt_base;
+       int i;
+
+       if (ctrl->resume)
+               ctrl->resume(drvdata);
+
+       for (i = 0; i < ctrl->nr_banks; i++) {
+               struct samsung_pin_bank *bank = &ctrl->pin_banks[i];
+               void __iomem *reg = virt_base + bank->pctl_offset;
+
+               u8 *offs = bank->type->reg_offset;
+               u8 *widths = bank->type->fld_width;
+               enum pincfg_type type;
+
+               /* Registers without a powerdown config aren't lost */
+               if (!widths[PINCFG_TYPE_CON_PDN])
+                       continue;
+
+               if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {
+                       /* Some banks have two config registers */
+                       pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n",
+                                bank->name, reg,
+                                readl(reg + offs[PINCFG_TYPE_FUNC]),
+                                readl(reg + offs[PINCFG_TYPE_FUNC] + 4),
+                                bank->pm_save[PINCFG_TYPE_FUNC],
+                                bank->pm_save[PINCFG_TYPE_NUM]);
+                       writel(bank->pm_save[PINCFG_TYPE_NUM],
+                              reg + offs[PINCFG_TYPE_FUNC] + 4);
+               } else {
+                       pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name,
+                                reg, readl(reg + offs[PINCFG_TYPE_FUNC]),
+                                bank->pm_save[PINCFG_TYPE_FUNC]);
+               }
+               for (type = 0; type < PINCFG_TYPE_NUM; type++)
+                       if (widths[type])
+                               writel(bank->pm_save[type], reg + offs[type]);
+       }
+}
+
+/**
+ * samsung_pinctrl_suspend - save pinctrl state for suspend
+ *
+ * Save data for all banks across all devices.
+ */
+static int samsung_pinctrl_suspend(void)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       list_for_each_entry(drvdata, &drvdata_list, node) {
+               samsung_pinctrl_suspend_dev(drvdata);
+       }
+
+       return 0;
+}
+
+/**
+ * samsung_pinctrl_resume - restore pinctrl state for suspend
+ *
+ * Restore data for all banks across all devices.
+ */
+static void samsung_pinctrl_resume(void)
+{
+       struct samsung_pinctrl_drv_data *drvdata;
+
+       list_for_each_entry_reverse(drvdata, &drvdata_list, node) {
+               samsung_pinctrl_resume_dev(drvdata);
+       }
+}
+
+#else
+#define samsung_pinctrl_suspend                NULL
+#define samsung_pinctrl_resume         NULL
+#endif
+
+static struct syscore_ops samsung_pinctrl_syscore_ops = {
+       .suspend        = samsung_pinctrl_suspend,
+       .resume         = samsung_pinctrl_resume,
+};
+
 static const struct of_device_id samsung_pinctrl_dt_match[] = {
 #ifdef CONFIG_PINCTRL_EXYNOS
        { .compatible = "samsung,exynos4210-pinctrl",
@@ -987,6 +1133,14 @@ static struct platform_driver samsung_pinctrl_driver = {
 
 static int __init samsung_pinctrl_drv_register(void)
 {
+       /*
+        * Register syscore ops for save/restore of registers across suspend.
+        * It's important to ensure that this driver is running at an earlier
+        * initcall level than any arch-specific init calls that install syscore
+        * ops that turn off pad retention (like exynos_pm_resume).
+        */
+       register_syscore_ops(&samsung_pinctrl_syscore_ops);
+
        return platform_driver_register(&samsung_pinctrl_driver);
 }
 postcore_initcall(samsung_pinctrl_drv_register);
index 7c7f9eb..26d3519 100644 (file)
@@ -127,6 +127,7 @@ struct samsung_pin_bank_type {
  * @gpio_chip: GPIO chip of the bank.
  * @grange: linux gpio pin range supported by this bank.
  * @slock: spinlock protecting bank registers
+ * @pm_save: saved register values during suspend
  */
 struct samsung_pin_bank {
        struct samsung_pin_bank_type *type;
@@ -138,12 +139,15 @@ struct samsung_pin_bank {
        u32             eint_mask;
        u32             eint_offset;
        char            *name;
+       void            *soc_priv;
        struct device_node *of_node;
        struct samsung_pinctrl_drv_data *drvdata;
        struct irq_domain *irq_domain;
        struct gpio_chip gpio_chip;
        struct pinctrl_gpio_range grange;
        spinlock_t slock;
+
+       u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/
 };
 
 /**
@@ -184,11 +188,15 @@ struct samsung_pin_ctrl {
 
        int             (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
        int             (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
+       void            (*suspend)(struct samsung_pinctrl_drv_data *);
+       void            (*resume)(struct samsung_pinctrl_drv_data *);
+
        char            *label;
 };
 
 /**
  * struct samsung_pinctrl_drv_data: wrapper for holding driver data together.
+ * @node: global list node
  * @virt_base: register base address of the controller.
  * @dev: device instance representing the controller.
  * @irq: interrpt number used by the controller to notify gpio interrupts.
@@ -201,6 +209,7 @@ struct samsung_pin_ctrl {
  * @nr_function: number of such pin functions.
  */
 struct samsung_pinctrl_drv_data {
+       struct list_head                node;
        void __iomem                    *virt_base;
        struct device                   *dev;
        int                             irq;
index c52fc2c..b7d8c89 100644 (file)
@@ -1990,8 +1990,10 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
        }
 
        clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(clk))
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
                goto gpiochip_error;
+       }
 
        clk_prepare_enable(clk);
 
@@ -2000,7 +2002,8 @@ static int sunxi_pinctrl_probe(struct platform_device *pdev)
        return 0;
 
 gpiochip_error:
-       ret = gpiochip_remove(pctl->chip);
+       if (gpiochip_remove(pctl->chip))
+               dev_err(&pdev->dev, "failed to remove gpio chip\n");
 pinctrl_error:
        pinctrl_unregister(pctl->pctl_dev);
        return ret;
index 791a671..8cd90e7 100644 (file)
@@ -2357,27 +2357,48 @@ static const unsigned int sdhi3_wp_mux[] = {
 };
 /* - USB0 ------------------------------------------------------------------- */
 static const unsigned int usb0_pins[] = {
-       /* OVC */
-       150, 154,
+       /* PENC */
+       154,
 };
 static const unsigned int usb0_mux[] = {
-       USB_OVC0_MARK, USB_PENC0_MARK,
+       USB_PENC0_MARK,
+};
+static const unsigned int usb0_ovc_pins[] = {
+       /* USB_OVC */
+       150
+};
+static const unsigned int usb0_ovc_mux[] = {
+       USB_OVC0_MARK,
 };
 /* - USB1 ------------------------------------------------------------------- */
 static const unsigned int usb1_pins[] = {
-       /* OVC */
-       152, 155,
+       /* PENC */
+       155,
 };
 static const unsigned int usb1_mux[] = {
-       USB_OVC1_MARK, USB_PENC1_MARK,
+       USB_PENC1_MARK,
+};
+static const unsigned int usb1_ovc_pins[] = {
+       /* USB_OVC */
+       152,
+};
+static const unsigned int usb1_ovc_mux[] = {
+       USB_OVC1_MARK,
 };
 /* - USB2 ------------------------------------------------------------------- */
 static const unsigned int usb2_pins[] = {
-       /* OVC, PENC */
-       125, 156,
+       /* PENC */
+       156,
 };
 static const unsigned int usb2_mux[] = {
-       USB_OVC2_MARK, USB_PENC2_MARK,
+       USB_PENC2_MARK,
+};
+static const unsigned int usb2_ovc_pins[] = {
+       /* USB_OVC */
+       125,
+};
+static const unsigned int usb2_ovc_mux[] = {
+       USB_OVC2_MARK,
 };
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
@@ -2501,8 +2522,11 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
        SH_PFC_PIN_GROUP(sdhi3_cd),
        SH_PFC_PIN_GROUP(sdhi3_wp),
        SH_PFC_PIN_GROUP(usb0),
+       SH_PFC_PIN_GROUP(usb0_ovc),
        SH_PFC_PIN_GROUP(usb1),
+       SH_PFC_PIN_GROUP(usb1_ovc),
        SH_PFC_PIN_GROUP(usb2),
+       SH_PFC_PIN_GROUP(usb2_ovc),
 };
 
 static const char * const du0_groups[] = {
@@ -2683,14 +2707,17 @@ static const char * const sdhi3_groups[] = {
 
 static const char * const usb0_groups[] = {
        "usb0",
+       "usb0_ovc",
 };
 
 static const char * const usb1_groups[] = {
        "usb1",
+       "usb1_ovc",
 };
 
 static const char * const usb2_groups[] = {
        "usb2",
+       "usb2_ovc",
 };
 
 static const struct sh_pfc_function pinmux_functions[] = {
index ab63104..70d986e 100644 (file)
@@ -609,8 +609,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
        return 0;
 
 fail_range:
-       err = gpiochip_remove(&data->gpio_chip);
-       if (err)
+       if (gpiochip_remove(&data->gpio_chip))
                dev_err(&pdev->dev, "failed to remove gpio chip\n");
 fail_gpio:
        pinctrl_unregister(data->pctl_dev);
index 8df0c5a..d111c86 100644 (file)
@@ -703,7 +703,7 @@ static int hp_wmi_rfkill_setup(struct platform_device *device)
                }
                rfkill_init_sw_state(gps_rfkill,
                                     hp_wmi_get_sw_state(HPWMI_GPS));
-               rfkill_set_hw_state(bluetooth_rfkill,
+               rfkill_set_hw_state(gps_rfkill,
                                    hp_wmi_get_hw_state(HPWMI_GPS));
                err = rfkill_register(gps_rfkill);
                if (err)
index bea9451..71a2559 100644 (file)
@@ -628,9 +628,10 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        chip->caps = ptp_pch_caps;
        chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev);
-
-       if (IS_ERR(chip->ptp_clock))
-               return PTR_ERR(chip->ptp_clock);
+       if (IS_ERR(chip->ptp_clock)) {
+               ret = PTR_ERR(chip->ptp_clock);
+               goto err_ptp_clock_reg;
+       }
 
        spin_lock_init(&chip->register_lock);
 
@@ -669,6 +670,7 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 err_req_irq:
        ptp_clock_unregister(chip->ptp_clock);
+err_ptp_clock_reg:
        iounmap(chip->regs);
        chip->regs = NULL;
 
index 6e50178..815d6df 100644 (file)
@@ -1539,7 +1539,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
 }
 
 /**
- * Balance enable_count of each GPIO and actual GPIO pin control.
+ * regulator_ena_gpio_ctrl - balance enable_count of each GPIO and actual GPIO pin control
+ * @rdev: regulator_dev structure
+ * @enable: enable GPIO at initial use?
+ *
  * GPIO is enabled in case of initial use. (enable_count is 0)
  * GPIO is disabled when it is not shared any more. (enable_count <= 1)
  */
@@ -2702,7 +2705,7 @@ EXPORT_SYMBOL_GPL(regulator_get_voltage);
 /**
  * regulator_set_current_limit - set regulator output current limit
  * @regulator: regulator source
- * @min_uA: Minimuum supported current in uA
+ * @min_uA: Minimum supported current in uA
  * @max_uA: Maximum supported current in uA
  *
  * Sets current sink to the desired output current. This can be set during
index 89bd2fa..ce89f78 100644 (file)
 static int power_state_active_cnt; /* will initialize to zero */
 static DEFINE_SPINLOCK(power_state_active_lock);
 
-int power_state_active_get(void)
-{
-       unsigned long flags;
-       int cnt;
-
-       spin_lock_irqsave(&power_state_active_lock, flags);
-       cnt = power_state_active_cnt;
-       spin_unlock_irqrestore(&power_state_active_lock, flags);
-
-       return cnt;
-}
-
 void power_state_active_enable(void)
 {
        unsigned long flags;
@@ -65,6 +53,18 @@ out:
 
 #ifdef CONFIG_REGULATOR_DEBUG
 
+static int power_state_active_get(void)
+{
+       unsigned long flags;
+       int cnt;
+
+       spin_lock_irqsave(&power_state_active_lock, flags);
+       cnt = power_state_active_cnt;
+       spin_unlock_irqrestore(&power_state_active_lock, flags);
+
+       return cnt;
+}
+
 static struct ux500_regulator_debug {
        struct dentry *dir;
        struct dentry *status_file;
index 92ceed0..3ae44ac 100644 (file)
@@ -840,7 +840,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                        break;
                }
 
-               if ((id == PALMAS_REG_SMPS6) && (id == PALMAS_REG_SMPS8))
+               if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8))
                        ramp_delay_support = true;
 
                if (ramp_delay_support) {
@@ -878,7 +878,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                        pmic->desc[id].vsel_mask = SMPS10_VSEL;
                        pmic->desc[id].enable_reg =
                                        PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                                       PALMAS_SMPS10_STATUS);
+                                                       PALMAS_SMPS10_CTRL);
                        pmic->desc[id].enable_mask = SMPS10_BOOST_EN;
                        pmic->desc[id].min_uV = 3750000;
                        pmic->desc[id].uV_step = 1250000;
index 0eab77b..f296f3f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/interrupt.h>
+#include <linux/spinlock.h>
 #include <linux/ioctl.h>
 #include <linux/completion.h>
 #include <linux/io.h>
 
 #define AT91_RTC_EPOCH         1900UL  /* just like arch/arm/common/rtctime.c */
 
+struct at91_rtc_config {
+       bool use_shadow_imr;
+};
+
+static const struct at91_rtc_config *at91_rtc_config;
 static DECLARE_COMPLETION(at91_rtc_updated);
 static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
 static void __iomem *at91_rtc_regs;
 static int irq;
+static DEFINE_SPINLOCK(at91_rtc_lock);
+static u32 at91_rtc_shadow_imr;
+
+static void at91_rtc_write_ier(u32 mask)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&at91_rtc_lock, flags);
+       at91_rtc_shadow_imr |= mask;
+       at91_rtc_write(AT91_RTC_IER, mask);
+       spin_unlock_irqrestore(&at91_rtc_lock, flags);
+}
+
+static void at91_rtc_write_idr(u32 mask)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&at91_rtc_lock, flags);
+       at91_rtc_write(AT91_RTC_IDR, mask);
+       /*
+        * Register read back (of any RTC-register) needed to make sure
+        * IDR-register write has reached the peripheral before updating
+        * shadow mask.
+        *
+        * Note that there is still a possibility that the mask is updated
+        * before interrupts have actually been disabled in hardware. The only
+        * way to be certain would be to poll the IMR-register, which is is
+        * the very register we are trying to emulate. The register read back
+        * is a reasonable heuristic.
+        */
+       at91_rtc_read(AT91_RTC_SR);
+       at91_rtc_shadow_imr &= ~mask;
+       spin_unlock_irqrestore(&at91_rtc_lock, flags);
+}
+
+static u32 at91_rtc_read_imr(void)
+{
+       unsigned long flags;
+       u32 mask;
+
+       if (at91_rtc_config->use_shadow_imr) {
+               spin_lock_irqsave(&at91_rtc_lock, flags);
+               mask = at91_rtc_shadow_imr;
+               spin_unlock_irqrestore(&at91_rtc_lock, flags);
+       } else {
+               mask = at91_rtc_read(AT91_RTC_IMR);
+       }
+
+       return mask;
+}
 
 /*
  * Decode time/date into rtc_time structure
@@ -110,9 +166,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
        cr = at91_rtc_read(AT91_RTC_CR);
        at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM);
 
-       at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD);
+       at91_rtc_write_ier(AT91_RTC_ACKUPD);
        wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */
-       at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD);
+       at91_rtc_write_idr(AT91_RTC_ACKUPD);
 
        at91_rtc_write(AT91_RTC_TIMR,
                          bin2bcd(tm->tm_sec) << 0
@@ -144,7 +200,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
        tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
        tm->tm_year = at91_alarm_year - 1900;
 
-       alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM)
+       alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM)
                        ? 1 : 0;
 
        dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
@@ -169,7 +225,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
        tm.tm_min = alrm->time.tm_min;
        tm.tm_sec = alrm->time.tm_sec;
 
-       at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
+       at91_rtc_write_idr(AT91_RTC_ALARM);
        at91_rtc_write(AT91_RTC_TIMALR,
                  bin2bcd(tm.tm_sec) << 0
                | bin2bcd(tm.tm_min) << 8
@@ -182,7 +238,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        if (alrm->enabled) {
                at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
-               at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
+               at91_rtc_write_ier(AT91_RTC_ALARM);
        }
 
        dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
@@ -198,9 +254,9 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
        if (enabled) {
                at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
-               at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM);
+               at91_rtc_write_ier(AT91_RTC_ALARM);
        } else
-               at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM);
+               at91_rtc_write_idr(AT91_RTC_ALARM);
 
        return 0;
 }
@@ -209,7 +265,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  */
 static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       unsigned long imr = at91_rtc_read(AT91_RTC_IMR);
+       unsigned long imr = at91_rtc_read_imr();
 
        seq_printf(seq, "update_IRQ\t: %s\n",
                        (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
@@ -229,7 +285,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
        unsigned int rtsr;
        unsigned long events = 0;
 
-       rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR);
+       rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read_imr();
        if (rtsr) {             /* this interrupt is shared!  Is it ours? */
                if (rtsr & AT91_RTC_ALARM)
                        events |= (RTC_AF | RTC_IRQF);
@@ -250,6 +306,43 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
        return IRQ_NONE;                /* not handled */
 }
 
+static const struct at91_rtc_config at91rm9200_config = {
+};
+
+static const struct at91_rtc_config at91sam9x5_config = {
+       .use_shadow_imr = true,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id at91_rtc_dt_ids[] = {
+       {
+               .compatible = "atmel,at91rm9200-rtc",
+               .data = &at91rm9200_config,
+       }, {
+               .compatible = "atmel,at91sam9x5-rtc",
+               .data = &at91sam9x5_config,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
+#endif
+
+static const struct at91_rtc_config *
+at91_rtc_get_config(struct platform_device *pdev)
+{
+       const struct of_device_id *match;
+
+       if (pdev->dev.of_node) {
+               match = of_match_node(at91_rtc_dt_ids, pdev->dev.of_node);
+               if (!match)
+                       return NULL;
+               return (const struct at91_rtc_config *)match->data;
+       }
+
+       return &at91rm9200_config;
+}
+
 static const struct rtc_class_ops at91_rtc_ops = {
        .read_time      = at91_rtc_readtime,
        .set_time       = at91_rtc_settime,
@@ -268,6 +361,10 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
        struct resource *regs;
        int ret = 0;
 
+       at91_rtc_config = at91_rtc_get_config(pdev);
+       if (!at91_rtc_config)
+               return -ENODEV;
+
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!regs) {
                dev_err(&pdev->dev, "no mmio resource defined\n");
@@ -290,7 +387,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
        at91_rtc_write(AT91_RTC_MR, 0);         /* 24 hour mode */
 
        /* Disable all interrupts */
-       at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
+       at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
                                        AT91_RTC_SECEV | AT91_RTC_TIMEV |
                                        AT91_RTC_CALEV);
 
@@ -335,7 +432,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
        struct rtc_device *rtc = platform_get_drvdata(pdev);
 
        /* Disable all interrupts */
-       at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM |
+       at91_rtc_write_idr(AT91_RTC_ACKUPD | AT91_RTC_ALARM |
                                        AT91_RTC_SECEV | AT91_RTC_TIMEV |
                                        AT91_RTC_CALEV);
        free_irq(irq, pdev);
@@ -358,13 +455,13 @@ static int at91_rtc_suspend(struct device *dev)
        /* this IRQ is shared with DBGU and other hardware which isn't
         * necessarily doing PM like we are...
         */
-       at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR)
+       at91_rtc_imr = at91_rtc_read_imr()
                        & (AT91_RTC_ALARM|AT91_RTC_SECEV);
        if (at91_rtc_imr) {
                if (device_may_wakeup(dev))
                        enable_irq_wake(irq);
                else
-                       at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr);
+                       at91_rtc_write_idr(at91_rtc_imr);
        }
        return 0;
 }
@@ -375,7 +472,7 @@ static int at91_rtc_resume(struct device *dev)
                if (device_may_wakeup(dev))
                        disable_irq_wake(irq);
                else
-                       at91_rtc_write(AT91_RTC_IER, at91_rtc_imr);
+                       at91_rtc_write_ier(at91_rtc_imr);
        }
        return 0;
 }
@@ -383,12 +480,6 @@ static int at91_rtc_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume);
 
-static const struct of_device_id at91_rtc_dt_ids[] = {
-       { .compatible = "atmel,at91rm9200-rtc" },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids);
-
 static struct platform_driver at91_rtc_driver = {
        .remove         = __exit_p(at91_rtc_remove),
        .driver         = {
index cc5bea9..f1cb706 100644 (file)
@@ -854,6 +854,9 @@ static int cmos_resume(struct device *dev)
                }
 
                spin_lock_irq(&rtc_lock);
+               if (device_may_wakeup(dev))
+                       hpet_rtc_timer_init();
+
                do {
                        CMOS_WRITE(tmp, RTC_CONTROL);
                        hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
@@ -869,7 +872,6 @@ static int cmos_resume(struct device *dev)
                        rtc_update_irq(cmos->rtc, 1, mask);
                        tmp &= ~RTC_AIE;
                        hpet_mask_rtc_irq_bit(RTC_AIE);
-                       hpet_rtc_timer_init();
                } while (mask & RTC_AIE);
                spin_unlock_irq(&rtc_lock);
        }
index 459c2ff..426901c 100644 (file)
@@ -273,6 +273,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
                return ret;
        }
 
+       device_init_wakeup(&pdev->dev, 1);
+
        platform_set_drvdata(pdev, rtc);
        rtc->rtc = devm_rtc_device_register(&pdev->dev, dev_name(&pdev->dev),
                                       &tps6586x_rtc_ops, THIS_MODULE);
@@ -292,7 +294,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
                goto fail_rtc_register;
        }
        disable_irq(rtc->irq);
-       device_set_wakeup_capable(&pdev->dev, 1);
        return 0;
 
 fail_rtc_register:
index 8751a52..b2eab34 100644 (file)
@@ -524,6 +524,7 @@ static int twl_rtc_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, rtc);
+       device_init_wakeup(&pdev->dev, 1);
        return 0;
 
 out2:
index 4361d97..d72a921 100644 (file)
@@ -3440,8 +3440,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
                        device->path_data.opm &= ~eventlpm;
                        device->path_data.ppm &= ~eventlpm;
                        device->path_data.npm &= ~eventlpm;
-                       if (oldopm && !device->path_data.opm)
-                               dasd_generic_last_path_gone(device);
+                       if (oldopm && !device->path_data.opm) {
+                               dev_warn(&device->cdev->dev,
+                                        "No verified channel paths remain "
+                                        "for the device\n");
+                               DBF_DEV_EVENT(DBF_WARNING, device,
+                                             "%s", "last verified path gone");
+                               dasd_eer_write(device, NULL, DASD_EER_NOPATH);
+                               dasd_device_set_stop_bits(device,
+                                                         DASD_STOPPED_DC_WAIT);
+                       }
                }
                if (path_event[chp] & PE_PATH_AVAILABLE) {
                        device->path_data.opm &= ~eventlpm;
index 4ffa66c..9ca3996 100644 (file)
@@ -2040,6 +2040,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
                           netiucv_setup_netdevice);
        if (!dev)
                return NULL;
+       rtnl_lock();
        if (dev_alloc_name(dev, dev->name) < 0)
                goto out_netdev;
 
@@ -2061,6 +2062,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
 out_fsm:
        kfree_fsm(privptr->fsm);
 out_netdev:
+       rtnl_unlock();
        free_netdev(dev);
        return NULL;
 }
@@ -2100,6 +2102,7 @@ static ssize_t conn_write(struct device_driver *drv,
 
        rc = netiucv_register_device(dev);
        if (rc) {
+               rtnl_unlock();
                IUCV_DBF_TEXT_(setup, 2,
                        "ret %d from netiucv_register_device\n", rc);
                goto out_free_ndev;
@@ -2109,7 +2112,8 @@ static ssize_t conn_write(struct device_driver *drv,
        priv = netdev_priv(dev);
        SET_NETDEV_DEV(dev, priv->dev);
 
-       rc = register_netdev(dev);
+       rc = register_netdevice(dev);
+       rtnl_unlock();
        if (rc)
                goto out_unreg;
 
index d182c96..7a3870f 100644 (file)
@@ -1370,7 +1370,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
                dump_stack();
                return;
        }
-       target_wait_for_sess_cmds(se_sess, 0);
+       target_wait_for_sess_cmds(se_sess);
 
        transport_deregister_session_configfs(sess->se_sess);
        transport_deregister_session(sess->se_sess);
index db66357..86f0c5d 100644 (file)
@@ -84,6 +84,7 @@ static int proc_scsi_host_open(struct inode *inode, struct file *file)
 
 static const struct file_operations proc_scsi_fops = {
        .open = proc_scsi_host_open,
+       .release = single_release,
        .read = seq_read,
        .llseek = seq_lseek,
        .write = proc_scsi_host_write
index 60cfae5..eab593e 100644 (file)
@@ -89,7 +89,7 @@ static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val)
                if ((mask & hspi_read(hspi, SPSR)) == val)
                        return 0;
 
-               msleep(20);
+               udelay(10);
        }
 
        dev_err(hspi->dev, "timeout\n");
index 35f60bd..637d728 100644 (file)
@@ -1487,7 +1487,7 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)
        return 0;
 
 err_spi_register_master:
-       free_irq(board_dat->pdev->irq, board_dat);
+       free_irq(board_dat->pdev->irq, data);
 err_request_irq:
        pch_spi_free_resources(board_dat, data);
 err_spi_get_resources:
@@ -1667,6 +1667,7 @@ static int pch_spi_probe(struct pci_dev *pdev,
                pd_dev = platform_device_alloc("pch-spi", i);
                if (!pd_dev) {
                        dev_err(&pdev->dev, "platform_device_alloc failed\n");
+                       retval = -ENOMEM;
                        goto err_platform_device;
                }
                pd_dev_save->pd_save[i] = pd_dev;
index e1d7696..34d18dc 100644 (file)
@@ -267,7 +267,6 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
        struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
        u32 ipif_ier;
-       u16 cr;
 
        /* We get here with transmitter inhibited */
 
@@ -276,7 +275,6 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
        xspi->remaining_bytes = t->len;
        INIT_COMPLETION(xspi->done);
 
-       xilinx_spi_fill_tx_fifo(xspi);
 
        /* Enable the transmit empty interrupt, which we use to determine
         * progress on the transmission.
@@ -285,12 +283,41 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
        xspi->write_fn(ipif_ier | XSPI_INTR_TX_EMPTY,
                xspi->regs + XIPIF_V123B_IIER_OFFSET);
 
-       /* Start the transfer by not inhibiting the transmitter any longer */
-       cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) &
-               ~XSPI_CR_TRANS_INHIBIT;
-       xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
+       for (;;) {
+               u16 cr;
+               u8 sr;
+
+               xilinx_spi_fill_tx_fifo(xspi);
+
+               /* Start the transfer by not inhibiting the transmitter any
+                * longer
+                */
+               cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) &
+                                                       ~XSPI_CR_TRANS_INHIBIT;
+               xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
+
+               wait_for_completion(&xspi->done);
+
+               /* A transmit has just completed. Process received data and
+                * check for more data to transmit. Always inhibit the
+                * transmitter while the Isr refills the transmit register/FIFO,
+                * or make sure it is stopped if we're done.
+                */
+               cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
+               xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
+                              xspi->regs + XSPI_CR_OFFSET);
+
+               /* Read out all the data from the Rx FIFO */
+               sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
+               while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) {
+                       xspi->rx_fn(xspi);
+                       sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
+               }
 
-       wait_for_completion(&xspi->done);
+               /* See if there is more data to send */
+               if (!xspi->remaining_bytes > 0)
+                       break;
+       }
 
        /* Disable the transmit empty interrupt */
        xspi->write_fn(ipif_ier, xspi->regs + XIPIF_V123B_IIER_OFFSET);
@@ -314,38 +341,7 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id)
        xspi->write_fn(ipif_isr, xspi->regs + XIPIF_V123B_IISR_OFFSET);
 
        if (ipif_isr & XSPI_INTR_TX_EMPTY) {    /* Transmission completed */
-               u16 cr;
-               u8 sr;
-
-               /* A transmit has just completed. Process received data and
-                * check for more data to transmit. Always inhibit the
-                * transmitter while the Isr refills the transmit register/FIFO,
-                * or make sure it is stopped if we're done.
-                */
-               cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
-               xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
-                       xspi->regs + XSPI_CR_OFFSET);
-
-               /* Read out all the data from the Rx FIFO */
-               sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
-               while ((sr & XSPI_SR_RX_EMPTY_MASK) == 0) {
-                       xspi->rx_fn(xspi);
-                       sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
-               }
-
-               /* See if there is more data to send */
-               if (xspi->remaining_bytes > 0) {
-                       xilinx_spi_fill_tx_fifo(xspi);
-                       /* Start the transfer by not inhibiting the
-                        * transmitter any longer
-                        */
-                       xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
-               } else {
-                       /* No more data to send.
-                        * Indicate the transfer is completed.
-                        */
-                       complete(&xspi->done);
-               }
+               complete(&xspi->done);
        }
 
        return IRQ_HANDLED;
index ceb1c64..6dc27da 100644 (file)
@@ -264,6 +264,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        }
 
        rv = alarm_do_ioctl(file, cmd, &ts);
+       if (rv)
+               return rv;
 
        switch (ANDROID_ALARM_BASE_CMD(cmd)) {
        case ANDROID_ALARM_GET_TIME(0):
@@ -272,7 +274,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
        }
 
-       return rv;
+       return 0;
 }
 #ifdef CONFIG_COMPAT
 static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
@@ -295,6 +297,8 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
        }
 
        rv = alarm_do_ioctl(file, cmd, &ts);
+       if (rv)
+               return rv;
 
        switch (ANDROID_ALARM_BASE_CMD(cmd)) {
        case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
@@ -303,7 +307,7 @@ static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
                break;
        }
 
-       return rv;
+       return 0;
 }
 #endif
 
index 827ab78..8551cce 100644 (file)
@@ -2804,9 +2804,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
 
        /* Set device flags indicating whether the HCD supports DMA */
        if (hsotg->core_params->dma_enable > 0) {
-               if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0)
-                       dev_warn(hsotg->dev,
-                                "can't enable workaround for >2GB RAM\n");
+               if (dma_set_mask(hsotg->dev, DMA_BIT_MASK(32)) < 0)
+                       dev_warn(hsotg->dev, "can't set DMA mask\n");
                if (dma_set_coherent_mask(hsotg->dev, DMA_BIT_MASK(31)) < 0)
                        dev_warn(hsotg->dev,
                                 "can't enable workaround for >2GB RAM\n");
index ea61c86..ff5c633 100644 (file)
@@ -316,31 +316,14 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
 
 static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
 {
-       struct drm_pending_vblank_event *e;
-       struct timeval now;
        unsigned long flags;
        struct drm_device *drm = ipu_crtc->base.dev;
 
        spin_lock_irqsave(&drm->event_lock, flags);
-
-       e = ipu_crtc->page_flip_event;
-       if (!e) {
-               spin_unlock_irqrestore(&drm->event_lock, flags);
-               return;
-       }
-
-       do_gettimeofday(&now);
-       e->event.sequence = 0;
-       e->event.tv_sec = now.tv_sec;
-       e->event.tv_usec = now.tv_usec;
+       if (ipu_crtc->page_flip_event)
+               drm_send_vblank_event(drm, -1, ipu_crtc->page_flip_event);
        ipu_crtc->page_flip_event = NULL;
-
        imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc);
-
-       list_add_tail(&e->base.link, &e->base.file_priv->event_list);
-
-       wake_up_interruptible(&e->base.file_priv->event_wait);
-
        spin_unlock_irqrestore(&drm->event_lock, flags);
 }
 
index e1f91d5..a858666 100644 (file)
 #ifndef _ZCACHE_RAMSTER_H_
 #define _ZCACHE_RAMSTER_H_
 
-#ifdef CONFIG_RAMSTER_MODULE
-#define CONFIG_RAMSTER
-#endif
-
 #ifdef CONFIG_RAMSTER
 #include "ramster/ramster.h"
 #else
index 327e4f0..5b26ee9 100644 (file)
@@ -1,6 +1,8 @@
 #include <linux/atomic.h>
 #include "debug.h"
 
+ssize_t ramster_foreign_eph_pages;
+ssize_t ramster_foreign_pers_pages;
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 
index b18b887..a937ce1 100644 (file)
@@ -66,8 +66,6 @@ static int ramster_remote_target_nodenum __read_mostly = -1;
 
 /* Used by this code. */
 long ramster_flnodes;
-ssize_t ramster_foreign_eph_pages;
-ssize_t ramster_foreign_pers_pages;
 /* FIXME frontswap selfshrinking knobs in debugfs? */
 
 static LIST_HEAD(ramster_rem_op_list);
@@ -399,14 +397,18 @@ void ramster_count_foreign_pages(bool eph, int count)
                        inc_ramster_foreign_eph_pages();
                } else {
                        dec_ramster_foreign_eph_pages();
+#ifdef CONFIG_RAMSTER_DEBUG
                        WARN_ON_ONCE(ramster_foreign_eph_pages < 0);
+#endif
                }
        } else {
                if (count > 0) {
                        inc_ramster_foreign_pers_pages();
                } else {
                        dec_ramster_foreign_pers_pages();
+#ifdef CONFIG_RAMSTER_DEBUG
                        WARN_ON_ONCE(ramster_foreign_pers_pages < 0);
+#endif
                }
        }
 }
index 262ef1f..d7705e5 100644 (file)
@@ -651,7 +651,7 @@ static int iscsit_add_reject(
        cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
        if (!cmd->buf_ptr) {
                pr_err("Unable to allocate memory for cmd->buf_ptr\n");
-               iscsit_release_cmd(cmd);
+               iscsit_free_cmd(cmd, false);
                return -1;
        }
 
@@ -697,7 +697,7 @@ int iscsit_add_reject_from_cmd(
        cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
        if (!cmd->buf_ptr) {
                pr_err("Unable to allocate memory for cmd->buf_ptr\n");
-               iscsit_release_cmd(cmd);
+               iscsit_free_cmd(cmd, false);
                return -1;
        }
 
@@ -1743,7 +1743,7 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
        return 0;
 out:
        if (cmd)
-               iscsit_release_cmd(cmd);
+               iscsit_free_cmd(cmd, false);
 ping_out:
        kfree(ping_data);
        return ret;
@@ -2251,7 +2251,7 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
        if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) {
                pr_err("Received logout request on connection that"
                        " is not in logged in state, ignoring request.\n");
-               iscsit_release_cmd(cmd);
+               iscsit_free_cmd(cmd, false);
                return 0;
        }
 
@@ -3665,7 +3665,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state
                list_del(&cmd->i_conn_node);
                spin_unlock_bh(&conn->cmd_lock);
 
-               iscsit_free_cmd(cmd);
+               iscsit_free_cmd(cmd, false);
                break;
        case ISTATE_SEND_NOPIN_WANT_RESPONSE:
                iscsit_mod_nopin_response_timer(conn);
@@ -4122,7 +4122,7 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn)
 
                iscsit_increment_maxcmdsn(cmd, sess);
 
-               iscsit_free_cmd(cmd);
+               iscsit_free_cmd(cmd, true);
 
                spin_lock_bh(&conn->cmd_lock);
        }
index ba6091b..45a5afd 100644 (file)
@@ -143,7 +143,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess)
                        list_del(&cmd->i_conn_node);
                        cmd->conn = NULL;
                        spin_unlock(&cr->conn_recovery_cmd_lock);
-                       iscsit_free_cmd(cmd);
+                       iscsit_free_cmd(cmd, true);
                        spin_lock(&cr->conn_recovery_cmd_lock);
                }
                spin_unlock(&cr->conn_recovery_cmd_lock);
@@ -165,7 +165,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess)
                        list_del(&cmd->i_conn_node);
                        cmd->conn = NULL;
                        spin_unlock(&cr->conn_recovery_cmd_lock);
-                       iscsit_free_cmd(cmd);
+                       iscsit_free_cmd(cmd, true);
                        spin_lock(&cr->conn_recovery_cmd_lock);
                }
                spin_unlock(&cr->conn_recovery_cmd_lock);
@@ -248,7 +248,7 @@ void iscsit_discard_cr_cmds_by_expstatsn(
                iscsit_remove_cmd_from_connection_recovery(cmd, sess);
 
                spin_unlock(&cr->conn_recovery_cmd_lock);
-               iscsit_free_cmd(cmd);
+               iscsit_free_cmd(cmd, true);
                spin_lock(&cr->conn_recovery_cmd_lock);
        }
        spin_unlock(&cr->conn_recovery_cmd_lock);
@@ -302,7 +302,7 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn)
                list_del(&cmd->i_conn_node);
 
                spin_unlock_bh(&conn->cmd_lock);
-               iscsit_free_cmd(cmd);
+               iscsit_free_cmd(cmd, true);
                spin_lock_bh(&conn->cmd_lock);
        }
        spin_unlock_bh(&conn->cmd_lock);
@@ -355,7 +355,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
 
                        list_del(&cmd->i_conn_node);
                        spin_unlock_bh(&conn->cmd_lock);
-                       iscsit_free_cmd(cmd);
+                       iscsit_free_cmd(cmd, true);
                        spin_lock_bh(&conn->cmd_lock);
                        continue;
                }
@@ -375,7 +375,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
                     iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) {
                        list_del(&cmd->i_conn_node);
                        spin_unlock_bh(&conn->cmd_lock);
-                       iscsit_free_cmd(cmd);
+                       iscsit_free_cmd(cmd, true);
                        spin_lock_bh(&conn->cmd_lock);
                        continue;
                }
index c2185fc..e382221 100644 (file)
@@ -758,9 +758,9 @@ static int iscsi_add_notunderstood_response(
        }
        INIT_LIST_HEAD(&extra_response->er_list);
 
-       strncpy(extra_response->key, key, strlen(key) + 1);
-       strncpy(extra_response->value, NOTUNDERSTOOD,
-                       strlen(NOTUNDERSTOOD) + 1);
+       strlcpy(extra_response->key, key, sizeof(extra_response->key));
+       strlcpy(extra_response->value, NOTUNDERSTOOD,
+               sizeof(extra_response->value));
 
        list_add_tail(&extra_response->er_list,
                        &param_list->extra_response_list);
@@ -1629,8 +1629,6 @@ int iscsi_decode_text_input(
 
                if (phase & PHASE_SECURITY) {
                        if (iscsi_check_for_auth_key(key) > 0) {
-                               char *tmpptr = key + strlen(key);
-                               *tmpptr = '=';
                                kfree(tmpbuf);
                                return 1;
                        }
index 915b067..a47046a 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef ISCSI_PARAMETERS_H
 #define ISCSI_PARAMETERS_H
 
+#include <scsi/iscsi_proto.h>
+
 struct iscsi_extra_response {
-       char key[64];
+       char key[KEY_MAXLEN];
        char value[32];
        struct list_head er_list;
 } ____cacheline_aligned;
index 2cc6c9a..08a3bac 100644 (file)
@@ -676,40 +676,56 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
 
 void iscsit_release_cmd(struct iscsi_cmd *cmd)
 {
-       struct iscsi_conn *conn = cmd->conn;
-
-       iscsit_free_r2ts_from_list(cmd);
-       iscsit_free_all_datain_reqs(cmd);
-
        kfree(cmd->buf_ptr);
        kfree(cmd->pdu_list);
        kfree(cmd->seq_list);
        kfree(cmd->tmr_req);
        kfree(cmd->iov_data);
 
-       if (conn) {
+       kmem_cache_free(lio_cmd_cache, cmd);
+}
+
+static void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd,
+                             bool check_queues)
+{
+       struct iscsi_conn *conn = cmd->conn;
+
+       if (scsi_cmd) {
+               if (cmd->data_direction == DMA_TO_DEVICE) {
+                       iscsit_stop_dataout_timer(cmd);
+                       iscsit_free_r2ts_from_list(cmd);
+               }
+               if (cmd->data_direction == DMA_FROM_DEVICE)
+                       iscsit_free_all_datain_reqs(cmd);
+       }
+
+       if (conn && check_queues) {
                iscsit_remove_cmd_from_immediate_queue(cmd, conn);
                iscsit_remove_cmd_from_response_queue(cmd, conn);
        }
-
-       kmem_cache_free(lio_cmd_cache, cmd);
 }
 
-void iscsit_free_cmd(struct iscsi_cmd *cmd)
+void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
 {
+       struct se_cmd *se_cmd = NULL;
+       int rc;
        /*
         * Determine if a struct se_cmd is associated with
         * this struct iscsi_cmd.
         */
        switch (cmd->iscsi_opcode) {
        case ISCSI_OP_SCSI_CMD:
-               if (cmd->data_direction == DMA_TO_DEVICE)
-                       iscsit_stop_dataout_timer(cmd);
+               se_cmd = &cmd->se_cmd;
+               __iscsit_free_cmd(cmd, true, shutdown);
                /*
                 * Fallthrough
                 */
        case ISCSI_OP_SCSI_TMFUNC:
-               transport_generic_free_cmd(&cmd->se_cmd, 1);
+               rc = transport_generic_free_cmd(&cmd->se_cmd, 1);
+               if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
+                       __iscsit_free_cmd(cmd, true, shutdown);
+                       target_put_sess_cmd(se_cmd->se_sess, se_cmd);
+               }
                break;
        case ISCSI_OP_REJECT:
                /*
@@ -718,11 +734,19 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd)
                 * associated cmd->se_cmd needs to be released.
                 */
                if (cmd->se_cmd.se_tfo != NULL) {
-                       transport_generic_free_cmd(&cmd->se_cmd, 1);
+                       se_cmd = &cmd->se_cmd;
+                       __iscsit_free_cmd(cmd, true, shutdown);
+
+                       rc = transport_generic_free_cmd(&cmd->se_cmd, 1);
+                       if (!rc && shutdown && se_cmd->se_sess) {
+                               __iscsit_free_cmd(cmd, true, shutdown);
+                               target_put_sess_cmd(se_cmd->se_sess, se_cmd);
+                       }
                        break;
                }
                /* Fall-through */
        default:
+               __iscsit_free_cmd(cmd, false, shutdown);
                cmd->release_cmd(cmd);
                break;
        }
index 4f8e01a..a442265 100644 (file)
@@ -29,7 +29,7 @@ extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_co
 extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);
 extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
 extern void iscsit_release_cmd(struct iscsi_cmd *);
-extern void iscsit_free_cmd(struct iscsi_cmd *);
+extern void iscsit_free_cmd(struct iscsi_cmd *, bool);
 extern int iscsit_check_session_usage_count(struct iscsi_session *);
 extern void iscsit_dec_session_usage_count(struct iscsi_session *);
 extern void iscsit_inc_session_usage_count(struct iscsi_session *);
index 1b1d544..b11890d 100644 (file)
@@ -153,6 +153,7 @@ static int fd_configure_device(struct se_device *dev)
                struct request_queue *q = bdev_get_queue(inode->i_bdev);
                unsigned long long dev_size;
 
+               fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
                /*
                 * Determine the number of bytes from i_size_read() minus
                 * one (1) logical sector from underlying struct block_device
@@ -199,6 +200,7 @@ static int fd_configure_device(struct se_device *dev)
                        goto fail;
                }
 
+               fd_dev->fd_block_size = FD_BLOCKSIZE;
                /*
                 * Limit UNMAP emulation to 8k Number of LBAs (NoLB)
                 */
@@ -217,9 +219,7 @@ static int fd_configure_device(struct se_device *dev)
                dev->dev_attrib.max_write_same_len = 0x1000;
        }
 
-       fd_dev->fd_block_size = dev->dev_attrib.hw_block_size;
-
-       dev->dev_attrib.hw_block_size = FD_BLOCKSIZE;
+       dev->dev_attrib.hw_block_size = fd_dev->fd_block_size;
        dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS;
        dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
 
@@ -694,11 +694,12 @@ static sector_t fd_get_blocks(struct se_device *dev)
         * to handle underlying block_device resize operations.
         */
        if (S_ISBLK(i->i_mode))
-               dev_size = (i_size_read(i) - fd_dev->fd_block_size);
+               dev_size = i_size_read(i);
        else
                dev_size = fd_dev->fd_dev_size;
 
-       return div_u64(dev_size, dev->dev_attrib.block_size);
+       return div_u64(dev_size - dev->dev_attrib.block_size,
+                      dev->dev_attrib.block_size);
 }
 
 static struct sbc_ops fd_sbc_ops = {
index 4a79336..21e3158 100644 (file)
@@ -65,7 +65,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd);
 static void transport_handle_queue_full(struct se_cmd *cmd,
                struct se_device *dev);
 static int transport_generic_get_mem(struct se_cmd *cmd);
-static void transport_put_cmd(struct se_cmd *cmd);
+static int transport_put_cmd(struct se_cmd *cmd);
 static void target_complete_ok_work(struct work_struct *work);
 
 int init_se_kmem_caches(void)
@@ -221,6 +221,7 @@ struct se_session *transport_init_session(void)
        INIT_LIST_HEAD(&se_sess->sess_list);
        INIT_LIST_HEAD(&se_sess->sess_acl_list);
        INIT_LIST_HEAD(&se_sess->sess_cmd_list);
+       INIT_LIST_HEAD(&se_sess->sess_wait_list);
        spin_lock_init(&se_sess->sess_cmd_lock);
        kref_init(&se_sess->sess_kref);
 
@@ -1943,7 +1944,7 @@ static inline void transport_free_pages(struct se_cmd *cmd)
  * This routine unconditionally frees a command, and reference counting
  * or list removal must be done in the caller.
  */
-static void transport_release_cmd(struct se_cmd *cmd)
+static int transport_release_cmd(struct se_cmd *cmd)
 {
        BUG_ON(!cmd->se_tfo);
 
@@ -1955,11 +1956,11 @@ static void transport_release_cmd(struct se_cmd *cmd)
         * If this cmd has been setup with target_get_sess_cmd(), drop
         * the kref and call ->release_cmd() in kref callback.
         */
-        if (cmd->check_release != 0) {
-               target_put_sess_cmd(cmd->se_sess, cmd);
-               return;
-       }
+        if (cmd->check_release != 0)
+               return target_put_sess_cmd(cmd->se_sess, cmd);
+
        cmd->se_tfo->release_cmd(cmd);
+       return 1;
 }
 
 /**
@@ -1968,7 +1969,7 @@ static void transport_release_cmd(struct se_cmd *cmd)
  *
  * This routine releases our reference to the command and frees it if possible.
  */
-static void transport_put_cmd(struct se_cmd *cmd)
+static int transport_put_cmd(struct se_cmd *cmd)
 {
        unsigned long flags;
 
@@ -1976,7 +1977,7 @@ static void transport_put_cmd(struct se_cmd *cmd)
        if (atomic_read(&cmd->t_fe_count) &&
            !atomic_dec_and_test(&cmd->t_fe_count)) {
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               return;
+               return 0;
        }
 
        if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
@@ -1986,8 +1987,7 @@ static void transport_put_cmd(struct se_cmd *cmd)
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
        transport_free_pages(cmd);
-       transport_release_cmd(cmd);
-       return;
+       return transport_release_cmd(cmd);
 }
 
 void *transport_kmap_data_sg(struct se_cmd *cmd)
@@ -2152,13 +2152,15 @@ static void transport_write_pending_qf(struct se_cmd *cmd)
        }
 }
 
-void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
+int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 {
+       int ret = 0;
+
        if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {
                if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
                         transport_wait_for_tasks(cmd);
 
-               transport_release_cmd(cmd);
+               ret = transport_release_cmd(cmd);
        } else {
                if (wait_for_tasks)
                        transport_wait_for_tasks(cmd);
@@ -2166,8 +2168,9 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
                if (cmd->se_lun)
                        transport_lun_remove_cmd(cmd);
 
-               transport_put_cmd(cmd);
+               ret = transport_put_cmd(cmd);
        }
+       return ret;
 }
 EXPORT_SYMBOL(transport_generic_free_cmd);
 
@@ -2250,11 +2253,14 @@ void target_sess_cmd_list_set_waiting(struct se_session *se_sess)
        unsigned long flags;
 
        spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
-
-       WARN_ON(se_sess->sess_tearing_down);
+       if (se_sess->sess_tearing_down) {
+               spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+               return;
+       }
        se_sess->sess_tearing_down = 1;
+       list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list);
 
-       list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list)
+       list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list)
                se_cmd->cmd_wait_set = 1;
 
        spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
@@ -2263,44 +2269,32 @@ EXPORT_SYMBOL(target_sess_cmd_list_set_waiting);
 
 /* target_wait_for_sess_cmds - Wait for outstanding descriptors
  * @se_sess:    session to wait for active I/O
- * @wait_for_tasks:    Make extra transport_wait_for_tasks call
  */
-void target_wait_for_sess_cmds(
-       struct se_session *se_sess,
-       int wait_for_tasks)
+void target_wait_for_sess_cmds(struct se_session *se_sess)
 {
        struct se_cmd *se_cmd, *tmp_cmd;
-       bool rc = false;
+       unsigned long flags;
 
        list_for_each_entry_safe(se_cmd, tmp_cmd,
-                               &se_sess->sess_cmd_list, se_cmd_list) {
+                               &se_sess->sess_wait_list, se_cmd_list) {
                list_del(&se_cmd->se_cmd_list);
 
                pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:"
                        " %d\n", se_cmd, se_cmd->t_state,
                        se_cmd->se_tfo->get_cmd_state(se_cmd));
 
-               if (wait_for_tasks) {
-                       pr_debug("Calling transport_wait_for_tasks se_cmd: %p t_state: %d,"
-                               " fabric state: %d\n", se_cmd, se_cmd->t_state,
-                               se_cmd->se_tfo->get_cmd_state(se_cmd));
-
-                       rc = transport_wait_for_tasks(se_cmd);
-
-                       pr_debug("After transport_wait_for_tasks se_cmd: %p t_state: %d,"
-                               " fabric state: %d\n", se_cmd, se_cmd->t_state,
-                               se_cmd->se_tfo->get_cmd_state(se_cmd));
-               }
-
-               if (!rc) {
-                       wait_for_completion(&se_cmd->cmd_wait_comp);
-                       pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
-                               " fabric state: %d\n", se_cmd, se_cmd->t_state,
-                               se_cmd->se_tfo->get_cmd_state(se_cmd));
-               }
+               wait_for_completion(&se_cmd->cmd_wait_comp);
+               pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
+                       " fabric state: %d\n", se_cmd, se_cmd->t_state,
+                       se_cmd->se_tfo->get_cmd_state(se_cmd));
 
                se_cmd->se_tfo->release_cmd(se_cmd);
        }
+
+       spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+       WARN_ON(!list_empty(&se_sess->sess_cmd_list));
+       spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
 }
 EXPORT_SYMBOL(target_wait_for_sess_cmds);
 
index 46528d5..86c00b1 100644 (file)
@@ -2755,7 +2755,7 @@ static void __init serial8250_isa_init_ports(void)
        if (nr_uarts > UART_NR)
                nr_uarts = UART_NR;
 
-       for (i = 0; i < UART_NR; i++) {
+       for (i = 0; i < nr_uarts; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
                struct uart_port *port = &up->port;
 
@@ -2916,7 +2916,7 @@ static int __init serial8250_console_setup(struct console *co, char *options)
         * if so, search for the first available port that does have
         * console support.
         */
-       if (co->index >= UART_NR)
+       if (co->index >= nr_uarts)
                co->index = 0;
        port = &serial8250_ports[co->index].port;
        if (!port->iobase && !port->membase)
@@ -2957,7 +2957,7 @@ int serial8250_find_port(struct uart_port *p)
        int line;
        struct uart_port *port;
 
-       for (line = 0; line < UART_NR; line++) {
+       for (line = 0; line < nr_uarts; line++) {
                port = &serial8250_ports[line].port;
                if (uart_match_port(p, port))
                        return line;
@@ -3110,7 +3110,7 @@ static int serial8250_remove(struct platform_device *dev)
 {
        int i;
 
-       for (i = 0; i < UART_NR; i++) {
+       for (i = 0; i < nr_uarts; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
 
                if (up->port.dev == &dev->dev)
@@ -3178,7 +3178,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
        /*
         * First, find a port entry which matches.
         */
-       for (i = 0; i < UART_NR; i++)
+       for (i = 0; i < nr_uarts; i++)
                if (uart_match_port(&serial8250_ports[i].port, port))
                        return &serial8250_ports[i];
 
@@ -3187,7 +3187,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
         * free entry.  We look for one which hasn't been previously
         * used (indicated by zero iobase).
         */
-       for (i = 0; i < UART_NR; i++)
+       for (i = 0; i < nr_uarts; i++)
                if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
                    serial8250_ports[i].port.iobase == 0)
                        return &serial8250_ports[i];
@@ -3196,7 +3196,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *
         * That also failed.  Last resort is to find any entry which
         * doesn't have a real port associated with it.
         */
-       for (i = 0; i < UART_NR; i++)
+       for (i = 0; i < nr_uarts; i++)
                if (serial8250_ports[i].port.type == PORT_UNKNOWN)
                        return &serial8250_ports[i];
 
index 147c9e1..8cdfbd3 100644 (file)
@@ -761,6 +761,8 @@ static int imx_startup(struct uart_port *port)
 
        temp = readl(sport->port.membase + UCR2);
        temp |= (UCR2_RXEN | UCR2_TXEN);
+       if (!sport->have_rtscts)
+               temp |= UCR2_IRTS;
        writel(temp, sport->port.membase + UCR2);
 
        if (USE_IRDA(sport)) {
index 8942941..0c8a9fa 100644 (file)
@@ -1166,6 +1166,18 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
                ourport->tx_irq = ret;
 
        ourport->clk    = clk_get(&platdev->dev, "uart");
+       if (IS_ERR(ourport->clk)) {
+               pr_err("%s: Controller clock not found\n",
+                               dev_name(&platdev->dev));
+               return PTR_ERR(ourport->clk);
+       }
+
+       ret = clk_prepare_enable(ourport->clk);
+       if (ret) {
+               pr_err("uart: clock failed to prepare+enable: %d\n", ret);
+               clk_put(ourport->clk);
+               return ret;
+       }
 
        /* Keep all interrupts masked and cleared */
        if (s3c24xx_serial_has_interrupt_mask(port)) {
@@ -1180,6 +1192,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 
        /* reset the fifos (and setup the uart) */
        s3c24xx_serial_resetport(port, cfg);
+       clk_disable_unprepare(ourport->clk);
        return 0;
 }
 
index 49b098b..475c9c1 100644 (file)
@@ -276,8 +276,9 @@ static void ci_role_work(struct work_struct *work)
 
                ci_role_stop(ci);
                ci_role_start(ci, role);
-               enable_irq(ci->irq);
        }
+
+       enable_irq(ci->irq);
 }
 
 static irqreturn_t ci_irq(int irq, void *data)
index 519ead2..b501346 100644 (file)
@@ -1678,8 +1678,11 @@ static int udc_start(struct ci13xxx *ci)
 
        ci->gadget.ep0 = &ci->ep0in->ep;
 
-       if (ci->global_phy)
+       if (ci->global_phy) {
                ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
+               if (IS_ERR(ci->transceiver))
+                       ci->transceiver = NULL;
+       }
 
        if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
                if (ci->transceiver == NULL) {
@@ -1694,7 +1697,7 @@ static int udc_start(struct ci13xxx *ci)
                        goto put_transceiver;
        }
 
-       if (!IS_ERR_OR_NULL(ci->transceiver)) {
+       if (ci->transceiver) {
                retval = otg_set_peripheral(ci->transceiver->otg,
                                                &ci->gadget);
                if (retval)
@@ -1711,7 +1714,7 @@ static int udc_start(struct ci13xxx *ci)
        return retval;
 
 remove_trans:
-       if (!IS_ERR_OR_NULL(ci->transceiver)) {
+       if (ci->transceiver) {
                otg_set_peripheral(ci->transceiver->otg, NULL);
                if (ci->global_phy)
                        usb_put_phy(ci->transceiver);
@@ -1719,7 +1722,7 @@ remove_trans:
 
        dev_err(dev, "error = %i\n", retval);
 put_transceiver:
-       if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy)
+       if (ci->transceiver && ci->global_phy)
                usb_put_phy(ci->transceiver);
 destroy_eps:
        destroy_eps(ci);
@@ -1747,7 +1750,7 @@ static void udc_stop(struct ci13xxx *ci)
        dma_pool_destroy(ci->td_pool);
        dma_pool_destroy(ci->qh_pool);
 
-       if (!IS_ERR_OR_NULL(ci->transceiver)) {
+       if (ci->transceiver) {
                otg_set_peripheral(ci->transceiver->otg, NULL);
                if (ci->global_phy)
                        usb_put_phy(ci->transceiver);
index caefc80..c88c4fb 100644 (file)
@@ -1287,9 +1287,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        goto error;
                }
                for (totlen = u = 0; u < uurb->number_of_packets; u++) {
-                       /* arbitrary limit,
-                        * sufficient for USB 2.0 high-bandwidth iso */
-                       if (isopkt[u].length > 8192) {
+                       /*
+                        * arbitrary limit need for USB 3.0
+                        * bMaxBurst (0~15 allowed, 1~16 packets)
+                        * bmAttributes (bit 1:0, mult 0~2, 1~3 packets)
+                        * sizemax: 1024 * 16 * 3 = 49152
+                        */
+                       if (isopkt[u].length > 49152) {
                                ret = -EINVAL;
                                goto error;
                        }
index 929e7dd..8ce9d7f 100644 (file)
@@ -164,9 +164,9 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
 {
        struct dwc3_exynos      *exynos = platform_get_drvdata(pdev);
 
+       device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
        platform_device_unregister(exynos->usb2_phy);
        platform_device_unregister(exynos->usb3_phy);
-       device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
 
        clk_disable_unprepare(exynos->clk);
 
index 227d4a7..eba9e2b 100644 (file)
@@ -196,9 +196,9 @@ static void dwc3_pci_remove(struct pci_dev *pci)
 {
        struct dwc3_pci *glue = pci_get_drvdata(pci);
 
+       platform_device_unregister(glue->dwc3);
        platform_device_unregister(glue->usb2_phy);
        platform_device_unregister(glue->usb3_phy);
-       platform_device_unregister(glue->dwc3);
        pci_set_drvdata(pci, NULL);
        pci_disable_device(pci);
 }
index 2b6e7e0..b5e5b35 100644 (file)
@@ -1706,11 +1706,19 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
                dep = dwc->eps[epnum];
                if (!dep)
                        continue;
-
-               dwc3_free_trb_pool(dep);
-
-               if (epnum != 0 && epnum != 1)
+               /*
+                * Physical endpoints 0 and 1 are special; they form the
+                * bi-directional USB endpoint 0.
+                *
+                * For those two physical endpoints, we don't allocate a TRB
+                * pool nor do we add them the endpoints list. Due to that, we
+                * shouldn't do these two operations otherwise we would end up
+                * with all sorts of bugs when removing dwc3.ko.
+                */
+               if (epnum != 0 && epnum != 1) {
+                       dwc3_free_trb_pool(dep);
                        list_del(&dep->endpoint.ep_list);
+               }
 
                kfree(dep);
        }
index acff5b8..f80d033 100644 (file)
@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
 }
 
 static const unsigned char
-max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
+max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 };
 
 /* carryover low/fullspeed bandwidth that crosses uframe boundries */
 static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
@@ -646,6 +646,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
        /* reschedule QH iff another request is queued */
        if (!list_empty(&qh->qtd_list) && ehci->rh_state == EHCI_RH_RUNNING) {
                rc = qh_schedule(ehci, qh);
+               if (rc == 0) {
+                       qh_refresh(ehci, qh);
+                       qh_link_periodic(ehci, qh);
+               }
 
                /* An error here likely indicates handshake failure
                 * or no space left in the schedule.  Neither fault
@@ -653,9 +657,10 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
                 *
                 * FIXME kill the now-dysfunctional queued urbs
                 */
-               if (rc != 0)
+               else {
                        ehci_err(ehci, "can't reschedule qh %p, err %d\n",
                                        qh, rc);
+               }
        }
 
        /* maybe turn off periodic schedule */
index 2cfc465..fbf75e5 100644 (file)
@@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        }
        spin_unlock_irqrestore(&xhci->lock, flags);
 
+       if (!xhci->rh_bw)
+               goto no_bw;
+
        num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
        for (i = 0; i < num_ports; i++) {
                struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
@@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
                }
        }
 
+no_bw:
        xhci->num_usb2_ports = 0;
        xhci->num_usb3_ports = 0;
        xhci->num_active_eps = 0;
@@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        u32 page_size, temp;
        int i;
 
+       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
+       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
+
        page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
        xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
        for (i = 0; i < 16; i++) {
@@ -2334,7 +2341,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
        if (!xhci->cmd_ring)
                goto fail;
-       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
        xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
        xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
                        (unsigned long long)xhci->cmd_ring->first_seg->dma);
@@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        if (xhci_setup_port_arrays(xhci, flags))
                goto fail;
 
-       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
-
        /* Enable USB 3.0 device notifications for function remote wake, which
         * is necessary for allowing USB 3.0 devices to do remote wakeup from
         * U3 (device suspend).
index 1a30c38..cc24e39 100644 (file)
@@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev)
 static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
+
+       /*
+        * Systems with the TI redriver that loses port status change events
+        * need to have the registers polled during D3, so avoid D3cold.
+        */
+       if (xhci_compliance_mode_recovery_timer_quirk_check())
+               pdev->no_d3cold = true;
 
        return xhci_suspend(xhci);
 }
index b4aa79d..d8f640b 100644 (file)
@@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
  * Systems:
  * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
  */
-static bool compliance_mode_recovery_timer_quirk_check(void)
+bool xhci_compliance_mode_recovery_timer_quirk_check(void)
 {
        const char *dmi_product_name, *dmi_sys_vendor;
 
@@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
        xhci_dbg(xhci, "Finished xhci_init\n");
 
        /* Initializing Compliance Mode Recovery Data If Needed */
-       if (compliance_mode_recovery_timer_quirk_check()) {
+       if (xhci_compliance_mode_recovery_timer_quirk_check()) {
                xhci->quirks |= XHCI_COMP_MODE_QUIRK;
                compliance_mode_recovery_timer_init(xhci);
        }
@@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        struct usb_hcd          *secondary_hcd;
        int                     retval = 0;
+       bool                    comp_timer_running = false;
 
        /* Wait a bit if either of the roothubs need to settle from the
         * transition into bus suspend.
@@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
 
        /* If restore operation fails, re-initialize the HC during resume */
        if ((temp & STS_SRE) || hibernated) {
+
+               if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
+                               !(xhci_all_ports_seen_u0(xhci))) {
+                       del_timer_sync(&xhci->comp_mode_recovery_timer);
+                       xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
+               }
+
                /* Let the USB core know _both_ roothubs lost power. */
                usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
                usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
@@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                retval = xhci_init(hcd->primary_hcd);
                if (retval)
                        return retval;
+               comp_timer_running = true;
+
                xhci_dbg(xhci, "Start the primary HCD\n");
                retval = xhci_run(hcd->primary_hcd);
                if (!retval) {
@@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
         * to suffer the Compliance Mode issue again. It doesn't matter if
         * ports have entered previously to U0 before system's suspension.
         */
-       if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
+       if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
                compliance_mode_recovery_timer_init(xhci);
 
        /* Re-enable port polling. */
index 29c978e..77600ce 100644 (file)
@@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
 
+/* xHCI quirks */
+bool xhci_compliance_mode_recovery_timer_quirk_check(void);
+
 #endif /* __LINUX_XHCI_HCD_H */
index 8914dec..9d3044b 100644 (file)
@@ -1232,7 +1232,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
        void __iomem            *mbase = musb->mregs;
        struct dma_channel      *dma;
        bool                    transfer_pending = false;
-       static bool use_sg;
 
        musb_ep_select(mbase, epnum);
        tx_csr = musb_readw(epio, MUSB_TXCSR);
@@ -1463,9 +1462,9 @@ done:
         * NULL.
         */
        if (!urb->transfer_buffer)
-               use_sg = true;
+               qh->use_sg = true;
 
-       if (use_sg) {
+       if (qh->use_sg) {
                /* sg_miter_start is already done in musb_ep_program */
                if (!sg_miter_next(&qh->sg_miter)) {
                        dev_err(musb->controller, "error: sg list empty\n");
@@ -1484,9 +1483,9 @@ done:
 
        qh->segsize = length;
 
-       if (use_sg) {
+       if (qh->use_sg) {
                if (offset + length >= urb->transfer_buffer_length)
-                       use_sg = false;
+                       qh->use_sg = false;
        }
 
        musb_ep_select(mbase, epnum);
@@ -1552,7 +1551,6 @@ void musb_host_rx(struct musb *musb, u8 epnum)
        bool                    done = false;
        u32                     status;
        struct dma_channel      *dma;
-       static bool use_sg;
        unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
 
        musb_ep_select(mbase, epnum);
@@ -1878,12 +1876,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                         * NULL.
                         */
                        if (!urb->transfer_buffer) {
-                               use_sg = true;
+                               qh->use_sg = true;
                                sg_miter_start(&qh->sg_miter, urb->sg, 1,
                                                sg_flags);
                        }
 
-                       if (use_sg) {
+                       if (qh->use_sg) {
                                if (!sg_miter_next(&qh->sg_miter)) {
                                        dev_err(musb->controller, "error: sg list empty\n");
                                        sg_miter_stop(&qh->sg_miter);
@@ -1913,8 +1911,8 @@ finish:
        urb->actual_length += xfer_len;
        qh->offset += xfer_len;
        if (done) {
-               if (use_sg)
-                       use_sg = false;
+               if (qh->use_sg)
+                       qh->use_sg = false;
 
                if (urb->status == -EINPROGRESS)
                        urb->status = status;
index 5a9c8fe..738f7eb 100644 (file)
@@ -74,6 +74,7 @@ struct musb_qh {
        u16                     frame;          /* for periodic schedule */
        unsigned                iso_idx;        /* in urb->iso_frame_desc[] */
        struct sg_mapping_iter sg_miter;        /* for highmem in PIO mode */
+       bool                    use_sg;         /* to track urb using sglist */
 };
 
 /* map from control or bulk queue head to the first qh on that ring */
index 3b16118..40e7fd9 100644 (file)
@@ -43,7 +43,7 @@
 #define DRIVER_NAME "ark3116"
 
 /* usb timeout of 1 second */
-#define ARK_TIMEOUT (1*HZ)
+#define ARK_TIMEOUT 1000
 
 static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x6547, 0x0232) },
index d341555..0821201 100644 (file)
@@ -65,6 +65,7 @@ static const struct usb_device_id id_table_earthmate[] = {
 static const struct usb_device_id id_table_cyphidcomrs232[] = {
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
        { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
+       { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
        { }                                             /* Terminating entry */
 };
 
@@ -78,6 +79,7 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) },
        { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) },
        { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) },
+       { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) },
        { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) },
        { }                                             /* Terminating entry */
 };
@@ -229,6 +231,12 @@ static struct usb_serial_driver * const serial_drivers[] = {
  * Cypress serial helper functions
  *****************************************************************************/
 
+/* FRWD Dongle hidcom needs to skip reset and speed checks */
+static inline bool is_frwd(struct usb_device *dev)
+{
+       return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) &&
+               (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD));
+}
 
 static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
 {
@@ -238,6 +246,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
        if (unstable_bauds)
                return new_rate;
 
+       /* FRWD Dongle uses 115200 bps */
+       if (is_frwd(port->serial->dev))
+               return new_rate;
+
        /*
         * The general purpose firmware for the Cypress M8 allows for
         * a maximum speed of 57600bps (I have no idea whether DeLorme
@@ -448,7 +460,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
                return -ENOMEM;
        }
 
-       usb_reset_configuration(serial->dev);
+       /* Skip reset for FRWD device. It is a workaound:
+          device hangs if it receives SET_CONFIGURE in Configured
+          state. */
+       if (!is_frwd(serial->dev))
+               usb_reset_configuration(serial->dev);
 
        priv->cmd_ctrl = 0;
        priv->line_control = 0;
index 67cf608..b461311 100644 (file)
 #define VENDOR_ID_CYPRESS              0x04b4
 #define PRODUCT_ID_CYPHIDCOM           0x5500
 
+/* FRWD Dongle - a GPS sports watch */
+#define VENDOR_ID_FRWD                 0x6737
+#define PRODUCT_ID_CYPHIDCOM_FRWD      0x0001
+
 /* Powercom UPS, chip CY7C63723 */
 #define VENDOR_ID_POWERCOM             0x0d9f
 #define PRODUCT_ID_UPS                 0x0002
index 090b411..7d8dd5a 100644 (file)
@@ -165,11 +165,12 @@ static void f81232_set_termios(struct tty_struct *tty,
        /* FIXME - Stubbed out for now */
 
        /* Don't change anything if nothing has changed */
-       if (!tty_termios_hw_change(&tty->termios, old_termios))
+       if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
                return;
 
        /* Do the real work here... */
-       tty_termios_copy_hw(&tty->termios, old_termios);
+       if (old_termios)
+               tty_termios_copy_hw(&tty->termios, old_termios);
 }
 
 static int f81232_tiocmget(struct tty_struct *tty)
@@ -187,12 +188,11 @@ static int f81232_tiocmset(struct tty_struct *tty,
 
 static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-       struct ktermios tmp_termios;
        int result;
 
        /* Setup termios */
        if (tty)
-               f81232_set_termios(tty, port, &tmp_termios);
+               f81232_set_termios(tty, port, NULL);
 
        result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
        if (result) {
index 9d74c27..790673e 100644 (file)
@@ -287,7 +287,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
            usb_bulk_msg(serial->dev,
                         usb_sndbulkpipe(serial->dev,
                                         port->bulk_out_endpointAddress), buf,
-                        count, &actual, HZ * 1);
+                        count, &actual, 1000);
 
        if (status != IUU_OPERATION_OK)
                dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
@@ -307,7 +307,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
            usb_bulk_msg(serial->dev,
                         usb_rcvbulkpipe(serial->dev,
                                         port->bulk_in_endpointAddress), buf,
-                        count, &actual, HZ * 1);
+                        count, &actual, 1000);
 
        if (status != IUU_OPERATION_OK)
                dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
index eb30d7b..3549d07 100644 (file)
@@ -1548,7 +1548,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
-       int                                     outcont_urb;
        struct urb                              *this_urb;
        int                                     device_port, err;
 
@@ -1559,7 +1558,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        d_details = s_priv->device_details;
        device_port = port->number - port->serial->minor;
 
-       outcont_urb = d_details->outcont_endpoints[port->number];
        this_urb = p_priv->outcont_urb;
 
        dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
@@ -1685,14 +1683,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        err = usb_submit_urb(this_urb, GFP_ATOMIC);
        if (err != 0)
                dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
-#if 0
-       else {
-               dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__
-                       outcont_urb, this_urb->transfer_buffer_length,
-                       usb_pipeendpoint(this_urb->pipe));
-       }
-#endif
-
        return 0;
 }
 
index cc0e543..f27c621 100644 (file)
@@ -40,7 +40,7 @@
 #define DRIVER_DESC "Moschip USB Serial Driver"
 
 /* default urb timeout */
-#define MOS_WDR_TIMEOUT        (HZ * 5)
+#define MOS_WDR_TIMEOUT        5000
 
 #define MOS_MAX_PORT   0x02
 #define MOS_WRITE      0x0E
@@ -227,11 +227,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum,
        __u8 requesttype = (__u8)0xc0;
        __u16 index = get_reg_index(reg);
        __u16 value = get_reg_value(reg, serial_portnum);
-       int status = usb_control_msg(usbdev, pipe, request, requesttype, value,
-                                    index, data, 1, MOS_WDR_TIMEOUT);
-       if (status < 0)
+       u8 *buf;
+       int status;
+
+       buf = kmalloc(1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       status = usb_control_msg(usbdev, pipe, request, requesttype, value,
+                                    index, buf, 1, MOS_WDR_TIMEOUT);
+       if (status == 1)
+               *data = *buf;
+       else if (status < 0)
                dev_err(&usbdev->dev,
                        "mos7720: usb_control_msg() failed: %d", status);
+       kfree(buf);
+
        return status;
 }
 
@@ -1618,7 +1629,7 @@ static void change_port_settings(struct tty_struct *tty,
                mos7720_port->shadowMCR |= (UART_MCR_XONANY);
                /* To set hardware flow control to the specified *
                 * serial port, in SP1/2_CONTROL_REG             */
-               if (port->number)
+               if (port_number)
                        write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01);
                else
                        write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02);
@@ -1927,7 +1938,7 @@ static int mos7720_startup(struct usb_serial *serial)
 
        /* setting configuration feature to one */
        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
+                       (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
 
        /* start the interrupt urb */
        ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
@@ -1970,7 +1981,7 @@ static void mos7720_release(struct usb_serial *serial)
                /* wait for synchronous usb calls to return */
                if (mos_parport->msg_pending)
                        wait_for_completion_timeout(&mos_parport->syncmsg_compl,
-                                                   MOS_WDR_TIMEOUT);
+                                           msecs_to_jiffies(MOS_WDR_TIMEOUT));
 
                parport_remove_port(mos_parport->pp);
                usb_set_serial_data(serial, NULL);
index a0d5ea5..7e99808 100644 (file)
@@ -2142,13 +2142,21 @@ static int mos7840_ioctl(struct tty_struct *tty,
 static int mos7810_check(struct usb_serial *serial)
 {
        int i, pass_count = 0;
+       u8 *buf;
        __u16 data = 0, mcr_data = 0;
        __u16 test_pattern = 0x55AA;
+       int res;
+
+       buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+       if (!buf)
+               return 0;       /* failed to identify 7810 */
 
        /* Store MCR setting */
-       usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+       res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
-               &mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               buf, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+       if (res == VENDOR_READ_LENGTH)
+               mcr_data = *buf;
 
        for (i = 0; i < 16; i++) {
                /* Send the 1-bit test pattern out to MCS7810 test pin */
@@ -2158,9 +2166,12 @@ static int mos7810_check(struct usb_serial *serial)
                        MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
 
                /* Read the test pattern back */
-               usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                       MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
-                       VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               res = usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0), MCS_RDREQ,
+                               MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
+                               VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               if (res == VENDOR_READ_LENGTH)
+                       data = *buf;
 
                /* If this is a MCS7810 device, both test patterns must match */
                if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
@@ -2174,6 +2185,8 @@ static int mos7810_check(struct usb_serial *serial)
                MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
                0, MOS_WDR_TIMEOUT);
 
+       kfree(buf);
+
        if (pass_count == 16)
                return 1;
 
@@ -2183,11 +2196,17 @@ static int mos7810_check(struct usb_serial *serial)
 static int mos7840_calc_num_ports(struct usb_serial *serial)
 {
        __u16 data = 0x00;
+       u8 *buf;
        int mos7840_num_ports;
 
-       usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-               MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
-               VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+       buf = kzalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
+       if (buf) {
+               usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                       MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, buf,
+                       VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+               data = *buf;
+               kfree(buf);
+       }
 
        if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
                serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
index 93d02bc..bd4323d 100644 (file)
@@ -250,13 +250,7 @@ static void option_instat_callback(struct urb *urb);
 #define ZTE_PRODUCT_MF622                      0x0001
 #define ZTE_PRODUCT_MF628                      0x0015
 #define ZTE_PRODUCT_MF626                      0x0031
-#define ZTE_PRODUCT_CDMA_TECH                  0xfffe
-#define ZTE_PRODUCT_AC8710                     0xfff1
-#define ZTE_PRODUCT_AC2726                     0xfff5
-#define ZTE_PRODUCT_AC8710T                    0xffff
 #define ZTE_PRODUCT_MC2718                     0xffe8
-#define ZTE_PRODUCT_AD3812                     0xffeb
-#define ZTE_PRODUCT_MC2716                     0xffed
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -495,18 +489,10 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
        .reserved = BIT(4),
 };
 
-static const struct option_blacklist_info zte_ad3812_z_blacklist = {
-       .sendsetup = BIT(0) | BIT(1) | BIT(2),
-};
-
 static const struct option_blacklist_info zte_mc2718_z_blacklist = {
        .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
 };
 
-static const struct option_blacklist_info zte_mc2716_z_blacklist = {
-       .sendsetup = BIT(1) | BIT(2) | BIT(3),
-};
-
 static const struct option_blacklist_info huawei_cdc12_blacklist = {
        .reserved = BIT(1) | BIT(2),
 };
@@ -593,6 +579,8 @@ static const struct usb_device_id option_ids[] = {
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff),    /* Huawei E1820 */
+               .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
        { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
@@ -797,7 +785,6 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
-       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
@@ -1199,16 +1186,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       /* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
         .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
-        .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
-       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
-        .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
        { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
index 7151659..048cd44 100644 (file)
@@ -284,7 +284,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
           serial settings even to the same values as before. Thus
           we actually need to filter in this specific case */
 
-       if (!tty_termios_hw_change(&tty->termios, old_termios))
+       if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
                return;
 
        cflag = tty->termios.c_cflag;
@@ -293,7 +293,8 @@ static void pl2303_set_termios(struct tty_struct *tty,
        if (!buf) {
                dev_err(&port->dev, "%s - out of memory.\n", __func__);
                /* Report back no change occurred */
-               tty->termios = *old_termios;
+               if (old_termios)
+                       tty->termios = *old_termios;
                return;
        }
 
@@ -433,7 +434,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
        control = priv->line_control;
        if ((cflag & CBAUD) == B0)
                priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
-       else if ((old_termios->c_cflag & CBAUD) == B0)
+       else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
                priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
        if (control != priv->line_control) {
                control = priv->line_control;
@@ -492,7 +493,6 @@ static void pl2303_close(struct usb_serial_port *port)
 
 static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-       struct ktermios tmp_termios;
        struct usb_serial *serial = port->serial;
        struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
        int result;
@@ -508,7 +508,7 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        /* Setup termios */
        if (tty)
-               pl2303_set_termios(tty, port, &tmp_termios);
+               pl2303_set_termios(tty, port, NULL);
 
        result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
        if (result) {
index 59b32b7..bd794b4 100644 (file)
@@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = {
        {USB_DEVICE(0x1199, 0x901b)},   /* Sierra Wireless MC7770 */
        {USB_DEVICE(0x12D1, 0x14F0)},   /* Sony Gobi 3000 QDL */
        {USB_DEVICE(0x12D1, 0x14F1)},   /* Sony Gobi 3000 Composite */
+       {USB_DEVICE(0x0AF0, 0x8120)},   /* Option GTM681W */
 
        /* non Gobi Qualcomm serial devices */
        {USB_DEVICE_INTERFACE_NUMBER(0x0f3d, 0x68a2, 0)},       /* Sierra Wireless MC7700 Device Management */
index cf3df79..ddf6c47 100644 (file)
@@ -291,7 +291,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned int cflag = tty->termios.c_cflag;
-       unsigned int old_cflag = old_termios->c_cflag;
        unsigned short uartdata;
        unsigned char buf[2] = {0, 0};
        int baud;
@@ -299,15 +298,15 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
        u8 control;
 
        /* check that they really want us to change something */
-       if (!tty_termios_hw_change(&tty->termios, old_termios))
+       if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
                return;
 
        /* set DTR/RTS active */
        spin_lock_irqsave(&priv->lock, flags);
        control = priv->line_control;
-       if ((old_cflag & CBAUD) == B0) {
+       if (old_termios && (old_termios->c_cflag & CBAUD) == B0) {
                priv->line_control |= MCR_DTR;
-               if (!(old_cflag & CRTSCTS))
+               if (!(old_termios->c_cflag & CRTSCTS))
                        priv->line_control |= MCR_RTS;
        }
        if (control != priv->line_control) {
@@ -394,7 +393,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
 
 static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-       struct ktermios tmp_termios;
        struct usb_serial *serial = port->serial;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        int ret;
@@ -411,7 +409,7 @@ static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
        spcp8x5_set_ctrl_line(port, priv->line_control);
 
        if (tty)
-               spcp8x5_set_termios(tty, port, &tmp_termios);
+               spcp8x5_set_termios(tty, port, NULL);
 
        port->port.drain_delay = 256;
 
index 4753c00..5f6b1ff 100644 (file)
@@ -408,7 +408,7 @@ static int serial_ioctl(struct tty_struct *tty,
                                        unsigned int cmd, unsigned long arg)
 {
        struct usb_serial_port *port = tty->driver_data;
-       int retval = -ENODEV;
+       int retval = -ENOIOCTLCMD;
 
        dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd);
 
@@ -420,8 +420,6 @@ static int serial_ioctl(struct tty_struct *tty,
        default:
                if (port->serial->type->ioctl)
                        retval = port->serial->type->ioctl(tty, cmd, arg);
-               else
-                       retval = -ENOIOCTLCMD;
        }
 
        return retval;
index 7573ec8..9910aa2 100644 (file)
@@ -560,10 +560,19 @@ static int treo_attach(struct usb_serial *serial)
        */
 #define COPY_PORT(dest, src)                                           \
        do { \
+               int i;                                                  \
+                                                                       \
+               for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) {      \
+                       dest->read_urbs[i] = src->read_urbs[i];         \
+                       dest->read_urbs[i]->context = dest;             \
+                       dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \
+               }                                                       \
                dest->read_urb = src->read_urb;                         \
                dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
                dest->bulk_in_buffer = src->bulk_in_buffer;             \
+               dest->bulk_in_size = src->bulk_in_size;                 \
                dest->interrupt_in_urb = src->interrupt_in_urb;         \
+               dest->interrupt_in_urb->context = dest;                 \
                dest->interrupt_in_endpointAddress = \
                                        src->interrupt_in_endpointAddress;\
                dest->interrupt_in_buffer = src->interrupt_in_buffer;   \
index b9fca35..347caad 100644 (file)
@@ -649,7 +649,7 @@ static void firm_setup_port(struct tty_struct *tty)
        struct whiteheat_port_settings port_settings;
        unsigned int cflag = tty->termios.c_cflag;
 
-       port_settings.port = port->number + 1;
+       port_settings.port = port->number - port->serial->minor + 1;
 
        /* get the byte size */
        switch (cflag & CSIZE) {
index 39ee737..fca4c75 100644 (file)
@@ -41,9 +41,6 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        int len;
        unsigned char *buf;
 
-       if (port->number != 0)
-               return -ENODEV;
-
        buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
@@ -53,7 +50,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0001, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send  2st cmd and recieve data */
@@ -65,7 +62,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 3 cmd */
@@ -84,7 +81,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 4 cmd */
@@ -95,7 +92,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send 5 cmd */
@@ -107,7 +104,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 6 cmd */
@@ -126,7 +123,7 @@ static int zte_ev_usb_serial_open(struct tty_struct *tty,
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
        kfree(buf);
 
@@ -166,9 +163,6 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        int len;
        unsigned char *buf;
 
-       if (port->number != 0)
-               return;
-
        buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL);
        if (!buf)
                return;
@@ -178,7 +172,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0002, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send 2st ctl cmd(CTL    21 22 03 00  00 00 00 00 ) */
@@ -186,7 +180,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send  3st cmd and recieve data */
@@ -198,7 +192,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 4 cmd */
@@ -217,7 +211,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 5 cmd */
@@ -228,7 +222,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        /* send 6 cmd */
@@ -240,7 +234,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                                 0x21, 0xa1,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 7 cmd */
@@ -259,7 +253,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x20, 0x21,
                                 0x0000, 0x0000, buf, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        debug_data(dev, __func__, len, buf, result);
 
        /* send 8 cmd */
@@ -270,7 +264,7 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
        result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                                 0x22, 0x21,
                                 0x0003, 0x0000, NULL, len,
-                                HZ * USB_CTRL_GET_TIMEOUT);
+                                USB_CTRL_GET_TIMEOUT);
        dev_dbg(dev, "result = %d\n", result);
 
        kfree(buf);
@@ -279,11 +273,29 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port)
 }
 
 static const struct usb_device_id id_table[] = {
-       { USB_DEVICE(0x19d2, 0xffff) }, /* AC8700 */
-       { USB_DEVICE(0x19d2, 0xfffe) },
-       { USB_DEVICE(0x19d2, 0xfffd) }, /* MG880 */
+       /* AC8710, AC8710T */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) },
+        /* AC8700 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) },
+       /* MG880 */
+       { USB_DEVICE(0x19d2, 0xfffd) },
+       { USB_DEVICE(0x19d2, 0xfffc) },
+       { USB_DEVICE(0x19d2, 0xfffb) },
+       /* AC2726, AC8710_V3 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfff1, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(0x19d2, 0xfff6) },
+       { USB_DEVICE(0x19d2, 0xfff7) },
+       { USB_DEVICE(0x19d2, 0xfff8) },
+       { USB_DEVICE(0x19d2, 0xfff9) },
+       { USB_DEVICE(0x19d2, 0xffee) },
+       /* AC2716, MC2716 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) },
+       /* AD3812 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(0x19d2, 0xffec) },
        { USB_DEVICE(0x05C6, 0x3197) },
        { USB_DEVICE(0x05C6, 0x6000) },
+       { USB_DEVICE(0x05C6, 0x9008) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index acb7121..6d78736 100644 (file)
@@ -1360,7 +1360,7 @@ static const struct file_operations vfio_device_fops = {
  */
 static char *vfio_devnode(struct device *dev, umode_t *mode)
 {
-       if (MINOR(dev->devt) == 0)
+       if (mode && (MINOR(dev->devt) == 0))
                *mode = S_IRUGO | S_IWUGO;
 
        return kasprintf(GFP_KERNEL, "vfio/%s", dev_name(dev));
index 2b51e23..f80d3dd 100644 (file)
@@ -155,14 +155,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
 
 static void vhost_net_clear_ubuf_info(struct vhost_net *n)
 {
-
-       bool zcopy;
        int i;
 
-       for (i = 0; i < n->dev.nvqs; ++i) {
-               zcopy = vhost_net_zcopy_mask & (0x1 << i);
-               if (zcopy)
-                       kfree(n->vqs[i].ubuf_info);
+       for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
+               kfree(n->vqs[i].ubuf_info);
+               n->vqs[i].ubuf_info = NULL;
        }
 }
 
@@ -171,7 +168,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
        bool zcopy;
        int i;
 
-       for (i = 0; i < n->dev.nvqs; ++i) {
+       for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
                zcopy = vhost_net_zcopy_mask & (0x1 << i);
                if (!zcopy)
                        continue;
@@ -183,12 +180,7 @@ int vhost_net_set_ubuf_info(struct vhost_net *n)
        return 0;
 
 err:
-       while (i--) {
-               zcopy = vhost_net_zcopy_mask & (0x1 << i);
-               if (!zcopy)
-                       continue;
-               kfree(n->vqs[i].ubuf_info);
-       }
+       vhost_net_clear_ubuf_info(n);
        return -ENOMEM;
 }
 
@@ -196,12 +188,12 @@ void vhost_net_vq_reset(struct vhost_net *n)
 {
        int i;
 
+       vhost_net_clear_ubuf_info(n);
+
        for (i = 0; i < VHOST_NET_VQ_MAX; i++) {
                n->vqs[i].done_idx = 0;
                n->vqs[i].upend_idx = 0;
                n->vqs[i].ubufs = NULL;
-               kfree(n->vqs[i].ubuf_info);
-               n->vqs[i].ubuf_info = NULL;
                n->vqs[i].vhost_hlen = 0;
                n->vqs[i].sock_hlen = 0;
        }
@@ -436,7 +428,8 @@ static void handle_tx(struct vhost_net *net)
                                kref_get(&ubufs->kref);
                        }
                        nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV;
-               }
+               } else
+                       msg.msg_control = NULL;
                /* TODO: Check specific error and bomb out unless ENOBUFS? */
                err = sock->ops->sendmsg(NULL, sock, &msg, len);
                if (unlikely(err < 0)) {
@@ -1053,6 +1046,10 @@ static long vhost_net_set_owner(struct vhost_net *n)
        int r;
 
        mutex_lock(&n->dev.mutex);
+       if (vhost_dev_has_owner(&n->dev)) {
+               r = -EBUSY;
+               goto out;
+       }
        r = vhost_net_set_ubuf_info(n);
        if (r)
                goto out;
index beee7f5..60aa5ad 100644 (file)
@@ -344,13 +344,19 @@ static int vhost_attach_cgroups(struct vhost_dev *dev)
 }
 
 /* Caller should have device mutex */
+bool vhost_dev_has_owner(struct vhost_dev *dev)
+{
+       return dev->mm;
+}
+
+/* Caller should have device mutex */
 long vhost_dev_set_owner(struct vhost_dev *dev)
 {
        struct task_struct *worker;
        int err;
 
        /* Is there an owner already? */
-       if (dev->mm) {
+       if (vhost_dev_has_owner(dev)) {
                err = -EBUSY;
                goto err_mm;
        }
index a7ad635..64adcf9 100644 (file)
@@ -133,6 +133,7 @@ struct vhost_dev {
 
 long vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, int nvqs);
 long vhost_dev_set_owner(struct vhost_dev *dev);
+bool vhost_dev_has_owner(struct vhost_dev *dev);
 long vhost_dev_check_owner(struct vhost_dev *);
 struct vhost_memory *vhost_dev_reset_owner_prepare(void);
 void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_memory *);
index 540909d..effdb37 100644 (file)
@@ -223,8 +223,14 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
 
 static void exit_backlight(struct atmel_lcdfb_info *sinfo)
 {
-       if (sinfo->backlight)
-               backlight_device_unregister(sinfo->backlight);
+       if (!sinfo->backlight)
+               return;
+
+       if (sinfo->backlight->ops) {
+               sinfo->backlight->props.power = FB_BLANK_POWERDOWN;
+               sinfo->backlight->ops->update_status(sinfo->backlight);
+       }
+       backlight_device_unregister(sinfo->backlight);
 }
 
 #else
@@ -461,8 +467,11 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
        if (info->fix.smem_len) {
                unsigned int smem_len = (var->xres_virtual * var->yres_virtual
                                         * ((var->bits_per_pixel + 7) / 8));
-               if (smem_len > info->fix.smem_len)
+               if (smem_len > info->fix.smem_len) {
+                       dev_err(dev, "Frame buffer is too small (%u) for screen size (need at least %u)\n",
+                               info->fix.smem_len, smem_len);
                        return -EINVAL;
+               }
        }
 
        /* Saturate vertical and horizontal timings at maximum values */
index 60cc6fe..c9c2252 100644 (file)
@@ -53,6 +53,8 @@ static char *def_disp_name;
 module_param_named(def_disp, def_disp_name, charp, 0);
 MODULE_PARM_DESC(def_disp, "default display name");
 
+static bool dss_initialized;
+
 const char *omapdss_get_default_display_name(void)
 {
        return core.default_display_name;
@@ -66,6 +68,12 @@ enum omapdss_version omapdss_get_version(void)
 }
 EXPORT_SYMBOL(omapdss_get_version);
 
+bool omapdss_is_initialized(void)
+{
+       return dss_initialized;
+}
+EXPORT_SYMBOL(omapdss_is_initialized);
+
 struct platform_device *dss_get_core_pdev(void)
 {
        return core.pdev;
@@ -603,6 +611,8 @@ static int __init omap_dss_init(void)
                return r;
        }
 
+       dss_initialized = true;
+
        return 0;
 }
 
@@ -633,7 +643,15 @@ static int __init omap_dss_init(void)
 
 static int __init omap_dss_init2(void)
 {
-       return omap_dss_register_drivers();
+       int r;
+
+       r = omap_dss_register_drivers();
+       if (r)
+               return r;
+
+       dss_initialized = true;
+
+       return 0;
 }
 
 core_initcall(omap_dss_init);
index c84bb8a..856917b 100644 (file)
@@ -2416,6 +2416,9 @@ static int omapfb_probe(struct platform_device *pdev)
 
        DBG("omapfb_probe\n");
 
+       if (omapdss_is_initialized() == false)
+               return -EPROBE_DEFER;
+
        if (pdev->num_resources != 0) {
                dev_err(&pdev->dev, "probed for an unknown device\n");
                r = -ENODEV;
index d9f08c6..dbfe2c1 100644 (file)
@@ -710,7 +710,7 @@ static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
        r = vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len);
 
        dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
-               info->fix.smem_start + vma->vm_pgoff << PAGE_SHIFT,
+               info->fix.smem_start + (vma->vm_pgoff << PAGE_SHIFT),
                vma->vm_start);
 
        return r;
index 18e8bd8..0f0493c 100644 (file)
@@ -41,6 +41,8 @@ module_param(selfballooning, bool, S_IRUGO);
 #ifdef CONFIG_FRONTSWAP
 static bool frontswap __read_mostly = true;
 module_param(frontswap, bool, S_IRUGO);
+#else /* CONFIG_FRONTSWAP */
+#define frontswap (0)
 #endif /* CONFIG_FRONTSWAP */
 
 #ifdef CONFIG_XEN_SELFBALLOONING
@@ -377,10 +379,10 @@ static int xen_tmem_init(void)
 #ifdef CONFIG_FRONTSWAP
        if (tmem_enabled && frontswap) {
                char *s = "";
-               struct frontswap_ops *old_ops =
-                       frontswap_register_ops(&tmem_frontswap_ops);
+               struct frontswap_ops *old_ops;
 
                tmem_frontswap_poolid = -1;
+               old_ops = frontswap_register_ops(&tmem_frontswap_ops);
                if (IS_ERR(old_ops) || old_ops) {
                        if (IS_ERR(old_ops))
                                return PTR_ERR(old_ops);
index a2278ba..4e8ba38 100644 (file)
@@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref)
        else
                pci_restore_state(dev);
 
-       if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
+       if (dev->msix_cap) {
                struct physdev_pci_device ppdev = {
                        .seg = pci_domain_nr(dev->bus),
                        .bus = dev->bus->number,
@@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev)
        if (err)
                goto config_release;
 
-       if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
+       if (dev->msix_cap) {
                struct physdev_pci_device ppdev = {
                        .seg = pci_domain_nr(dev->bus),
                        .bus = dev->bus->number,
index 61786be..ec097d6 100644 (file)
@@ -534,7 +534,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
 
        err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr);
        if (err)
-               goto out_err;
+               goto out_err_free_ballooned_pages;
 
        spin_lock(&xenbus_valloc_lock);
        list_add(&node->next, &xenbus_valloc_pages);
@@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
        *vaddr = addr;
        return 0;
 
- out_err:
+ out_err_free_ballooned_pages:
        free_xenballooned_pages(1, &node->page);
+ out_err:
        kfree(node);
        return err;
 }
index c8abd3b..e74f9c1 100644 (file)
@@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void);
 int xs_input_avail(void);
 extern struct xenstore_domain_interface *xen_store_interface;
 extern int xen_store_evtchn;
+extern enum xenstore_init xen_store_domain_type;
 
 extern const struct file_operations xen_xenbus_fops;
 
index 3325884..56cfaaa 100644 (file)
@@ -69,6 +69,9 @@ EXPORT_SYMBOL_GPL(xen_store_evtchn);
 struct xenstore_domain_interface *xen_store_interface;
 EXPORT_SYMBOL_GPL(xen_store_interface);
 
+enum xenstore_init xen_store_domain_type;
+EXPORT_SYMBOL_GPL(xen_store_domain_type);
+
 static unsigned long xen_store_mfn;
 
 static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
@@ -719,17 +722,11 @@ static int __init xenstored_local_init(void)
        return err;
 }
 
-enum xenstore_init {
-       UNKNOWN,
-       PV,
-       HVM,
-       LOCAL,
-};
 static int __init xenbus_init(void)
 {
        int err = 0;
-       enum xenstore_init usage = UNKNOWN;
        uint64_t v = 0;
+       xen_store_domain_type = XS_UNKNOWN;
 
        if (!xen_domain())
                return -ENODEV;
@@ -737,29 +734,29 @@ static int __init xenbus_init(void)
        xenbus_ring_ops_init();
 
        if (xen_pv_domain())
-               usage = PV;
+               xen_store_domain_type = XS_PV;
        if (xen_hvm_domain())
-               usage = HVM;
+               xen_store_domain_type = XS_HVM;
        if (xen_hvm_domain() && xen_initial_domain())
-               usage = LOCAL;
+               xen_store_domain_type = XS_LOCAL;
        if (xen_pv_domain() && !xen_start_info->store_evtchn)
-               usage = LOCAL;
+               xen_store_domain_type = XS_LOCAL;
        if (xen_pv_domain() && xen_start_info->store_evtchn)
                xenstored_ready = 1;
 
-       switch (usage) {
-       case LOCAL:
+       switch (xen_store_domain_type) {
+       case XS_LOCAL:
                err = xenstored_local_init();
                if (err)
                        goto out_error;
                xen_store_interface = mfn_to_virt(xen_store_mfn);
                break;
-       case PV:
+       case XS_PV:
                xen_store_evtchn = xen_start_info->store_evtchn;
                xen_store_mfn = xen_start_info->store_mfn;
                xen_store_interface = mfn_to_virt(xen_store_mfn);
                break;
-       case HVM:
+       case XS_HVM:
                err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
                if (err)
                        goto out_error;
index bb4f92e..146f857 100644 (file)
@@ -47,6 +47,13 @@ struct xen_bus_type {
        struct bus_type bus;
 };
 
+enum xenstore_init {
+       XS_UNKNOWN,
+       XS_PV,
+       XS_HVM,
+       XS_LOCAL,
+};
+
 extern struct device_attribute xenbus_dev_attrs[];
 
 extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
index 3159a37..a7e2507 100644 (file)
@@ -29,6 +29,8 @@
 #include "xenbus_probe.h"
 
 
+static struct workqueue_struct *xenbus_frontend_wq;
+
 /* device/<type>/<id> => <type>-<id> */
 static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename)
 {
@@ -89,9 +91,40 @@ static void backend_changed(struct xenbus_watch *watch,
        xenbus_otherend_changed(watch, vec, len, 1);
 }
 
+static void xenbus_frontend_delayed_resume(struct work_struct *w)
+{
+       struct xenbus_device *xdev = container_of(w, struct xenbus_device, work);
+
+       xenbus_dev_resume(&xdev->dev);
+}
+
+static int xenbus_frontend_dev_resume(struct device *dev)
+{
+       /*
+        * If xenstored is running in this domain, we cannot access the backend
+        * state at the moment, so we need to defer xenbus_dev_resume
+        */
+       if (xen_store_domain_type == XS_LOCAL) {
+               struct xenbus_device *xdev = to_xenbus_device(dev);
+
+               if (!xenbus_frontend_wq) {
+                       pr_err("%s: no workqueue to process delayed resume\n",
+                              xdev->nodename);
+                       return -EFAULT;
+               }
+
+               INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume);
+               queue_work(xenbus_frontend_wq, &xdev->work);
+
+               return 0;
+       }
+
+       return xenbus_dev_resume(dev);
+}
+
 static const struct dev_pm_ops xenbus_pm_ops = {
        .suspend        = xenbus_dev_suspend,
-       .resume         = xenbus_dev_resume,
+       .resume         = xenbus_frontend_dev_resume,
        .freeze         = xenbus_dev_suspend,
        .thaw           = xenbus_dev_cancel,
        .restore        = xenbus_dev_resume,
@@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void)
 
        register_xenstore_notifier(&xenstore_notifier);
 
+       xenbus_frontend_wq = create_workqueue("xenbus_frontend");
+
        return 0;
 }
 subsys_initcall(xenbus_probe_frontend_init);
index 7fe5bde..2bbcacf 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -141,9 +141,6 @@ static void aio_free_ring(struct kioctx *ctx)
        for (i = 0; i < ctx->nr_pages; i++)
                put_page(ctx->ring_pages[i]);
 
-       if (ctx->mmap_size)
-               vm_munmap(ctx->mmap_base, ctx->mmap_size);
-
        if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages)
                kfree(ctx->ring_pages);
 }
@@ -322,11 +319,6 @@ static void free_ioctx(struct kioctx *ctx)
 
        aio_free_ring(ctx);
 
-       spin_lock(&aio_nr_lock);
-       BUG_ON(aio_nr - ctx->max_reqs > aio_nr);
-       aio_nr -= ctx->max_reqs;
-       spin_unlock(&aio_nr_lock);
-
        pr_debug("freeing %p\n", ctx);
 
        /*
@@ -435,17 +427,24 @@ static void kill_ioctx(struct kioctx *ctx)
 {
        if (!atomic_xchg(&ctx->dead, 1)) {
                hlist_del_rcu(&ctx->list);
-               /* Between hlist_del_rcu() and dropping the initial ref */
-               synchronize_rcu();
 
                /*
-                * We can't punt to workqueue here because put_ioctx() ->
-                * free_ioctx() will unmap the ringbuffer, and that has to be
-                * done in the original process's context. kill_ioctx_rcu/work()
-                * exist for exit_aio(), as in that path free_ioctx() won't do
-                * the unmap.
+                * It'd be more correct to do this in free_ioctx(), after all
+                * the outstanding kiocbs have finished - but by then io_destroy
+                * has already returned, so io_setup() could potentially return
+                * -EAGAIN with no ioctxs actually in use (as far as userspace
+                *  could tell).
                 */
-               kill_ioctx_work(&ctx->rcu_work);
+               spin_lock(&aio_nr_lock);
+               BUG_ON(aio_nr - ctx->max_reqs > aio_nr);
+               aio_nr -= ctx->max_reqs;
+               spin_unlock(&aio_nr_lock);
+
+               if (ctx->mmap_size)
+                       vm_munmap(ctx->mmap_base, ctx->mmap_size);
+
+               /* Between hlist_del_rcu() and dropping the initial ref */
+               call_rcu(&ctx->rcu_head, kill_ioctx_rcu);
        }
 }
 
@@ -495,10 +494,7 @@ void exit_aio(struct mm_struct *mm)
                 */
                ctx->mmap_size = 0;
 
-               if (!atomic_xchg(&ctx->dead, 1)) {
-                       hlist_del_rcu(&ctx->list);
-                       call_rcu(&ctx->rcu_head, kill_ioctx_rcu);
-               }
+               kill_ioctx(ctx);
        }
 }
 
index 8615ee8..f95dddc 100644 (file)
@@ -265,8 +265,8 @@ befs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                result = filldir(dirent, keybuf, keysize, filp->f_pos,
                                 (ino_t) value, d_type);
        }
-
-       filp->f_pos++;
+       if (!result)
+               filp->f_pos++;
 
        befs_debug(sb, "<--- befs_readdir() filp->f_pos %Ld", filp->f_pos);
 
index e7b3cb5..b8b60b6 100644 (file)
@@ -2859,8 +2859,8 @@ fail_qgroup:
        btrfs_free_qgroup_config(fs_info);
 fail_trans_kthread:
        kthread_stop(fs_info->transaction_kthread);
-       del_fs_roots(fs_info);
        btrfs_cleanup_transaction(fs_info->tree_root);
+       del_fs_roots(fs_info);
 fail_cleaner:
        kthread_stop(fs_info->cleaner_kthread);
 
@@ -3512,15 +3512,15 @@ int close_ctree(struct btrfs_root *root)
                       percpu_counter_sum(&fs_info->delalloc_bytes));
        }
 
-       free_root_pointers(fs_info, 1);
-
        btrfs_free_block_groups(fs_info);
 
+       btrfs_stop_all_workers(fs_info);
+
        del_fs_roots(fs_info);
 
-       iput(fs_info->btree_inode);
+       free_root_pointers(fs_info, 1);
 
-       btrfs_stop_all_workers(fs_info);
+       iput(fs_info->btree_inode);
 
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        if (btrfs_test_opt(root, CHECK_INTEGRITY))
index af978f7..17f3064 100644 (file)
@@ -8012,6 +8012,9 @@ int btrfs_drop_inode(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
+       if (root == NULL)
+               return 1;
+
        /* the snap/subvol tree is on deleting */
        if (btrfs_root_refs(&root->root_item) == 0 &&
            root != root->fs_info->tree_root)
index 395b820..4febca4 100644 (file)
@@ -4082,7 +4082,7 @@ out:
        return inode;
 }
 
-static struct reloc_control *alloc_reloc_control(void)
+static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
 {
        struct reloc_control *rc;
 
@@ -4093,7 +4093,8 @@ static struct reloc_control *alloc_reloc_control(void)
        INIT_LIST_HEAD(&rc->reloc_roots);
        backref_cache_init(&rc->backref_cache);
        mapping_tree_init(&rc->reloc_root_tree);
-       extent_io_tree_init(&rc->processed_blocks, NULL);
+       extent_io_tree_init(&rc->processed_blocks,
+                           fs_info->btree_inode->i_mapping);
        return rc;
 }
 
@@ -4110,7 +4111,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        int rw = 0;
        int err = 0;
 
-       rc = alloc_reloc_control();
+       rc = alloc_reloc_control(fs_info);
        if (!rc)
                return -ENOMEM;
 
@@ -4311,7 +4312,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
        if (list_empty(&reloc_roots))
                goto out;
 
-       rc = alloc_reloc_control();
+       rc = alloc_reloc_control(root->fs_info);
        if (!rc) {
                err = -ENOMEM;
                goto out;
index 202dd3d..ebbf680 100644 (file)
@@ -191,27 +191,23 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
 }
 
 /**
- * Encode the flock and fcntl locks for the given inode into the pagelist.
- * Format is: #fcntl locks, sequential fcntl locks, #flock locks,
- * sequential flock locks.
- * Must be called with lock_flocks() already held.
- * If we encounter more of a specific lock type than expected,
- * we return the value 1.
+ * Encode the flock and fcntl locks for the given inode into the ceph_filelock
+ * array. Must be called with lock_flocks() already held.
+ * If we encounter more of a specific lock type than expected, return -ENOSPC.
  */
-int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist,
-                     int num_fcntl_locks, int num_flock_locks)
+int ceph_encode_locks_to_buffer(struct inode *inode,
+                               struct ceph_filelock *flocks,
+                               int num_fcntl_locks, int num_flock_locks)
 {
        struct file_lock *lock;
-       struct ceph_filelock cephlock;
        int err = 0;
        int seen_fcntl = 0;
        int seen_flock = 0;
+       int l = 0;
 
        dout("encoding %d flock and %d fcntl locks", num_flock_locks,
             num_fcntl_locks);
-       err = ceph_pagelist_append(pagelist, &num_fcntl_locks, sizeof(u32));
-       if (err)
-               goto fail;
+
        for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) {
                if (lock->fl_flags & FL_POSIX) {
                        ++seen_fcntl;
@@ -219,19 +215,12 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist,
                                err = -ENOSPC;
                                goto fail;
                        }
-                       err = lock_to_ceph_filelock(lock, &cephlock);
+                       err = lock_to_ceph_filelock(lock, &flocks[l]);
                        if (err)
                                goto fail;
-                       err = ceph_pagelist_append(pagelist, &cephlock,
-                                          sizeof(struct ceph_filelock));
+                       ++l;
                }
-               if (err)
-                       goto fail;
        }
-
-       err = ceph_pagelist_append(pagelist, &num_flock_locks, sizeof(u32));
-       if (err)
-               goto fail;
        for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) {
                if (lock->fl_flags & FL_FLOCK) {
                        ++seen_flock;
@@ -239,19 +228,51 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist,
                                err = -ENOSPC;
                                goto fail;
                        }
-                       err = lock_to_ceph_filelock(lock, &cephlock);
+                       err = lock_to_ceph_filelock(lock, &flocks[l]);
                        if (err)
                                goto fail;
-                       err = ceph_pagelist_append(pagelist, &cephlock,
-                                          sizeof(struct ceph_filelock));
+                       ++l;
                }
-               if (err)
-                       goto fail;
        }
 fail:
        return err;
 }
 
+/**
+ * Copy the encoded flock and fcntl locks into the pagelist.
+ * Format is: #fcntl locks, sequential fcntl locks, #flock locks,
+ * sequential flock locks.
+ * Returns zero on success.
+ */
+int ceph_locks_to_pagelist(struct ceph_filelock *flocks,
+                          struct ceph_pagelist *pagelist,
+                          int num_fcntl_locks, int num_flock_locks)
+{
+       int err = 0;
+       __le32 nlocks;
+
+       nlocks = cpu_to_le32(num_fcntl_locks);
+       err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks));
+       if (err)
+               goto out_fail;
+
+       err = ceph_pagelist_append(pagelist, flocks,
+                                  num_fcntl_locks * sizeof(*flocks));
+       if (err)
+               goto out_fail;
+
+       nlocks = cpu_to_le32(num_flock_locks);
+       err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks));
+       if (err)
+               goto out_fail;
+
+       err = ceph_pagelist_append(pagelist,
+                                  &flocks[num_fcntl_locks],
+                                  num_flock_locks * sizeof(*flocks));
+out_fail:
+       return err;
+}
+
 /*
  * Given a pointer to a lock, convert it to a ceph filelock
  */
index 4f22671..4d29203 100644 (file)
@@ -2478,39 +2478,44 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
 
        if (recon_state->flock) {
                int num_fcntl_locks, num_flock_locks;
-               struct ceph_pagelist_cursor trunc_point;
-
-               ceph_pagelist_set_cursor(pagelist, &trunc_point);
-               do {
-                       lock_flocks();
-                       ceph_count_locks(inode, &num_fcntl_locks,
-                                        &num_flock_locks);
-                       rec.v2.flock_len = (2*sizeof(u32) +
-                                           (num_fcntl_locks+num_flock_locks) *
-                                           sizeof(struct ceph_filelock));
-                       unlock_flocks();
-
-                       /* pre-alloc pagelist */
-                       ceph_pagelist_truncate(pagelist, &trunc_point);
-                       err = ceph_pagelist_append(pagelist, &rec, reclen);
-                       if (!err)
-                               err = ceph_pagelist_reserve(pagelist,
-                                                           rec.v2.flock_len);
-
-                       /* encode locks */
-                       if (!err) {
-                               lock_flocks();
-                               err = ceph_encode_locks(inode,
-                                                       pagelist,
-                                                       num_fcntl_locks,
-                                                       num_flock_locks);
-                               unlock_flocks();
-                       }
-               } while (err == -ENOSPC);
+               struct ceph_filelock *flocks;
+
+encode_again:
+               lock_flocks();
+               ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks);
+               unlock_flocks();
+               flocks = kmalloc((num_fcntl_locks+num_flock_locks) *
+                                sizeof(struct ceph_filelock), GFP_NOFS);
+               if (!flocks) {
+                       err = -ENOMEM;
+                       goto out_free;
+               }
+               lock_flocks();
+               err = ceph_encode_locks_to_buffer(inode, flocks,
+                                                 num_fcntl_locks,
+                                                 num_flock_locks);
+               unlock_flocks();
+               if (err) {
+                       kfree(flocks);
+                       if (err == -ENOSPC)
+                               goto encode_again;
+                       goto out_free;
+               }
+               /*
+                * number of encoded locks is stable, so copy to pagelist
+                */
+               rec.v2.flock_len = cpu_to_le32(2*sizeof(u32) +
+                                   (num_fcntl_locks+num_flock_locks) *
+                                   sizeof(struct ceph_filelock));
+               err = ceph_pagelist_append(pagelist, &rec, reclen);
+               if (!err)
+                       err = ceph_locks_to_pagelist(flocks, pagelist,
+                                                    num_fcntl_locks,
+                                                    num_flock_locks);
+               kfree(flocks);
        } else {
                err = ceph_pagelist_append(pagelist, &rec, reclen);
        }
-
 out_free:
        kfree(path);
 out_dput:
index 8696be2..7ccfdb4 100644 (file)
@@ -822,8 +822,13 @@ extern const struct export_operations ceph_export_ops;
 extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl);
 extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl);
 extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num);
-extern int ceph_encode_locks(struct inode *i, struct ceph_pagelist *p,
-                            int p_locks, int f_locks);
+extern int ceph_encode_locks_to_buffer(struct inode *inode,
+                                      struct ceph_filelock *flocks,
+                                      int num_fcntl_locks,
+                                      int num_flock_locks);
+extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks,
+                                 struct ceph_pagelist *pagelist,
+                                 int num_fcntl_locks, int num_flock_locks);
 extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c);
 
 /* debugfs.c */
index 8e33ec6..58df174 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/vfs.h>
 #include <linux/fs.h>
+#include <linux/inet.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifsfs.h"
@@ -48,58 +49,74 @@ void cifs_dfs_release_automount_timer(void)
 }
 
 /**
- * cifs_get_share_name -       extracts share name from UNC
- * @node_name: pointer to UNC string
+ * cifs_build_devname - build a devicename from a UNC and optional prepath
+ * @nodename:  pointer to UNC string
+ * @prepath:   pointer to prefixpath (or NULL if there isn't one)
  *
- * Extracts sharename form full UNC.
- * i.e. strips from UNC trailing path that is not part of share
- * name and fixup missing '\' in the beginning of DFS node refferal
- * if necessary.
- * Returns pointer to share name on success or ERR_PTR on error.
- * Caller is responsible for freeing returned string.
+ * Build a new cifs devicename after chasing a DFS referral. Allocate a buffer
+ * big enough to hold the final thing. Copy the UNC from the nodename, and
+ * concatenate the prepath onto the end of it if there is one.
+ *
+ * Returns pointer to the built string, or a ERR_PTR. Caller is responsible
+ * for freeing the returned string.
  */
-static char *cifs_get_share_name(const char *node_name)
+static char *
+cifs_build_devname(char *nodename, const char *prepath)
 {
-       int len;
-       char *UNC;
-       char *pSep;
-
-       len = strlen(node_name);
-       UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */,
-                        GFP_KERNEL);
-       if (!UNC)
-               return ERR_PTR(-ENOMEM);
+       size_t pplen;
+       size_t unclen;
+       char *dev;
+       char *pos;
+
+       /* skip over any preceding delimiters */
+       nodename += strspn(nodename, "\\");
+       if (!*nodename)
+               return ERR_PTR(-EINVAL);
 
-       /* get share name and server name */
-       if (node_name[1] != '\\') {
-               UNC[0] = '\\';
-               strncpy(UNC+1, node_name, len);
-               len++;
-               UNC[len] = 0;
-       } else {
-               strncpy(UNC, node_name, len);
-               UNC[len] = 0;
-       }
+       /* get length of UNC and set pos to last char */
+       unclen = strlen(nodename);
+       pos = nodename + unclen - 1;
 
-       /* find server name end */
-       pSep = memchr(UNC+2, '\\', len-2);
-       if (!pSep) {
-               cifs_dbg(VFS, "%s: no server name end in node name: %s\n",
-                        __func__, node_name);
-               kfree(UNC);
-               return ERR_PTR(-EINVAL);
+       /* trim off any trailing delimiters */
+       while (*pos == '\\') {
+               --pos;
+               --unclen;
        }
 
-       /* find sharename end */
-       pSep++;
-       pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC));
-       if (pSep) {
-               /* trim path up to sharename end
-                * now we have share name in UNC */
-               *pSep = 0;
+       /* allocate a buffer:
+        * +2 for preceding "//"
+        * +1 for delimiter between UNC and prepath
+        * +1 for trailing NULL
+        */
+       pplen = prepath ? strlen(prepath) : 0;
+       dev = kmalloc(2 + unclen + 1 + pplen + 1, GFP_KERNEL);
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+
+       pos = dev;
+       /* add the initial "//" */
+       *pos = '/';
+       ++pos;
+       *pos = '/';
+       ++pos;
+
+       /* copy in the UNC portion from referral */
+       memcpy(pos, nodename, unclen);
+       pos += unclen;
+
+       /* copy the prefixpath remainder (if there is one) */
+       if (pplen) {
+               *pos = '/';
+               ++pos;
+               memcpy(pos, prepath, pplen);
+               pos += pplen;
        }
 
-       return UNC;
+       /* NULL terminator */
+       *pos = '\0';
+
+       convert_delimiter(dev, '/');
+       return dev;
 }
 
 
@@ -123,6 +140,7 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
 {
        int rc;
        char *mountdata = NULL;
+       const char *prepath = NULL;
        int md_len;
        char *tkn_e;
        char *srvIP = NULL;
@@ -132,7 +150,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
        if (sb_mountdata == NULL)
                return ERR_PTR(-EINVAL);
 
-       *devname = cifs_get_share_name(ref->node_name);
+       if (strlen(fullpath) - ref->path_consumed)
+               prepath = fullpath + ref->path_consumed;
+
+       *devname = cifs_build_devname(ref->node_name, prepath);
        if (IS_ERR(*devname)) {
                rc = PTR_ERR(*devname);
                *devname = NULL;
@@ -146,12 +167,14 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
                goto compose_mount_options_err;
        }
 
-       /* md_len = strlen(...) + 12 for 'sep+prefixpath='
-        * assuming that we have 'unc=' and 'ip=' in
-        * the original sb_mountdata
+       /*
+        * In most cases, we'll be building a shorter string than the original,
+        * but we do have to assume that the address in the ip= option may be
+        * much longer than the original. Add the max length of an address
+        * string to the length of the original string to allow for worst case.
         */
-       md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12;
-       mountdata = kzalloc(md_len+1, GFP_KERNEL);
+       md_len = strlen(sb_mountdata) + INET6_ADDRSTRLEN;
+       mountdata = kzalloc(md_len + 1, GFP_KERNEL);
        if (mountdata == NULL) {
                rc = -ENOMEM;
                goto compose_mount_options_err;
@@ -195,26 +218,6 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
                strncat(mountdata, &sep, 1);
        strcat(mountdata, "ip=");
        strcat(mountdata, srvIP);
-       strncat(mountdata, &sep, 1);
-       strcat(mountdata, "unc=");
-       strcat(mountdata, *devname);
-
-       /* find & copy prefixpath */
-       tkn_e = strchr(ref->node_name + 2, '\\');
-       if (tkn_e == NULL) {
-               /* invalid unc, missing share name*/
-               rc = -EINVAL;
-               goto compose_mount_options_err;
-       }
-
-       tkn_e = strchr(tkn_e + 1, '\\');
-       if (tkn_e || (strlen(fullpath) - ref->path_consumed)) {
-               strncat(mountdata, &sep, 1);
-               strcat(mountdata, "prefixpath=");
-               if (tkn_e)
-                       strcat(mountdata, tkn_e + 1);
-               strcat(mountdata, fullpath + ref->path_consumed);
-       }
 
        /*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
        /*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
index 72e4efe..3752b9f 100644 (file)
@@ -372,9 +372,6 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
        cifs_show_security(s, tcon->ses->server);
        cifs_show_cache_flavor(s, cifs_sb);
 
-       seq_printf(s, ",unc=");
-       seq_escape(s, tcon->treeName, " \t\n\\");
-
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
                seq_printf(s, ",multiuser");
        else if (tcon->ses->user_name)
index 99eeaa1..e3bc39b 100644 (file)
@@ -1061,6 +1061,7 @@ static int cifs_parse_security_flavors(char *value,
 #endif
        case Opt_sec_none:
                vol->nullauth = 1;
+               vol->secFlg |= CIFSSEC_MAY_NTLM;
                break;
        default:
                cifs_dbg(VFS, "bad security option: %s\n", value);
@@ -1257,14 +1258,18 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
        vol->backupuid_specified = false; /* no backup intent for a user */
        vol->backupgid_specified = false; /* no backup intent for a group */
 
-       /*
-        * For now, we ignore -EINVAL errors under the assumption that the
-        * unc= and prefixpath= options will be usable.
-        */
-       if (cifs_parse_devname(devname, vol) == -ENOMEM) {
-               printk(KERN_ERR "CIFS: Unable to allocate memory to parse "
-                               "device string.\n");
-               goto out_nomem;
+       switch (cifs_parse_devname(devname, vol)) {
+       case 0:
+               break;
+       case -ENOMEM:
+               cifs_dbg(VFS, "Unable to allocate memory for devname.\n");
+               goto cifs_parse_mount_err;
+       case -EINVAL:
+               cifs_dbg(VFS, "Malformed UNC in devname.\n");
+               goto cifs_parse_mount_err;
+       default:
+               cifs_dbg(VFS, "Unknown error parsing devname.\n");
+               goto cifs_parse_mount_err;
        }
 
        while ((data = strsep(&options, separator)) != NULL) {
@@ -1826,7 +1831,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
        }
 #endif
        if (!vol->UNC) {
-               cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string or in unc= option!\n");
+               cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
                goto cifs_parse_mount_err;
        }
 
@@ -3274,8 +3279,8 @@ build_unc_path_to_root(const struct smb_vol *vol,
        pos = full_path + unc_len;
 
        if (pplen) {
-               *pos++ = CIFS_DIR_SEP(cifs_sb);
-               strncpy(pos, vol->prepath, pplen);
+               *pos = CIFS_DIR_SEP(cifs_sb);
+               strncpy(pos + 1, vol->prepath, pplen);
                pos += pplen;
        }
 
index e7512e4..7ede730 100644 (file)
@@ -34,7 +34,7 @@
 
 /**
  * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address.
- * @unc: UNC path specifying the server
+ * @unc: UNC path specifying the server (with '/' as delimiter)
  * @ip_addr: Where to return the IP address.
  *
  * The IP address will be returned in string form, and the caller is
@@ -64,7 +64,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        hostname = unc + 2;
 
        /* Search for server name delimiter */
-       sep = memchr(hostname, '\\', len);
+       sep = memchr(hostname, '/', len);
        if (sep)
                len = sep - hostname;
        else
index 201f0a0..a7abbea 100644 (file)
@@ -295,6 +295,12 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
 static int
 ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
+       int rc;
+
+       rc = filemap_write_and_wait(file->f_mapping);
+       if (rc)
+               return rc;
+
        return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
 }
 
index bfb5315..8dd524f 100644 (file)
@@ -44,8 +44,11 @@ static ssize_t efivarfs_file_write(struct file *file,
 
        bytes = efivar_entry_set_get_size(var, attributes, &datasize,
                                          data, &set);
-       if (!set && bytes)
+       if (!set && bytes) {
+               if (bytes == -ENOENT)
+                       bytes = -EIO;
                goto out;
+       }
 
        if (bytes == -ENOENT) {
                drop_nlink(inode);
@@ -76,7 +79,14 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
        int err;
 
        err = efivar_entry_size(var, &datasize);
-       if (err)
+
+       /*
+        * efivarfs represents uncommitted variables with
+        * zero-length files. Reading them should return EOF.
+        */
+       if (err == -ENOENT)
+               return 0;
+       else if (err)
                return err;
 
        data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);
index cd4d87a..485dc0e 100644 (file)
@@ -306,17 +306,18 @@ void fput(struct file *file)
 {
        if (atomic_long_dec_and_test(&file->f_count)) {
                struct task_struct *task = current;
+               unsigned long flags;
+
                file_sb_list_del(file);
-               if (unlikely(in_interrupt() || task->flags & PF_KTHREAD)) {
-                       unsigned long flags;
-                       spin_lock_irqsave(&delayed_fput_lock, flags);
-                       list_add(&file->f_u.fu_list, &delayed_fput_list);
-                       schedule_work(&delayed_fput_work);
-                       spin_unlock_irqrestore(&delayed_fput_lock, flags);
-                       return;
+               if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
+                       init_task_work(&file->f_u.fu_rcuhead, ____fput);
+                       if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
+                               return;
                }
-               init_task_work(&file->f_u.fu_rcuhead, ____fput);
-               task_work_add(task, &file->f_u.fu_rcuhead, true);
+               spin_lock_irqsave(&delayed_fput_lock, flags);
+               list_add(&file->f_u.fu_list, &delayed_fput_list);
+               schedule_work(&delayed_fput_work);
+               spin_unlock_irqrestore(&delayed_fput_lock, flags);
        }
 }
 
index 254df56..f3f783d 100644 (file)
@@ -180,6 +180,8 @@ u64 fuse_get_attr_version(struct fuse_conn *fc)
 static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
 {
        struct inode *inode;
+       struct dentry *parent;
+       struct fuse_conn *fc;
 
        inode = ACCESS_ONCE(entry->d_inode);
        if (inode && is_bad_inode(inode))
@@ -187,10 +189,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
        else if (fuse_dentry_time(entry) < get_jiffies_64()) {
                int err;
                struct fuse_entry_out outarg;
-               struct fuse_conn *fc;
                struct fuse_req *req;
                struct fuse_forget_link *forget;
-               struct dentry *parent;
                u64 attr_version;
 
                /* For negative dentries, always do a fresh lookup */
@@ -241,8 +241,14 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                                       entry_attr_timeout(&outarg),
                                       attr_version);
                fuse_change_entry_timeout(entry, &outarg);
+       } else if (inode) {
+               fc = get_fuse_conn(inode);
+               if (fc->readdirplus_auto) {
+                       parent = dget_parent(entry);
+                       fuse_advise_use_readdirplus(parent->d_inode);
+                       dput(parent);
+               }
        }
-       fuse_advise_use_readdirplus(inode);
        return 1;
 }
 
index d1c9b85..e570081 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/compat.h>
 #include <linux/swap.h>
 #include <linux/aio.h>
+#include <linux/falloc.h>
 
 static const struct file_operations fuse_direct_io_file_operations;
 
@@ -1278,7 +1279,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
 
        iov_iter_init(&ii, iov, nr_segs, count, 0);
 
-       req = fuse_get_req(fc, fuse_iter_npages(&ii));
+       if (io->async)
+               req = fuse_get_req_for_background(fc, fuse_iter_npages(&ii));
+       else
+               req = fuse_get_req(fc, fuse_iter_npages(&ii));
        if (IS_ERR(req))
                return PTR_ERR(req);
 
@@ -1314,7 +1318,11 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, const struct iovec *iov,
                        break;
                if (count) {
                        fuse_put_request(fc, req);
-                       req = fuse_get_req(fc, fuse_iter_npages(&ii));
+                       if (io->async)
+                               req = fuse_get_req_for_background(fc,
+                                       fuse_iter_npages(&ii));
+                       else
+                               req = fuse_get_req(fc, fuse_iter_npages(&ii));
                        if (IS_ERR(req))
                                break;
                }
@@ -2365,6 +2373,11 @@ static void fuse_do_truncate(struct file *file)
        fuse_do_setattr(inode, &attr, file);
 }
 
+static inline loff_t fuse_round_up(loff_t off)
+{
+       return round_up(off, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
+}
+
 static ssize_t
 fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs)
@@ -2372,6 +2385,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        ssize_t ret = 0;
        struct file *file = iocb->ki_filp;
        struct fuse_file *ff = file->private_data;
+       bool async_dio = ff->fc->async_dio;
        loff_t pos = 0;
        struct inode *inode;
        loff_t i_size;
@@ -2383,10 +2397,10 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        i_size = i_size_read(inode);
 
        /* optimization for short read */
-       if (rw != WRITE && offset + count > i_size) {
+       if (async_dio && rw != WRITE && offset + count > i_size) {
                if (offset >= i_size)
                        return 0;
-               count = i_size - offset;
+               count = min_t(loff_t, count, fuse_round_up(i_size - offset));
        }
 
        io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL);
@@ -2404,7 +2418,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
         * By default, we want to optimize all I/Os with async request
         * submission to the client filesystem if supported.
         */
-       io->async = ff->fc->async_dio;
+       io->async = async_dio;
        io->iocb = iocb;
 
        /*
@@ -2412,7 +2426,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
         * to wait on real async I/O requests, so we must submit this request
         * synchronously.
         */
-       if (!is_sync_kiocb(iocb) && (offset + count > i_size))
+       if (!is_sync_kiocb(iocb) && (offset + count > i_size) && rw == WRITE)
                io->async = false;
 
        if (rw == WRITE)
@@ -2424,7 +2438,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
                fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
 
                /* we have a non-extending, async request, so return */
-               if (ret > 0 && !is_sync_kiocb(iocb))
+               if (!is_sync_kiocb(iocb))
                        return -EIOCBQUEUED;
 
                ret = wait_on_sync_kiocb(iocb);
@@ -2446,6 +2460,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
                                loff_t length)
 {
        struct fuse_file *ff = file->private_data;
+       struct inode *inode = file->f_inode;
        struct fuse_conn *fc = ff->fc;
        struct fuse_req *req;
        struct fuse_fallocate_in inarg = {
@@ -2459,9 +2474,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        if (fc->no_fallocate)
                return -EOPNOTSUPP;
 
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+               mutex_lock(&inode->i_mutex);
+               fuse_set_nowrite(inode);
+       }
+
        req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto out;
+       }
 
        req->in.h.opcode = FUSE_FALLOCATE;
        req->in.h.nodeid = ff->nodeid;
@@ -2476,6 +2498,24 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        }
        fuse_put_request(fc, req);
 
+       if (err)
+               goto out;
+
+       /* we could have extended the file */
+       if (!(mode & FALLOC_FL_KEEP_SIZE))
+               fuse_write_update_size(inode, offset + length);
+
+       if (mode & FALLOC_FL_PUNCH_HOLE)
+               truncate_pagecache_range(inode, offset, offset + length - 1);
+
+       fuse_invalidate_attr(inode);
+
+out:
+       if (mode & FALLOC_FL_PUNCH_HOLE) {
+               fuse_release_nowrite(inode);
+               mutex_unlock(&inode->i_mutex);
+       }
+
        return err;
 }
 
index 6201f81..9a0cdde 100644 (file)
@@ -867,10 +867,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
                                fc->dont_mask = 1;
                        if (arg->flags & FUSE_AUTO_INVAL_DATA)
                                fc->auto_inval_data = 1;
-                       if (arg->flags & FUSE_DO_READDIRPLUS)
+                       if (arg->flags & FUSE_DO_READDIRPLUS) {
                                fc->do_readdirplus = 1;
-                       if (arg->flags & FUSE_READDIRPLUS_AUTO)
-                               fc->readdirplus_auto = 1;
+                               if (arg->flags & FUSE_READDIRPLUS_AUTO)
+                                       fc->readdirplus_auto = 1;
+                       }
                        if (arg->flags & FUSE_ASYNC_DIO)
                                fc->async_dio = 1;
                } else {
index 1dc9a13..93b5809 100644 (file)
@@ -1286,17 +1286,26 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize)
        if (ret)
                return ret;
 
+       ret = get_write_access(inode);
+       if (ret)
+               return ret;
+
        inode_dio_wait(inode);
 
        ret = gfs2_rs_alloc(GFS2_I(inode));
        if (ret)
-               return ret;
+               goto out;
 
        oldsize = inode->i_size;
-       if (newsize >= oldsize)
-               return do_grow(inode, newsize);
+       if (newsize >= oldsize) {
+               ret = do_grow(inode, newsize);
+               goto out;
+       }
 
-       return do_shrink(inode, oldsize, newsize);
+       ret = do_shrink(inode, oldsize, newsize);
+out:
+       put_write_access(inode);
+       return ret;
 }
 
 int gfs2_truncatei_resume(struct gfs2_inode *ip)
index c3e82bd..b631c90 100644 (file)
@@ -354,22 +354,31 @@ static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip)
                return ERR_PTR(-EIO);
        }
 
-       hc = kmalloc(hsize, GFP_NOFS);
-       ret = -ENOMEM;
+       hc = kmalloc(hsize, GFP_NOFS | __GFP_NOWARN);
+       if (hc == NULL)
+               hc = __vmalloc(hsize, GFP_NOFS, PAGE_KERNEL);
+
        if (hc == NULL)
                return ERR_PTR(-ENOMEM);
 
        ret = gfs2_dir_read_data(ip, hc, hsize);
        if (ret < 0) {
-               kfree(hc);
+               if (is_vmalloc_addr(hc))
+                       vfree(hc);
+               else
+                       kfree(hc);
                return ERR_PTR(ret);
        }
 
        spin_lock(&inode->i_lock);
-       if (ip->i_hash_cache)
-               kfree(hc);
-       else
+       if (ip->i_hash_cache) {
+               if (is_vmalloc_addr(hc))
+                       vfree(hc);
+               else
+                       kfree(hc);
+       } else {
                ip->i_hash_cache = hc;
+       }
        spin_unlock(&inode->i_lock);
 
        return ip->i_hash_cache;
@@ -385,7 +394,10 @@ void gfs2_dir_hash_inval(struct gfs2_inode *ip)
 {
        __be64 *hc = ip->i_hash_cache;
        ip->i_hash_cache = NULL;
-       kfree(hc);
+       if (is_vmalloc_addr(hc))
+               vfree(hc);
+       else
+               kfree(hc);
 }
 
 static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
@@ -1113,7 +1125,10 @@ static int dir_double_exhash(struct gfs2_inode *dip)
        if (IS_ERR(hc))
                return PTR_ERR(hc);
 
-       h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS);
+       h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS | __GFP_NOWARN);
+       if (hc2 == NULL)
+               hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS, PAGE_KERNEL);
+
        if (!hc2)
                return -ENOMEM;
 
@@ -1145,7 +1160,10 @@ fail:
        gfs2_dinode_out(dip, dibh->b_data);
        brelse(dibh);
 out_kfree:
-       kfree(hc2);
+       if (is_vmalloc_addr(hc2))
+               vfree(hc2);
+       else
+               kfree(hc2);
        return error;
 }
 
@@ -1846,6 +1864,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
        memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
 
        ht = kzalloc(size, GFP_NOFS);
+       if (ht == NULL)
+               ht = vzalloc(size);
        if (!ht)
                return -ENOMEM;
 
@@ -1933,7 +1953,10 @@ out_rlist:
        gfs2_rlist_free(&rlist);
        gfs2_quota_unhold(dip);
 out:
-       kfree(ht);
+       if (is_vmalloc_addr(ht))
+               vfree(ht);
+       else
+               kfree(ht);
        return error;
 }
 
index acd1676..ad0dc38 100644 (file)
@@ -402,16 +402,20 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        /* Update file times before taking page lock */
        file_update_time(vma->vm_file);
 
+       ret = get_write_access(inode);
+       if (ret)
+               goto out;
+
        ret = gfs2_rs_alloc(ip);
        if (ret)
-               return ret;
+               goto out_write_access;
 
        gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE);
 
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
        ret = gfs2_glock_nq(&gh);
        if (ret)
-               goto out;
+               goto out_uninit;
 
        set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
        set_bit(GIF_SW_PAGED, &ip->i_flags);
@@ -480,12 +484,15 @@ out_quota_unlock:
        gfs2_quota_unlock(ip);
 out_unlock:
        gfs2_glock_dq(&gh);
-out:
+out_uninit:
        gfs2_holder_uninit(&gh);
        if (ret == 0) {
                set_page_dirty(page);
                wait_for_stable_page(page);
        }
+out_write_access:
+       put_write_access(inode);
+out:
        sb_end_pagefault(inode->i_sb);
        return block_page_mkwrite_return(ret);
 }
@@ -594,10 +601,10 @@ static int gfs2_release(struct inode *inode, struct file *file)
        kfree(file->private_data);
        file->private_data = NULL;
 
-       if ((file->f_mode & FMODE_WRITE) &&
-           (atomic_read(&inode->i_writecount) == 1))
-               gfs2_rs_delete(ip);
+       if (!(file->f_mode & FMODE_WRITE))
+               return 0;
 
+       gfs2_rs_delete(ip);
        return 0;
 }
 
index 8833a4f..62b484e 100644 (file)
@@ -189,6 +189,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
        return inode;
 
 fail_refresh:
+       ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
        ip->i_iopen_gh.gh_gl->gl_object = NULL;
        gfs2_glock_dq_uninit(&ip->i_iopen_gh);
 fail_iopen:
index 68b4c8f..6c33d7b 100644 (file)
@@ -419,7 +419,9 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit,
                if (total > limit)
                        num = limit;
                gfs2_log_unlock(sdp);
-               page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA, num + 1, num);
+               page = gfs2_get_log_desc(sdp,
+                                        is_databuf ? GFS2_LOG_DESC_JDATA :
+                                        GFS2_LOG_DESC_METADATA, num + 1, num);
                ld = page_address(page);
                gfs2_log_lock(sdp);
                ptr = (__be64 *)(ld + 1);
index 5232525..9809156 100644 (file)
@@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
  */
 void gfs2_rs_delete(struct gfs2_inode *ip)
 {
+       struct inode *inode = &ip->i_inode;
+
        down_write(&ip->i_rw_mutex);
-       if (ip->i_res) {
+       if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
                gfs2_rs_deltree(ip->i_res);
                BUG_ON(ip->i_res->rs_free);
                kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
index 917c8e1..e5639de 100644 (file)
@@ -1444,6 +1444,7 @@ static void gfs2_evict_inode(struct inode *inode)
        /* Must not read inode block until block type has been verified */
        error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh);
        if (unlikely(error)) {
+               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
                gfs2_glock_dq_uninit(&ip->i_iopen_gh);
                goto out;
        }
@@ -1514,8 +1515,10 @@ out_unlock:
        if (gfs2_rs_active(ip->i_res))
                gfs2_rs_deltree(ip->i_res);
 
-       if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
+       if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
+               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
                gfs2_glock_dq(&ip->i_iopen_gh);
+       }
        gfs2_holder_uninit(&ip->i_iopen_gh);
        gfs2_glock_dq_uninit(&gh);
        if (error && error != GLR_TRYFAILED && error != -EROFS)
@@ -1534,6 +1537,7 @@ out:
        ip->i_gl = NULL;
        if (ip->i_iopen_gh.gh_gl) {
                ip->i_iopen_gh.gh_gl->gl_object = NULL;
+               ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
                gfs2_glock_dq_uninit(&ip->i_iopen_gh);
        }
 }
index 546f6d3..834ac13 100644 (file)
@@ -33,25 +33,27 @@ static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence)
        if (whence == SEEK_DATA || whence == SEEK_HOLE)
                return -EINVAL;
 
+       mutex_lock(&i->i_mutex);
        hpfs_lock(s);
 
        /*printk("dir lseek\n");*/
        if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
-       mutex_lock(&i->i_mutex);
        pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1;
        while (pos != new_off) {
                if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh);
                else goto fail;
                if (pos == 12) goto fail;
        }
-       mutex_unlock(&i->i_mutex);
+       hpfs_add_pos(i, &filp->f_pos);
 ok:
+       filp->f_pos = new_off;
        hpfs_unlock(s);
-       return filp->f_pos = new_off;
-fail:
        mutex_unlock(&i->i_mutex);
+       return new_off;
+fail:
        /*printk("illegal lseek: %016llx\n", new_off);*/
        hpfs_unlock(s);
+       mutex_unlock(&i->i_mutex);
        return -ESPIPE;
 }
 
index 3027f4d..e4ba5fe 100644 (file)
@@ -109,10 +109,14 @@ static void hpfs_write_failed(struct address_space *mapping, loff_t to)
 {
        struct inode *inode = mapping->host;
 
+       hpfs_lock(inode->i_sb);
+
        if (to > inode->i_size) {
                truncate_pagecache(inode, to, inode->i_size);
                hpfs_truncate(inode);
        }
+
+       hpfs_unlock(inode->i_sb);
 }
 
 static int hpfs_write_begin(struct file *file, struct address_space *mapping,
index c57499d..360d27c 100644 (file)
@@ -2009,7 +2009,13 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
 
        bio->bi_end_io = lbmIODone;
        bio->bi_private = bp;
-       submit_bio(READ_SYNC, bio);
+       /*check if journaling to disk has been disabled*/
+       if (log->no_integrity) {
+               bio->bi_size = 0;
+               lbmIODone(bio, 0);
+       } else {
+               submit_bio(READ_SYNC, bio);
+       }
 
        wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD));
 
index 2003e83..788e0a9 100644 (file)
@@ -611,11 +611,28 @@ static int jfs_freeze(struct super_block *sb)
 {
        struct jfs_sb_info *sbi = JFS_SBI(sb);
        struct jfs_log *log = sbi->log;
+       int rc = 0;
 
        if (!(sb->s_flags & MS_RDONLY)) {
                txQuiesce(sb);
-               lmLogShutdown(log);
-               updateSuper(sb, FM_CLEAN);
+               rc = lmLogShutdown(log);
+               if (rc) {
+                       jfs_error(sb, "jfs_freeze: lmLogShutdown failed");
+
+                       /* let operations fail rather than hang */
+                       txResume(sb);
+
+                       return rc;
+               }
+               rc = updateSuper(sb, FM_CLEAN);
+               if (rc) {
+                       jfs_err("jfs_freeze: updateSuper failed\n");
+                       /*
+                        * Don't fail here. Everything succeeded except
+                        * marking the superblock clean, so there's really
+                        * no harm in leaving it frozen for now.
+                        */
+               }
        }
        return 0;
 }
@@ -627,13 +644,18 @@ static int jfs_unfreeze(struct super_block *sb)
        int rc = 0;
 
        if (!(sb->s_flags & MS_RDONLY)) {
-               updateSuper(sb, FM_MOUNT);
-               if ((rc = lmLogInit(log)))
-                       jfs_err("jfs_unlock failed with return code %d", rc);
-               else
-                       txResume(sb);
+               rc = updateSuper(sb, FM_MOUNT);
+               if (rc) {
+                       jfs_error(sb, "jfs_unfreeze: updateSuper failed");
+                       goto out;
+               }
+               rc = lmLogInit(log);
+               if (rc)
+                       jfs_error(sb, "jfs_unfreeze: lmLogInit failed");
+out:
+               txResume(sb);
        }
-       return 0;
+       return rc;
 }
 
 static struct dentry *jfs_do_mount(struct file_system_type *fs_type,
index 85e40d1..9ed9361 100644 (file)
@@ -1976,7 +1976,7 @@ static int path_lookupat(int dfd, const char *name,
                err = complete_walk(nd);
 
        if (!err && nd->flags & LOOKUP_DIRECTORY) {
-               if (!nd->inode->i_op->lookup) {
+               if (!can_lookup(nd->inode)) {
                        path_put(&nd->path);
                        err = -ENOTDIR;
                }
@@ -2850,7 +2850,7 @@ finish_lookup:
        if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
                goto out;
        error = -ENOTDIR;
-       if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup)
+       if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode))
                goto out;
        audit_inode(name, nd->path.dentry, 0);
 finish_open:
index 8163260..6792ce1 100644 (file)
@@ -1029,15 +1029,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
        DPRINTK("ncp_rmdir: removing %s/%s\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
 
-       /*
-        * fail with EBUSY if there are still references to this
-        * directory.
-        */
-       dentry_unhash(dentry);
-       error = -EBUSY;
-       if (!d_unhashed(dentry))
-               goto out;
-
        len = sizeof(__name);
        error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
                           dentry->d_name.len, !ncp_preserve_case(dir));
index 4e2fe71..d7ba561 100644 (file)
@@ -1078,7 +1078,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
        struct nfs4_state *state = opendata->state;
        struct nfs_inode *nfsi = NFS_I(state->inode);
        struct nfs_delegation *delegation;
-       int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC);
+       int open_mode = opendata->o_arg.open_flags;
        fmode_t fmode = opendata->o_arg.fmode;
        nfs4_stateid stateid;
        int ret = -EAGAIN;
index a366107..2d7525f 100644 (file)
@@ -1942,6 +1942,7 @@ static int nfs23_validate_mount_data(void *options,
                args->namlen            = data->namlen;
                args->bsize             = data->bsize;
 
+               args->auth_flavors[0] = RPC_AUTH_UNIX;
                if (data->flags & NFS_MOUNT_SECFLAVOUR)
                        args->auth_flavors[0] = data->pseudoflavor;
                if (!args->nfs_server.hostname)
@@ -2637,6 +2638,7 @@ static int nfs4_validate_mount_data(void *options,
                        goto out_no_address;
                args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
 
+               args->auth_flavors[0] = RPC_AUTH_UNIX;
                if (data->auth_flavourlen) {
                        if (data->auth_flavourlen > 1)
                                goto out_inval_auth;
index b3fdd1a..e68588e 100644 (file)
@@ -1408,6 +1408,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
                                     mres->lockname_len, mres->lockname);
                                ret = -EFAULT;
                                spin_unlock(&res->spinlock);
+                               dlm_lockres_put(res);
                                goto leave;
                        }
                        res->state |= DLM_LOCK_RES_MIGRATING;
index 04ee1b5..b4a5cdf 100644 (file)
@@ -947,7 +947,7 @@ leave:
        ocfs2_free_dir_lookup_result(&orphan_insert);
        ocfs2_free_dir_lookup_result(&lookup);
 
-       if (status)
+       if (status && (status != -ENOTEMPTY))
                mlog_errno(status);
 
        return status;
@@ -2216,7 +2216,7 @@ out:
 
        brelse(orphan_dir_bh);
 
-       return 0;
+       return ret;
 }
 
 int ocfs2_create_inode_in_orphan(struct inode *dir,
index 3d2a714..9af0df1 100644 (file)
@@ -83,7 +83,8 @@ static int do_make_slave(struct mount *mnt)
                if (peer_mnt == mnt)
                        peer_mnt = NULL;
        }
-       if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share))
+       if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) &&
+           list_empty(&mnt->mnt_share))
                mnt_release_group_id(mnt);
 
        list_del_init(&mnt->mnt_share);
index dd51e50..c3834da 100644 (file)
@@ -2118,6 +2118,7 @@ static int show_timer(struct seq_file *m, void *v)
                nstr[notify & ~SIGEV_THREAD_ID],
                (notify & SIGEV_THREAD_ID) ? "tid" : "pid",
                pid_nr_ns(timer->it_pid, tp->ns));
+       seq_printf(m, "ClockID: %d\n", timer->it_clock);
 
        return 0;
 }
index bd4b5a7..bdfabda 100644 (file)
@@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait;
 
 static int kmsg_open(struct inode * inode, struct file * file)
 {
-       return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE);
+       return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_PROC);
 }
 
 static int kmsg_release(struct inode * inode, struct file * file)
 {
-       (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE);
+       (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_PROC);
        return 0;
 }
 
@@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
                         size_t count, loff_t *ppos)
 {
        if ((file->f_flags & O_NONBLOCK) &&
-           !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
+           !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
                return -EAGAIN;
-       return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE);
+       return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_PROC);
 }
 
 static unsigned int kmsg_poll(struct file *file, poll_table *wait)
 {
        poll_wait(file, &log_wait, wait);
-       if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
+       if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
                return POLLIN | POLLRDNORM;
        return 0;
 }
index 8798d06..afa6be6 100644 (file)
@@ -120,7 +120,7 @@ static int qnx6_readdir(struct file *filp, void *dirent, filldir_t filldir)
        struct inode *inode = file_inode(filp);
        struct super_block *s = inode->i_sb;
        struct qnx6_sb_info *sbi = QNX6_SB(s);
-       loff_t pos = filp->f_pos & (QNX6_DIR_ENTRY_SIZE - 1);
+       loff_t pos = filp->f_pos & ~(QNX6_DIR_ENTRY_SIZE - 1);
        unsigned long npages = dir_pages(inode);
        unsigned long n = pos >> PAGE_CACHE_SHIFT;
        unsigned start = (pos & ~PAGE_CACHE_MASK) / QNX6_DIR_ENTRY_SIZE;
index 66c53b6..6c2d136 100644 (file)
@@ -204,6 +204,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent,
                                next_pos = deh_offset(deh) + 1;
 
                                if (item_moved(&tmp_ih, &path_to_entry)) {
+                                       set_cpu_key_k_offset(&pos_key,
+                                                            next_pos);
                                        goto research;
                                }
                        }       /* for */
index 77d6d47..f844533 100644 (file)
@@ -1811,11 +1811,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                                  TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
        memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE);
        args.dirid = le32_to_cpu(ih.ih_key.k_dir_id);
-       if (insert_inode_locked4(inode, args.objectid,
-                            reiserfs_find_actor, &args) < 0) {
+
+       reiserfs_write_unlock(inode->i_sb);
+       err = insert_inode_locked4(inode, args.objectid,
+                            reiserfs_find_actor, &args);
+       reiserfs_write_lock(inode->i_sb);
+       if (err) {
                err = -EINVAL;
                goto out_bad_inode;
        }
+
        if (old_format_only(sb))
                /* not a perfect generation count, as object ids can be reused, but
                 ** this is as good as reiserfs can do right now.
index 4cce1d9..821bcf7 100644 (file)
@@ -318,7 +318,19 @@ static int delete_one_xattr(struct dentry *dentry, void *data)
 static int chown_one_xattr(struct dentry *dentry, void *data)
 {
        struct iattr *attrs = data;
-       return reiserfs_setattr(dentry, attrs);
+       int ia_valid = attrs->ia_valid;
+       int err;
+
+       /*
+        * We only want the ownership bits. Otherwise, we'll do
+        * things like change a directory to a regular file if
+        * ATTR_MODE is set.
+        */
+       attrs->ia_valid &= (ATTR_UID|ATTR_GID);
+       err = reiserfs_setattr(dentry, attrs);
+       attrs->ia_valid = ia_valid;
+
+       return err;
 }
 
 /* No i_mutex, but the inode is unconnected. */
index d7c01ef..6c8767f 100644 (file)
@@ -443,6 +443,9 @@ int reiserfs_acl_chmod(struct inode *inode)
        int depth;
        int error;
 
+       if (IS_PRIVATE(inode))
+               return 0;
+
        if (S_ISLNK(inode->i_mode))
                return -EOPNOTSUPP;
 
index 1d32f1d..306d883 100644 (file)
@@ -21,6 +21,8 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_inode.h"
 #include "xfs_vnodeops.h"
+#include "xfs_sb.h"
+#include "xfs_mount.h"
 #include "xfs_trace.h"
 #include <linux/slab.h>
 #include <linux/xattr.h>
@@ -34,7 +36,9 @@
  */
 
 STATIC struct posix_acl *
-xfs_acl_from_disk(struct xfs_acl *aclp)
+xfs_acl_from_disk(
+       struct xfs_acl  *aclp,
+       int             max_entries)
 {
        struct posix_acl_entry *acl_e;
        struct posix_acl *acl;
@@ -42,7 +46,7 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
        unsigned int count, i;
 
        count = be32_to_cpu(aclp->acl_cnt);
-       if (count > XFS_ACL_MAX_ENTRIES)
+       if (count > max_entries)
                return ERR_PTR(-EFSCORRUPTED);
 
        acl = posix_acl_alloc(count, GFP_KERNEL);
@@ -108,9 +112,9 @@ xfs_get_acl(struct inode *inode, int type)
        struct xfs_inode *ip = XFS_I(inode);
        struct posix_acl *acl;
        struct xfs_acl *xfs_acl;
-       int len = sizeof(struct xfs_acl);
        unsigned char *ea_name;
        int error;
+       int len;
 
        acl = get_cached_acl(inode, type);
        if (acl != ACL_NOT_CACHED)
@@ -133,8 +137,8 @@ xfs_get_acl(struct inode *inode, int type)
         * If we have a cached ACLs value just return it, not need to
         * go out to the disk.
         */
-
-       xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
+       len = XFS_ACL_MAX_SIZE(ip->i_mount);
+       xfs_acl = kzalloc(len, GFP_KERNEL);
        if (!xfs_acl)
                return ERR_PTR(-ENOMEM);
 
@@ -153,7 +157,7 @@ xfs_get_acl(struct inode *inode, int type)
                goto out;
        }
 
-       acl = xfs_acl_from_disk(xfs_acl);
+       acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount));
        if (IS_ERR(acl))
                goto out;
 
@@ -189,16 +193,17 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 
        if (acl) {
                struct xfs_acl *xfs_acl;
-               int len;
+               int len = XFS_ACL_MAX_SIZE(ip->i_mount);
 
-               xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
+               xfs_acl = kzalloc(len, GFP_KERNEL);
                if (!xfs_acl)
                        return -ENOMEM;
 
                xfs_acl_to_disk(xfs_acl, acl);
-               len = sizeof(struct xfs_acl) -
-                       (sizeof(struct xfs_acl_entry) *
-                        (XFS_ACL_MAX_ENTRIES - acl->a_count));
+
+               /* subtract away the unused acl entries */
+               len -= sizeof(struct xfs_acl_entry) *
+                        (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
 
                error = -xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl,
                                len, ATTR_ROOT);
@@ -243,7 +248,7 @@ xfs_set_mode(struct inode *inode, umode_t mode)
 static int
 xfs_acl_exists(struct inode *inode, unsigned char *name)
 {
-       int len = sizeof(struct xfs_acl);
+       int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb));
 
        return (xfs_attr_get(XFS_I(inode), name, NULL, &len,
                            ATTR_ROOT|ATTR_KERNOVAL) == 0);
@@ -379,7 +384,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
                goto out_release;
 
        error = -EINVAL;
-       if (acl->a_count > XFS_ACL_MAX_ENTRIES)
+       if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
                goto out_release;
 
        if (type == ACL_TYPE_ACCESS) {
index 39632d9..4016a56 100644 (file)
@@ -22,19 +22,36 @@ struct inode;
 struct posix_acl;
 struct xfs_inode;
 
-#define XFS_ACL_MAX_ENTRIES 25
 #define XFS_ACL_NOT_PRESENT (-1)
 
 /* On-disk XFS access control list structure */
+struct xfs_acl_entry {
+       __be32  ae_tag;
+       __be32  ae_id;
+       __be16  ae_perm;
+       __be16  ae_pad;         /* fill the implicit hole in the structure */
+};
+
 struct xfs_acl {
-       __be32          acl_cnt;
-       struct xfs_acl_entry {
-               __be32  ae_tag;
-               __be32  ae_id;
-               __be16  ae_perm;
-       } acl_entry[XFS_ACL_MAX_ENTRIES];
+       __be32                  acl_cnt;
+       struct xfs_acl_entry    acl_entry[0];
 };
 
+/*
+ * The number of ACL entries allowed is defined by the on-disk format.
+ * For v4 superblocks, that is limited to 25 entries. For v5 superblocks, it is
+ * limited only by the maximum size of the xattr that stores the information.
+ */
+#define XFS_ACL_MAX_ENTRIES(mp)        \
+       (xfs_sb_version_hascrc(&mp->m_sb) \
+               ?  (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \
+                                               sizeof(struct xfs_acl_entry) \
+               : 25)
+
+#define XFS_ACL_MAX_SIZE(mp) \
+       (sizeof(struct xfs_acl) + \
+               sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp)))
+
 /* On-disk XFS extended attribute names */
 #define SGI_ACL_FILE           (unsigned char *)"SGI_ACL_FILE"
 #define SGI_ACL_DEFAULT                (unsigned char *)"SGI_ACL_DEFAULT"
index 0bce1b3..31d3cd1 100644 (file)
@@ -1412,7 +1412,7 @@ xfs_attr3_leaf_add_work(
                name_rmt->valuelen = 0;
                name_rmt->valueblk = 0;
                args->rmtblkno = 1;
-               args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen);
+               args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
        }
        xfs_trans_log_buf(args->trans, bp,
             XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
@@ -1445,11 +1445,12 @@ xfs_attr3_leaf_add_work(
 STATIC void
 xfs_attr3_leaf_compact(
        struct xfs_da_args      *args,
-       struct xfs_attr3_icleaf_hdr *ichdr_d,
+       struct xfs_attr3_icleaf_hdr *ichdr_dst,
        struct xfs_buf          *bp)
 {
-       xfs_attr_leafblock_t    *leaf_s, *leaf_d;
-       struct xfs_attr3_icleaf_hdr ichdr_s;
+       struct xfs_attr_leafblock *leaf_src;
+       struct xfs_attr_leafblock *leaf_dst;
+       struct xfs_attr3_icleaf_hdr ichdr_src;
        struct xfs_trans        *trans = args->trans;
        struct xfs_mount        *mp = trans->t_mountp;
        char                    *tmpbuffer;
@@ -1457,29 +1458,38 @@ xfs_attr3_leaf_compact(
        trace_xfs_attr_leaf_compact(args);
 
        tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP);
-       ASSERT(tmpbuffer != NULL);
        memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp));
        memset(bp->b_addr, 0, XFS_LBSIZE(mp));
+       leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
+       leaf_dst = bp->b_addr;
 
        /*
-        * Copy basic information
+        * Copy the on-disk header back into the destination buffer to ensure
+        * all the information in the header that is not part of the incore
+        * header structure is preserved.
         */
-       leaf_s = (xfs_attr_leafblock_t *)tmpbuffer;
-       leaf_d = bp->b_addr;
-       ichdr_s = *ichdr_d;     /* struct copy */
-       ichdr_d->firstused = XFS_LBSIZE(mp);
-       ichdr_d->usedbytes = 0;
-       ichdr_d->count = 0;
-       ichdr_d->holes = 0;
-       ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_s);
-       ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
+       memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
+
+       /* Initialise the incore headers */
+       ichdr_src = *ichdr_dst; /* struct copy */
+       ichdr_dst->firstused = XFS_LBSIZE(mp);
+       ichdr_dst->usedbytes = 0;
+       ichdr_dst->count = 0;
+       ichdr_dst->holes = 0;
+       ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
+       ichdr_dst->freemap[0].size = ichdr_dst->firstused -
+                                               ichdr_dst->freemap[0].base;
+
+
+       /* write the header back to initialise the underlying buffer */
+       xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst);
 
        /*
         * Copy all entry's in the same (sorted) order,
         * but allocate name/value pairs packed and in sequence.
         */
-       xfs_attr3_leaf_moveents(leaf_s, &ichdr_s, 0, leaf_d, ichdr_d, 0,
-                               ichdr_s.count, mp);
+       xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0,
+                               ichdr_src.count, mp);
        /*
         * this logs the entire buffer, but the caller must write the header
         * back to the buffer when it is finished modifying it.
@@ -2181,14 +2191,24 @@ xfs_attr3_leaf_unbalance(
                struct xfs_attr_leafblock *tmp_leaf;
                struct xfs_attr3_icleaf_hdr tmphdr;
 
-               tmp_leaf = kmem_alloc(state->blocksize, KM_SLEEP);
-               memset(tmp_leaf, 0, state->blocksize);
-               memset(&tmphdr, 0, sizeof(tmphdr));
+               tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP);
 
+               /*
+                * Copy the header into the temp leaf so that all the stuff
+                * not in the incore header is present and gets copied back in
+                * once we've moved all the entries.
+                */
+               memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
+
+               memset(&tmphdr, 0, sizeof(tmphdr));
                tmphdr.magic = savehdr.magic;
                tmphdr.forw = savehdr.forw;
                tmphdr.back = savehdr.back;
                tmphdr.firstused = state->blocksize;
+
+               /* write the header to the temp buffer to initialise it */
+               xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr);
+
                if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
                                         drop_blk->bp, &drophdr)) {
                        xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0,
@@ -2334,8 +2354,9 @@ xfs_attr3_leaf_lookup_int(
                        args->index = probe;
                        args->valuelen = be32_to_cpu(name_rmt->valuelen);
                        args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
-                       args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount,
-                                                      args->valuelen);
+                       args->rmtblkcnt = xfs_attr3_rmt_blocks(
+                                                       args->dp->i_mount,
+                                                       args->valuelen);
                        return XFS_ERROR(EEXIST);
                }
        }
@@ -2386,7 +2407,8 @@ xfs_attr3_leaf_getvalue(
                ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
                valuelen = be32_to_cpu(name_rmt->valuelen);
                args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
-               args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, valuelen);
+               args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
+                                                      valuelen);
                if (args->flags & ATTR_KERNOVAL) {
                        args->valuelen = valuelen;
                        return 0;
@@ -2712,7 +2734,8 @@ xfs_attr3_leaf_list_int(
                                args.valuelen = valuelen;
                                args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS);
                                args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
-                               args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen);
+                               args.rmtblkcnt = xfs_attr3_rmt_blocks(
+                                                       args.dp->i_mount, valuelen);
                                retval = xfs_attr_rmtval_get(&args);
                                if (retval)
                                        return retval;
@@ -3235,7 +3258,7 @@ xfs_attr3_leaf_inactive(
                        name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
                        if (name_rmt->valueblk) {
                                lp->valueblk = be32_to_cpu(name_rmt->valueblk);
-                               lp->valuelen = XFS_B_TO_FSB(dp->i_mount,
+                               lp->valuelen = xfs_attr3_rmt_blocks(dp->i_mount,
                                                    be32_to_cpu(name_rmt->valuelen));
                                lp++;
                        }
index f9d7846..444a770 100644 (file)
@@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr {
        __u8                    holes;
        __u8                    pad1;
        struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE];
+       __be32                  pad2;           /* 64 bit alignment */
 };
 
 #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc))
index dee8446..ef6b0c1 100644 (file)
  * Each contiguous block has a header, so it is not just a simple attribute
  * length to FSB conversion.
  */
-static int
+int
 xfs_attr3_rmt_blocks(
        struct xfs_mount *mp,
        int             attrlen)
 {
-       int             buflen = XFS_ATTR3_RMT_BUF_SPACE(mp,
-                                                        mp->m_sb.sb_blocksize);
-       return (attrlen + buflen - 1) / buflen;
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               int buflen = XFS_ATTR3_RMT_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
+               return (attrlen + buflen - 1) / buflen;
+       }
+       return XFS_B_TO_FSB(mp, attrlen);
+}
+
+/*
+ * Checking of the remote attribute header is split into two parts. The verifier
+ * does CRC, location and bounds checking, the unpacking function checks the
+ * attribute parameters and owner.
+ */
+static bool
+xfs_attr3_rmt_hdr_ok(
+       struct xfs_mount        *mp,
+       void                    *ptr,
+       xfs_ino_t               ino,
+       uint32_t                offset,
+       uint32_t                size,
+       xfs_daddr_t             bno)
+{
+       struct xfs_attr3_rmt_hdr *rmt = ptr;
+
+       if (bno != be64_to_cpu(rmt->rm_blkno))
+               return false;
+       if (offset != be32_to_cpu(rmt->rm_offset))
+               return false;
+       if (size != be32_to_cpu(rmt->rm_bytes))
+               return false;
+       if (ino != be64_to_cpu(rmt->rm_owner))
+               return false;
+
+       /* ok */
+       return true;
 }
 
 static bool
 xfs_attr3_rmt_verify(
-       struct xfs_buf          *bp)
+       struct xfs_mount        *mp,
+       void                    *ptr,
+       int                     fsbsize,
+       xfs_daddr_t             bno)
 {
-       struct xfs_mount        *mp = bp->b_target->bt_mount;
-       struct xfs_attr3_rmt_hdr *rmt = bp->b_addr;
+       struct xfs_attr3_rmt_hdr *rmt = ptr;
 
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return false;
@@ -70,7 +103,9 @@ xfs_attr3_rmt_verify(
                return false;
        if (!uuid_equal(&rmt->rm_uuid, &mp->m_sb.sb_uuid))
                return false;
-       if (bp->b_bn != be64_to_cpu(rmt->rm_blkno))
+       if (be64_to_cpu(rmt->rm_blkno) != bno)
+               return false;
+       if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt))
                return false;
        if (be32_to_cpu(rmt->rm_offset) +
                                be32_to_cpu(rmt->rm_bytes) >= XATTR_SIZE_MAX)
@@ -86,17 +121,40 @@ xfs_attr3_rmt_read_verify(
        struct xfs_buf  *bp)
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
+       char            *ptr;
+       int             len;
+       bool            corrupt = false;
+       xfs_daddr_t     bno;
 
        /* no verification of non-crc buffers */
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return;
 
-       if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
-                             XFS_ATTR3_RMT_CRC_OFF) ||
-           !xfs_attr3_rmt_verify(bp)) {
+       ptr = bp->b_addr;
+       bno = bp->b_bn;
+       len = BBTOB(bp->b_length);
+       ASSERT(len >= XFS_LBSIZE(mp));
+
+       while (len > 0) {
+               if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp),
+                                     XFS_ATTR3_RMT_CRC_OFF)) {
+                       corrupt = true;
+                       break;
+               }
+               if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
+                       corrupt = true;
+                       break;
+               }
+               len -= XFS_LBSIZE(mp);
+               ptr += XFS_LBSIZE(mp);
+               bno += mp->m_bsize;
+       }
+
+       if (corrupt) {
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, EFSCORRUPTED);
-       }
+       } else
+               ASSERT(len == 0);
 }
 
 static void
@@ -105,23 +163,39 @@ xfs_attr3_rmt_write_verify(
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
        struct xfs_buf_log_item *bip = bp->b_fspriv;
+       char            *ptr;
+       int             len;
+       xfs_daddr_t     bno;
 
        /* no verification of non-crc buffers */
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return;
 
-       if (!xfs_attr3_rmt_verify(bp)) {
-               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
-               xfs_buf_ioerror(bp, EFSCORRUPTED);
-               return;
-       }
+       ptr = bp->b_addr;
+       bno = bp->b_bn;
+       len = BBTOB(bp->b_length);
+       ASSERT(len >= XFS_LBSIZE(mp));
+
+       while (len > 0) {
+               if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
+                       XFS_CORRUPTION_ERROR(__func__,
+                                           XFS_ERRLEVEL_LOW, mp, bp->b_addr);
+                       xfs_buf_ioerror(bp, EFSCORRUPTED);
+                       return;
+               }
+               if (bip) {
+                       struct xfs_attr3_rmt_hdr *rmt;
+
+                       rmt = (struct xfs_attr3_rmt_hdr *)ptr;
+                       rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn);
+               }
+               xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF);
 
-       if (bip) {
-               struct xfs_attr3_rmt_hdr *rmt = bp->b_addr;
-               rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn);
+               len -= XFS_LBSIZE(mp);
+               ptr += XFS_LBSIZE(mp);
+               bno += mp->m_bsize;
        }
-       xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
-                        XFS_ATTR3_RMT_CRC_OFF);
+       ASSERT(len == 0);
 }
 
 const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = {
@@ -129,15 +203,16 @@ const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = {
        .verify_write = xfs_attr3_rmt_write_verify,
 };
 
-static int
+STATIC int
 xfs_attr3_rmt_hdr_set(
        struct xfs_mount        *mp,
+       void                    *ptr,
        xfs_ino_t               ino,
        uint32_t                offset,
        uint32_t                size,
-       struct xfs_buf          *bp)
+       xfs_daddr_t             bno)
 {
-       struct xfs_attr3_rmt_hdr *rmt = bp->b_addr;
+       struct xfs_attr3_rmt_hdr *rmt = ptr;
 
        if (!xfs_sb_version_hascrc(&mp->m_sb))
                return 0;
@@ -147,36 +222,107 @@ xfs_attr3_rmt_hdr_set(
        rmt->rm_bytes = cpu_to_be32(size);
        uuid_copy(&rmt->rm_uuid, &mp->m_sb.sb_uuid);
        rmt->rm_owner = cpu_to_be64(ino);
-       rmt->rm_blkno = cpu_to_be64(bp->b_bn);
-       bp->b_ops = &xfs_attr3_rmt_buf_ops;
+       rmt->rm_blkno = cpu_to_be64(bno);
 
        return sizeof(struct xfs_attr3_rmt_hdr);
 }
 
 /*
- * Checking of the remote attribute header is split into two parts. the verifier
- * does CRC, location and bounds checking, the unpacking function checks the
- * attribute parameters and owner.
+ * Helper functions to copy attribute data in and out of the one disk extents
  */
-static bool
-xfs_attr3_rmt_hdr_ok(
-       struct xfs_mount        *mp,
-       xfs_ino_t               ino,
-       uint32_t                offset,
-       uint32_t                size,
-       struct xfs_buf          *bp)
+STATIC int
+xfs_attr_rmtval_copyout(
+       struct xfs_mount *mp,
+       struct xfs_buf  *bp,
+       xfs_ino_t       ino,
+       int             *offset,
+       int             *valuelen,
+       char            **dst)
 {
-       struct xfs_attr3_rmt_hdr *rmt = bp->b_addr;
+       char            *src = bp->b_addr;
+       xfs_daddr_t     bno = bp->b_bn;
+       int             len = BBTOB(bp->b_length);
 
-       if (offset != be32_to_cpu(rmt->rm_offset))
-               return false;
-       if (size != be32_to_cpu(rmt->rm_bytes))
-               return false;
-       if (ino != be64_to_cpu(rmt->rm_owner))
-               return false;
+       ASSERT(len >= XFS_LBSIZE(mp));
 
-       /* ok */
-       return true;
+       while (len > 0 && *valuelen > 0) {
+               int hdr_size = 0;
+               int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp));
+
+               byte_cnt = min_t(int, *valuelen, byte_cnt);
+
+               if (xfs_sb_version_hascrc(&mp->m_sb)) {
+                       if (!xfs_attr3_rmt_hdr_ok(mp, src, ino, *offset,
+                                                 byte_cnt, bno)) {
+                               xfs_alert(mp,
+"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)",
+                                       bno, *offset, byte_cnt, ino);
+                               return EFSCORRUPTED;
+                       }
+                       hdr_size = sizeof(struct xfs_attr3_rmt_hdr);
+               }
+
+               memcpy(*dst, src + hdr_size, byte_cnt);
+
+               /* roll buffer forwards */
+               len -= XFS_LBSIZE(mp);
+               src += XFS_LBSIZE(mp);
+               bno += mp->m_bsize;
+
+               /* roll attribute data forwards */
+               *valuelen -= byte_cnt;
+               *dst += byte_cnt;
+               *offset += byte_cnt;
+       }
+       return 0;
+}
+
+STATIC void
+xfs_attr_rmtval_copyin(
+       struct xfs_mount *mp,
+       struct xfs_buf  *bp,
+       xfs_ino_t       ino,
+       int             *offset,
+       int             *valuelen,
+       char            **src)
+{
+       char            *dst = bp->b_addr;
+       xfs_daddr_t     bno = bp->b_bn;
+       int             len = BBTOB(bp->b_length);
+
+       ASSERT(len >= XFS_LBSIZE(mp));
+
+       while (len > 0 && *valuelen > 0) {
+               int hdr_size;
+               int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp));
+
+               byte_cnt = min(*valuelen, byte_cnt);
+               hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset,
+                                                byte_cnt, bno);
+
+               memcpy(dst + hdr_size, *src, byte_cnt);
+
+               /*
+                * If this is the last block, zero the remainder of it.
+                * Check that we are actually the last block, too.
+                */
+               if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) {
+                       ASSERT(*valuelen - byte_cnt == 0);
+                       ASSERT(len == XFS_LBSIZE(mp));
+                       memset(dst + hdr_size + byte_cnt, 0,
+                                       XFS_LBSIZE(mp) - hdr_size - byte_cnt);
+               }
+
+               /* roll buffer forwards */
+               len -= XFS_LBSIZE(mp);
+               dst += XFS_LBSIZE(mp);
+               bno += mp->m_bsize;
+
+               /* roll attribute data forwards */
+               *valuelen -= byte_cnt;
+               *src += byte_cnt;
+               *offset += byte_cnt;
+       }
 }
 
 /*
@@ -190,13 +336,12 @@ xfs_attr_rmtval_get(
        struct xfs_bmbt_irec    map[ATTR_RMTVALUE_MAPSIZE];
        struct xfs_mount        *mp = args->dp->i_mount;
        struct xfs_buf          *bp;
-       xfs_daddr_t             dblkno;
        xfs_dablk_t             lblkno = args->rmtblkno;
-       void                    *dst = args->value;
+       char                    *dst = args->value;
        int                     valuelen = args->valuelen;
        int                     nmap;
        int                     error;
-       int                     blkcnt;
+       int                     blkcnt = args->rmtblkcnt;
        int                     i;
        int                     offset = 0;
 
@@ -207,52 +352,36 @@ xfs_attr_rmtval_get(
        while (valuelen > 0) {
                nmap = ATTR_RMTVALUE_MAPSIZE;
                error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno,
-                                      args->rmtblkcnt, map, &nmap,
+                                      blkcnt, map, &nmap,
                                       XFS_BMAPI_ATTRFORK);
                if (error)
                        return error;
                ASSERT(nmap >= 1);
 
                for (i = 0; (i < nmap) && (valuelen > 0); i++) {
-                       int     byte_cnt;
-                       char    *src;
+                       xfs_daddr_t     dblkno;
+                       int             dblkcnt;
 
                        ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) &&
                               (map[i].br_startblock != HOLESTARTBLOCK));
                        dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
-                       blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
+                       dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
                        error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
-                                                  dblkno, blkcnt, 0, &bp,
+                                                  dblkno, dblkcnt, 0, &bp,
                                                   &xfs_attr3_rmt_buf_ops);
                        if (error)
                                return error;
 
-                       byte_cnt = min_t(int, valuelen, BBTOB(bp->b_length));
-                       byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt);
-
-                       src = bp->b_addr;
-                       if (xfs_sb_version_hascrc(&mp->m_sb)) {
-                               if (!xfs_attr3_rmt_hdr_ok(mp, args->dp->i_ino,
-                                                       offset, byte_cnt, bp)) {
-                                       xfs_alert(mp,
-"remote attribute header does not match required off/len/owner (0x%x/Ox%x,0x%llx)",
-                                               offset, byte_cnt, args->dp->i_ino);
-                                       xfs_buf_relse(bp);
-                                       return EFSCORRUPTED;
-
-                               }
-
-                               src += sizeof(struct xfs_attr3_rmt_hdr);
-                       }
-
-                       memcpy(dst, src, byte_cnt);
+                       error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino,
+                                                       &offset, &valuelen,
+                                                       &dst);
                        xfs_buf_relse(bp);
+                       if (error)
+                               return error;
 
-                       offset += byte_cnt;
-                       dst += byte_cnt;
-                       valuelen -= byte_cnt;
-
+                       /* roll attribute extent map forwards */
                        lblkno += map[i].br_blockcount;
+                       blkcnt -= map[i].br_blockcount;
                }
        }
        ASSERT(valuelen == 0);
@@ -270,17 +399,13 @@ xfs_attr_rmtval_set(
        struct xfs_inode        *dp = args->dp;
        struct xfs_mount        *mp = dp->i_mount;
        struct xfs_bmbt_irec    map;
-       struct xfs_buf          *bp;
-       xfs_daddr_t             dblkno;
        xfs_dablk_t             lblkno;
        xfs_fileoff_t           lfileoff = 0;
-       void                    *src = args->value;
+       char                    *src = args->value;
        int                     blkcnt;
        int                     valuelen;
        int                     nmap;
        int                     error;
-       int                     hdrcnt = 0;
-       bool                    crcs = xfs_sb_version_hascrc(&mp->m_sb);
        int                     offset = 0;
 
        trace_xfs_attr_rmtval_set(args);
@@ -289,24 +414,14 @@ xfs_attr_rmtval_set(
         * Find a "hole" in the attribute address space large enough for
         * us to drop the new attribute's value into. Because CRC enable
         * attributes have headers, we can't just do a straight byte to FSB
-        * conversion. We calculate the worst case block count in this case
-        * and we may not need that many, so we have to handle this when
-        * allocating the blocks below. 
+        * conversion and have to take the header space into account.
         */
-       if (!crcs)
-               blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
-       else
-               blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
-
+       blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
        error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
                                                   XFS_ATTR_FORK);
        if (error)
                return error;
 
-       /* Start with the attribute data. We'll allocate the rest afterwards. */
-       if (crcs)
-               blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
-
        args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;
        args->rmtblkcnt = blkcnt;
 
@@ -349,26 +464,6 @@ xfs_attr_rmtval_set(
                       (map.br_startblock != HOLESTARTBLOCK));
                lblkno += map.br_blockcount;
                blkcnt -= map.br_blockcount;
-               hdrcnt++;
-
-               /*
-                * If we have enough blocks for the attribute data, calculate
-                * how many extra blocks we need for headers. We might run
-                * through this multiple times in the case that the additional
-                * headers in the blocks needed for the data fragments spills
-                * into requiring more blocks. e.g. for 512 byte blocks, we'll
-                * spill for another block every 9 headers we require in this
-                * loop.
-                */
-               if (crcs && blkcnt == 0) {
-                       int total_len;
-
-                       total_len = args->valuelen +
-                                   hdrcnt * sizeof(struct xfs_attr3_rmt_hdr);
-                       blkcnt = XFS_B_TO_FSB(mp, total_len);
-                       blkcnt -= args->rmtblkcnt;
-                       args->rmtblkcnt += blkcnt;
-               }
 
                /*
                 * Start the next trans in the chain.
@@ -385,18 +480,19 @@ xfs_attr_rmtval_set(
         * the INCOMPLETE flag.
         */
        lblkno = args->rmtblkno;
+       blkcnt = args->rmtblkcnt;
        valuelen = args->valuelen;
        while (valuelen > 0) {
-               int     byte_cnt;
-               char    *buf;
+               struct xfs_buf  *bp;
+               xfs_daddr_t     dblkno;
+               int             dblkcnt;
+
+               ASSERT(blkcnt > 0);
 
-               /*
-                * Try to remember where we decided to put the value.
-                */
                xfs_bmap_init(args->flist, args->firstblock);
                nmap = 1;
                error = xfs_bmapi_read(dp, (xfs_fileoff_t)lblkno,
-                                      args->rmtblkcnt, &map, &nmap,
+                                      blkcnt, &map, &nmap,
                                       XFS_BMAPI_ATTRFORK);
                if (error)
                        return(error);
@@ -405,41 +501,27 @@ xfs_attr_rmtval_set(
                       (map.br_startblock != HOLESTARTBLOCK));
 
                dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
-               blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
+               dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
 
-               bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 0);
+               bp = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt, 0);
                if (!bp)
                        return ENOMEM;
                bp->b_ops = &xfs_attr3_rmt_buf_ops;
 
-               byte_cnt = BBTOB(bp->b_length);
-               byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, byte_cnt);
-               if (valuelen < byte_cnt)
-                       byte_cnt = valuelen;
-
-               buf = bp->b_addr;
-               buf += xfs_attr3_rmt_hdr_set(mp, dp->i_ino, offset,
-                                            byte_cnt, bp);
-               memcpy(buf, src, byte_cnt);
-
-               if (byte_cnt < BBTOB(bp->b_length))
-                       xfs_buf_zero(bp, byte_cnt,
-                                    BBTOB(bp->b_length) - byte_cnt);
+               xfs_attr_rmtval_copyin(mp, bp, args->dp->i_ino, &offset,
+                                      &valuelen, &src);
 
                error = xfs_bwrite(bp); /* GROT: NOTE: synchronous write */
                xfs_buf_relse(bp);
                if (error)
                        return error;
 
-               src += byte_cnt;
-               valuelen -= byte_cnt;
-               offset += byte_cnt;
-               hdrcnt--;
 
+               /* roll attribute extent map forwards */
                lblkno += map.br_blockcount;
+               blkcnt -= map.br_blockcount;
        }
        ASSERT(valuelen == 0);
-       ASSERT(hdrcnt == 0);
        return 0;
 }
 
@@ -448,33 +530,40 @@ xfs_attr_rmtval_set(
  * out-of-line buffer that it is stored on.
  */
 int
-xfs_attr_rmtval_remove(xfs_da_args_t *args)
+xfs_attr_rmtval_remove(
+       struct xfs_da_args      *args)
 {
-       xfs_mount_t *mp;
-       xfs_bmbt_irec_t map;
-       xfs_buf_t *bp;
-       xfs_daddr_t dblkno;
-       xfs_dablk_t lblkno;
-       int valuelen, blkcnt, nmap, error, done, committed;
+       struct xfs_mount        *mp = args->dp->i_mount;
+       xfs_dablk_t             lblkno;
+       int                     blkcnt;
+       int                     error;
+       int                     done;
 
        trace_xfs_attr_rmtval_remove(args);
 
-       mp = args->dp->i_mount;
-
        /*
-        * Roll through the "value", invalidating the attribute value's
-        * blocks.
+        * Roll through the "value", invalidating the attribute value's blocks.
+        * Note that args->rmtblkcnt is the minimum number of data blocks we'll
+        * see for a CRC enabled remote attribute. Each extent will have a
+        * header, and so we may have more blocks than we realise here.  If we
+        * fail to map the blocks correctly, we'll have problems with the buffer
+        * lookups.
         */
        lblkno = args->rmtblkno;
-       valuelen = args->rmtblkcnt;
-       while (valuelen > 0) {
+       blkcnt = args->rmtblkcnt;
+       while (blkcnt > 0) {
+               struct xfs_bmbt_irec    map;
+               struct xfs_buf          *bp;
+               xfs_daddr_t             dblkno;
+               int                     dblkcnt;
+               int                     nmap;
+
                /*
                 * Try to remember where we decided to put the value.
                 */
                nmap = 1;
                error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno,
-                                      args->rmtblkcnt, &map, &nmap,
-                                      XFS_BMAPI_ATTRFORK);
+                                      blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK);
                if (error)
                        return(error);
                ASSERT(nmap == 1);
@@ -482,21 +571,20 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
                       (map.br_startblock != HOLESTARTBLOCK));
 
                dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
-               blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
+               dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
 
                /*
                 * If the "remote" value is in the cache, remove it.
                 */
-               bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK);
+               bp = xfs_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK);
                if (bp) {
                        xfs_buf_stale(bp);
                        xfs_buf_relse(bp);
                        bp = NULL;
                }
 
-               valuelen -= map.br_blockcount;
-
                lblkno += map.br_blockcount;
+               blkcnt -= map.br_blockcount;
        }
 
        /*
@@ -506,6 +594,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
        blkcnt = args->rmtblkcnt;
        done = 0;
        while (!done) {
+               int committed;
+
                xfs_bmap_init(args->flist, args->firstblock);
                error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
                                    XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
index c7cca60..92a8fd7 100644 (file)
 
 #define XFS_ATTR3_RMT_MAGIC    0x5841524d      /* XARM */
 
+/*
+ * There is one of these headers per filesystem block in a remote attribute.
+ * This is done to ensure there is a 1:1 mapping between the attribute value
+ * length and the number of blocks needed to store the attribute. This makes the
+ * verification of a buffer a little more complex, but greatly simplifies the
+ * allocation, reading and writing of these attributes as we don't have to guess
+ * the number of blocks needed to store the attribute data.
+ */
 struct xfs_attr3_rmt_hdr {
        __be32  rm_magic;
        __be32  rm_offset;
@@ -39,6 +47,8 @@ struct xfs_attr3_rmt_hdr {
 
 extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops;
 
+int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
+
 int xfs_attr_rmtval_get(struct xfs_da_args *args);
 int xfs_attr_rmtval_set(struct xfs_da_args *args);
 int xfs_attr_rmtval_remove(struct xfs_da_args *args);
index 8804b8a..0903960 100644 (file)
@@ -2544,7 +2544,17 @@ xfs_btree_new_iroot(
        if (error)
                goto error0;
 
+       /*
+        * we can't just memcpy() the root in for CRC enabled btree blocks.
+        * In that case have to also ensure the blkno remains correct
+        */
        memcpy(cblock, block, xfs_btree_block_len(cur));
+       if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
+               if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+                       cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn);
+               else
+                       cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn);
+       }
 
        be16_add_cpu(&block->bb_level, 1);
        xfs_btree_set_numrecs(block, 1);
index 0d25542..1b2472a 100644 (file)
@@ -513,6 +513,7 @@ _xfs_buf_find(
                xfs_alert(btp->bt_mount,
                          "%s: Block out of range: block 0x%llx, EOFS 0x%llx ",
                          __func__, blkno, eofs);
+               WARN_ON(1);
                return NULL;
        }
 
index cf26347..4ec4317 100644 (file)
@@ -262,12 +262,7 @@ xfs_buf_item_format_segment(
                        vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
                        vecp->i_len = nbits * XFS_BLF_CHUNK;
                        vecp->i_type = XLOG_REG_TYPE_BCHUNK;
-/*
- * You would think we need to bump the nvecs here too, but we do not
- * this number is used by recovery, and it gets confused by the boundary
- * split here
- *                     nvecs++;
- */
+                       nvecs++;
                        vecp++;
                        first_bit = next_bit;
                        last_bit = next_bit;
index f852b08..c407e1c 100644 (file)
@@ -219,6 +219,14 @@ xfs_swap_extents(
        int             taforkblks = 0;
        __uint64_t      tmp;
 
+       /*
+        * We have no way of updating owner information in the BMBT blocks for
+        * each inode on CRC enabled filesystems, so to avoid corrupting the
+        * this metadata we simply don't allow extent swaps to occur.
+        */
+       if (xfs_sb_version_hascrc(&mp->m_sb))
+               return XFS_ERROR(EINVAL);
+
        tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
        if (!tempifp) {
                error = XFS_ERROR(ENOMEM);
index a3b1bd8..7826782 100644 (file)
@@ -266,6 +266,7 @@ struct xfs_dir3_blk_hdr {
 struct xfs_dir3_data_hdr {
        struct xfs_dir3_blk_hdr hdr;
        xfs_dir2_data_free_t    best_free[XFS_DIR2_DATA_FD_COUNT];
+       __be32                  pad;    /* 64 bit alignment */
 };
 
 #define XFS_DIR3_DATA_CRC_OFF  offsetof(struct xfs_dir3_data_hdr, hdr.crc)
@@ -477,7 +478,7 @@ struct xfs_dir3_leaf_hdr {
        struct xfs_da3_blkinfo  info;           /* header for da routines */
        __be16                  count;          /* count of entries */
        __be16                  stale;          /* count of stale entries */
-       __be32                  pad;
+       __be32                  pad;            /* 64 bit alignment */
 };
 
 struct xfs_dir3_icleaf_hdr {
@@ -715,6 +716,7 @@ struct xfs_dir3_free_hdr {
        __be32                  firstdb;        /* db of first entry */
        __be32                  nvalid;         /* count of valid entries */
        __be32                  nused;          /* count of used entries */
+       __be32                  pad;            /* 64 bit alignment */
 };
 
 struct xfs_dir3_free {
index 5246de4..2226a00 100644 (file)
@@ -263,18 +263,19 @@ xfs_dir3_free_get_buf(
         * Initialize the new block to be empty, and remember
         * its first slot as our empty slot.
         */
-       hdr.magic = XFS_DIR2_FREE_MAGIC;
-       hdr.firstdb = 0;
-       hdr.nused = 0;
-       hdr.nvalid = 0;
+       memset(bp->b_addr, 0, sizeof(struct xfs_dir3_free_hdr));
+       memset(&hdr, 0, sizeof(hdr));
+
        if (xfs_sb_version_hascrc(&mp->m_sb)) {
                struct xfs_dir3_free_hdr *hdr3 = bp->b_addr;
 
                hdr.magic = XFS_DIR3_FREE_MAGIC;
+
                hdr3->hdr.blkno = cpu_to_be64(bp->b_bn);
                hdr3->hdr.owner = cpu_to_be64(dp->i_ino);
                uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid);
-       }
+       } else
+               hdr.magic = XFS_DIR2_FREE_MAGIC;
        xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr);
        *bpp = bp;
        return 0;
@@ -1921,8 +1922,6 @@ xfs_dir2_node_addname_int(
                         */
                        freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
                                        xfs_dir3_free_max_bests(mp);
-                       free->hdr.nvalid = 0;
-                       free->hdr.nused = 0;
                } else {
                        free = fbp->b_addr;
                        bests = xfs_dir3_free_bests_p(mp, free);
index a41f8bf..044e97a 100644 (file)
@@ -249,8 +249,11 @@ xfs_qm_init_dquot_blk(
                d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
                d->dd_diskdq.d_id = cpu_to_be32(curid);
                d->dd_diskdq.d_flags = type;
-               if (xfs_sb_version_hascrc(&mp->m_sb))
+               if (xfs_sb_version_hascrc(&mp->m_sb)) {
                        uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
+                       xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
+                                        XFS_DQUOT_CRC_OFF);
+               }
        }
 
        xfs_trans_dquot_buf(tp, bp,
@@ -286,23 +289,6 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
        dqp->q_low_space[XFS_QLOWSP_5_PCNT] = space * 5;
 }
 
-STATIC void
-xfs_dquot_buf_calc_crc(
-       struct xfs_mount        *mp,
-       struct xfs_buf          *bp)
-{
-       struct xfs_dqblk        *d = (struct xfs_dqblk *)bp->b_addr;
-       int                     i;
-
-       if (!xfs_sb_version_hascrc(&mp->m_sb))
-               return;
-
-       for (i = 0; i < mp->m_quotainfo->qi_dqperchunk; i++, d++) {
-               xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
-                                offsetof(struct xfs_dqblk, dd_crc));
-       }
-}
-
 STATIC bool
 xfs_dquot_buf_verify_crc(
        struct xfs_mount        *mp,
@@ -328,12 +314,11 @@ xfs_dquot_buf_verify_crc(
 
        for (i = 0; i < ndquots; i++, d++) {
                if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
-                                offsetof(struct xfs_dqblk, dd_crc)))
+                                XFS_DQUOT_CRC_OFF))
                        return false;
                if (!uuid_equal(&d->dd_uuid, &mp->m_sb.sb_uuid))
                        return false;
        }
-
        return true;
 }
 
@@ -393,6 +378,11 @@ xfs_dquot_buf_read_verify(
        }
 }
 
+/*
+ * we don't calculate the CRC here as that is done when the dquot is flushed to
+ * the buffer after the update is done. This ensures that the dquot in the
+ * buffer always has an up-to-date CRC value.
+ */
 void
 xfs_dquot_buf_write_verify(
        struct xfs_buf  *bp)
@@ -404,7 +394,6 @@ xfs_dquot_buf_write_verify(
                xfs_buf_ioerror(bp, EFSCORRUPTED);
                return;
        }
-       xfs_dquot_buf_calc_crc(mp, bp);
 }
 
 const struct xfs_buf_ops xfs_dquot_buf_ops = {
@@ -1151,11 +1140,17 @@ xfs_qm_dqflush(
         * copy the lsn into the on-disk dquot now while we have the in memory
         * dquot here. This can't be done later in the write verifier as we
         * can't get access to the log item at that point in time.
+        *
+        * We also calculate the CRC here so that the on-disk dquot in the
+        * buffer always has a valid CRC. This ensures there is no possibility
+        * of a dquot without an up-to-date CRC getting to disk.
         */
        if (xfs_sb_version_hascrc(&mp->m_sb)) {
                struct xfs_dqblk *dqb = (struct xfs_dqblk *)ddqp;
 
                dqb->dd_lsn = cpu_to_be64(dqp->q_logitem.qli_item.li_lsn);
+               xfs_update_cksum((char *)dqb, sizeof(struct xfs_dqblk),
+                                XFS_DQUOT_CRC_OFF);
        }
 
        /*
index 6dda3f9..d046955 100644 (file)
@@ -236,6 +236,7 @@ typedef struct xfs_fsop_resblks {
 #define XFS_FSOP_GEOM_FLAGS_PROJID32   0x0800  /* 32-bit project IDs   */
 #define XFS_FSOP_GEOM_FLAGS_DIRV2CI    0x1000  /* ASCII only CI names  */
 #define XFS_FSOP_GEOM_FLAGS_LAZYSB     0x4000  /* lazy superblock counters */
+#define XFS_FSOP_GEOM_FLAGS_V5SB       0x8000  /* version 5 superblock */
 
 
 /*
index 87595b2..3c3644e 100644 (file)
@@ -99,7 +99,9 @@ xfs_fs_geometry(
                        (xfs_sb_version_hasattr2(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_ATTR2 : 0) |
                        (xfs_sb_version_hasprojid32bit(&mp->m_sb) ?
-                               XFS_FSOP_GEOM_FLAGS_PROJID32 : 0);
+                               XFS_FSOP_GEOM_FLAGS_PROJID32 : 0) |
+                       (xfs_sb_version_hascrc(&mp->m_sb) ?
+                               XFS_FSOP_GEOM_FLAGS_V5SB : 0);
                geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?
                                mp->m_sb.sb_logsectsize : BBSIZE;
                geo->rtsectsize = mp->m_sb.sb_blocksize;
index efbe1ac..7f7be5f 100644 (file)
@@ -1638,6 +1638,10 @@ xfs_iunlink(
                dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
                offset = ip->i_imap.im_boffset +
                        offsetof(xfs_dinode_t, di_next_unlinked);
+
+               /* need to recalc the inode CRC if appropriate */
+               xfs_dinode_calc_crc(mp, dip);
+
                xfs_trans_inode_buf(tp, ibp);
                xfs_trans_log_buf(tp, ibp, offset,
                                  (offset + sizeof(xfs_agino_t) - 1));
@@ -1723,6 +1727,10 @@ xfs_iunlink_remove(
                        dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
                        offset = ip->i_imap.im_boffset +
                                offsetof(xfs_dinode_t, di_next_unlinked);
+
+                       /* need to recalc the inode CRC if appropriate */
+                       xfs_dinode_calc_crc(mp, dip);
+
                        xfs_trans_inode_buf(tp, ibp);
                        xfs_trans_log_buf(tp, ibp, offset,
                                          (offset + sizeof(xfs_agino_t) - 1));
@@ -1796,6 +1804,10 @@ xfs_iunlink_remove(
                        dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
                        offset = ip->i_imap.im_boffset +
                                offsetof(xfs_dinode_t, di_next_unlinked);
+
+                       /* need to recalc the inode CRC if appropriate */
+                       xfs_dinode_calc_crc(mp, dip);
+
                        xfs_trans_inode_buf(tp, ibp);
                        xfs_trans_log_buf(tp, ibp, offset,
                                          (offset + sizeof(xfs_agino_t) - 1));
@@ -1809,6 +1821,10 @@ xfs_iunlink_remove(
                last_dip->di_next_unlinked = cpu_to_be32(next_agino);
                ASSERT(next_agino != 0);
                offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
+
+               /* need to recalc the inode CRC if appropriate */
+               xfs_dinode_calc_crc(mp, last_dip);
+
                xfs_trans_inode_buf(tp, last_ibp);
                xfs_trans_log_buf(tp, last_ibp, offset,
                                  (offset + sizeof(xfs_agino_t) - 1));
index d82efaa..ca9ecaa 100644 (file)
@@ -455,6 +455,28 @@ xfs_vn_getattr(
        return 0;
 }
 
+static void
+xfs_setattr_mode(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,
+       struct iattr            *iattr)
+{
+       struct inode    *inode = VFS_I(ip);
+       umode_t         mode = iattr->ia_mode;
+
+       ASSERT(tp);
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+       if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+               mode &= ~S_ISGID;
+
+       ip->i_d.di_mode &= S_IFMT;
+       ip->i_d.di_mode |= mode & ~S_IFMT;
+
+       inode->i_mode &= S_IFMT;
+       inode->i_mode |= mode & ~S_IFMT;
+}
+
 int
 xfs_setattr_nonsize(
        struct xfs_inode        *ip,
@@ -606,18 +628,8 @@ xfs_setattr_nonsize(
        /*
         * Change file access modes.
         */
-       if (mask & ATTR_MODE) {
-               umode_t mode = iattr->ia_mode;
-
-               if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
-                       mode &= ~S_ISGID;
-
-               ip->i_d.di_mode &= S_IFMT;
-               ip->i_d.di_mode |= mode & ~S_IFMT;
-
-               inode->i_mode &= S_IFMT;
-               inode->i_mode |= mode & ~S_IFMT;
-       }
+       if (mask & ATTR_MODE)
+               xfs_setattr_mode(tp, ip, iattr);
 
        /*
         * Change file access or modified times.
@@ -714,9 +726,8 @@ xfs_setattr_size(
                return XFS_ERROR(error);
 
        ASSERT(S_ISREG(ip->i_d.di_mode));
-       ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
-                       ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID|
-                       ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
+       ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
+                       ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
 
        if (!(flags & XFS_ATTR_NOLOCK)) {
                lock_flags |= XFS_IOLOCK_EXCL;
@@ -860,6 +871,12 @@ xfs_setattr_size(
                xfs_inode_clear_eofblocks_tag(ip);
        }
 
+       /*
+        * Change file access modes.
+        */
+       if (mask & ATTR_MODE)
+               xfs_setattr_mode(tp, ip, iattr);
+
        if (mask & ATTR_CTIME) {
                inode->i_ctime = iattr->ia_ctime;
                ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
index 93f03ec..7cf5e4e 100644 (file)
@@ -1599,10 +1599,43 @@ xlog_recover_add_to_trans(
 }
 
 /*
- * Sort the log items in the transaction. Cancelled buffers need
- * to be put first so they are processed before any items that might
- * modify the buffers. If they are cancelled, then the modifications
- * don't need to be replayed.
+ * Sort the log items in the transaction.
+ *
+ * The ordering constraints are defined by the inode allocation and unlink
+ * behaviour. The rules are:
+ *
+ *     1. Every item is only logged once in a given transaction. Hence it
+ *        represents the last logged state of the item. Hence ordering is
+ *        dependent on the order in which operations need to be performed so
+ *        required initial conditions are always met.
+ *
+ *     2. Cancelled buffers are recorded in pass 1 in a separate table and
+ *        there's nothing to replay from them so we can simply cull them
+ *        from the transaction. However, we can't do that until after we've
+ *        replayed all the other items because they may be dependent on the
+ *        cancelled buffer and replaying the cancelled buffer can remove it
+ *        form the cancelled buffer table. Hence they have tobe done last.
+ *
+ *     3. Inode allocation buffers must be replayed before inode items that
+ *        read the buffer and replay changes into it.
+ *
+ *     4. Inode unlink buffers must be replayed after inode items are replayed.
+ *        This ensures that inodes are completely flushed to the inode buffer
+ *        in a "free" state before we remove the unlinked inode list pointer.
+ *
+ * Hence the ordering needs to be inode allocation buffers first, inode items
+ * second, inode unlink buffers third and cancelled buffers last.
+ *
+ * But there's a problem with that - we can't tell an inode allocation buffer
+ * apart from a regular buffer, so we can't separate them. We can, however,
+ * tell an inode unlink buffer from the others, and so we can separate them out
+ * from all the other buffers and move them to last.
+ *
+ * Hence, 4 lists, in order from head to tail:
+ *     - buffer_list for all buffers except cancelled/inode unlink buffers
+ *     - item_list for all non-buffer items
+ *     - inode_buffer_list for inode unlink buffers
+ *     - cancel_list for the cancelled buffers
  */
 STATIC int
 xlog_recover_reorder_trans(
@@ -1612,6 +1645,10 @@ xlog_recover_reorder_trans(
 {
        xlog_recover_item_t     *item, *n;
        LIST_HEAD(sort_list);
+       LIST_HEAD(cancel_list);
+       LIST_HEAD(buffer_list);
+       LIST_HEAD(inode_buffer_list);
+       LIST_HEAD(inode_list);
 
        list_splice_init(&trans->r_itemq, &sort_list);
        list_for_each_entry_safe(item, n, &sort_list, ri_list) {
@@ -1619,12 +1656,18 @@ xlog_recover_reorder_trans(
 
                switch (ITEM_TYPE(item)) {
                case XFS_LI_BUF:
-                       if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) {
+                       if (buf_f->blf_flags & XFS_BLF_CANCEL) {
                                trace_xfs_log_recover_item_reorder_head(log,
                                                        trans, item, pass);
-                               list_move(&item->ri_list, &trans->r_itemq);
+                               list_move(&item->ri_list, &cancel_list);
+                               break;
+                       }
+                       if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
+                               list_move(&item->ri_list, &inode_buffer_list);
                                break;
                        }
+                       list_move_tail(&item->ri_list, &buffer_list);
+                       break;
                case XFS_LI_INODE:
                case XFS_LI_DQUOT:
                case XFS_LI_QUOTAOFF:
@@ -1632,7 +1675,7 @@ xlog_recover_reorder_trans(
                case XFS_LI_EFI:
                        trace_xfs_log_recover_item_reorder_tail(log,
                                                        trans, item, pass);
-                       list_move_tail(&item->ri_list, &trans->r_itemq);
+                       list_move_tail(&item->ri_list, &inode_list);
                        break;
                default:
                        xfs_warn(log->l_mp,
@@ -1643,6 +1686,14 @@ xlog_recover_reorder_trans(
                }
        }
        ASSERT(list_empty(&sort_list));
+       if (!list_empty(&buffer_list))
+               list_splice(&buffer_list, &trans->r_itemq);
+       if (!list_empty(&inode_list))
+               list_splice_tail(&inode_list, &trans->r_itemq);
+       if (!list_empty(&inode_buffer_list))
+               list_splice_tail(&inode_buffer_list, &trans->r_itemq);
+       if (!list_empty(&cancel_list))
+               list_splice_tail(&cancel_list, &trans->r_itemq);
        return 0;
 }
 
@@ -1794,7 +1845,13 @@ xlog_recover_do_inode_buffer(
        xfs_agino_t             *buffer_nextp;
 
        trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
-       bp->b_ops = &xfs_inode_buf_ops;
+
+       /*
+        * Post recovery validation only works properly on CRC enabled
+        * filesystems.
+        */
+       if (xfs_sb_version_hascrc(&mp->m_sb))
+               bp->b_ops = &xfs_inode_buf_ops;
 
        inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
        for (i = 0; i < inodes_per_buf; i++) {
@@ -1861,6 +1918,15 @@ xlog_recover_do_inode_buffer(
                buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
                                              next_unlinked_offset);
                *buffer_nextp = *logged_nextp;
+
+               /*
+                * If necessary, recalculate the CRC in the on-disk inode. We
+                * have to leave the inode in a consistent state for whoever
+                * reads it next....
+                */
+               xfs_dinode_calc_crc(mp, (struct xfs_dinode *)
+                               xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
+
        }
 
        return 0;
@@ -2097,6 +2163,17 @@ xlog_recover_do_reg_buffer(
                       ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
 
                /*
+                * The dirty regions logged in the buffer, even though
+                * contiguous, may span multiple chunks. This is because the
+                * dirty region may span a physical page boundary in a buffer
+                * and hence be split into two separate vectors for writing into
+                * the log. Hence we need to trim nbits back to the length of
+                * the current region being copied out of the log.
+                */
+               if (item->ri_buf[i].i_len < (nbits << XFS_BLF_SHIFT))
+                       nbits = item->ri_buf[i].i_len >> XFS_BLF_SHIFT;
+
+               /*
                 * Do a sanity check if this is a dquot buffer. Just checking
                 * the first dquot in the buffer should do. XXXThis is
                 * probably a good thing to do for other buf types also.
@@ -2134,7 +2211,16 @@ xlog_recover_do_reg_buffer(
        /* Shouldn't be any more regions */
        ASSERT(i == item->ri_total);
 
-       xlog_recovery_validate_buf_type(mp, bp, buf_f);
+       /*
+        * We can only do post recovery validation on items on CRC enabled
+        * fielsystems as we need to know when the buffer was written to be able
+        * to determine if we should have replayed the item. If we replay old
+        * metadata over a newer buffer, then it will enter a temporarily
+        * inconsistent state resulting in verification failures. Hence for now
+        * just avoid the verification stage for non-crc filesystems
+        */
+       if (xfs_sb_version_hascrc(&mp->m_sb))
+               xlog_recovery_validate_buf_type(mp, bp, buf_f);
 }
 
 /*
@@ -2255,6 +2341,12 @@ xfs_qm_dqcheck(
        d->dd_diskdq.d_flags = type;
        d->dd_diskdq.d_id = cpu_to_be32(id);
 
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid);
+               xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk),
+                                XFS_DQUOT_CRC_OFF);
+       }
+
        return errs;
 }
 
@@ -2782,6 +2874,10 @@ xlog_recover_dquot_pass2(
        }
 
        memcpy(ddq, recddq, item->ri_buf[1].i_len);
+       if (xfs_sb_version_hascrc(&mp->m_sb)) {
+               xfs_update_cksum((char *)ddq, sizeof(struct xfs_dqblk),
+                                XFS_DQUOT_CRC_OFF);
+       }
 
        ASSERT(dq_f->qlf_size == 2);
        ASSERT(bp->b_target->bt_mount == mp);
index f6bfbd7..e8e310c 100644 (file)
@@ -314,7 +314,8 @@ STATIC int
 xfs_mount_validate_sb(
        xfs_mount_t     *mp,
        xfs_sb_t        *sbp,
-       bool            check_inprogress)
+       bool            check_inprogress,
+       bool            check_version)
 {
 
        /*
@@ -337,9 +338,10 @@ xfs_mount_validate_sb(
 
        /*
         * Version 5 superblock feature mask validation. Reject combinations the
-        * kernel cannot support up front before checking anything else.
+        * kernel cannot support up front before checking anything else. For
+        * write validation, we don't need to check feature masks.
         */
-       if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
+       if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
                xfs_alert(mp,
 "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n"
 "Use of these features in this kernel is at your own risk!");
@@ -675,7 +677,8 @@ xfs_sb_to_disk(
 
 static int
 xfs_sb_verify(
-       struct xfs_buf  *bp)
+       struct xfs_buf  *bp,
+       bool            check_version)
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
        struct xfs_sb   sb;
@@ -686,7 +689,8 @@ xfs_sb_verify(
         * Only check the in progress field for the primary superblock as
         * mkfs.xfs doesn't clear it from secondary superblocks.
         */
-       return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR);
+       return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
+                                    check_version);
 }
 
 /*
@@ -719,7 +723,7 @@ xfs_sb_read_verify(
                        goto out_error;
                }
        }
-       error = xfs_sb_verify(bp);
+       error = xfs_sb_verify(bp, true);
 
 out_error:
        if (error) {
@@ -758,7 +762,7 @@ xfs_sb_write_verify(
        struct xfs_buf_log_item *bip = bp->b_fspriv;
        int                     error;
 
-       error = xfs_sb_verify(bp);
+       error = xfs_sb_verify(bp, false);
        if (error) {
                XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
                xfs_buf_ioerror(bp, error);
index f41702b..b75c9bb 100644 (file)
@@ -41,6 +41,7 @@
 #include "xfs_qm.h"
 #include "xfs_trace.h"
 #include "xfs_icache.h"
+#include "xfs_cksum.h"
 
 /*
  * The global quota manager. There is only one of these for the entire
@@ -839,7 +840,7 @@ xfs_qm_reset_dqcounts(
        xfs_dqid_t      id,
        uint            type)
 {
-       xfs_disk_dquot_t        *ddq;
+       struct xfs_dqblk        *dqb;
        int                     j;
 
        trace_xfs_reset_dqcounts(bp, _RET_IP_);
@@ -853,8 +854,12 @@ xfs_qm_reset_dqcounts(
        do_div(j, sizeof(xfs_dqblk_t));
        ASSERT(mp->m_quotainfo->qi_dqperchunk == j);
 #endif
-       ddq = bp->b_addr;
+       dqb = bp->b_addr;
        for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) {
+               struct xfs_disk_dquot   *ddq;
+
+               ddq = (struct xfs_disk_dquot *)&dqb[j];
+
                /*
                 * Do a sanity check, and if needed, repair the dqblk. Don't
                 * output any warnings because it's perfectly possible to
@@ -871,7 +876,12 @@ xfs_qm_reset_dqcounts(
                ddq->d_bwarns = 0;
                ddq->d_iwarns = 0;
                ddq->d_rtbwarns = 0;
-               ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
+
+               if (xfs_sb_version_hascrc(&mp->m_sb)) {
+                       xfs_update_cksum((char *)&dqb[j],
+                                        sizeof(struct xfs_dqblk),
+                                        XFS_DQUOT_CRC_OFF);
+               }
        }
 }
 
@@ -907,19 +917,29 @@ xfs_qm_dqiter_bufs(
                              XFS_FSB_TO_DADDR(mp, bno),
                              mp->m_quotainfo->qi_dqchunklen, 0, &bp,
                              &xfs_dquot_buf_ops);
-               if (error)
-                       break;
 
                /*
-                * XXX(hch): need to figure out if it makes sense to validate
-                *           the CRC here.
+                * CRC and validation errors will return a EFSCORRUPTED here. If
+                * this occurs, re-read without CRC validation so that we can
+                * repair the damage via xfs_qm_reset_dqcounts(). This process
+                * will leave a trace in the log indicating corruption has
+                * been detected.
                 */
+               if (error == EFSCORRUPTED) {
+                       error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
+                                     XFS_FSB_TO_DADDR(mp, bno),
+                                     mp->m_quotainfo->qi_dqchunklen, 0, &bp,
+                                     NULL);
+               }
+
+               if (error)
+                       break;
+
                xfs_qm_reset_dqcounts(mp, bp, firstid, type);
                xfs_buf_delwri_queue(bp, buffer_list);
                xfs_buf_relse(bp);
-               /*
-                * goto the next block.
-                */
+
+               /* goto the next block. */
                bno++;
                firstid += mp->m_quotainfo->qi_dqperchunk;
        }
index c41190c..6cdf6ff 100644 (file)
@@ -489,31 +489,36 @@ xfs_qm_scall_setqlim(
        if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0)
                return 0;
 
-       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
-       error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp),
-                                 0, 0, XFS_DEFAULT_LOG_COUNT);
-       if (error) {
-               xfs_trans_cancel(tp, 0);
-               return (error);
-       }
-
        /*
         * We don't want to race with a quotaoff so take the quotaoff lock.
-        * (We don't hold an inode lock, so there's nothing else to stop
-        * a quotaoff from happening). (XXXThis doesn't currently happen
-        * because we take the vfslock before calling xfs_qm_sysent).
+        * We don't hold an inode lock, so there's nothing else to stop
+        * a quotaoff from happening.
         */
        mutex_lock(&q->qi_quotaofflock);
 
        /*
-        * Get the dquot (locked), and join it to the transaction.
-        * Allocate the dquot if this doesn't exist.
+        * Get the dquot (locked) before we start, as we need to do a
+        * transaction to allocate it if it doesn't exist. Once we have the
+        * dquot, unlock it so we can start the next transaction safely. We hold
+        * a reference to the dquot, so it's safe to do this unlock/lock without
+        * it being reclaimed in the mean time.
         */
-       if ((error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp))) {
-               xfs_trans_cancel(tp, XFS_TRANS_ABORT);
+       error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp);
+       if (error) {
                ASSERT(error != ENOENT);
                goto out_unlock;
        }
+       xfs_dqunlock(dqp);
+
+       tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
+       error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp),
+                                 0, 0, XFS_DEFAULT_LOG_COUNT);
+       if (error) {
+               xfs_trans_cancel(tp, 0);
+               goto out_rele;
+       }
+
+       xfs_dqlock(dqp);
        xfs_trans_dqjoin(tp, dqp);
        ddq = &dqp->q_core;
 
@@ -621,9 +626,10 @@ xfs_qm_scall_setqlim(
        xfs_trans_log_dquot(tp, dqp);
 
        error = xfs_trans_commit(tp, 0);
-       xfs_qm_dqrele(dqp);
 
- out_unlock:
+out_rele:
+       xfs_qm_dqrele(dqp);
+out_unlock:
        mutex_unlock(&q->qi_quotaofflock);
        return error;
 }
index c61e31c..c38068f 100644 (file)
@@ -87,6 +87,8 @@ typedef struct xfs_dqblk {
        uuid_t            dd_uuid;      /* location information */
 } xfs_dqblk_t;
 
+#define XFS_DQUOT_CRC_OFF      offsetof(struct xfs_dqblk, dd_crc)
+
 /*
  * flags for q_flags field in the dquot.
  */
index ea341ce..3033ba5 100644 (file)
@@ -1373,6 +1373,17 @@ xfs_finish_flags(
        }
 
        /*
+        * V5 filesystems always use attr2 format for attributes.
+        */
+       if (xfs_sb_version_hascrc(&mp->m_sb) &&
+           (mp->m_flags & XFS_MOUNT_NOATTR2)) {
+               xfs_warn(mp,
+"Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.",
+                       MNTOPT_NOATTR2, MNTOPT_ATTR2);
+               return XFS_ERROR(EINVAL);
+       }
+
+       /*
         * mkfs'ed attr2 will turn on attr2 mount unless explicitly
         * told by noattr2 to turn it off
         */
index 5f23438..195a403 100644 (file)
@@ -56,16 +56,9 @@ xfs_symlink_blocks(
        struct xfs_mount *mp,
        int             pathlen)
 {
-       int             fsblocks = 0;
-       int             len = pathlen;
+       int buflen = XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
 
-       do {
-               fsblocks++;
-               len -= XFS_SYMLINK_BUF_SPACE(mp, mp->m_sb.sb_blocksize);
-       } while (len > 0);
-
-       ASSERT(fsblocks <= XFS_SYMLINK_MAPS);
-       return fsblocks;
+       return (pathlen + buflen - 1) / buflen;
 }
 
 static int
@@ -405,7 +398,7 @@ xfs_symlink(
        if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version))
                fs_blocks = 0;
        else
-               fs_blocks = XFS_B_TO_FSB(mp, pathlen);
+               fs_blocks = xfs_symlink_blocks(mp, pathlen);
        resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
        error = xfs_trans_reserve(tp, resblks, XFS_SYMLINK_LOG_RES(mp), 0,
                        XFS_TRANS_PERM_LOG_RES, XFS_SYMLINK_LOG_COUNT);
@@ -512,7 +505,7 @@ xfs_symlink(
                cur_chunk = target_path;
                offset = 0;
                for (n = 0; n < nmaps; n++) {
-                       char *buf;
+                       char    *buf;
 
                        d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
                        byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
@@ -525,9 +518,7 @@ xfs_symlink(
                        bp->b_ops = &xfs_symlink_buf_ops;
 
                        byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
-                       if (pathlen < byte_cnt) {
-                               byte_cnt = pathlen;
-                       }
+                       byte_cnt = min(byte_cnt, pathlen);
 
                        buf = bp->b_addr;
                        buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset,
@@ -542,6 +533,7 @@ xfs_symlink(
                        xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) -
                                                        (char *)bp->b_addr);
                }
+               ASSERT(pathlen == 0);
        }
 
        /*
index ac9da00..d5afe96 100644 (file)
@@ -343,8 +343,12 @@ extern void ioport_unmap(void __iomem *p);
 #endif /* CONFIG_GENERIC_IOMAP */
 #endif /* CONFIG_HAS_IOPORT */
 
+#ifndef xlate_dev_kmem_ptr
 #define xlate_dev_kmem_ptr(p)  p
+#endif
+#ifndef xlate_dev_mem_ptr
 #define xlate_dev_mem_ptr(p)   __va(p)
+#endif
 
 #ifdef CONFIG_VIRT_TO_BUS
 #ifndef virt_to_bus
index 9d96605..fa25bec 100644 (file)
@@ -18,4 +18,9 @@ static inline unsigned int kvm_arch_para_features(void)
        return 0;
 }
 
+static inline bool kvm_para_available(void)
+{
+       return false;
+}
+
 #endif
index b1b1fa6..13821c3 100644 (file)
@@ -97,11 +97,9 @@ struct mmu_gather {
        unsigned long           start;
        unsigned long           end;
        unsigned int            need_flush : 1, /* Did free PTEs */
-                               fast_mode  : 1; /* No batching   */
-
        /* we are in the middle of an operation to clear
         * a full mm and can make some optimizations */
-       unsigned int            fullmm : 1,
+                               fullmm : 1,
        /* we have performed an operation which
         * requires a complete flush of the tlb */
                                need_flush_all : 1;
@@ -114,19 +112,6 @@ struct mmu_gather {
 
 #define HAVE_GENERIC_MMU_GATHER
 
-static inline int tlb_fast_mode(struct mmu_gather *tlb)
-{
-#ifdef CONFIG_SMP
-       return tlb->fast_mode;
-#else
-       /*
-        * For UP we don't need to worry about TLB flush
-        * and page free order so much..
-        */
-       return 1;
-#endif
-}
-
 void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
 void tlb_flush_mmu(struct mmu_gather *tlb);
 void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
index ec10e1b..737f90a 100644 (file)
@@ -49,10 +49,11 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 }
 #endif
 
-extern void cper_print_aer(const char *prefix, struct pci_dev *dev,
+extern void cper_print_aer(struct pci_dev *dev,
                           int cper_severity, struct aer_capability_regs *aer);
 extern int cper_severity_to_aer(int cper_severity);
 extern void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
-                             int severity);
+                             int severity,
+                             struct aer_capability_regs *aer_regs);
 #endif //_AER_H_
 
index 5047355..8bda129 100644 (file)
@@ -707,7 +707,7 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos);
  *
  * If a subsystem synchronizes against the parent in its ->css_online() and
  * before starting iterating, and synchronizes against @pos on each
- * iteration, any descendant cgroup which finished ->css_offline() is
+ * iteration, any descendant cgroup which finished ->css_online() is
  * guaranteed to be visible in the future iterations.
  *
  * In other words, the following guarantees that a descendant can't escape
index c6f6e08..9f3c7e8 100644 (file)
@@ -175,6 +175,8 @@ extern struct bus_type cpu_subsys;
 
 extern void get_online_cpus(void);
 extern void put_online_cpus(void);
+extern void cpu_hotplug_disable(void);
+extern void cpu_hotplug_enable(void);
 #define hotcpu_notifier(fn, pri)       cpu_notifier(fn, pri)
 #define register_hotcpu_notifier(nb)   register_cpu_notifier(nb)
 #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb)
@@ -198,6 +200,8 @@ static inline void cpu_hotplug_driver_unlock(void)
 
 #define get_online_cpus()      do { } while (0)
 #define put_online_cpus()      do { } while (0)
+#define cpu_hotplug_disable()  do { } while (0)
+#define cpu_hotplug_enable()   do { } while (0)
 #define hotcpu_notifier(fn, pri)       do { (void)(fn); } while (0)
 /* These aren't inline functions due to a GCC bug. */
 #define register_hotcpu_notifier(nb)   ({ (void)(nb); 0; })
index c050dcc..f65f5a6 100644 (file)
@@ -46,6 +46,7 @@ extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
 extern int sk_detach_filter(struct sock *sk);
 extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
 extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len);
+extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);
 
 #ifdef CONFIG_BPF_JIT
 #include <stdarg.h>
index 4474557..16fae64 100644 (file)
@@ -249,12 +249,12 @@ team_get_first_port_txable_rcu(struct team *team, struct team_port *port)
                return port;
        cur = port;
        list_for_each_entry_continue_rcu(cur, &team->port_list, list)
-               if (team_port_txable(port))
+               if (team_port_txable(cur))
                        return cur;
        list_for_each_entry_rcu(cur, &team->port_list, list) {
                if (cur == port)
                        break;
-               if (team_port_txable(port))
+               if (team_port_txable(cur))
                        return cur;
        }
        return NULL;
index 6a1f8df..b83e565 100644 (file)
@@ -362,6 +362,17 @@ static inline void list_splice_tail_init(struct list_head *list,
        list_entry((ptr)->next, type, member)
 
 /**
+ * list_first_entry_or_null - get the first element from a list
+ * @ptr:       the list head to take the element from.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Note that if the list is empty, it returns NULL.
+ */
+#define list_first_entry_or_null(ptr, type, member) \
+       (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
+
+/**
  * list_for_each       -       iterate over a list
  * @pos:       the &struct list_head to use as a loop cursor.
  * @head:      the head for your list.
index b8ba855..2913b86 100644 (file)
@@ -6,7 +6,8 @@
 
 #if BITS_PER_LONG == 64
 
-#define div64_long(x,y) div64_s64((x),(y))
+#define div64_long(x, y) div64_s64((x), (y))
+#define div64_ul(x, y)   div64_u64((x), (y))
 
 /**
  * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
@@ -47,7 +48,8 @@ static inline s64 div64_s64(s64 dividend, s64 divisor)
 
 #elif BITS_PER_LONG == 32
 
-#define div64_long(x,y) div_s64((x),(y))
+#define div64_long(x, y) div_s64((x), (y))
+#define div64_ul(x, y)   div_u64((x), (y))
 
 #ifndef div_u64_rem
 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
index cc28136..f797bb9 100644 (file)
@@ -95,6 +95,8 @@ struct arizona {
 
        struct arizona_pdata pdata;
 
+       unsigned int external_dcvdd:1;
+
        int irq;
        struct irq_domain *virq;
        struct regmap_irq_chip_data *aod_irq_chip;
index 80dead1..12a5c13 100644 (file)
@@ -77,7 +77,7 @@ struct arizona_micbias {
        int mV;                    /** Regulated voltage */
        unsigned int ext_cap:1;    /** External capacitor fitted */
        unsigned int discharge:1;  /** Actively discharge */
-       unsigned int fast_start:1; /** Enable aggressive startup ramp rate */
+       unsigned int soft_start:1; /** Disable aggressive startup ramp rate */
        unsigned int bypass:1;     /** Use bypass mode */
 };
 
index 715b6ba..4706d3d 100644 (file)
 #define ARIZONA_DAC_DIGITAL_VOLUME_6R            0x43D
 #define ARIZONA_DAC_VOLUME_LIMIT_6R              0x43E
 #define ARIZONA_NOISE_GATE_SELECT_6R             0x43F
+#define ARIZONA_DRE_ENABLE                       0x440
+#define ARIZONA_DRE_CONTROL_2                    0x442
+#define ARIZONA_DRE_CONTROL_3                    0x443
 #define ARIZONA_DAC_AEC_CONTROL_1                0x450
 #define ARIZONA_NOISE_GATE_CONTROL               0x458
 #define ARIZONA_PDM_SPK1_CTRL_1                  0x490
 #define ARIZONA_DSP2_CLOCKING_1                  0x1201
 #define ARIZONA_DSP2_STATUS_1                    0x1204
 #define ARIZONA_DSP2_STATUS_2                    0x1205
+#define ARIZONA_DSP2_STATUS_3                    0x1206
 #define ARIZONA_DSP2_SCRATCH_0                   0x1240
 #define ARIZONA_DSP2_SCRATCH_1                   0x1241
 #define ARIZONA_DSP2_SCRATCH_2                   0x1242
 #define ARIZONA_DSP3_CLOCKING_1                  0x1301
 #define ARIZONA_DSP3_STATUS_1                    0x1304
 #define ARIZONA_DSP3_STATUS_2                    0x1305
+#define ARIZONA_DSP3_STATUS_3                    0x1306
 #define ARIZONA_DSP3_SCRATCH_0                   0x1340
 #define ARIZONA_DSP3_SCRATCH_1                   0x1341
 #define ARIZONA_DSP3_SCRATCH_2                   0x1342
 #define ARIZONA_DSP4_CLOCKING_1                  0x1401
 #define ARIZONA_DSP4_STATUS_1                    0x1404
 #define ARIZONA_DSP4_STATUS_2                    0x1405
+#define ARIZONA_DSP4_STATUS_3                    0x1406
 #define ARIZONA_DSP4_SCRATCH_0                   0x1440
 #define ARIZONA_DSP4_SCRATCH_1                   0x1441
 #define ARIZONA_DSP4_SCRATCH_2                   0x1442
 #define ARIZONA_OUT6R_NGATE_SRC_WIDTH                12  /* OUT6R_NGATE_SRC - [11:0] */
 
 /*
+ * R1088 (0x440) - DRE Enable
+ */
+#define ARIZONA_DRE3L_ENA                        0x0010  /* DRE3L_ENA */
+#define ARIZONA_DRE3L_ENA_MASK                   0x0010  /* DRE3L_ENA */
+#define ARIZONA_DRE3L_ENA_SHIFT                       4  /* DRE3L_ENA */
+#define ARIZONA_DRE3L_ENA_WIDTH                       1  /* DRE3L_ENA */
+#define ARIZONA_DRE2R_ENA                        0x0008  /* DRE2R_ENA */
+#define ARIZONA_DRE2R_ENA_MASK                   0x0008  /* DRE2R_ENA */
+#define ARIZONA_DRE2R_ENA_SHIFT                       3  /* DRE2R_ENA */
+#define ARIZONA_DRE2R_ENA_WIDTH                       1  /* DRE2R_ENA */
+#define ARIZONA_DRE2L_ENA                        0x0004  /* DRE2L_ENA */
+#define ARIZONA_DRE2L_ENA_MASK                   0x0004  /* DRE2L_ENA */
+#define ARIZONA_DRE2L_ENA_SHIFT                       2  /* DRE2L_ENA */
+#define ARIZONA_DRE2L_ENA_WIDTH                       1  /* DRE2L_ENA */
+#define ARIZONA_DRE1R_ENA                        0x0002  /* DRE1R_ENA */
+#define ARIZONA_DRE1R_ENA_MASK                   0x0002  /* DRE1R_ENA */
+#define ARIZONA_DRE1R_ENA_SHIFT                       1  /* DRE1R_ENA */
+#define ARIZONA_DRE1R_ENA_WIDTH                       1  /* DRE1R_ENA */
+#define ARIZONA_DRE1L_ENA                        0x0001  /* DRE1L_ENA */
+#define ARIZONA_DRE1L_ENA_MASK                   0x0001  /* DRE1L_ENA */
+#define ARIZONA_DRE1L_ENA_SHIFT                       0  /* DRE1L_ENA */
+#define ARIZONA_DRE1L_ENA_WIDTH                       1  /* DRE1L_ENA */
+
+/*
+ * R1090 (0x442) - DRE Control 2
+ */
+#define ARIZONA_DRE_T_LOW_MASK                   0x3F00  /* DRE_T_LOW - [13:8] */
+#define ARIZONA_DRE_T_LOW_SHIFT                       8  /* DRE_T_LOW - [13:8] */
+#define ARIZONA_DRE_T_LOW_WIDTH                       6  /* DRE_T_LOW - [13:8] */
+
+/*
+ * R1091 (0x443) - DRE Control 3
+ */
+#define ARIZONA_DRE_GAIN_SHIFT_MASK              0xC000  /* DRE_GAIN_SHIFT - [15:14] */
+#define ARIZONA_DRE_GAIN_SHIFT_SHIFT                 14  /* DRE_GAIN_SHIFT - [15:14] */
+#define ARIZONA_DRE_GAIN_SHIFT_WIDTH                  2  /* DRE_GAIN_SHIFT - [15:14] */
+#define ARIZONA_DRE_LOW_LEVEL_ABS_MASK           0x000F  /* LOW_LEVEL_ABS - [3:0] */
+#define ARIZONA_DRE_LOW_LEVEL_ABS_SHIFT               0  /* LOW_LEVEL_ABS - [3:0] */
+#define ARIZONA_DRE_LOW_LEVEL_ABS_WIDTH               4  /* LOW_LEVEL_ABS - [3:0] */
+
+/*
  * R1104 (0x450) - DAC AEC Control 1
  */
 #define ARIZONA_AEC_LOOPBACK_SRC_MASK            0x003C  /* AEC_LOOPBACK_SRC - [5:2] */
index 98ffb54..2d4df6c 100644 (file)
@@ -17,6 +17,22 @@ extern __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
 
 extern int ipv6_netfilter_init(void);
 extern void ipv6_netfilter_fini(void);
+
+/*
+ * Hook functions for ipv6 to allow xt_* modules to be built-in even
+ * if IPv6 is a module.
+ */
+struct nf_ipv6_ops {
+       int (*chk_addr)(struct net *net, const struct in6_addr *addr,
+                       const struct net_device *dev, int strict);
+};
+
+extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops;
+static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void)
+{
+       return rcu_dereference(nf_ipv6_ops);
+}
+
 #else /* CONFIG_NETFILTER */
 static inline int ipv6_netfilter_init(void) { return 0; }
 static inline void ipv6_netfilter_fini(void) { return; }
diff --git a/include/linux/platform_data/ssm2518.h b/include/linux/platform_data/ssm2518.h
new file mode 100644 (file)
index 0000000..9a8e3ea
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * SSM2518 amplifier audio driver
+ *
+ * Copyright 2013 Analog Devices Inc.
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_SSM2518_H__
+#define __LINUX_PLATFORM_DATA_SSM2518_H__
+
+/**
+ * struct ssm2518_platform_data - Platform data for the ssm2518 driver
+ * @enable_gpio: GPIO connected to the nSD pin. Set to -1 if the nSD pin is
+ *            hardwired.
+ */
+struct ssm2518_platform_data {
+       int enable_gpio;
+};
+
+#endif
index 8089e35..f4b1001 100644 (file)
@@ -461,6 +461,26 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
                        &(pos)->member)), typeof(*(pos)), member))
 
 /**
+ * hlist_for_each_entry_rcu_notrace - iterate over rcu list of given type (for tracing)
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ *
+ * This list-traversal primitive may safely run concurrently with
+ * the _rcu list-mutation primitives such as hlist_add_head_rcu()
+ * as long as the traversal is guarded by rcu_read_lock().
+ *
+ * This is the same as hlist_for_each_entry_rcu() except that it does
+ * not do any RCU debugging or tracing.
+ */
+#define hlist_for_each_entry_rcu_notrace(pos, head, member)                    \
+       for (pos = hlist_entry_safe (rcu_dereference_raw_notrace(hlist_first_rcu(head)),\
+                       typeof(*(pos)), member);                        \
+               pos;                                                    \
+               pos = hlist_entry_safe(rcu_dereference_raw_notrace(hlist_next_rcu(\
+                       &(pos)->member)), typeof(*(pos)), member))
+
+/**
  * hlist_for_each_entry_rcu_bh - iterate over rcu list of given type
  * @pos:       the type * to use as a loop cursor.
  * @head:      the head for your list.
index 2ae1371..1c33dd7 100644 (file)
@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
  * @head:      the head for your list.
  * @member:    the name of the hlist_nulls_node within the struct.
  *
+ * The barrier() is needed to make sure compiler doesn't cache first element [1],
+ * as this loop can be restarted [2]
+ * [1] Documentation/atomic_ops.txt around line 114
+ * [2] Documentation/RCU/rculist_nulls.txt around line 146
  */
 #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member)                        \
-       for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head));            \
+       for (({barrier();}),                                                    \
+            pos = rcu_dereference_raw(hlist_nulls_first_rcu(head));            \
                (!is_a_nulls(pos)) &&                                           \
                ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
                pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)))
index 4ccd68e..ddcc782 100644 (file)
@@ -640,6 +640,15 @@ static inline void rcu_preempt_sleep_check(void)
 
 #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
 
+/*
+ * The tracing infrastructure traces RCU (we want that), but unfortunately
+ * some of the RCU checks causes tracing to lock up the system.
+ *
+ * The tracing version of rcu_dereference_raw() must not call
+ * rcu_read_lock_held().
+ */
+#define rcu_dereference_raw_notrace(p) __rcu_dereference_check((p), 1, __rcu)
+
 /**
  * rcu_access_index() - fetch RCU index with no dereferencing
  * @p: The index to read
index 5951e3f..2680677 100644 (file)
@@ -111,6 +111,9 @@ static inline struct page *sg_page(struct scatterlist *sg)
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
                              unsigned int buflen)
 {
+#ifdef CONFIG_DEBUG_SG
+       BUG_ON(!virt_addr_valid(buf));
+#endif
        sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
index 2e0ced1..9c676ea 100644 (file)
@@ -2852,6 +2852,21 @@ static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
                SKB_GSO_CB(inner_skb)->mac_offset;
 }
 
+static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra)
+{
+       int new_headroom, headroom;
+       int ret;
+
+       headroom = skb_headroom(skb);
+       ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC);
+       if (ret)
+               return ret;
+
+       new_headroom = skb_headroom(skb);
+       SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom);
+       return 0;
+}
+
 static inline bool skb_is_gso(const struct sk_buff *skb)
 {
        return skb_shinfo(skb)->gso_size;
index e6564c1..c848876 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/list.h>
 #include <linux/cpumask.h>
 #include <linux/init.h>
+#include <linux/irqflags.h>
 
 extern void cpu_idle(void);
 
@@ -139,13 +140,17 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info)
 }
 #define smp_call_function(func, info, wait) \
                        (up_smp_call_function(func, info))
-#define on_each_cpu(func,info,wait)            \
-       ({                                      \
-               local_irq_disable();            \
-               func(info);                     \
-               local_irq_enable();             \
-               0;                              \
-       })
+
+static inline int on_each_cpu(smp_call_func_t func, void *info, int wait)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       func(info);
+       local_irq_restore(flags);
+       return 0;
+}
+
 /*
  * Note we still need to test the mask even for UP
  * because we actually can get an empty mask from
index 33bf2df..b10ce4b 100644 (file)
@@ -320,6 +320,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 
 struct timespec;
 
+/* The __sys_...msg variants allow MSG_CMSG_COMPAT */
+extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
+extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
 extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                          unsigned int flags, struct timespec *timeout);
 extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
index 47ead51..c5fd30d 100644 (file)
@@ -137,6 +137,7 @@ static inline void make_migration_entry_read(swp_entry_t *entry)
 
 extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
                                        unsigned long address);
+extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte);
 #else
 
 #define make_migration_entry(page, write) swp_entry(0, 0)
@@ -148,6 +149,8 @@ static inline int is_migration_entry(swp_entry_t swp)
 static inline void make_migration_entry_read(swp_entry_t *entryp) { }
 static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
                                         unsigned long address) { }
+static inline void migration_entry_wait_huge(struct mm_struct *mm,
+                                       pte_t *pte) { }
 static inline int is_write_migration_entry(swp_entry_t entry)
 {
        return 0;
index 3891139..98a3153 100644 (file)
@@ -44,8 +44,8 @@
 /* Return size of the log buffer */
 #define SYSLOG_ACTION_SIZE_BUFFER   10
 
-#define SYSLOG_FROM_CALL 0
-#define SYSLOG_FROM_FILE 1
+#define SYSLOG_FROM_READER           0
+#define SYSLOG_FROM_PROC             1
 
 int do_syslog(int type, char __user *buf, int count, bool from_file);
 
index 2f322c3..f8e084d 100644 (file)
@@ -145,8 +145,8 @@ static inline void tracepoint_synchronize_unregister(void)
                                TP_PROTO(data_proto),                   \
                                TP_ARGS(data_args),                     \
                                TP_CONDITION(cond),                     \
-                               rcu_idle_exit(),                        \
-                               rcu_idle_enter());                      \
+                               rcu_irq_enter(),                        \
+                               rcu_irq_exit());                        \
        }
 #else
 #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)
index 84a6440..21f7027 100644 (file)
@@ -65,7 +65,7 @@ extern int                    addrconf_set_dstaddr(struct net *net,
 
 extern int                     ipv6_chk_addr(struct net *net,
                                              const struct in6_addr *addr,
-                                             struct net_device *dev,
+                                             const struct net_device *dev,
                                              int strict);
 
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
index 35a57cd..7cb6d36 100644 (file)
@@ -1117,6 +1117,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
 int mgmt_index_added(struct hci_dev *hdev);
 int mgmt_index_removed(struct hci_dev *hdev);
+int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
 int mgmt_powered(struct hci_dev *hdev, u8 powered);
 int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
 int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
index 22980a7..9944c3e 100644 (file)
@@ -42,6 +42,7 @@
 #define MGMT_STATUS_NOT_POWERED                0x0f
 #define MGMT_STATUS_CANCELLED          0x10
 #define MGMT_STATUS_INVALID_INDEX      0x11
+#define MGMT_STATUS_RFKILLED           0x12
 
 struct mgmt_hdr {
        __le16  opcode;
index 4b6f0b2..09b1360 100644 (file)
@@ -95,10 +95,10 @@ struct ip_tunnel_net {
 int ip_tunnel_init(struct net_device *dev);
 void ip_tunnel_uninit(struct net_device *dev);
 void  ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
-int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
-                                 struct rtnl_link_ops *ops, char *devname);
+int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
+                      struct rtnl_link_ops *ops, char *devname);
 
-void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn);
+void ip_tunnel_delete_net(struct ip_tunnel_net *itn);
 
 void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
                    const struct iphdr *tnl_params);
index f10818f..e7f4e21 100644 (file)
@@ -679,22 +679,26 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
 #endif
 
 struct psched_ratecfg {
-       u64 rate_bps;
-       u32 mult;
-       u32 shift;
+       u64     rate_bps;
+       u32     mult;
+       u16     overhead;
+       u8      shift;
 };
 
 static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
                                unsigned int len)
 {
-       return ((u64)len * r->mult) >> r->shift;
+       return ((u64)(len + r->overhead) * r->mult) >> r->shift;
 }
 
-extern void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate);
+extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct tc_ratespec *conf);
 
-static inline u32 psched_ratecfg_getrate(const struct psched_ratecfg *r)
+static inline void psched_ratecfg_getrate(struct tc_ratespec *res,
+                                         const struct psched_ratecfg *r)
 {
-       return r->rate_bps >> 3;
+       memset(res, 0, sizeof(*res));
+       res->rate = r->rate_bps >> 3;
+       res->overhead = r->overhead;
 }
 
 #endif
index ae16531..94ce082 100644 (file)
@@ -1160,6 +1160,8 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
        }
 }
 
+extern void xfrm_garbage_collect(struct net *net);
+
 #else
 
 static inline void xfrm_sk_free_policy(struct sock *sk) {}
@@ -1194,6 +1196,9 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
 {
        return 1;
 }
+static inline void xfrm_garbage_collect(struct net *net)
+{
+}
 #endif
 
 static __inline__
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
new file mode 100644 (file)
index 0000000..27cc75e
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * linux/sound/rt5640.h -- Platform data for RT5640
+ *
+ * Copyright 2011 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_RT5640_H
+#define __LINUX_SND_RT5640_H
+
+struct rt5640_platform_data {
+       /* IN1 & IN2 can optionally be differential */
+       bool in1_diff;
+       bool in2_diff;
+
+       int ldo1_en; /* GPIO for LDO1_EN */
+};
+
+#endif
index d460902..3e479f4 100644 (file)
@@ -311,6 +311,8 @@ struct device;
 #define SND_SOC_DAPM_POST_PMD  0x8             /* after widget power down */
 #define SND_SOC_DAPM_PRE_REG   0x10    /* before audio path setup */
 #define SND_SOC_DAPM_POST_REG  0x20    /* after audio path setup */
+#define SND_SOC_DAPM_WILL_PMU   0x40    /* called at start of sequence */
+#define SND_SOC_DAPM_WILL_PMD   0x80    /* called at start of sequence */
 #define SND_SOC_DAPM_PRE_POST_PMD \
                                (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
 
@@ -450,7 +452,8 @@ enum snd_soc_dapm_type {
        snd_soc_dapm_aif_in,            /* audio interface input */
        snd_soc_dapm_aif_out,           /* audio interface output */
        snd_soc_dapm_siggen,            /* signal generator */
-       snd_soc_dapm_dai,               /* link to DAI structure */
+       snd_soc_dapm_dai_in,            /* link to DAI structure */
+       snd_soc_dapm_dai_out,
        snd_soc_dapm_dai_link,          /* link between two DAI structures */
 };
 
@@ -478,7 +481,6 @@ struct snd_soc_dapm_route {
 /* dapm audio path between two widgets */
 struct snd_soc_dapm_path {
        const char *name;
-       const char *long_name;
 
        /* source (input) and sink (output) widgets */
        struct snd_soc_dapm_widget *source;
index e773dfa..4ea4f98 100644 (file)
@@ -543,6 +543,7 @@ struct se_session {
        struct list_head        sess_list;
        struct list_head        sess_acl_list;
        struct list_head        sess_cmd_list;
+       struct list_head        sess_wait_list;
        spinlock_t              sess_cmd_lock;
        struct kref             sess_kref;
 };
index ba3471b..1dcce9c 100644 (file)
@@ -114,7 +114,7 @@ sense_reason_t      transport_generic_new_cmd(struct se_cmd *);
 
 void   target_execute_cmd(struct se_cmd *cmd);
 
-void   transport_generic_free_cmd(struct se_cmd *, int);
+int    transport_generic_free_cmd(struct se_cmd *, int);
 
 bool   transport_wait_for_tasks(struct se_cmd *);
 int    transport_check_aborted_status(struct se_cmd *, int);
@@ -123,7 +123,7 @@ int transport_send_check_condition_and_sense(struct se_cmd *,
 int    target_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
 int    target_put_sess_cmd(struct se_session *, struct se_cmd *);
 void   target_sess_cmd_list_set_waiting(struct se_session *);
-void   target_wait_for_sess_cmds(struct se_session *, int);
+void   target_wait_for_sess_cmds(struct se_session *);
 
 int    core_alua_check_nonop_delay(struct se_cmd *);
 
index a5c86fc..d88c8ee 100644 (file)
@@ -783,6 +783,7 @@ struct kvm_dirty_tlb {
 #define KVM_REG_IA64           0x3000000000000000ULL
 #define KVM_REG_ARM            0x4000000000000000ULL
 #define KVM_REG_S390           0x5000000000000000ULL
+#define KVM_REG_MIPS           0x7000000000000000ULL
 
 #define KVM_REG_SIZE_SHIFT     52
 #define KVM_REG_SIZE_MASK      0x00f0000000000000ULL
index 62ca9a7..aeb4e9a 100644 (file)
@@ -748,6 +748,7 @@ struct omap_dss_driver {
 };
 
 enum omapdss_version omapdss_get_version(void);
+bool omapdss_is_initialized(void);
 
 int omap_dss_register_driver(struct omap_dss_driver *);
 void omap_dss_unregister_driver(struct omap_dss_driver *);
index 0a7515c..569c07f 100644 (file)
@@ -70,6 +70,7 @@ struct xenbus_device {
        struct device dev;
        enum xenbus_state state;
        struct completion down;
+       struct work_struct work;
 };
 
 static inline struct xenbus_device *to_xenbus_device(struct device *dev)
index 9d3a788..2d9b831 100644 (file)
@@ -431,6 +431,7 @@ choice
 config TREE_RCU
        bool "Tree-based hierarchical RCU"
        depends on !PREEMPT && SMP
+       select IRQ_WORK
        help
          This option selects the RCU implementation that is
          designed for very large SMP system with hundreds or
index 21c7fa6..91e53d0 100644 (file)
@@ -1056,7 +1056,7 @@ static inline void audit_get_stamp(struct audit_context *ctx,
 static void wait_for_auditd(unsigned long sleep_time)
 {
        DECLARE_WAITQUEUE(wait, current);
-       set_current_state(TASK_INTERRUPTIBLE);
+       set_current_state(TASK_UNINTERRUPTIBLE);
        add_wait_queue(&audit_backlog_wait, &wait);
 
        if (audit_backlog_limit &&
index a291aa2..43c307d 100644 (file)
@@ -658,6 +658,7 @@ int audit_add_tree_rule(struct audit_krule *rule)
        struct vfsmount *mnt;
        int err;
 
+       rule->tree = NULL;
        list_for_each_entry(tree, &tree_list, list) {
                if (!strcmp(seed->pathname, tree->pathname)) {
                        put_tree(seed);
index 2a99262..a7c9e6d 100644 (file)
@@ -1686,11 +1686,14 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
                 */
                cgroup_drop_root(opts.new_root);
 
-               if (((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) &&
-                   root->flags != opts.flags) {
-                       pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n");
-                       ret = -EINVAL;
-                       goto drop_new_super;
+               if (root->flags != opts.flags) {
+                       if ((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) {
+                               pr_err("cgroup: sane_behavior: new mount options should match the existing superblock\n");
+                               ret = -EINVAL;
+                               goto drop_new_super;
+                       } else {
+                               pr_warning("cgroup: new mount options do not match the existing superblock, will be ignored\n");
+                       }
                }
 
                /* no subsys rebinding, so refcounts don't change */
@@ -2699,13 +2702,14 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
                goto out;
        }
 
+       cfe->type = (void *)cft;
+       cfe->dentry = dentry;
+       dentry->d_fsdata = cfe;
+       simple_xattrs_init(&cfe->xattrs);
+
        mode = cgroup_file_mode(cft);
        error = cgroup_create_file(dentry, mode | S_IFREG, cgrp->root->sb);
        if (!error) {
-               cfe->type = (void *)cft;
-               cfe->dentry = dentry;
-               dentry->d_fsdata = cfe;
-               simple_xattrs_init(&cfe->xattrs);
                list_add_tail(&cfe->node, &parent->files);
                cfe = NULL;
        }
@@ -2953,11 +2957,8 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
        WARN_ON_ONCE(!rcu_read_lock_held());
 
        /* if first iteration, pretend we just visited @cgroup */
-       if (!pos) {
-               if (list_empty(&cgroup->children))
-                       return NULL;
+       if (!pos)
                pos = cgroup;
-       }
 
        /* visit the first child if exists */
        next = list_first_or_null_rcu(&pos->children, struct cgroup, sibling);
@@ -2965,14 +2966,14 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
                return next;
 
        /* no child, visit my or the closest ancestor's next sibling */
-       do {
+       while (pos != cgroup) {
                next = list_entry_rcu(pos->sibling.next, struct cgroup,
                                      sibling);
                if (&next->sibling != &pos->parent->children)
                        return next;
 
                pos = pos->parent;
-       } while (pos != cgroup);
+       }
 
        return NULL;
 }
index b5e4ab2..198a388 100644 (file)
@@ -133,6 +133,27 @@ static void cpu_hotplug_done(void)
        mutex_unlock(&cpu_hotplug.lock);
 }
 
+/*
+ * Wait for currently running CPU hotplug operations to complete (if any) and
+ * disable future CPU hotplug (from sysfs). The 'cpu_add_remove_lock' protects
+ * the 'cpu_hotplug_disabled' flag. The same lock is also acquired by the
+ * hotplug path before performing hotplug operations. So acquiring that lock
+ * guarantees mutual exclusion from any currently running hotplug operations.
+ */
+void cpu_hotplug_disable(void)
+{
+       cpu_maps_update_begin();
+       cpu_hotplug_disabled = 1;
+       cpu_maps_update_done();
+}
+
+void cpu_hotplug_enable(void)
+{
+       cpu_maps_update_begin();
+       cpu_hotplug_disabled = 0;
+       cpu_maps_update_done();
+}
+
 #else /* #if CONFIG_HOTPLUG_CPU */
 static void cpu_hotplug_begin(void) {}
 static void cpu_hotplug_done(void) {}
@@ -541,36 +562,6 @@ static int __init alloc_frozen_cpus(void)
 core_initcall(alloc_frozen_cpus);
 
 /*
- * Prevent regular CPU hotplug from racing with the freezer, by disabling CPU
- * hotplug when tasks are about to be frozen. Also, don't allow the freezer
- * to continue until any currently running CPU hotplug operation gets
- * completed.
- * To modify the 'cpu_hotplug_disabled' flag, we need to acquire the
- * 'cpu_add_remove_lock'. And this same lock is also taken by the regular
- * CPU hotplug path and released only after it is complete. Thus, we
- * (and hence the freezer) will block here until any currently running CPU
- * hotplug operation gets completed.
- */
-void cpu_hotplug_disable_before_freeze(void)
-{
-       cpu_maps_update_begin();
-       cpu_hotplug_disabled = 1;
-       cpu_maps_update_done();
-}
-
-
-/*
- * When tasks have been thawed, re-enable regular CPU hotplug (which had been
- * disabled while beginning to freeze tasks).
- */
-void cpu_hotplug_enable_after_thaw(void)
-{
-       cpu_maps_update_begin();
-       cpu_hotplug_disabled = 0;
-       cpu_maps_update_done();
-}
-
-/*
  * When callbacks for CPU hotplug notifications are being executed, we must
  * ensure that the state of the system with respect to the tasks being frozen
  * or not, as reported by the notification, remains unchanged *throughout the
@@ -589,12 +580,12 @@ cpu_hotplug_pm_callback(struct notifier_block *nb,
 
        case PM_SUSPEND_PREPARE:
        case PM_HIBERNATION_PREPARE:
-               cpu_hotplug_disable_before_freeze();
+               cpu_hotplug_disable();
                break;
 
        case PM_POST_SUSPEND:
        case PM_POST_HIBERNATION:
-               cpu_hotplug_enable_after_thaw();
+               cpu_hotplug_enable();
                break;
 
        default:
index af2eb3c..7bb73f9 100644 (file)
@@ -649,7 +649,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
         *      jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
         */
        forget_original_parent(tsk);
-       exit_task_namespaces(tsk);
 
        write_lock_irq(&tasklist_lock);
        if (group_dead)
@@ -795,6 +794,7 @@ void do_exit(long code)
        exit_shm(tsk);
        exit_files(tsk);
        exit_fs(tsk);
+       exit_task_namespaces(tsk);
        exit_task_work(tsk);
        check_stack_usage();
        exit_thread();
index 5a83dde..54a4d52 100644 (file)
@@ -143,7 +143,10 @@ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
  * irq_domain_add_simple() - Allocate and register a simple irq_domain.
  * @of_node: pointer to interrupt controller's device tree node.
  * @size: total number of irqs in mapping
- * @first_irq: first number of irq block assigned to the domain
+ * @first_irq: first number of irq block assigned to the domain,
+ *     pass zero to assign irqs on-the-fly. This will result in a
+ *     linear IRQ domain so it is important to use irq_create_mapping()
+ *     for each used IRQ, especially when SPARSE_IRQ is enabled.
  * @ops: map/unmap domain callbacks
  * @host_data: Controller private data pointer
  *
@@ -191,6 +194,7 @@ struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
        /* A linear domain is the default */
        return irq_domain_add_linear(of_node, size, ops, host_data);
 }
+EXPORT_SYMBOL_GPL(irq_domain_add_simple);
 
 /**
  * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
@@ -397,11 +401,12 @@ static void irq_domain_disassociate_many(struct irq_domain *domain,
        while (count--) {
                int irq = irq_base + count;
                struct irq_data *irq_data = irq_get_irq_data(irq);
-               irq_hw_number_t hwirq = irq_data->hwirq;
+               irq_hw_number_t hwirq;
 
                if (WARN_ON(!irq_data || irq_data->domain != domain))
                        continue;
 
+               hwirq = irq_data->hwirq;
                irq_set_status_flags(irq, IRQ_NOREQUEST);
 
                /* remove chip and handler */
index fa36e14..8212c1a 100644 (file)
@@ -363,6 +363,53 @@ static void log_store(int facility, int level,
        log_next_seq++;
 }
 
+#ifdef CONFIG_SECURITY_DMESG_RESTRICT
+int dmesg_restrict = 1;
+#else
+int dmesg_restrict;
+#endif
+
+static int syslog_action_restricted(int type)
+{
+       if (dmesg_restrict)
+               return 1;
+       /*
+        * Unless restricted, we allow "read all" and "get buffer size"
+        * for everybody.
+        */
+       return type != SYSLOG_ACTION_READ_ALL &&
+              type != SYSLOG_ACTION_SIZE_BUFFER;
+}
+
+static int check_syslog_permissions(int type, bool from_file)
+{
+       /*
+        * If this is from /proc/kmsg and we've already opened it, then we've
+        * already done the capabilities checks at open time.
+        */
+       if (from_file && type != SYSLOG_ACTION_OPEN)
+               return 0;
+
+       if (syslog_action_restricted(type)) {
+               if (capable(CAP_SYSLOG))
+                       return 0;
+               /*
+                * For historical reasons, accept CAP_SYS_ADMIN too, with
+                * a warning.
+                */
+               if (capable(CAP_SYS_ADMIN)) {
+                       pr_warn_once("%s (%d): Attempt to access syslog with "
+                                    "CAP_SYS_ADMIN but no CAP_SYSLOG "
+                                    "(deprecated).\n",
+                                current->comm, task_pid_nr(current));
+                       return 0;
+               }
+               return -EPERM;
+       }
+       return security_syslog(type);
+}
+
+
 /* /dev/kmsg - userspace message inject/listen interface */
 struct devkmsg_user {
        u64 seq;
@@ -620,7 +667,8 @@ static int devkmsg_open(struct inode *inode, struct file *file)
        if ((file->f_flags & O_ACCMODE) == O_WRONLY)
                return 0;
 
-       err = security_syslog(SYSLOG_ACTION_READ_ALL);
+       err = check_syslog_permissions(SYSLOG_ACTION_READ_ALL,
+                                      SYSLOG_FROM_READER);
        if (err)
                return err;
 
@@ -813,45 +861,6 @@ static inline void boot_delay_msec(int level)
 }
 #endif
 
-#ifdef CONFIG_SECURITY_DMESG_RESTRICT
-int dmesg_restrict = 1;
-#else
-int dmesg_restrict;
-#endif
-
-static int syslog_action_restricted(int type)
-{
-       if (dmesg_restrict)
-               return 1;
-       /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
-       return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
-}
-
-static int check_syslog_permissions(int type, bool from_file)
-{
-       /*
-        * If this is from /proc/kmsg and we've already opened it, then we've
-        * already done the capabilities checks at open time.
-        */
-       if (from_file && type != SYSLOG_ACTION_OPEN)
-               return 0;
-
-       if (syslog_action_restricted(type)) {
-               if (capable(CAP_SYSLOG))
-                       return 0;
-               /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
-               if (capable(CAP_SYS_ADMIN)) {
-                       printk_once(KERN_WARNING "%s (%d): "
-                                "Attempt to access syslog with CAP_SYS_ADMIN "
-                                "but no CAP_SYSLOG (deprecated).\n",
-                                current->comm, task_pid_nr(current));
-                       return 0;
-               }
-               return -EPERM;
-       }
-       return 0;
-}
-
 #if defined(CONFIG_PRINTK_TIME)
 static bool printk_time = 1;
 #else
@@ -1249,7 +1258,7 @@ out:
 
 SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
 {
-       return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
+       return do_syslog(type, buf, len, SYSLOG_FROM_READER);
 }
 
 /*
index 071b0ab..eb911db 100644 (file)
@@ -48,9 +48,11 @@ int add_range_with_merge(struct range *range, int az, int nr_range,
                final_start = min(range[i].start, start);
                final_end = max(range[i].end, end);
 
-               range[i].start = final_start;
-               range[i].end =  final_end;
-               return nr_range;
+               /* clear it and add it back for further merge */
+               range[i].start = 0;
+               range[i].end =  0;
+               return add_range_with_merge(range, az, nr_range,
+                       final_start, final_end);
        }
 
        /* Need to add it: */
index 16ea679..3538001 100644 (file)
@@ -1451,9 +1451,9 @@ static int rcu_gp_init(struct rcu_state *rsp)
                                            rnp->grphi, rnp->qsmask);
                raw_spin_unlock_irq(&rnp->lock);
 #ifdef CONFIG_PROVE_RCU_DELAY
-               if ((prandom_u32() % (rcu_num_nodes * 8)) == 0 &&
+               if ((prandom_u32() % (rcu_num_nodes + 1)) == 0 &&
                    system_state == SYSTEM_RUNNING)
-                       schedule_timeout_uninterruptible(2);
+                       udelay(200);
 #endif /* #ifdef CONFIG_PROVE_RCU_DELAY */
                cond_resched();
        }
@@ -1613,6 +1613,14 @@ static int __noreturn rcu_gp_kthread(void *arg)
        }
 }
 
+static void rsp_wakeup(struct irq_work *work)
+{
+       struct rcu_state *rsp = container_of(work, struct rcu_state, wakeup_work);
+
+       /* Wake up rcu_gp_kthread() to start the grace period. */
+       wake_up(&rsp->gp_wq);
+}
+
 /*
  * Start a new RCU grace period if warranted, re-initializing the hierarchy
  * in preparation for detecting the next grace period.  The caller must hold
@@ -1637,8 +1645,12 @@ rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
        }
        rsp->gp_flags = RCU_GP_FLAG_INIT;
 
-       /* Wake up rcu_gp_kthread() to start the grace period. */
-       wake_up(&rsp->gp_wq);
+       /*
+        * We can't do wakeups while holding the rnp->lock, as that
+        * could cause possible deadlocks with the rq->lock. Deter
+        * the wakeup to interrupt context.
+        */
+       irq_work_queue(&rsp->wakeup_work);
 }
 
 /*
@@ -3235,6 +3247,7 @@ static void __init rcu_init_one(struct rcu_state *rsp,
 
        rsp->rda = rda;
        init_waitqueue_head(&rsp->gp_wq);
+       init_irq_work(&rsp->wakeup_work, rsp_wakeup);
        rnp = rsp->level[rcu_num_lvls - 1];
        for_each_possible_cpu(i) {
                while (i > rnp->grphi)
index da77a8f..4df5034 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/threads.h>
 #include <linux/cpumask.h>
 #include <linux/seqlock.h>
+#include <linux/irq_work.h>
 
 /*
  * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
@@ -442,6 +443,7 @@ struct rcu_state {
        char *name;                             /* Name of structure. */
        char abbr;                              /* Abbreviated name. */
        struct list_head flavors;               /* List of RCU flavors. */
+       struct irq_work wakeup_work;            /* Postponed wakeups */
 };
 
 /* Values for rcu_state structure's gp_flags field. */
index b5197dc..3d6833f 100644 (file)
@@ -195,8 +195,12 @@ void local_bh_enable_ip(unsigned long ip)
 EXPORT_SYMBOL(local_bh_enable_ip);
 
 /*
- * We restart softirq processing for at most 2 ms,
- * and if need_resched() is not set.
+ * We restart softirq processing for at most MAX_SOFTIRQ_RESTART times,
+ * but break the loop if need_resched() is set or after 2 ms.
+ * The MAX_SOFTIRQ_TIME provides a nice upper bound in most cases, but in
+ * certain cases, such as stop_machine(), jiffies may cease to
+ * increment and so we need the MAX_SOFTIRQ_RESTART limit as
+ * well to make sure we eventually return from this method.
  *
  * These limits have been established via experimentation.
  * The two things to balance is latency against fairness -
@@ -204,6 +208,7 @@ EXPORT_SYMBOL(local_bh_enable_ip);
  * should not be able to lock up the box.
  */
 #define MAX_SOFTIRQ_TIME  msecs_to_jiffies(2)
+#define MAX_SOFTIRQ_RESTART 10
 
 asmlinkage void __do_softirq(void)
 {
@@ -212,6 +217,7 @@ asmlinkage void __do_softirq(void)
        unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
        int cpu;
        unsigned long old_flags = current->flags;
+       int max_restart = MAX_SOFTIRQ_RESTART;
 
        /*
         * Mask out PF_MEMALLOC s current task context is borrowed for the
@@ -265,7 +271,8 @@ restart:
 
        pending = local_softirq_pending();
        if (pending) {
-               if (time_before(jiffies, end) && !need_resched())
+               if (time_before(jiffies, end) && !need_resched() &&
+                   --max_restart)
                        goto restart;
 
                wakeup_softirqd();
index b95d3c7..2bbd9a7 100644 (file)
@@ -362,6 +362,29 @@ int unregister_reboot_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL(unregister_reboot_notifier);
 
+/* Add backwards compatibility for stable trees. */
+#ifndef PF_NO_SETAFFINITY
+#define PF_NO_SETAFFINITY              PF_THREAD_BOUND
+#endif
+
+static void migrate_to_reboot_cpu(void)
+{
+       /* The boot cpu is always logical cpu 0 */
+       int cpu = 0;
+
+       cpu_hotplug_disable();
+
+       /* Make certain the cpu I'm about to reboot on is online */
+       if (!cpu_online(cpu))
+               cpu = cpumask_first(cpu_online_mask);
+
+       /* Prevent races with other tasks migrating this task */
+       current->flags |= PF_NO_SETAFFINITY;
+
+       /* Make certain I only run on the appropriate processor */
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
+}
+
 /**
  *     kernel_restart - reboot the system
  *     @cmd: pointer to buffer containing command to execute for restart
@@ -373,7 +396,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
 void kernel_restart(char *cmd)
 {
        kernel_restart_prepare(cmd);
-       disable_nonboot_cpus();
+       migrate_to_reboot_cpu();
        syscore_shutdown();
        if (!cmd)
                printk(KERN_EMERG "Restarting system.\n");
@@ -400,7 +423,7 @@ static void kernel_shutdown_prepare(enum system_states state)
 void kernel_halt(void)
 {
        kernel_shutdown_prepare(SYSTEM_HALT);
-       disable_nonboot_cpus();
+       migrate_to_reboot_cpu();
        syscore_shutdown();
        printk(KERN_EMERG "System halted.\n");
        kmsg_dump(KMSG_DUMP_HALT);
@@ -419,7 +442,7 @@ void kernel_power_off(void)
        kernel_shutdown_prepare(SYSTEM_POWER_OFF);
        if (pm_power_off_prepare)
                pm_power_off_prepare();
-       disable_nonboot_cpus();
+       migrate_to_reboot_cpu();
        syscore_shutdown();
        printk(KERN_EMERG "Power down.\n");
        kmsg_dump(KMSG_DUMP_POWEROFF);
index 12ff13a..8f5b3b9 100644 (file)
@@ -874,7 +874,6 @@ static void hardpps_update_phase(long error)
 void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
 {
        struct pps_normtime pts_norm, freq_norm;
-       unsigned long flags;
 
        pts_norm = pps_normalize_ts(*phase_ts);
 
index 24938d5..0c73942 100644 (file)
@@ -511,6 +511,12 @@ again:
                }
        }
 
+       /*
+        * Remove the current cpu from the pending mask. The event is
+        * delivered immediately in tick_do_broadcast() !
+        */
+       cpumask_clear_cpu(smp_processor_id(), tick_broadcast_pending_mask);
+
        /* Take care of enforced broadcast requests */
        cpumask_or(tmpmask, tmpmask, tick_broadcast_force_mask);
        cpumask_clear(tick_broadcast_force_mask);
@@ -575,8 +581,8 @@ void tick_broadcast_oneshot_control(unsigned long reason)
 
        raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
        if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
-               WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
                if (!cpumask_test_and_set_cpu(cpu, tick_broadcast_oneshot_mask)) {
+                       WARN_ON_ONCE(cpumask_test_cpu(cpu, tick_broadcast_pending_mask));
                        clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
                        /*
                         * We only reprogram the broadcast timer if we
index 98cd470..baeeb5c 100644 (file)
@@ -975,6 +975,14 @@ static int timekeeping_suspend(void)
 
        read_persistent_clock(&timekeeping_suspend_time);
 
+       /*
+        * On some systems the persistent_clock can not be detected at
+        * timekeeping_init by its return value, so if we see a valid
+        * value returned, update the persistent_clock_exists flag.
+        */
+       if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
+               persistent_clock_exist = true;
+
        raw_spin_lock_irqsave(&timekeeper_lock, flags);
        write_seqcount_begin(&timekeeper_seq);
        timekeeping_forward_now(tk);
index b549b0f..6c508ff 100644 (file)
@@ -120,22 +120,22 @@ static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip);
 
 /*
  * Traverse the ftrace_global_list, invoking all entries.  The reason that we
- * can use rcu_dereference_raw() is that elements removed from this list
+ * can use rcu_dereference_raw_notrace() is that elements removed from this list
  * are simply leaked, so there is no need to interact with a grace-period
- * mechanism.  The rcu_dereference_raw() calls are needed to handle
+ * mechanism.  The rcu_dereference_raw_notrace() calls are needed to handle
  * concurrent insertions into the ftrace_global_list.
  *
  * Silly Alpha and silly pointer-speculation compiler optimizations!
  */
 #define do_for_each_ftrace_op(op, list)                        \
-       op = rcu_dereference_raw(list);                 \
+       op = rcu_dereference_raw_notrace(list);                 \
        do
 
 /*
  * Optimized for just a single item in the list (as that is the normal case).
  */
 #define while_for_each_ftrace_op(op)                           \
-       while (likely(op = rcu_dereference_raw((op)->next)) &&  \
+       while (likely(op = rcu_dereference_raw_notrace((op)->next)) &&  \
               unlikely((op) != &ftrace_list_end))
 
 static inline void ftrace_ops_init(struct ftrace_ops *ops)
@@ -779,7 +779,7 @@ ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
        if (hlist_empty(hhd))
                return NULL;
 
-       hlist_for_each_entry_rcu(rec, hhd, node) {
+       hlist_for_each_entry_rcu_notrace(rec, hhd, node) {
                if (rec->ip == ip)
                        return rec;
        }
@@ -1165,7 +1165,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
 
        hhd = &hash->buckets[key];
 
-       hlist_for_each_entry_rcu(entry, hhd, hlist) {
+       hlist_for_each_entry_rcu_notrace(entry, hhd, hlist) {
                if (entry->ip == ip)
                        return entry;
        }
@@ -1422,8 +1422,8 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip)
        struct ftrace_hash *notrace_hash;
        int ret;
 
-       filter_hash = rcu_dereference_raw(ops->filter_hash);
-       notrace_hash = rcu_dereference_raw(ops->notrace_hash);
+       filter_hash = rcu_dereference_raw_notrace(ops->filter_hash);
+       notrace_hash = rcu_dereference_raw_notrace(ops->notrace_hash);
 
        if ((ftrace_hash_empty(filter_hash) ||
             ftrace_lookup_ip(filter_hash, ip)) &&
@@ -2920,7 +2920,7 @@ static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip,
         * on the hash. rcu_read_lock is too dangerous here.
         */
        preempt_disable_notrace();
-       hlist_for_each_entry_rcu(entry, hhd, node) {
+       hlist_for_each_entry_rcu_notrace(entry, hhd, node) {
                if (entry->ip == ip)
                        entry->ops->func(ip, parent_ip, &entry->data);
        }
index b59aea2..e444ff8 100644 (file)
@@ -620,6 +620,9 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
        if (cpu == RING_BUFFER_ALL_CPUS)
                work = &buffer->irq_work;
        else {
+               if (!cpumask_test_cpu(cpu, buffer->cpumask))
+                       return -EINVAL;
+
                cpu_buffer = buffer->buffers[cpu];
                work = &cpu_buffer->irq_work;
        }
index ae6fa2d..e71a8be 100644 (file)
@@ -652,8 +652,6 @@ static struct {
        ARCH_TRACE_CLOCKS
 };
 
-int trace_clock_id;
-
 /*
  * trace_parser_get_init - gets the buffer for trace parser
  */
@@ -843,7 +841,15 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 
        memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN);
        max_data->pid = tsk->pid;
-       max_data->uid = task_uid(tsk);
+       /*
+        * If tsk == current, then use current_uid(), as that does not use
+        * RCU. The irq tracer can be called out of RCU scope.
+        */
+       if (tsk == current)
+               max_data->uid = current_uid();
+       else
+               max_data->uid = task_uid(tsk);
+
        max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO;
        max_data->policy = tsk->policy;
        max_data->rt_priority = tsk->rt_priority;
@@ -2818,7 +2824,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
                iter->iter_flags |= TRACE_FILE_ANNOTATE;
 
        /* Output in nanoseconds only if we are using a clock in nanoseconds. */
-       if (trace_clocks[trace_clock_id].in_ns)
+       if (trace_clocks[tr->clock_id].in_ns)
                iter->iter_flags |= TRACE_FILE_TIME_IN_NS;
 
        /* stop the trace while dumping if we are not opening "snapshot" */
@@ -3817,7 +3823,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
                iter->iter_flags |= TRACE_FILE_LAT_FMT;
 
        /* Output in nanoseconds only if we are using a clock in nanoseconds. */
-       if (trace_clocks[trace_clock_id].in_ns)
+       if (trace_clocks[tr->clock_id].in_ns)
                iter->iter_flags |= TRACE_FILE_TIME_IN_NS;
 
        iter->cpu_file = tc->cpu;
@@ -5087,7 +5093,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
        cnt = ring_buffer_bytes_cpu(trace_buf->buffer, cpu);
        trace_seq_printf(s, "bytes: %ld\n", cnt);
 
-       if (trace_clocks[trace_clock_id].in_ns) {
+       if (trace_clocks[tr->clock_id].in_ns) {
                /* local or global for trace_clock */
                t = ns2usecs(ring_buffer_oldest_event_ts(trace_buf->buffer, cpu));
                usec_rem = do_div(t, USEC_PER_SEC);
@@ -6216,10 +6222,15 @@ __init static int tracer_alloc_buffers(void)
 
        trace_init_cmdlines();
 
-       register_tracer(&nop_trace);
-
+       /*
+        * register_tracer() might reference current_trace, so it
+        * needs to be set before we register anything. This is
+        * just a bootstrap of current_trace anyway.
+        */
        global_trace.current_trace = &nop_trace;
 
+       register_tracer(&nop_trace);
+
        /* All seems OK, enable tracing */
        tracing_disabled = 0;
 
index 711ca7d..20572ed 100644 (file)
@@ -700,8 +700,6 @@ enum print_line_t print_trace_line(struct trace_iterator *iter);
 
 extern unsigned long trace_flags;
 
-extern int trace_clock_id;
-
 /* Standard output formatting function used for function return traces */
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
index 55e2cf6..2901e3b 100644 (file)
@@ -1159,7 +1159,7 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
        /* stop the tracing. */
        tracing_stop();
        /* check the trace buffer */
-       ret = trace_test_buffer(tr, &count);
+       ret = trace_test_buffer(&tr->trace_buffer, &count);
        trace->reset(tr);
        tracing_start();
 
index 5f9c44c..4cc6442 100644 (file)
@@ -37,7 +37,7 @@ MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
        mpi_limb_t a;
        MPI val = NULL;
 
-       while (nbytes >= 0 && buffer[0] == 0) {
+       while (nbytes > 0 && buffer[0] == 0) {
                buffer++;
                nbytes--;
        }
index 538367e..1b24bdc 100644 (file)
@@ -319,7 +319,7 @@ void __frontswap_invalidate_area(unsigned type)
                        return;
                frontswap_ops->invalidate_area(type);
                atomic_set(&sis->frontswap_pages, 0);
-               memset(sis->frontswap_map, 0, sis->max / sizeof(long));
+               bitmap_zero(sis->frontswap_map, sis->max);
        }
        clear_bit(type, need_init);
 }
index f8feeec..e2bfbf7 100644 (file)
@@ -2839,7 +2839,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        if (ptep) {
                entry = huge_ptep_get(ptep);
                if (unlikely(is_hugetlb_entry_migration(entry))) {
-                       migration_entry_wait(mm, (pmd_t *)ptep, address);
+                       migration_entry_wait_huge(mm, ptep);
                        return 0;
                } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
                        return VM_FAULT_HWPOISON_LARGE |
index 010d6c1..1947218 100644 (file)
@@ -1199,7 +1199,6 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
 
                        mz = mem_cgroup_zoneinfo(root, nid, zid);
                        iter = &mz->reclaim_iter[reclaim->priority];
-                       last_visited = iter->last_visited;
                        if (prev && reclaim->generation != iter->generation) {
                                iter->last_visited = NULL;
                                goto out_unlock;
@@ -1218,13 +1217,12 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
                         * is alive.
                         */
                        dead_count = atomic_read(&root->dead_count);
-                       smp_rmb();
-                       last_visited = iter->last_visited;
-                       if (last_visited) {
-                               if ((dead_count != iter->last_dead_count) ||
-                                       !css_tryget(&last_visited->css)) {
+                       if (dead_count == iter->last_dead_count) {
+                               smp_rmb();
+                               last_visited = iter->last_visited;
+                               if (last_visited &&
+                                   !css_tryget(&last_visited->css))
                                        last_visited = NULL;
-                               }
                        }
                }
 
@@ -3141,8 +3139,6 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
                        return -ENOMEM;
                }
 
-               INIT_WORK(&s->memcg_params->destroy,
-                               kmem_cache_destroy_work_func);
                s->memcg_params->is_root_cache = true;
 
                /*
index 6dc1882..61a262b 100644 (file)
@@ -220,7 +220,6 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
        tlb->start      = -1UL;
        tlb->end        = 0;
        tlb->need_flush = 0;
-       tlb->fast_mode  = (num_possible_cpus() == 1);
        tlb->local.next = NULL;
        tlb->local.nr   = 0;
        tlb->local.max  = ARRAY_SIZE(tlb->__pages);
@@ -244,9 +243,6 @@ void tlb_flush_mmu(struct mmu_gather *tlb)
        tlb_table_flush(tlb);
 #endif
 
-       if (tlb_fast_mode(tlb))
-               return;
-
        for (batch = &tlb->local; batch; batch = batch->next) {
                free_pages_and_swap_cache(batch->pages, batch->nr);
                batch->nr = 0;
@@ -288,11 +284,6 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 
        VM_BUG_ON(!tlb->need_flush);
 
-       if (tlb_fast_mode(tlb)) {
-               free_page_and_swap_cache(page);
-               return 1; /* avoid calling tlb_flush_mmu() */
-       }
-
        batch = tlb->active;
        batch->pages[batch->nr++] = page;
        if (batch->nr == batch->max) {
index b1f5750..6f0c244 100644 (file)
@@ -200,15 +200,14 @@ static void remove_migration_ptes(struct page *old, struct page *new)
  * get to the page and wait until migration is finished.
  * When we return from this function the fault will be retried.
  */
-void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
-                               unsigned long address)
+static void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
+                               spinlock_t *ptl)
 {
-       pte_t *ptep, pte;
-       spinlock_t *ptl;
+       pte_t pte;
        swp_entry_t entry;
        struct page *page;
 
-       ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
+       spin_lock(ptl);
        pte = *ptep;
        if (!is_swap_pte(pte))
                goto out;
@@ -236,6 +235,20 @@ out:
        pte_unmap_unlock(ptep, ptl);
 }
 
+void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+                               unsigned long address)
+{
+       spinlock_t *ptl = pte_lockptr(mm, pmd);
+       pte_t *ptep = pte_offset_map(pmd, address);
+       __migration_entry_wait(mm, ptep, ptl);
+}
+
+void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte)
+{
+       spinlock_t *ptl = &(mm)->page_table_lock;
+       __migration_entry_wait(mm, pte, ptl);
+}
+
 #ifdef CONFIG_BLOCK
 /* Returns true if all buffers are successfully locked */
 static bool buffer_migrate_lock_buffers(struct buffer_head *head,
index 378a15b..c3edb62 100644 (file)
@@ -1628,6 +1628,7 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
        long min = mark;
        long lowmem_reserve = z->lowmem_reserve[classzone_idx];
        int o;
+       long free_cma = 0;
 
        free_pages -= (1 << order) - 1;
        if (alloc_flags & ALLOC_HIGH)
@@ -1637,9 +1638,10 @@ static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
 #ifdef CONFIG_CMA
        /* If allocation can't use CMA areas don't use free CMA pages */
        if (!(alloc_flags & ALLOC_CMA))
-               free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
+               free_cma = zone_page_state(z, NR_FREE_CMA_PAGES);
 #endif
-       if (free_pages <= min + lowmem_reserve)
+
+       if (free_pages - free_cma <= min + lowmem_reserve)
                return false;
        for (o = 0; o < order; o++) {
                /* At the next order, this order's pages become unavailable */
index b3d40dc..f24ab0d 100644 (file)
@@ -336,8 +336,24 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
                 * Swap entry may have been freed since our caller observed it.
                 */
                err = swapcache_prepare(entry);
-               if (err == -EEXIST) {   /* seems racy */
+               if (err == -EEXIST) {
                        radix_tree_preload_end();
+                       /*
+                        * We might race against get_swap_page() and stumble
+                        * across a SWAP_HAS_CACHE swap_map entry whose page
+                        * has not been brought into the swapcache yet, while
+                        * the other end is scheduled away waiting on discard
+                        * I/O completion at scan_swap_map().
+                        *
+                        * In order to avoid turning this transitory state
+                        * into a permanent loop around this -EEXIST case
+                        * if !CONFIG_PREEMPT and the I/O completion happens
+                        * to be waiting on the CPU waitqueue where we are now
+                        * busy looping, we just conditionally invoke the
+                        * scheduler here, if there are some more important
+                        * tasks to run.
+                        */
+                       cond_resched();
                        continue;
                }
                if (err) {              /* swp entry is obsolete ? */
index 6c340d9..746af55 100644 (file)
@@ -2116,7 +2116,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
        }
        /* frontswap enabled? set up bit-per-page map for frontswap */
        if (frontswap_enabled)
-               frontswap_map = vzalloc(maxpages / sizeof(long));
+               frontswap_map = vzalloc(BITS_TO_LONGS(maxpages) * sizeof(long));
 
        if (p->bdev) {
                if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
index 8eb7542..addc116 100644 (file)
@@ -562,36 +562,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
 
        if (!p9_is_proto_dotl(c)) {
                /* Error is reported in string format */
-               uint16_t len;
-               /* 7 = header size for RERROR, 2 is the size of string len; */
-               int inline_len = in_hdrlen - (7 + 2);
+               int len;
+               /* 7 = header size for RERROR; */
+               int inline_len = in_hdrlen - 7;
 
-               /* Read the size of error string */
-               err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
-               if (err)
-                       goto out_err;
-
-               ename = kmalloc(len + 1, GFP_NOFS);
-               if (!ename) {
-                       err = -ENOMEM;
+               len =  req->rc->size - req->rc->offset;
+               if (len > (P9_ZC_HDR_SZ - 7)) {
+                       err = -EFAULT;
                        goto out_err;
                }
-               if (len <= inline_len) {
-                       /* We have error in protocol buffer itself */
-                       if (pdu_read(req->rc, ename, len)) {
-                               err = -EFAULT;
-                               goto out_free;
 
-                       }
-               } else {
-                       /*
-                        *  Part of the data is in user space buffer.
-                        */
-                       if (pdu_read(req->rc, ename, inline_len)) {
-                               err = -EFAULT;
-                               goto out_free;
-
-                       }
+               ename = &req->rc->sdata[req->rc->offset];
+               if (len > inline_len) {
+                       /* We have error in external buffer */
                        if (kern_buf) {
                                memcpy(ename + inline_len, uidata,
                                       len - inline_len);
@@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
                                                     uidata, len - inline_len);
                                if (err) {
                                        err = -EFAULT;
-                                       goto out_free;
+                                       goto out_err;
                                }
                        }
                }
-               ename[len] = 0;
-               if (p9_is_proto_dotu(c)) {
-                       /* For dotu we also have error code */
-                       err = p9pdu_readf(req->rc,
-                                         c->proto_version, "d", &ecode);
-                       if (err)
-                               goto out_free;
+               ename = NULL;
+               err = p9pdu_readf(req->rc, c->proto_version, "s?d",
+                                 &ename, &ecode);
+               if (err)
+                       goto out_err;
+
+               if (p9_is_proto_dotu(c))
                        err = -ecode;
-               }
+
                if (!err || !IS_ERR_VALUE(err)) {
                        err = p9_errstr2errno(ename, strlen(ename));
 
@@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
        }
        return err;
 
-out_free:
-       kfree(ename);
 out_err:
        p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
        return err;
index 071f288..f680ee1 100644 (file)
 #include "bat_algo.h"
 #include "network-coding.h"
 
+/**
+ * batadv_dup_status - duplicate status
+ * @BATADV_NO_DUP: the packet is a duplicate
+ * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
+ *  neighbor)
+ * @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
+ * @BATADV_PROTECTED: originator is currently protected (after reboot)
+ */
+enum batadv_dup_status {
+       BATADV_NO_DUP = 0,
+       BATADV_ORIG_DUP,
+       BATADV_NEIGH_DUP,
+       BATADV_PROTECTED,
+};
+
 static struct batadv_neigh_node *
 batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
                        const uint8_t *neigh_addr,
@@ -650,7 +665,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
                          const struct batadv_ogm_packet *batadv_ogm_packet,
                          struct batadv_hard_iface *if_incoming,
                          const unsigned char *tt_buff,
-                         int is_duplicate)
+                         enum batadv_dup_status dup_status)
 {
        struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
        struct batadv_neigh_node *router = NULL;
@@ -676,7 +691,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
                        continue;
                }
 
-               if (is_duplicate)
+               if (dup_status != BATADV_NO_DUP)
                        continue;
 
                spin_lock_bh(&tmp_neigh_node->lq_update_lock);
@@ -718,7 +733,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
        neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv);
        spin_unlock_bh(&neigh_node->lq_update_lock);
 
-       if (!is_duplicate) {
+       if (dup_status == BATADV_NO_DUP) {
                orig_node->last_ttl = batadv_ogm_packet->header.ttl;
                neigh_node->last_ttl = batadv_ogm_packet->header.ttl;
        }
@@ -902,15 +917,16 @@ out:
        return ret;
 }
 
-/* processes a batman packet for all interfaces, adjusts the sequence number and
- * finds out whether it is a duplicate.
- * returns:
- *   1 the packet is a duplicate
- *   0 the packet has not yet been received
- *  -1 the packet is old and has been received while the seqno window
- *     was protected. Caller should drop it.
+/**
+ * batadv_iv_ogm_update_seqnos -  process a batman packet for all interfaces,
+ *  adjust the sequence number and find out whether it is a duplicate
+ * @ethhdr: ethernet header of the packet
+ * @batadv_ogm_packet: OGM packet to be considered
+ * @if_incoming: interface on which the OGM packet was received
+ *
+ * Returns duplicate status as enum batadv_dup_status
  */
-static int
+static enum batadv_dup_status
 batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
                            const struct batadv_ogm_packet *batadv_ogm_packet,
                            const struct batadv_hard_iface *if_incoming)
@@ -918,17 +934,18 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
        struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
        struct batadv_orig_node *orig_node;
        struct batadv_neigh_node *tmp_neigh_node;
-       int is_duplicate = 0;
+       int is_dup;
        int32_t seq_diff;
        int need_update = 0;
-       int set_mark, ret = -1;
+       int set_mark;
+       enum batadv_dup_status ret = BATADV_NO_DUP;
        uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
        uint8_t *neigh_addr;
        uint8_t packet_count;
 
        orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
        if (!orig_node)
-               return 0;
+               return BATADV_NO_DUP;
 
        spin_lock_bh(&orig_node->ogm_cnt_lock);
        seq_diff = seqno - orig_node->last_real_seqno;
@@ -936,22 +953,29 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
        /* signalize caller that the packet is to be dropped. */
        if (!hlist_empty(&orig_node->neigh_list) &&
            batadv_window_protected(bat_priv, seq_diff,
-                                   &orig_node->batman_seqno_reset))
+                                   &orig_node->batman_seqno_reset)) {
+               ret = BATADV_PROTECTED;
                goto out;
+       }
 
        rcu_read_lock();
        hlist_for_each_entry_rcu(tmp_neigh_node,
                                 &orig_node->neigh_list, list) {
-               is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits,
-                                               orig_node->last_real_seqno,
-                                               seqno);
-
                neigh_addr = tmp_neigh_node->addr;
+               is_dup = batadv_test_bit(tmp_neigh_node->real_bits,
+                                        orig_node->last_real_seqno,
+                                        seqno);
+
                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
-                   tmp_neigh_node->if_incoming == if_incoming)
+                   tmp_neigh_node->if_incoming == if_incoming) {
                        set_mark = 1;
-               else
+                       if (is_dup)
+                               ret = BATADV_NEIGH_DUP;
+               } else {
                        set_mark = 0;
+                       if (is_dup && (ret != BATADV_NEIGH_DUP))
+                               ret = BATADV_ORIG_DUP;
+               }
 
                /* if the window moved, set the update flag. */
                need_update |= batadv_bit_get_packet(bat_priv,
@@ -971,8 +995,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
                orig_node->last_real_seqno = seqno;
        }
 
-       ret = is_duplicate;
-
 out:
        spin_unlock_bh(&orig_node->ogm_cnt_lock);
        batadv_orig_node_free_ref(orig_node);
@@ -994,7 +1016,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
        int is_broadcast = 0, is_bidirect;
        bool is_single_hop_neigh = false;
        bool is_from_best_next_hop = false;
-       int is_duplicate, sameseq, simlar_ttl;
+       int sameseq, similar_ttl;
+       enum batadv_dup_status dup_status;
        uint32_t if_incoming_seqno;
        uint8_t *prev_sender;
 
@@ -1138,10 +1161,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
        if (!orig_node)
                return;
 
-       is_duplicate = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
-                                                  if_incoming);
+       dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
+                                                if_incoming);
 
-       if (is_duplicate == -1) {
+       if (dup_status == BATADV_PROTECTED) {
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Drop packet: packet within seqno protection time (sender: %pM)\n",
                           ethhdr->h_source);
@@ -1211,11 +1234,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
         * seqno and similar ttl as the non-duplicate
         */
        sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno);
-       simlar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
-       if (is_bidirect && (!is_duplicate || (sameseq && simlar_ttl)))
+       similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
+       if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
+                           (sameseq && similar_ttl)))
                batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
                                          batadv_ogm_packet, if_incoming,
-                                         tt_buff, is_duplicate);
+                                         tt_buff, dup_status);
 
        /* is single hop (direct) neighbor */
        if (is_single_hop_neigh) {
@@ -1236,7 +1260,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
                goto out_neigh;
        }
 
-       if (is_duplicate) {
+       if (dup_status == BATADV_NEIGH_DUP) {
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Drop packet: duplicate packet received\n");
                goto out_neigh;
index 379061c..de27b31 100644 (file)
@@ -1067,6 +1067,10 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
        group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
        bat_priv->bla.claim_dest.group = group;
 
+       /* purge everything when bridge loop avoidance is turned off */
+       if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+               oldif = NULL;
+
        if (!oldif) {
                batadv_bla_purge_claims(bat_priv, NULL, 1);
                batadv_bla_purge_backbone_gw(bat_priv, 1);
index 15a22ef..929e304 100644 (file)
@@ -582,10 +582,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
            (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
                goto out;
 
-       if (!rtnl_trylock()) {
-               ret = -ERESTARTSYS;
-               goto out;
-       }
+       rtnl_lock();
 
        if (status_tmp == BATADV_IF_NOT_IN_USE) {
                batadv_hardif_disable_interface(hard_iface,
index 33843c5..d817c93 100644 (file)
@@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = {
 static void hci_power_on(struct work_struct *work)
 {
        struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
+       int err;
 
        BT_DBG("%s", hdev->name);
 
-       if (hci_dev_open(hdev->id) < 0)
+       err = hci_dev_open(hdev->id);
+       if (err < 0) {
+               mgmt_set_powered_failed(hdev, err);
                return;
+       }
 
        if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
                queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
index a76d1ac..24bee07 100644 (file)
@@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
 }
 
 static inline int l2cap_command_rej(struct l2cap_conn *conn,
-                                   struct l2cap_cmd_hdr *cmd, u8 *data)
+                                   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                   u8 *data)
 {
        struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
 
+       if (cmd_len < sizeof(*rej))
+               return -EPROTO;
+
        if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
                return 0;
 
@@ -3829,11 +3833,14 @@ sendresp:
 }
 
 static int l2cap_connect_req(struct l2cap_conn *conn,
-                            struct l2cap_cmd_hdr *cmd, u8 *data)
+                            struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
        struct hci_dev *hdev = conn->hcon->hdev;
        struct hci_conn *hcon = conn->hcon;
 
+       if (cmd_len < sizeof(struct l2cap_conn_req))
+               return -EPROTO;
+
        hci_dev_lock(hdev);
        if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
            !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
@@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
 }
 
 static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
-                                   struct l2cap_cmd_hdr *cmd, u8 *data)
+                                   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                   u8 *data)
 {
        struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
        u16 scid, dcid, result, status;
@@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
        u8 req[128];
        int err;
 
+       if (cmd_len < sizeof(*rsp))
+               return -EPROTO;
+
        scid   = __le16_to_cpu(rsp->scid);
        dcid   = __le16_to_cpu(rsp->dcid);
        result = __le16_to_cpu(rsp->result);
@@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
        struct l2cap_chan *chan;
        int len, err = 0;
 
+       if (cmd_len < sizeof(*req))
+               return -EPROTO;
+
        dcid  = __le16_to_cpu(req->dcid);
        flags = __le16_to_cpu(req->flags);
 
@@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
 
        /* Reject if config buffer is too small. */
        len = cmd_len - sizeof(*req);
-       if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
+       if (chan->conf_len + len > sizeof(chan->conf_req)) {
                l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
                               l2cap_build_conf_rsp(chan, rsp,
                               L2CAP_CONF_REJECT, flags), rsp);
@@ -4053,14 +4067,18 @@ unlock:
 }
 
 static inline int l2cap_config_rsp(struct l2cap_conn *conn,
-                                  struct l2cap_cmd_hdr *cmd, u8 *data)
+                                  struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                  u8 *data)
 {
        struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
        u16 scid, flags, result;
        struct l2cap_chan *chan;
-       int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
+       int len = cmd_len - sizeof(*rsp);
        int err = 0;
 
+       if (cmd_len < sizeof(*rsp))
+               return -EPROTO;
+
        scid   = __le16_to_cpu(rsp->scid);
        flags  = __le16_to_cpu(rsp->flags);
        result = __le16_to_cpu(rsp->result);
@@ -4161,7 +4179,8 @@ done:
 }
 
 static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
-                                      struct l2cap_cmd_hdr *cmd, u8 *data)
+                                      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                      u8 *data)
 {
        struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
        struct l2cap_disconn_rsp rsp;
@@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
        struct l2cap_chan *chan;
        struct sock *sk;
 
+       if (cmd_len != sizeof(*req))
+               return -EPROTO;
+
        scid = __le16_to_cpu(req->scid);
        dcid = __le16_to_cpu(req->dcid);
 
@@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
 }
 
 static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
-                                      struct l2cap_cmd_hdr *cmd, u8 *data)
+                                      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                      u8 *data)
 {
        struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
        u16 dcid, scid;
        struct l2cap_chan *chan;
 
+       if (cmd_len != sizeof(*rsp))
+               return -EPROTO;
+
        scid = __le16_to_cpu(rsp->scid);
        dcid = __le16_to_cpu(rsp->dcid);
 
@@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
 }
 
 static inline int l2cap_information_req(struct l2cap_conn *conn,
-                                       struct l2cap_cmd_hdr *cmd, u8 *data)
+                                       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                       u8 *data)
 {
        struct l2cap_info_req *req = (struct l2cap_info_req *) data;
        u16 type;
 
+       if (cmd_len != sizeof(*req))
+               return -EPROTO;
+
        type = __le16_to_cpu(req->type);
 
        BT_DBG("type 0x%4.4x", type);
@@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,
 }
 
 static inline int l2cap_information_rsp(struct l2cap_conn *conn,
-                                       struct l2cap_cmd_hdr *cmd, u8 *data)
+                                       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+                                       u8 *data)
 {
        struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
        u16 type, result;
 
+       if (cmd_len != sizeof(*rsp))
+               return -EPROTO;
+
        type   = __le16_to_cpu(rsp->type);
        result = __le16_to_cpu(rsp->result);
 
@@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
 
        switch (cmd->code) {
        case L2CAP_COMMAND_REJ:
-               l2cap_command_rej(conn, cmd, data);
+               l2cap_command_rej(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CONN_REQ:
-               err = l2cap_connect_req(conn, cmd, data);
+               err = l2cap_connect_req(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CONN_RSP:
        case L2CAP_CREATE_CHAN_RSP:
-               err = l2cap_connect_create_rsp(conn, cmd, data);
+               err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CONF_REQ:
@@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
                break;
 
        case L2CAP_CONF_RSP:
-               err = l2cap_config_rsp(conn, cmd, data);
+               err = l2cap_config_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_DISCONN_REQ:
-               err = l2cap_disconnect_req(conn, cmd, data);
+               err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_DISCONN_RSP:
-               err = l2cap_disconnect_rsp(conn, cmd, data);
+               err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_ECHO_REQ:
@@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
                break;
 
        case L2CAP_INFO_REQ:
-               err = l2cap_information_req(conn, cmd, data);
+               err = l2cap_information_req(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_INFO_RSP:
-               err = l2cap_information_rsp(conn, cmd, data);
+               err = l2cap_information_rsp(conn, cmd, cmd_len, data);
                break;
 
        case L2CAP_CREATE_CHAN_REQ:
index 35fef22..f8ecbc7 100644 (file)
@@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
                break;
 
        case DISCOV_TYPE_LE:
-               if (!lmp_host_le_capable(hdev)) {
+               if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
                        err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
                                         MGMT_STATUS_NOT_SUPPORTED);
                        mgmt_pending_remove(cmd);
@@ -3418,6 +3418,27 @@ new_settings:
        return err;
 }
 
+int mgmt_set_powered_failed(struct hci_dev *hdev, int err)
+{
+       struct pending_cmd *cmd;
+       u8 status;
+
+       cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
+       if (!cmd)
+               return -ENOENT;
+
+       if (err == -ERFKILL)
+               status = MGMT_STATUS_RFKILLED;
+       else
+               status = MGMT_STATUS_FAILED;
+
+       err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
+
+       mgmt_pending_remove(cmd);
+
+       return err;
+}
+
 int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
 {
        struct cmd_lookup match = { NULL, hdev };
index b2296d3..b5562ab 100644 (file)
@@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 
        BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
 
-       if (!lmp_host_le_capable(hcon->hdev))
+       if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
                return 1;
 
        if (sec_level == BT_SECURITY_LOW)
@@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
        __u8 reason;
        int err = 0;
 
-       if (!lmp_host_le_capable(conn->hcon->hdev)) {
+       if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) {
                err = -ENOTSUPP;
                reason = SMP_PAIRING_NOTSUPP;
                goto done;
index d5953b8..3a246a6 100644 (file)
@@ -1675,13 +1675,13 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
                __register_request(osdc, req);
                __unregister_linger_request(osdc, req);
        }
+       reset_changed_osds(osdc);
        mutex_unlock(&osdc->request_mutex);
 
        if (needmap) {
                dout("%d requests for down osds, need new map\n", needmap);
                ceph_monc_request_next_osdmap(&osdc->client->monc);
        }
-       reset_changed_osds(osdc);
 }
 
 
index 79ae884..f0a1ba6 100644 (file)
@@ -734,19 +734,25 @@ static unsigned char nas[21] = {
 
 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
 {
-       return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
                                    unsigned int vlen, unsigned int flags)
 {
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
        return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
                              flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
 {
-       return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
 asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags)
@@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
        int datagrams;
        struct timespec ktspec;
 
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+
        if (COMPAT_USE_64BIT_TIME)
                return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
                                      flags | MSG_CMSG_COMPAT,
index c013f38..6cda4e2 100644 (file)
@@ -39,6 +39,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
        ha->refcount = 1;
        ha->global_use = global;
        ha->synced = sync;
+       ha->sync_cnt = 0;
        list_add_tail_rcu(&ha->list, &list->list);
        list->count++;
 
@@ -66,7 +67,7 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
                        }
                        if (sync) {
                                if (ha->synced)
-                                       return 0;
+                                       return -EEXIST;
                                else
                                        ha->synced = true;
                        }
@@ -139,10 +140,13 @@ static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list,
 
        err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type,
                               false, true);
-       if (err)
+       if (err && err != -EEXIST)
                return err;
-       ha->sync_cnt++;
-       ha->refcount++;
+
+       if (!err) {
+               ha->sync_cnt++;
+               ha->refcount++;
+       }
 
        return 0;
 }
@@ -159,7 +163,8 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
        if (err)
                return;
        ha->sync_cnt--;
-       __hw_addr_del_entry(from_list, ha, false, true);
+       /* address on from list is not marked synced */
+       __hw_addr_del_entry(from_list, ha, false, false);
 }
 
 static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
@@ -796,7 +801,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from)
                return -EINVAL;
 
        netif_addr_lock_nested(to);
-       err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
+       err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len);
        if (!err)
                __dev_set_rx_mode(to);
        netif_addr_unlock(to);
index dad2a17..6438f29 100644 (file)
@@ -778,7 +778,7 @@ int sk_detach_filter(struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(sk_detach_filter);
 
-static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
+void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
 {
        static const u16 decodes[] = {
                [BPF_S_ALU_ADD_K]       = BPF_ALU|BPF_ADD|BPF_K,
index af9185d..cfd777b 100644 (file)
@@ -195,7 +195,7 @@ struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node)
         * the tail pointer in struct sk_buff!
         */
        memset(skb, 0, offsetof(struct sk_buff, tail));
-       skb->data = NULL;
+       skb->head = NULL;
        skb->truesize = sizeof(struct sk_buff);
        atomic_set(&skb->users, 1);
 
@@ -611,7 +611,7 @@ static void skb_release_head_state(struct sk_buff *skb)
 static void skb_release_all(struct sk_buff *skb)
 {
        skb_release_head_state(skb);
-       if (likely(skb->data))
+       if (likely(skb->head))
                skb_release_data(skb);
 }
 
index 6ba327d..88868a9 100644 (file)
@@ -210,7 +210,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
   "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
   "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG"      ,
-  "sk_lock-AF_NFC"   , "sk_lock-AF_MAX"
+  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_MAX"
 };
 static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
@@ -226,7 +226,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
   "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG"      ,
-  "slock-AF_NFC"   , "slock-AF_MAX"
+  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_MAX"
 };
 static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
@@ -242,7 +242,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
   "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
   "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG"      ,
-  "clock-AF_NFC"   , "clock-AF_MAX"
+  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_MAX"
 };
 
 /*
index d5bef0b..a0e9cf6 100644 (file)
@@ -73,8 +73,13 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
                goto out;
        }
 
-       if (filter)
-               memcpy(nla_data(attr), filter->insns, len);
+       if (filter) {
+               struct sock_filter *fb = (struct sock_filter *)nla_data(attr);
+               int i;
+
+               for (i = 0; i < filter->len; i++, fb++)
+                       sk_decode_filter(&filter->insns[i], fb);
+       }
 
 out:
        rcu_read_unlock();
index e4147ec..7fa8f08 100644 (file)
@@ -503,6 +503,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
 
+       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
        dst = tnl_params->daddr;
        if (dst == 0) {
                /* NBMA tunnel */
@@ -658,7 +659,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        skb_dst_drop(skb);
        skb_dst_set(skb, &rt->dst);
-       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 
        /* Push down and install the IP header. */
        skb_push(skb, sizeof(struct iphdr));
@@ -853,7 +853,7 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
 
-int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
+int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
                                  struct rtnl_link_ops *ops, char *devname)
 {
        struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
@@ -899,7 +899,7 @@ static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head)
                unregister_netdevice_queue(itn->fb_tunnel_dev, head);
 }
 
-void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn)
+void ip_tunnel_delete_net(struct ip_tunnel_net *itn)
 {
        LIST_HEAD(list);
 
index 9d2bdb2..c118f6b 100644 (file)
@@ -361,8 +361,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                        tunnel->err_count = 0;
        }
 
-       IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
-                             IPSKB_REROUTED);
+       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
        skb_dst_drop(skb);
        skb_dst_set(skb, &rt->dst);
        nf_reset(skb);
index cf08218..ff4b781 100644 (file)
@@ -231,8 +231,10 @@ static void ipt_ulog_packet(struct net *net,
        put_unaligned(tv.tv_usec, &pm->timestamp_usec);
        put_unaligned(skb->mark, &pm->mark);
        pm->hook = hooknum;
-       if (prefix != NULL)
-               strncpy(pm->prefix, prefix, sizeof(pm->prefix));
+       if (prefix != NULL) {
+               strncpy(pm->prefix, prefix, sizeof(pm->prefix) - 1);
+               pm->prefix[sizeof(pm->prefix) - 1] = '\0';
+       }
        else if (loginfo->prefix[0] != '\0')
                strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
        else
index 550781a..d35bbf0 100644 (file)
@@ -737,10 +737,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf
 {
        struct rtable *rt;
        struct flowi4 fl4;
+       const struct iphdr *iph = (const struct iphdr *) skb->data;
+       int oif = skb->dev->ifindex;
+       u8 tos = RT_TOS(iph->tos);
+       u8 prot = iph->protocol;
+       u32 mark = skb->mark;
 
        rt = (struct rtable *) dst;
 
-       ip_rt_build_flow_key(&fl4, sk, skb);
+       __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0);
        __ip_do_redirect(rt, skb, &fl4, true);
 }
 
index d1ab6ab..1bbf744 100644 (file)
@@ -1487,7 +1487,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
 }
 
 int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
-                 struct net_device *dev, int strict)
+                 const struct net_device *dev, int strict)
 {
        struct inet6_ifaddr *ifp;
        unsigned int hash = inet6_addr_hash(addr);
@@ -2658,8 +2658,10 @@ static void init_loopback(struct net_device *dev)
                        sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
 
                        /* Failure cases are ignored */
-                       if (!IS_ERR(sp_rt))
+                       if (!IS_ERR(sp_rt)) {
+                               sp_ifa->rt = sp_rt;
                                ip6_ins_rt(sp_rt);
+                       }
                }
                read_unlock_bh(&idev->lock);
        }
index 72836f4..95f3f1d 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/export.h>
+#include <net/addrconf.h>
 #include <net/dst.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
@@ -186,6 +187,10 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
        return csum;
 };
 
+static const struct nf_ipv6_ops ipv6ops = {
+       .chk_addr       = ipv6_chk_addr,
+};
+
 static const struct nf_afinfo nf_ip6_afinfo = {
        .family                 = AF_INET6,
        .checksum               = nf_ip6_checksum,
@@ -198,6 +203,7 @@ static const struct nf_afinfo nf_ip6_afinfo = {
 
 int __init ipv6_netfilter_init(void)
 {
+       RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops);
        return nf_register_afinfo(&nf_ip6_afinfo);
 }
 
@@ -206,5 +212,6 @@ int __init ipv6_netfilter_init(void)
  */
 void ipv6_netfilter_fini(void)
 {
+       RCU_INIT_POINTER(nf_ipv6_ops, NULL);
        nf_unregister_afinfo(&nf_ip6_afinfo);
 }
index f3c1ff4..51c3285 100644 (file)
@@ -90,7 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = {
        SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
        SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
        SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
-       SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
+       /* IPSTATS_MIB_CSUMERRORS is not relevant in IPv6 (no checksum) */
        SNMP_MIB_SENTINEL
 };
 
index 3bb3a89..d3cfaf9 100644 (file)
@@ -46,11 +46,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        unsigned int mss;
        unsigned int unfrag_ip6hlen, unfrag_len;
        struct frag_hdr *fptr;
-       u8 *mac_start, *prevhdr;
+       u8 *packet_start, *prevhdr;
        u8 nexthdr;
        u8 frag_hdr_sz = sizeof(struct frag_hdr);
        int offset;
        __wsum csum;
+       int tnl_hlen;
 
        mss = skb_shinfo(skb)->gso_size;
        if (unlikely(skb->len <= mss))
@@ -83,9 +84,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        skb->ip_summed = CHECKSUM_NONE;
 
        /* Check if there is enough headroom to insert fragment header. */
-       if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) &&
-           pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC))
-               goto out;
+       tnl_hlen = skb_tnl_header_len(skb);
+       if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) {
+               if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
+                       goto out;
+       }
 
        /* Find the unfragmentable header and shift it left by frag_hdr_sz
         * bytes to insert fragment header.
@@ -93,11 +96,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
        nexthdr = *prevhdr;
        *prevhdr = NEXTHDR_FRAGMENT;
-       unfrag_len = skb_network_header(skb) - skb_mac_header(skb) +
-                    unfrag_ip6hlen;
-       mac_start = skb_mac_header(skb);
-       memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len);
+       unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) +
+                    unfrag_ip6hlen + tnl_hlen;
+       packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset;
+       memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len);
 
+       SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz;
        skb->mac_header -= frag_hdr_sz;
        skb->network_header -= frag_hdr_sz;
 
index 5b1e5af..c5fbd75 100644 (file)
@@ -2366,6 +2366,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
 
 out:
        xfrm_pol_put(xp);
+       if (err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
@@ -2615,6 +2617,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_
 
 out:
        xfrm_pol_put(xp);
+       if (delete && err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
index 637a341..8dec687 100644 (file)
@@ -346,19 +346,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
        skb_put(skb, 2);
 
        /* Copy user data into skb */
-       error = memcpy_fromiovec(skb->data, m->msg_iov, total_len);
+       error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov,
+                                total_len);
        if (error < 0) {
                kfree_skb(skb);
                goto error_put_sess_tun;
        }
-       skb_put(skb, total_len);
 
        l2tp_xmit_skb(session, skb, session->hdr_len);
 
        sock_put(ps->tunnel_sock);
        sock_put(sk);
 
-       return error;
+       return total_len;
 
 error_put_sess_tun:
        sock_put(ps->tunnel_sock);
index 60f1ce5..98d20c0 100644 (file)
@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
+static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_sub_if_data *iter;
        u64 new, mask, tmp;
        u8 *m;
        int ret = 0;
@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
 
 
        mutex_lock(&local->iflist_mtx);
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+       list_for_each_entry(iter, &local->interfaces, list) {
+               if (iter == sdata)
+                       continue;
+
+               if (iter->vif.type == NL80211_IFTYPE_MONITOR)
                        continue;
 
-               m = sdata->vif.addr;
+               m = iter->vif.addr;
                tmp =   ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
                        ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                        ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
        if (ieee80211_sdata_running(sdata))
                return -EBUSY;
 
-       ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
+       ret = ieee80211_verify_mac(sdata, sa->sa_data);
        if (ret)
                return ret;
 
@@ -474,6 +478,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                        master->control_port_protocol;
                sdata->control_port_no_encrypt =
                        master->control_port_no_encrypt;
+               sdata->vif.cab_queue = master->vif.cab_queue;
+               memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
+                      sizeof(sdata->vif.hw_queue));
                break;
                }
        case NL80211_IFTYPE_AP:
@@ -653,7 +660,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 
        ieee80211_recalc_ps(local, -1);
 
-       if (dev) {
+       if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+           sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+               /* XXX: for AP_VLAN, actually track AP queues */
+               netif_tx_start_all_queues(dev);
+       } else if (dev) {
                unsigned long flags;
                int n_acs = IEEE80211_NUM_ACS;
                int ac;
@@ -1479,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
                        break;
                }
 
+               /*
+                * Pick address of existing interface in case user changed
+                * MAC address manually, default to perm_addr.
+                */
                m = local->hw.wiphy->perm_addr;
+               list_for_each_entry(sdata, &local->interfaces, list) {
+                       if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+                               continue;
+                       m = sdata->vif.addr;
+                       break;
+               }
                start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
                        ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                        ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
@@ -1696,6 +1717,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
 
        ASSERT_RTNL();
 
+       /*
+        * Close all AP_VLAN interfaces first, as otherwise they
+        * might be closed while the AP interface they belong to
+        * is closed, causing unregister_netdevice_many() to crash.
+        */
+       list_for_each_entry(sdata, &local->interfaces, list)
+               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       dev_close(sdata->dev);
+
        mutex_lock(&local->iflist_mtx);
        list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
                list_del(&sdata->list);
index a46e490..a8c2130 100644 (file)
@@ -3321,10 +3321,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
        if (WARN_ON_ONCE(!auth_data))
                return -EINVAL;
 
-       if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
-               tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
-                          IEEE80211_TX_INTFL_MLME_CONN_TX;
-
        auth_data->tries++;
 
        if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -3358,6 +3354,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
                        auth_data->expected_transaction = trans;
                }
 
+               if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+                       tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
+                                  IEEE80211_TX_INTFL_MLME_CONN_TX;
+
                ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
                                    auth_data->data, auth_data->data_len,
                                    auth_data->bss->bssid,
@@ -3381,12 +3381,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
                 * will not answer to direct packet in unassociated state.
                 */
                ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
-                                        NULL, 0, (u32) -1, true, tx_flags,
+                                        NULL, 0, (u32) -1, true, 0,
                                         auth_data->bss->channel, false);
                rcu_read_unlock();
        }
 
-       if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
+       if (tx_flags == 0) {
                auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
                ifmgd->auth_data->timeout_started = true;
                run_again(ifmgd, auth_data->timeout);
index 07c865a..857ca9f 100644 (file)
@@ -30,6 +30,8 @@ static DEFINE_MUTEX(afinfo_mutex);
 
 const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
 EXPORT_SYMBOL(nf_afinfo);
+const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly;
+EXPORT_SYMBOL_GPL(nf_ipv6_ops);
 
 int nf_register_afinfo(const struct nf_afinfo *afinfo)
 {
index 085b588..05565d2 100644 (file)
@@ -1001,6 +1001,32 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
        return th->rst;
 }
 
+static inline bool is_new_conn(const struct sk_buff *skb,
+                              struct ip_vs_iphdr *iph)
+{
+       switch (iph->protocol) {
+       case IPPROTO_TCP: {
+               struct tcphdr _tcph, *th;
+
+               th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph);
+               if (th == NULL)
+                       return false;
+               return th->syn;
+       }
+       case IPPROTO_SCTP: {
+               sctp_chunkhdr_t *sch, schunk;
+
+               sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t),
+                                        sizeof(schunk), &schunk);
+               if (sch == NULL)
+                       return false;
+               return sch->type == SCTP_CID_INIT;
+       }
+       default:
+               return false;
+       }
+}
+
 /* Handle response packets: rewrite addresses and send away...
  */
 static unsigned int
@@ -1612,6 +1638,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
         * Check if the packet belongs to an existing connection entry
         */
        cp = pp->conn_in_get(af, skb, &iph, 0);
+
+       if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp && cp->dest &&
+           unlikely(!atomic_read(&cp->dest->weight)) && !iph.fragoffs &&
+           is_new_conn(skb, &iph)) {
+               ip_vs_conn_expire_now(cp);
+               __ip_vs_conn_put(cp);
+               cp = NULL;
+       }
+
        if (unlikely(!cp) && !iph.fragoffs) {
                /* No (second) fragments need to enter here, as nf_defrag_ipv6
                 * replayed fragment zero will already have created the cp
index 5b142fb..9e6c2a0 100644 (file)
@@ -2542,6 +2542,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get,
                struct ip_vs_dest *dest;
                struct ip_vs_dest_entry entry;
 
+               memset(&entry, 0, sizeof(entry));
                list_for_each_entry(dest, &svc->destinations, n_list) {
                        if (count >= get->num_dests)
                                break;
index 0df269d..a65edfe 100644 (file)
@@ -67,8 +67,8 @@ struct ip_vs_sh_bucket {
 #define IP_VS_SH_TAB_MASK               (IP_VS_SH_TAB_SIZE - 1)
 
 struct ip_vs_sh_state {
-       struct ip_vs_sh_bucket          buckets[IP_VS_SH_TAB_SIZE];
        struct rcu_head                 rcu_head;
+       struct ip_vs_sh_bucket          buckets[IP_VS_SH_TAB_SIZE];
 };
 
 /*
index dc3fd5d..c7b6d46 100644 (file)
@@ -149,9 +149,12 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
        rcu_read_lock();
        list_for_each_entry_rcu(cur, &nfnl_acct_list, head) {
-               if (last && cur != last)
-                       continue;
+               if (last) {
+                       if (cur != last)
+                               continue;
 
+                       last = NULL;
+               }
                if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                       cb->nlh->nlmsg_seq,
                                       NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
index 701c88a..65074df 100644 (file)
@@ -220,9 +220,12 @@ ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
        rcu_read_lock();
        list_for_each_entry_rcu(cur, &cttimeout_list, head) {
-               if (last && cur != last)
-                       continue;
+               if (last) {
+                       if (cur != last)
+                               continue;
 
+                       last = NULL;
+               }
                if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid,
                                           cb->nlh->nlmsg_seq,
                                           NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
index 4e27fa0..5352b2d 100644 (file)
@@ -637,9 +637,6 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
        if (queue->copy_mode == NFQNL_COPY_NONE)
                return -EINVAL;
 
-       if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(entry->skb))
-               return __nfqnl_enqueue_packet(net, queue, entry);
-
        skb = entry->skb;
 
        switch (entry->pf) {
@@ -651,6 +648,9 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
                break;
        }
 
+       if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(skb))
+               return __nfqnl_enqueue_packet(net, queue, entry);
+
        nf_bridge_adjust_skb_data(skb);
        segs = skb_gso_segment(skb, 0);
        /* Does not use PTR_ERR to limit the number of error codes that can be
index 491c7d8..5ab2484 100644 (file)
@@ -737,7 +737,7 @@ static void dump_ipv6_packet(struct sbuff *m,
                dump_sk_uid_gid(m, skb->sk);
 
        /* Max length: 16 "MARK=0xFFFFFFFF " */
-       if (!recurse && skb->mark)
+       if (recurse && skb->mark)
                sb_add(m, "MARK=0x%x ", skb->mark);
 }
 
index a75240f..afaebc7 100644 (file)
@@ -125,6 +125,12 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 
        skb_put(skb, TCPOLEN_MSS);
 
+       /* RFC 879 states that the default MSS is 536 without specific
+        * knowledge that the destination host is prepared to accept larger.
+        * Since no MSS was provided, we MUST NOT set a value > 536.
+        */
+       newmss = min(newmss, (u16)536);
+
        opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
        memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
 
index 49c5ff7..68ff29f 100644 (file)
@@ -22,6 +22,7 @@
 #include <net/ip6_fib.h>
 #endif
 
+#include <linux/netfilter_ipv6.h>
 #include <linux/netfilter/xt_addrtype.h>
 #include <linux/netfilter/x_tables.h>
 
@@ -33,12 +34,12 @@ MODULE_ALIAS("ip6t_addrtype");
 
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
 static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
-                           const struct in6_addr *addr)
+                           const struct in6_addr *addr, u16 mask)
 {
        const struct nf_afinfo *afinfo;
        struct flowi6 flow;
        struct rt6_info *rt;
-       u32 ret;
+       u32 ret = 0;
        int route_err;
 
        memset(&flow, 0, sizeof(flow));
@@ -49,12 +50,19 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
        rcu_read_lock();
 
        afinfo = nf_get_afinfo(NFPROTO_IPV6);
-       if (afinfo != NULL)
+       if (afinfo != NULL) {
+               const struct nf_ipv6_ops *v6ops;
+
+               if (dev && (mask & XT_ADDRTYPE_LOCAL)) {
+                       v6ops = nf_get_ipv6_ops();
+                       if (v6ops && v6ops->chk_addr(net, addr, dev, true))
+                               ret = XT_ADDRTYPE_LOCAL;
+               }
                route_err = afinfo->route(net, (struct dst_entry **)&rt,
-                                       flowi6_to_flowi(&flow), !!dev);
-       else
+                                         flowi6_to_flowi(&flow), false);
+       } else {
                route_err = 1;
-
+       }
        rcu_read_unlock();
 
        if (route_err)
@@ -62,15 +70,12 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
 
        if (rt->rt6i_flags & RTF_REJECT)
                ret = XT_ADDRTYPE_UNREACHABLE;
-       else
-               ret = 0;
 
-       if (rt->rt6i_flags & RTF_LOCAL)
+       if (dev == NULL && rt->rt6i_flags & RTF_LOCAL)
                ret |= XT_ADDRTYPE_LOCAL;
        if (rt->rt6i_flags & RTF_ANYCAST)
                ret |= XT_ADDRTYPE_ANYCAST;
 
-
        dst_release(&rt->dst);
        return ret;
 }
@@ -90,7 +95,7 @@ static bool match_type6(struct net *net, const struct net_device *dev,
 
        if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |
             XT_ADDRTYPE_UNREACHABLE) & mask)
-               return !!(mask & match_lookup_rt6(net, dev, addr));
+               return !!(mask & match_lookup_rt6(net, dev, addr, mask));
        return true;
 }
 
index 12ac6b4..57ee84d 100644 (file)
@@ -371,7 +371,7 @@ static int netlink_mmap(struct file *file, struct socket *sock,
        err = 0;
 out:
        mutex_unlock(&nlk->pg_vec_lock);
-       return 0;
+       return err;
 }
 
 static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr)
@@ -747,7 +747,7 @@ static void netlink_skb_destructor(struct sk_buff *skb)
                atomic_dec(&ring->pending);
                sock_put(sk);
 
-               skb->data = NULL;
+               skb->head = NULL;
        }
 #endif
        if (skb->sk != NULL)
index fb799de..a76f453 100644 (file)
@@ -5,7 +5,6 @@
 obj-$(CONFIG_NFC) += nfc.o
 obj-$(CONFIG_NFC_NCI) += nci/
 obj-$(CONFIG_NFC_HCI) += hci/
-#obj-$(CONFIG_NFC_LLCP) += llcp/
 
 nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
                llcp_sock.o
index 8ec1bca..20a1bd0 100644 (file)
@@ -2851,12 +2851,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
                return -EOPNOTSUPP;
 
        uaddr->sa_family = AF_PACKET;
+       memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data));
        rcu_read_lock();
        dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
        if (dev)
-               strncpy(uaddr->sa_data, dev->name, 14);
-       else
-               memset(uaddr->sa_data, 0, 14);
+               strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data));
        rcu_read_unlock();
        *uaddr_len = sizeof(*uaddr);
 
index 823463a..189e3c5 100644 (file)
@@ -231,14 +231,14 @@ override:
        }
        if (R_tab) {
                police->rate_present = true;
-               psched_ratecfg_precompute(&police->rate, R_tab->rate.rate);
+               psched_ratecfg_precompute(&police->rate, &R_tab->rate);
                qdisc_put_rtab(R_tab);
        } else {
                police->rate_present = false;
        }
        if (P_tab) {
                police->peak_present = true;
-               psched_ratecfg_precompute(&police->peak, P_tab->rate.rate);
+               psched_ratecfg_precompute(&police->peak, &P_tab->rate);
                qdisc_put_rtab(P_tab);
        } else {
                police->peak_present = false;
@@ -376,9 +376,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
        };
 
        if (police->rate_present)
-               opt.rate.rate = psched_ratecfg_getrate(&police->rate);
+               psched_ratecfg_getrate(&opt.rate, &police->rate);
        if (police->peak_present)
-               opt.peakrate.rate = psched_ratecfg_getrate(&police->peak);
+               psched_ratecfg_getrate(&opt.peakrate, &police->peak);
        if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
                goto nla_put_failure;
        if (police->tcfp_result &&
index 2b935e7..281c1bd 100644 (file)
@@ -291,17 +291,18 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *ta
 {
        struct qdisc_rate_table *rtab;
 
+       if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
+           nla_len(tab) != TC_RTAB_SIZE)
+               return NULL;
+
        for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
-               if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) {
+               if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
+                   !memcmp(&rtab->data, nla_data(tab), 1024)) {
                        rtab->refcnt++;
                        return rtab;
                }
        }
 
-       if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
-           nla_len(tab) != TC_RTAB_SIZE)
-               return NULL;
-
        rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
        if (rtab) {
                rtab->rate = *r;
index eac7e0e..2022408 100644 (file)
@@ -898,14 +898,16 @@ void dev_shutdown(struct net_device *dev)
        WARN_ON(timer_pending(&dev->watchdog_timer));
 }
 
-void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate)
+void psched_ratecfg_precompute(struct psched_ratecfg *r,
+                              const struct tc_ratespec *conf)
 {
        u64 factor;
        u64 mult;
        int shift;
 
-       r->rate_bps = (u64)rate << 3;
-       r->shift = 0;
+       memset(r, 0, sizeof(*r));
+       r->overhead = conf->overhead;
+       r->rate_bps = (u64)conf->rate << 3;
        r->mult = 1;
        /*
         * Calibrate mult, shift so that token counting is accurate
index 79b1876..adaedd7 100644 (file)
@@ -109,7 +109,7 @@ struct htb_class {
        } un;
        struct rb_node node[TC_HTB_NUMPRIO];    /* node for self or feed tree */
        struct rb_node pq_node; /* node for event queue */
-       psched_time_t pq_key;
+       s64     pq_key;
 
        int prio_activity;      /* for which prios are we active */
        enum htb_cmode cmode;   /* current mode of the class */
@@ -121,10 +121,10 @@ struct htb_class {
        /* token bucket parameters */
        struct psched_ratecfg rate;
        struct psched_ratecfg ceil;
-       s64 buffer, cbuffer;    /* token bucket depth/rate */
-       psched_tdiff_t mbuffer; /* max wait time */
-       s64 tokens, ctokens;    /* current number of tokens */
-       psched_time_t t_c;      /* checkpoint time */
+       s64     buffer, cbuffer;        /* token bucket depth/rate */
+       s64     mbuffer;                /* max wait time */
+       s64     tokens, ctokens;        /* current number of tokens */
+       s64     t_c;                    /* checkpoint time */
 };
 
 struct htb_sched {
@@ -141,15 +141,15 @@ struct htb_sched {
        struct rb_root wait_pq[TC_HTB_MAXDEPTH];
 
        /* time of nearest event per level (row) */
-       psched_time_t near_ev_cache[TC_HTB_MAXDEPTH];
+       s64     near_ev_cache[TC_HTB_MAXDEPTH];
 
        int defcls;             /* class where unclassified flows go to */
 
        /* filters for qdisc itself */
        struct tcf_proto *filter_list;
 
-       int rate2quantum;       /* quant = rate / rate2quantum */
-       psched_time_t now;      /* cached dequeue time */
+       int     rate2quantum;   /* quant = rate / rate2quantum */
+       s64     now;    /* cached dequeue time */
        struct qdisc_watchdog watchdog;
 
        /* non shaped skbs; let them go directly thru */
@@ -664,8 +664,8 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
  * next pending event (0 for no event in pq, q->now for too many events).
  * Note: Applied are events whose have cl->pq_key <= q->now.
  */
-static psched_time_t htb_do_events(struct htb_sched *q, int level,
-                                  unsigned long start)
+static s64 htb_do_events(struct htb_sched *q, int level,
+                        unsigned long start)
 {
        /* don't run for longer than 2 jiffies; 2 is used instead of
         * 1 to simplify things when jiffy is going to be incremented
@@ -857,7 +857,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
        struct sk_buff *skb;
        struct htb_sched *q = qdisc_priv(sch);
        int level;
-       psched_time_t next_event;
+       s64 next_event;
        unsigned long start_at;
 
        /* try to dequeue direct packets as high prio (!) to minimize cpu work */
@@ -880,7 +880,7 @@ ok:
        for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
                /* common case optimization - skip event handler quickly */
                int m;
-               psched_time_t event;
+               s64 event;
 
                if (q->now >= q->near_ev_cache[level]) {
                        event = htb_do_events(q, level, start_at);
@@ -1090,9 +1090,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
 
        memset(&opt, 0, sizeof(opt));
 
-       opt.rate.rate = psched_ratecfg_getrate(&cl->rate);
+       psched_ratecfg_getrate(&opt.rate, &cl->rate);
        opt.buffer = PSCHED_NS2TICKS(cl->buffer);
-       opt.ceil.rate = psched_ratecfg_getrate(&cl->ceil);
+       psched_ratecfg_getrate(&opt.ceil, &cl->ceil);
        opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer);
        opt.quantum = cl->quantum;
        opt.prio = cl->prio;
@@ -1117,8 +1117,8 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
 
        if (!cl->level && cl->un.leaf.q)
                cl->qstats.qlen = cl->un.leaf.q->q.qlen;
-       cl->xstats.tokens = cl->tokens;
-       cl->xstats.ctokens = cl->ctokens;
+       cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens);
+       cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens);
 
        if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
            gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 ||
@@ -1200,7 +1200,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
        parent->un.leaf.q = new_q ? new_q : &noop_qdisc;
        parent->tokens = parent->buffer;
        parent->ctokens = parent->cbuffer;
-       parent->t_c = psched_get_time();
+       parent->t_c = ktime_to_ns(ktime_get());
        parent->cmode = HTB_CAN_SEND;
 }
 
@@ -1417,8 +1417,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                /* set class to be in HTB_CAN_SEND state */
                cl->tokens = PSCHED_TICKS2NS(hopt->buffer);
                cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer);
-               cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC;        /* 1min */
-               cl->t_c = psched_get_time();
+               cl->mbuffer = 60ULL * NSEC_PER_SEC;     /* 1min */
+               cl->t_c = ktime_to_ns(ktime_get());
                cl->cmode = HTB_CAN_SEND;
 
                /* attach to the hash list and parent's family */
@@ -1459,8 +1459,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                        cl->prio = TC_HTB_NUMPRIO - 1;
        }
 
-       psched_ratecfg_precompute(&cl->rate, hopt->rate.rate);
-       psched_ratecfg_precompute(&cl->ceil, hopt->ceil.rate);
+       psched_ratecfg_precompute(&cl->rate, &hopt->rate);
+       psched_ratecfg_precompute(&cl->ceil, &hopt->ceil);
 
        cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
        cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer);
index c8388f3..e478d31 100644 (file)
@@ -298,9 +298,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
        q->tokens = q->buffer;
        q->ptokens = q->mtu;
 
-       psched_ratecfg_precompute(&q->rate, rtab->rate.rate);
+       psched_ratecfg_precompute(&q->rate, &rtab->rate);
        if (ptab) {
-               psched_ratecfg_precompute(&q->peak, ptab->rate.rate);
+               psched_ratecfg_precompute(&q->peak, &ptab->rate);
                q->peak_present = true;
        } else {
                q->peak_present = false;
@@ -350,9 +350,9 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
                goto nla_put_failure;
 
        opt.limit = q->limit;
-       opt.rate.rate = psched_ratecfg_getrate(&q->rate);
+       psched_ratecfg_getrate(&opt.rate, &q->rate);
        if (q->peak_present)
-               opt.peakrate.rate = psched_ratecfg_getrate(&q->peak);
+               psched_ratecfg_getrate(&opt.peakrate, &q->peak);
        else
                memset(&opt.peakrate, 0, sizeof(opt.peakrate));
        opt.mtu = PSCHED_NS2TICKS(q->mtu);
index 32a4625..be35e2d 100644 (file)
@@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
  */
 void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
 {
+       memset(q, 0, sizeof(struct sctp_outq));
+
        q->asoc = asoc;
        INIT_LIST_HEAD(&q->out_chunk_list);
        INIT_LIST_HEAD(&q->control_chunk_list);
@@ -213,11 +215,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
        INIT_LIST_HEAD(&q->sacked);
        INIT_LIST_HEAD(&q->abandoned);
 
-       q->fast_rtx = 0;
-       q->outstanding_bytes = 0;
        q->empty = 1;
-       q->cork  = 0;
-       q->out_qlen = 0;
 }
 
 /* Free the outqueue structure and any related pending chunks.
index f631c5f..6abb1ca 100644 (file)
@@ -4003,6 +4003,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
 
        /* Release our hold on the endpoint. */
        sp = sctp_sk(sk);
+       /* This could happen during socket init, thus we bail out
+        * early, since the rest of the below is not setup either.
+        */
+       if (sp->ep == NULL)
+               return;
+
        if (sp->do_auto_asconf) {
                sp->do_auto_asconf = 0;
                list_del(&sp->auto_asconf_list);
index 6b94633..4ca1526 100644 (file)
@@ -1956,7 +1956,7 @@ struct used_address {
        unsigned int name_len;
 };
 
-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned int flags,
                         struct used_address *used_address)
 {
@@ -2071,22 +2071,30 @@ out:
  *     BSD sendmsg interface
  */
 
-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
+long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
-       struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
+       struct socket *sock;
 
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
+       err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
 
        fput_light(sock->file, fput_needed);
 out:
        return err;
 }
 
+SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
+{
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_sendmsg(fd, msg, flags);
+}
+
 /*
  *     Linux sendmmsg interface
  */
@@ -2117,15 +2125,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 
        while (datagrams < vlen) {
                if (MSG_CMSG_COMPAT & flags) {
-                       err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags, &used_address);
+                       err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
+                                            &msg_sys, flags, &used_address);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
-                       err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags, &used_address);
+                       err = ___sys_sendmsg(sock,
+                                            (struct msghdr __user *)entry,
+                                            &msg_sys, flags, &used_address);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@ -2149,10 +2158,12 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
                unsigned int, vlen, unsigned int, flags)
 {
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
        return __sys_sendmmsg(fd, mmsg, vlen, flags);
 }
 
-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned int flags, int nosec)
 {
        struct compat_msghdr __user *msg_compat =
@@ -2244,23 +2255,31 @@ out:
  *     BSD recvmsg interface
  */
 
-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
-               unsigned int, flags)
+long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
 {
        int fput_needed, err;
        struct msghdr msg_sys;
-       struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
+       struct socket *sock;
 
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
                goto out;
 
-       err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
+       err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
 
        fput_light(sock->file, fput_needed);
 out:
        return err;
 }
 
+SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
+               unsigned int, flags)
+{
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+       return __sys_recvmsg(fd, msg, flags);
+}
+
 /*
  *     Linux recvmmsg interface
  */
@@ -2298,17 +2317,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
                 * No need to ask LSM for more than the first datagram.
                 */
                if (MSG_CMSG_COMPAT & flags) {
-                       err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags & ~MSG_WAITFORONE,
-                                           datagrams);
+                       err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
+                                            &msg_sys, flags & ~MSG_WAITFORONE,
+                                            datagrams);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
-                       err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags & ~MSG_WAITFORONE,
-                                           datagrams);
+                       err = ___sys_recvmsg(sock,
+                                            (struct msghdr __user *)entry,
+                                            &msg_sys, flags & ~MSG_WAITFORONE,
+                                            datagrams);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@ -2375,6 +2395,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
        int datagrams;
        struct timespec timeout_sys;
 
+       if (flags & MSG_CMSG_COMPAT)
+               return -EINVAL;
+
        if (!timeout)
                return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
 
index 871c73c..29b4ba9 100644 (file)
@@ -1287,7 +1287,7 @@ static bool use_gss_proxy(struct net *net)
 
 #ifdef CONFIG_PROC_FS
 
-static bool set_gss_proxy(struct net *net, int type)
+static int set_gss_proxy(struct net *net, int type)
 {
        struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
        int ret = 0;
@@ -1317,10 +1317,12 @@ static inline bool gssp_ready(struct sunrpc_net *sn)
        return false;
 }
 
-static int wait_for_gss_proxy(struct net *net)
+static int wait_for_gss_proxy(struct net *net, struct file *file)
 {
        struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
+       if (file->f_flags & O_NONBLOCK && !gssp_ready(sn))
+               return -EAGAIN;
        return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn));
 }
 
@@ -1362,7 +1364,7 @@ static ssize_t read_gssp(struct file *file, char __user *buf,
        size_t len;
        int ret;
 
-       ret = wait_for_gss_proxy(net);
+       ret = wait_for_gss_proxy(net, file);
        if (ret)
                return ret;
 
index c3f9e1e..06bdf5a 100644 (file)
@@ -810,11 +810,15 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
                goto badcred;
        argv->iov_base = (void*)((__be32*)argv->iov_base + slen);       /* skip machname */
        argv->iov_len -= slen*4;
-
+       /*
+        * Note: we skip uid_valid()/gid_valid() checks here for
+        * backwards compatibility with clients that use -1 id's.
+        * Instead, -1 uid or gid is later mapped to the
+        * (export-specific) anonymous id by nfsd_setuser.
+        * Supplementary gid's will be left alone.
+        */
        cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
        cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
-       if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid))
-               goto badcred;
        slen = svc_getnl(argv);                 /* gids length */
        if (slen > 16 || (len -= (slen + 2)*4) < 0)
                goto badcred;
@@ -823,8 +827,6 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
                return SVC_CLOSE;
        for (i = 0; i < slen; i++) {
                kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv));
-               if (!gid_valid(kgid))
-                       goto badcred;
                GROUP_AT(cred->cr_group_info, i) = kgid;
        }
        if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
index dfdb5e6..d5aed3b 100644 (file)
@@ -3411,7 +3411,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
                        (u32)sinfo->rx_bytes))
                goto nla_put_failure;
        if ((sinfo->filled & (STATION_INFO_TX_BYTES |
-                             NL80211_STA_INFO_TX_BYTES64)) &&
+                             STATION_INFO_TX_BYTES64)) &&
            nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
                        (u32)sinfo->tx_bytes))
                goto nla_put_failure;
index 8b5eddf..3ed35c3 100644 (file)
@@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work)
        mutex_lock(&rdev->sched_scan_mtx);
 
        list_for_each_entry(wdev, &rdev->wdev_list, list) {
+               if (!wdev->netdev)
+                       continue;
+
                wdev_lock(wdev);
                if (!netif_running(wdev->netdev)) {
                        wdev_unlock(wdev);
index 23cea0f..ea970b8 100644 (file)
@@ -2557,11 +2557,12 @@ static void __xfrm_garbage_collect(struct net *net)
        }
 }
 
-static void xfrm_garbage_collect(struct net *net)
+void xfrm_garbage_collect(struct net *net)
 {
        flow_cache_flush();
        __xfrm_garbage_collect(net);
 }
+EXPORT_SYMBOL(xfrm_garbage_collect);
 
 static void xfrm_garbage_collect_deferred(struct net *net)
 {
index aa77874..3f565e4 100644 (file)
@@ -1681,6 +1681,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 out:
        xfrm_pol_put(xp);
+       if (delete && err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
index 51bb3de..f97869f 100644 (file)
@@ -149,7 +149,7 @@ cpp_flags      = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 
 ld_flags       = $(LDFLAGS) $(ldflags-y)
 
-dtc_cpp_flags  = -Wp,-MD,$(depfile).pre -nostdinc                        \
+dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc                    \
                 -I$(srctree)/arch/$(SRCARCH)/boot/dts                   \
                 -I$(srctree)/arch/$(SRCARCH)/boot/dts/include           \
                 -undef -D__DTS__
@@ -264,14 +264,14 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
 quiet_cmd_dtc = DTC     $@
 cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
        $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
-               -i $(srctree)/arch/$(SRCARCH)/boot/dts $(DTC_FLAGS) \
-               -d $(depfile).dtc $(dtc-tmp) ; \
-       cat $(depfile).pre $(depfile).dtc > $(depfile)
+               -i $(dir $<) $(DTC_FLAGS) \
+               -d $(depfile).dtc.tmp $(dtc-tmp) ; \
+       cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
 $(obj)/%.dtb: $(src)/%.dts FORCE
        $(call if_changed_dep,dtc)
 
-dtc-tmp = $(subst $(comma),_,$(dot-target).dts)
+dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
 
 # Bzip2
 # ---------------------------------------------------------------------------
index bb4d3de..a65ecbb 100755 (executable)
@@ -105,7 +105,7 @@ while [ "$1" != "" ] ; do
                ;;
        --refresh)
                ;;
-       --*-after)
+       --*-after|-E|-D|-M)
                checkarg "$1"
                A=$ARG
                checkarg "$2"
index 254d5af..3b41bfc 100644 (file)
@@ -71,7 +71,7 @@ static int pop_input_file(void);
                        push_input_file(name);
                }
 
-<*>^"#"(line)?{WS}+[0-9]+{WS}+{STRING}({WS}+[0-9]+)? {
+<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
                        char *line, *tmp, *fn;
                        /* skip text before line # */
                        line = yytext;
index a6c5fcd..2d30f41 100644 (file)
@@ -405,19 +405,19 @@ static yyconst flex_int16_t yy_accept[161] =
 static yyconst flex_int32_t yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
+        4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    4,    5,    6,    1,    1,    7,    8,    1,
-        1,    9,   10,   10,   11,   10,   12,   13,   14,   15,
-       15,   15,   15,   15,   15,   15,   15,   16,    1,   17,
-       18,   19,   10,   10,   20,   20,   20,   20,   20,   20,
-       21,   21,   21,   21,   21,   22,   21,   21,   21,   21,
-       21,   21,   21,   21,   23,   21,   21,   24,   21,   21,
-        1,   25,   26,    1,   21,    1,   20,   27,   28,   29,
-
-       30,   20,   21,   21,   31,   21,   21,   32,   33,   34,
-       35,   36,   21,   37,   38,   39,   40,   41,   21,   24,
-       42,   21,   43,   44,   45,    1,    1,    1,    1,    1,
+        1,    2,    5,    6,    7,    1,    1,    8,    9,    1,
+        1,   10,   11,   11,   12,   11,   13,   14,   15,   16,
+       16,   16,   16,   16,   16,   16,   16,   17,    1,   18,
+       19,   20,   11,   11,   21,   21,   21,   21,   21,   21,
+       22,   22,   22,   22,   22,   23,   22,   22,   22,   22,
+       22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
+        1,   26,   27,    1,   22,    1,   21,   28,   29,   30,
+
+       31,   21,   22,   22,   32,   22,   22,   33,   34,   35,
+       36,   37,   22,   38,   39,   40,   41,   42,   22,   25,
+       43,   22,   44,   45,   46,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -434,36 +434,36 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[46] =
+static yyconst flex_int32_t yy_meta[47] =
     {   0,
-        1,    1,    1,    1,    1,    2,    3,    1,    2,    2,
-        2,    4,    5,    5,    5,    6,    1,    1,    1,    7,
-        8,    8,    8,    8,    1,    1,    7,    7,    7,    7,
-        8,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    3,    1,    1
+        1,    1,    1,    1,    1,    1,    2,    3,    1,    2,
+        2,    2,    4,    5,    5,    5,    6,    1,    1,    1,
+        7,    8,    8,    8,    8,    1,    1,    7,    7,    7,
+        7,    8,    8,    8,    8,    8,    8,    8,    8,    8,
+        8,    8,    8,    3,    1,    1
     } ;
 
 static yyconst flex_int16_t yy_base[175] =
     {   0,
-        0,  388,  381,   40,   41,  386,   71,  385,   34,   44,
-      390,  395,   60,   62,  371,  112,  111,  111,  111,  104,
-      370,  106,  371,  342,  124,  119,    0,  144,  395,    0,
-      123,    0,  159,  153,  165,  167,  395,  130,  395,  382,
-      395,    0,  372,  122,  395,  157,  374,  379,  350,   21,
-      346,  349,  395,  395,  395,  395,  395,  362,  395,  395,
-      181,  346,  342,  395,  359,    0,  191,  343,  190,  351,
-      350,    0,    0,    0,  173,  362,  177,  367,  357,  329,
-      335,  328,  337,  331,  206,  329,  334,  327,  395,  338,
-      170,  314,  346,  345,  318,  325,  343,  158,  316,  212,
-
-      322,  319,  320,  395,  340,  336,  308,  305,  314,  304,
-      295,  138,  208,  220,  395,  292,  305,  265,  264,  254,
-      201,  222,  285,  275,  273,  270,  236,  235,  225,  115,
-      395,  395,  252,  216,  216,  217,  214,  230,  209,  220,
-      213,  239,  211,  217,  216,  209,  229,  395,  240,  225,
-      206,  169,  395,  395,  116,  106,   99,   54,  395,  395,
-      254,  260,  268,  272,  276,  282,  289,  293,  301,  309,
-      313,  319,  327,  335
+        0,  385,  378,   40,   41,  383,   72,  382,   34,   44,
+      388,  393,   61,  117,  368,  116,  115,  115,  115,   48,
+      367,  107,  368,  339,  127,  120,    0,  147,  393,    0,
+      127,    0,  133,  156,  168,  153,  393,  125,  393,  380,
+      393,    0,  369,  127,  393,  160,  371,  377,  347,   21,
+      343,  346,  393,  393,  393,  393,  393,  359,  393,  393,
+      183,  343,  339,  393,  356,    0,  183,  340,  187,  348,
+      347,    0,    0,    0,  178,  359,  195,  365,  354,  326,
+      332,  325,  334,  328,  204,  326,  331,  324,  393,  335,
+      150,  311,  343,  342,  315,  322,  340,  179,  313,  207,
+
+      319,  316,  317,  393,  337,  333,  305,  302,  311,  301,
+      310,  190,  338,  337,  393,  307,  322,  301,  305,  277,
+      208,  311,  307,  278,  271,  270,  248,  246,  213,  130,
+      393,  393,  263,  235,  207,  221,  218,  229,  213,  213,
+      206,  234,  218,  210,  208,  193,  219,  393,  223,  204,
+      176,  157,  393,  393,  120,  106,   97,  119,  393,  393,
+      245,  251,  259,  263,  267,  273,  280,  284,  292,  300,
+      304,  310,  318,  326
     } ;
 
 static yyconst flex_int16_t yy_def[175] =
@@ -489,108 +489,108 @@ static yyconst flex_int16_t yy_def[175] =
       160,  160,  160,  160
     } ;
 
-static yyconst flex_int16_t yy_nxt[441] =
+static yyconst flex_int16_t yy_nxt[440] =
     {   0,
-       12,   13,   14,   15,   16,   12,   17,   18,   12,   12,
-       12,   19,   12,   12,   12,   12,   20,   21,   22,   23,
-       23,   23,   23,   23,   12,   12,   23,   23,   23,   23,
+       12,   13,   14,   13,   15,   16,   12,   17,   18,   12,
+       12,   12,   19,   12,   12,   12,   12,   20,   21,   22,
+       23,   23,   23,   23,   23,   12,   12,   23,   23,   23,
        23,   23,   23,   23,   23,   23,   23,   23,   23,   23,
-       23,   23,   12,   24,   12,   25,   34,   35,   35,   25,
-       81,   26,   26,   27,   27,   27,   34,   35,   35,   82,
-       28,   36,   36,   36,   36,  159,   29,   28,   28,   28,
-       28,   12,   13,   14,   15,   16,   30,   17,   18,   30,
-       30,   30,   26,   30,   30,   30,   12,   20,   21,   22,
-       31,   31,   31,   31,   31,   32,   12,   31,   31,   31,
+       23,   23,   23,   12,   24,   12,   25,   34,   35,   35,
+       25,   81,   26,   26,   27,   27,   27,   34,   35,   35,
+       82,   28,   36,   36,   36,   53,   54,   29,   28,   28,
+       28,   28,   12,   13,   14,   13,   15,   16,   30,   17,
+       18,   30,   30,   30,   26,   30,   30,   30,   12,   20,
+       21,   22,   31,   31,   31,   31,   31,   32,   12,   31,
 
        31,   31,   31,   31,   31,   31,   31,   31,   31,   31,
-       31,   31,   31,   12,   24,   12,   39,   41,   45,   47,
-       53,   54,   48,   56,   57,   61,   61,   47,   66,   45,
-       48,   66,   66,   66,   39,   46,   40,   49,   59,   50,
-      158,   51,  122,   52,  157,   49,   46,   50,  136,   63,
-      137,   52,  156,   43,   40,   62,   65,   65,   65,   59,
-       61,   61,  123,   65,   75,   69,   69,   69,   36,   36,
-       65,   65,   65,   65,   70,   71,   72,   69,   69,   69,
-       45,   46,   61,   61,  109,   77,   70,   71,   93,  110,
-       68,   70,   71,   85,   85,   85,   66,   46,  155,   66,
-
-       66,   66,   69,   69,   69,  122,   59,  100,  100,   61,
-       61,   70,   71,  100,  100,  148,  112,  154,   85,   85,
-       85,   61,   61,  129,  129,  123,  129,  129,  135,  135,
-      135,  142,  142,  148,  143,  149,  153,  135,  135,  135,
-      142,  142,  160,  143,  152,  151,  150,  146,  145,  144,
-      141,  140,  139,  149,   38,   38,   38,   38,   38,   38,
-       38,   38,   42,  138,  134,  133,   42,   42,   44,   44,
-       44,   44,   44,   44,   44,   44,   58,   58,   58,   58,
-       64,  132,   64,   66,  131,  130,   66,  160,   66,   66,
-       67,  128,  127,   67,   67,   67,   67,   73,  126,   73,
-
-       73,   76,   76,   76,   76,   76,   76,   76,   76,   78,
-       78,   78,   78,   78,   78,   78,   78,   91,  125,   91,
-       92,  124,   92,   92,  120,   92,   92,  121,  121,  121,
-      121,  121,  121,  121,  121,  147,  147,  147,  147,  147,
-      147,  147,  147,  119,  118,  117,  116,  115,   47,  114,
-      110,  113,  111,  108,  107,  106,   48,  105,  104,   89,
-      103,  102,  101,   99,   98,   97,   96,   95,   94,   79,
-       77,   90,   89,   88,   59,   87,   86,   59,   84,   83,
-       80,   79,   77,   74,  160,   60,   59,   55,   37,  160,
-       33,   25,   26,   25,   11,  160,  160,  160,  160,  160,
+       31,   31,   31,   31,   31,   12,   24,   12,   36,   36,
+       36,   39,   41,   45,   47,   56,   57,   48,   61,   47,
+       39,  159,   48,   66,   61,   45,   66,   66,   66,  158,
+       46,   40,   49,   59,   50,  157,   51,   49,   52,   50,
+       40,   63,   46,   52,   36,   36,   36,  156,   43,   62,
+       65,   65,   65,   59,  136,   68,  137,   65,   75,   69,
+       69,   69,   70,   71,   65,   65,   65,   65,   70,   71,
+       72,   69,   69,   69,   61,   46,   45,  155,  154,   66,
+       70,   71,   66,   66,   66,  122,   85,   85,   85,   59,
+
+       69,   69,   69,   46,   77,  100,  109,   93,  100,   70,
+       71,  110,  112,  122,  129,  123,  153,   85,   85,   85,
+      135,  135,  135,  148,  148,  160,  135,  135,  135,  152,
+      142,  142,  142,  123,  143,  142,  142,  142,  151,  143,
+      150,  146,  145,  149,  149,   38,   38,   38,   38,   38,
+       38,   38,   38,   42,  144,  141,  140,   42,   42,   44,
+       44,   44,   44,   44,   44,   44,   44,   58,   58,   58,
+       58,   64,  139,   64,   66,  138,  134,   66,  133,   66,
+       66,   67,  132,  131,   67,   67,   67,   67,   73,  130,
+       73,   73,   76,   76,   76,   76,   76,   76,   76,   76,
+
+       78,   78,   78,   78,   78,   78,   78,   78,   91,  160,
+       91,   92,  129,   92,   92,  128,   92,   92,  121,  121,
+      121,  121,  121,  121,  121,  121,  147,  147,  147,  147,
+      147,  147,  147,  147,  127,  126,  125,  124,   61,   61,
+      120,  119,  118,  117,  116,  115,   47,  114,  110,  113,
+      111,  108,  107,  106,   48,  105,  104,   89,  103,  102,
+      101,   99,   98,   97,   96,   95,   94,   79,   77,   90,
+       89,   88,   59,   87,   86,   59,   84,   83,   80,   79,
+       77,   74,  160,   60,   59,   55,   37,  160,   33,   25,
+       26,   25,   11,  160,  160,  160,  160,  160,  160,  160,
 
       160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
       160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
       160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160
+      160,  160,  160,  160,  160,  160,  160,  160,  160
     } ;
 
-static yyconst flex_int16_t yy_chk[441] =
+static yyconst flex_int16_t yy_chk[440] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    4,    9,    9,    9,   10,
-       50,    4,    5,    5,    5,    5,   10,   10,   10,   50,
-        5,   13,   13,   14,   14,  158,    5,    5,    5,    5,
-        5,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        1,    1,    1,    1,    1,    1,    4,    9,    9,    9,
+       10,   50,    4,    5,    5,    5,    5,   10,   10,   10,
+       50,    5,   13,   13,   13,   20,   20,    5,    5,    5,
+        5,    5,    7,    7,    7,    7,    7,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
 
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    7,    7,    7,    7,    7,   16,   17,   18,   19,
-       20,   20,   19,   22,   22,   25,   25,   26,   31,   44,
-       26,   31,   31,   31,   38,   18,   16,   19,   31,   19,
-      157,   19,  112,   19,  156,   26,   44,   26,  130,   26,
-      130,   26,  155,   17,   38,   25,   28,   28,   28,   28,
-       33,   33,  112,   28,   46,   34,   34,   34,   36,   36,
-       28,   28,   28,   28,   34,   34,   34,   35,   35,   35,
-       75,   46,   61,   61,   98,   77,   35,   35,   77,   98,
-       33,   91,   91,   61,   61,   61,   67,   75,  152,   67,
-
-       67,   67,   69,   69,   69,  121,   67,   85,   85,  113,
-      113,   69,   69,  100,  100,  143,  100,  151,   85,   85,
-       85,  114,  114,  122,  122,  121,  129,  129,  135,  135,
-      135,  138,  138,  147,  138,  143,  150,  129,  129,  129,
-      142,  142,  149,  142,  146,  145,  144,  141,  140,  139,
-      137,  136,  134,  147,  161,  161,  161,  161,  161,  161,
-      161,  161,  162,  133,  128,  127,  162,  162,  163,  163,
-      163,  163,  163,  163,  163,  163,  164,  164,  164,  164,
-      165,  126,  165,  166,  125,  124,  166,  123,  166,  166,
-      167,  120,  119,  167,  167,  167,  167,  168,  118,  168,
-
-      168,  169,  169,  169,  169,  169,  169,  169,  169,  170,
-      170,  170,  170,  170,  170,  170,  170,  171,  117,  171,
-      172,  116,  172,  172,  111,  172,  172,  173,  173,  173,
-      173,  173,  173,  173,  173,  174,  174,  174,  174,  174,
-      174,  174,  174,  110,  109,  108,  107,  106,  105,  103,
-      102,  101,   99,   97,   96,   95,   94,   93,   92,   90,
-       88,   87,   86,   84,   83,   82,   81,   80,   79,   78,
-       76,   71,   70,   68,   65,   63,   62,   58,   52,   51,
-       49,   48,   47,   43,   40,   24,   23,   21,   15,   11,
-        8,    6,    3,    2,  160,  160,  160,  160,  160,  160,
+        7,    7,    7,    7,    7,    7,    7,    7,   14,   14,
+       14,   16,   17,   18,   19,   22,   22,   19,   25,   26,
+       38,  158,   26,   31,   33,   44,   31,   31,   31,  157,
+       18,   16,   19,   31,   19,  156,   19,   26,   19,   26,
+       38,   26,   44,   26,   36,   36,   36,  155,   17,   25,
+       28,   28,   28,   28,  130,   33,  130,   28,   46,   34,
+       34,   34,   91,   91,   28,   28,   28,   28,   34,   34,
+       34,   35,   35,   35,   61,   46,   75,  152,  151,   67,
+       35,   35,   67,   67,   67,  112,   61,   61,   61,   67,
+
+       69,   69,   69,   75,   77,   85,   98,   77,  100,   69,
+       69,   98,  100,  121,  129,  112,  150,   85,   85,   85,
+      135,  135,  135,  143,  147,  149,  129,  129,  129,  146,
+      138,  138,  138,  121,  138,  142,  142,  142,  145,  142,
+      144,  141,  140,  143,  147,  161,  161,  161,  161,  161,
+      161,  161,  161,  162,  139,  137,  136,  162,  162,  163,
+      163,  163,  163,  163,  163,  163,  163,  164,  164,  164,
+      164,  165,  134,  165,  166,  133,  128,  166,  127,  166,
+      166,  167,  126,  125,  167,  167,  167,  167,  168,  124,
+      168,  168,  169,  169,  169,  169,  169,  169,  169,  169,
+
+      170,  170,  170,  170,  170,  170,  170,  170,  171,  123,
+      171,  172,  122,  172,  172,  120,  172,  172,  173,  173,
+      173,  173,  173,  173,  173,  173,  174,  174,  174,  174,
+      174,  174,  174,  174,  119,  118,  117,  116,  114,  113,
+      111,  110,  109,  108,  107,  106,  105,  103,  102,  101,
+       99,   97,   96,   95,   94,   93,   92,   90,   88,   87,
+       86,   84,   83,   82,   81,   80,   79,   78,   76,   71,
+       70,   68,   65,   63,   62,   58,   52,   51,   49,   48,
+       47,   43,   40,   24,   23,   21,   15,   11,    8,    6,
+        3,    2,  160,  160,  160,  160,  160,  160,  160,  160,
 
       160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
       160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
       160,  160,  160,  160,  160,  160,  160,  160,  160,  160,
-      160,  160,  160,  160,  160,  160,  160,  160,  160,  160
+      160,  160,  160,  160,  160,  160,  160,  160,  160
     } ;
 
 static yy_state_type yy_last_accepting_state;
index 4af5590..ee1d8c3 100644 (file)
@@ -1,10 +1,8 @@
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "2.5"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,7 +65,7 @@
 
 /* Copy the first part of user declarations.  */
 
-/* Line 189 of yacc.c  */
+/* Line 268 of yacc.c  */
 #line 21 "dtc-parser.y"
 
 #include <stdio.h>
@@ -88,8 +86,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
 static unsigned char eval_char_literal(const char *s);
 
 
-/* Line 189 of yacc.c  */
-#line 93 "dtc-parser.tab.c"
+/* Line 268 of yacc.c  */
+#line 91 "dtc-parser.tab.c"
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
@@ -147,7 +145,7 @@ static unsigned char eval_char_literal(const char *s);
 typedef union YYSTYPE
 {
 
-/* Line 214 of yacc.c  */
+/* Line 293 of yacc.c  */
 #line 40 "dtc-parser.y"
 
        char *propnodename;
@@ -171,8 +169,8 @@ typedef union YYSTYPE
 
 
 
-/* Line 214 of yacc.c  */
-#line 176 "dtc-parser.tab.c"
+/* Line 293 of yacc.c  */
+#line 174 "dtc-parser.tab.c"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -183,8 +181,8 @@ typedef union YYSTYPE
 /* Copy the second part of user declarations.  */
 
 
-/* Line 264 of yacc.c  */
-#line 188 "dtc-parser.tab.c"
+/* Line 343 of yacc.c  */
+#line 186 "dtc-parser.tab.c"
 
 #ifdef short
 # undef short
@@ -234,7 +232,7 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -287,11 +285,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -314,24 +312,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
             && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -360,23 +358,7 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)             \
-      do                                       \
-       {                                       \
-         YYSIZE_T yyi;                         \
-         for (yyi = 0; yyi < (Count); yyi++)   \
-           (To)[yyi] = (From)[yyi];            \
-       }                                       \
-      while (YYID (0))
-#  endif
-# endif
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
@@ -396,6 +378,26 @@ union yyalloc
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  4
 /* YYLAST -- Last index in YYTABLE.  */
@@ -571,8 +573,8 @@ static const yytype_uint8 yyr2[] =
        2,     0,     2,     2,     0,     2,     2,     2,     3,     2
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
@@ -633,8 +635,7 @@ static const yytype_int8 yypgoto[] =
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
@@ -654,6 +655,12 @@ static const yytype_uint8 yytable[] =
      137,     0,    73,   139
 };
 
+#define yypact_value_is_default(yystate) \
+  ((yystate) == (-78))
+
+#define yytable_value_is_error(yytable_value) \
+  YYID (0)
+
 static const yytype_int16 yycheck[] =
 {
        5,    38,    39,    17,    18,    19,    12,    12,    17,    18,
@@ -705,9 +712,18 @@ static const yytype_uint8 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
 
 #define YYFAIL         goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
@@ -717,7 +733,6 @@ do                                                          \
     {                                                          \
       yychar = (Token);                                                \
       yylval = (Value);                                                \
-      yytoken = YYTRANSLATE (yychar);                          \
       YYPOPSTACK (1);                                          \
       goto yybackup;                                           \
     }                                                          \
@@ -759,19 +774,10 @@ while (YYID (0))
 #endif
 
 
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
+/* This macro is provided for backward compatibility. */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)                 \
-     fprintf (File, "%d.%d-%d.%d",                     \
-             (Loc).first_line, (Loc).first_column,     \
-             (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 #endif
 
 
@@ -963,7 +969,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-\f
 
 #if YYERROR_VERBOSE
 
@@ -1066,115 +1071,142 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  YYSIZE_T yysize1;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = 0;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
     {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-        constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-                   + sizeof yyexpecting - 1
-                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-                      * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-        YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-         {
-           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-             {
-               yycount = 1;
-               yysize = yysize0;
-               yyformat[sizeof yyunexpected - 1] = '\0';
-               break;
-             }
-           yyarg[yycount++] = yytname[yyx];
-           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-           yysize_overflow |= (yysize1 < yysize);
-           yysize = yysize1;
-           yyfmt = yystpcpy (yyfmt, yyprefix);
-           yyprefix = yyor;
-         }
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+                if (! (yysize <= yysize1
+                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  return 2;
+                yysize = yysize1;
+              }
+        }
+    }
 
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
 
-      if (yysize_overflow)
-       return YYSIZE_MAXIMUM;
+  yysize1 = yysize + yystrlen (yyformat);
+  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    return 2;
+  yysize = yysize1;
 
-      if (yyresult)
-       {
-         /* Avoid sprintf, as that infringes on the user's name space.
-            Don't have undefined behavior even if the translation
-            produced a string with the wrong number of "%s"s.  */
-         char *yyp = yyresult;
-         int yyi = 0;
-         while ((*yyp = *yyf) != '\0')
-           {
-             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-               {
-                 yyp += yytnamerr (yyp, yyarg[yyi++]);
-                 yyf += 2;
-               }
-             else
-               {
-                 yyp++;
-                 yyf++;
-               }
-           }
-       }
-      return yysize;
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-\f
 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1207,6 +1239,7 @@ yydestruct (yymsg, yytype, yyvaluep)
     }
 }
 
+
 /* Prevent warnings from -Wmissing-prototypes.  */
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
@@ -1233,10 +1266,9 @@ YYSTYPE yylval;
 int yynerrs;
 
 
-
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
+/*----------.
+| yyparse.  |
+`----------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1260,8 +1292,6 @@ yyparse ()
 #endif
 #endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
@@ -1416,7 +1446,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1447,8 +1477,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-       goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1503,72 +1533,72 @@ yyreduce:
     {
         case 2:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 110 "dtc-parser.y"
     {
                        the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node),
                                                        guess_boot_cpuid((yyvsp[(4) - (4)].node)));
-               ;}
+               }
     break;
 
   case 3:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 118 "dtc-parser.y"
     {
                        (yyval.re) = NULL;
-               ;}
+               }
     break;
 
   case 4:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 122 "dtc-parser.y"
     {
                        (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
-               ;}
+               }
     break;
 
   case 5:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 129 "dtc-parser.y"
     {
                        (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer));
-               ;}
+               }
     break;
 
   case 6:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 133 "dtc-parser.y"
     {
                        add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref));
                        (yyval.re) = (yyvsp[(2) - (2)].re);
-               ;}
+               }
     break;
 
   case 7:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 141 "dtc-parser.y"
     {
                        (yyval.node) = name_node((yyvsp[(2) - (2)].node), "");
-               ;}
+               }
     break;
 
   case 8:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 145 "dtc-parser.y"
     {
                        (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
-               ;}
+               }
     break;
 
   case 9:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 149 "dtc-parser.y"
     {
                        struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref));
@@ -1578,12 +1608,12 @@ yyreduce:
                        else
                                print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref));
                        (yyval.node) = (yyvsp[(1) - (3)].node);
-               ;}
+               }
     break;
 
   case 10:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 159 "dtc-parser.y"
     {
                        struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref));
@@ -1594,112 +1624,112 @@ yyreduce:
                                delete_node(target);
 
                        (yyval.node) = (yyvsp[(1) - (4)].node);
-               ;}
+               }
     break;
 
   case 11:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 173 "dtc-parser.y"
     {
                        (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
-               ;}
+               }
     break;
 
   case 12:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 180 "dtc-parser.y"
     {
                        (yyval.proplist) = NULL;
-               ;}
+               }
     break;
 
   case 13:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 184 "dtc-parser.y"
     {
                        (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
-               ;}
+               }
     break;
 
   case 14:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 191 "dtc-parser.y"
     {
                        (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data));
-               ;}
+               }
     break;
 
   case 15:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 195 "dtc-parser.y"
     {
                        (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data);
-               ;}
+               }
     break;
 
   case 16:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 199 "dtc-parser.y"
     {
                        (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename));
-               ;}
+               }
     break;
 
   case 17:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 203 "dtc-parser.y"
     {
                        add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref));
                        (yyval.prop) = (yyvsp[(2) - (2)].prop);
-               ;}
+               }
     break;
 
   case 18:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 211 "dtc-parser.y"
     {
                        (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
-               ;}
+               }
     break;
 
   case 19:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 215 "dtc-parser.y"
     {
                        (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data);
-               ;}
+               }
     break;
 
   case 20:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 219 "dtc-parser.y"
     {
                        (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
-               ;}
+               }
     break;
 
   case 21:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 223 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
-               ;}
+               }
     break;
 
   case 22:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 227 "dtc-parser.y"
     {
                        FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL);
@@ -1716,12 +1746,12 @@ yyreduce:
 
                        (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
                        fclose(f);
-               ;}
+               }
     break;
 
   case 23:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 244 "dtc-parser.y"
     {
                        FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL);
@@ -1731,48 +1761,48 @@ yyreduce:
 
                        (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d);
                        fclose(f);
-               ;}
+               }
     break;
 
   case 24:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 254 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-               ;}
+               }
     break;
 
   case 25:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 261 "dtc-parser.y"
     {
                        (yyval.data) = empty_data;
-               ;}
+               }
     break;
 
   case 26:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 265 "dtc-parser.y"
     {
                        (yyval.data) = (yyvsp[(1) - (2)].data);
-               ;}
+               }
     break;
 
   case 27:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 269 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-               ;}
+               }
     break;
 
   case 28:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 276 "dtc-parser.y"
     {
                        (yyval.array).data = empty_data;
@@ -1787,22 +1817,22 @@ yyreduce:
                                            " are currently supported");
                                (yyval.array).bits = 32;
                        }
-               ;}
+               }
     break;
 
   case 29:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 291 "dtc-parser.y"
     {
                        (yyval.array).data = empty_data;
                        (yyval.array).bits = 32;
-               ;}
+               }
     break;
 
   case 30:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 296 "dtc-parser.y"
     {
                        if ((yyvsp[(1) - (2)].array).bits < 64) {
@@ -1822,12 +1852,12 @@ yyreduce:
                        }
 
                        (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits);
-               ;}
+               }
     break;
 
   case 31:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 316 "dtc-parser.y"
     {
                        uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits);
@@ -1841,288 +1871,299 @@ yyreduce:
                                            "arrays with 32-bit elements.");
 
                        (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits);
-               ;}
+               }
     break;
 
   case 32:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 330 "dtc-parser.y"
     {
                        (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref));
-               ;}
+               }
     break;
 
   case 33:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 337 "dtc-parser.y"
     {
                        (yyval.integer) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
-               ;}
+               }
     break;
 
   case 34:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 341 "dtc-parser.y"
     {
                        (yyval.integer) = eval_char_literal((yyvsp[(1) - (1)].literal));
-               ;}
+               }
     break;
 
   case 35:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 345 "dtc-parser.y"
     {
                        (yyval.integer) = (yyvsp[(2) - (3)].integer);
-               ;}
+               }
     break;
 
   case 38:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 356 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); }
     break;
 
   case 40:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 361 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); }
     break;
 
   case 42:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 366 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); }
     break;
 
   case 44:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 371 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); }
     break;
 
   case 46:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 376 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); }
     break;
 
   case 48:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 381 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); }
     break;
 
   case 50:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 386 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); }
     break;
 
   case 51:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 387 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); }
     break;
 
   case 53:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 392 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); }
     break;
 
   case 54:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 393 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); }
     break;
 
   case 55:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 394 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); }
     break;
 
   case 56:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 395 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); }
     break;
 
   case 57:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 399 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); }
     break;
 
   case 58:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 400 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); }
     break;
 
   case 60:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 405 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); }
     break;
 
   case 61:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 406 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); }
     break;
 
   case 63:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 411 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); }
     break;
 
   case 64:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 412 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); }
     break;
 
   case 65:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 413 "dtc-parser.y"
-    { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); ;}
+    { (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); }
     break;
 
   case 68:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 419 "dtc-parser.y"
-    { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
+    { (yyval.integer) = -(yyvsp[(2) - (2)].integer); }
     break;
 
   case 69:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 420 "dtc-parser.y"
-    { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); ;}
+    { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); }
     break;
 
   case 70:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 421 "dtc-parser.y"
-    { (yyval.integer) = !(yyvsp[(2) - (2)].integer); ;}
+    { (yyval.integer) = !(yyvsp[(2) - (2)].integer); }
     break;
 
   case 71:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 426 "dtc-parser.y"
     {
                        (yyval.data) = empty_data;
-               ;}
+               }
     break;
 
   case 72:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 430 "dtc-parser.y"
     {
                        (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
-               ;}
+               }
     break;
 
   case 73:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 434 "dtc-parser.y"
     {
                        (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
-               ;}
+               }
     break;
 
   case 74:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 441 "dtc-parser.y"
     {
                        (yyval.nodelist) = NULL;
-               ;}
+               }
     break;
 
   case 75:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 445 "dtc-parser.y"
     {
                        (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
-               ;}
+               }
     break;
 
   case 76:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 449 "dtc-parser.y"
     {
                        print_error("syntax error: properties must precede subnodes");
                        YYERROR;
-               ;}
+               }
     break;
 
   case 77:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 457 "dtc-parser.y"
     {
                        (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename));
-               ;}
+               }
     break;
 
   case 78:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 461 "dtc-parser.y"
     {
                        (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename));
-               ;}
+               }
     break;
 
   case 79:
 
-/* Line 1455 of yacc.c  */
+/* Line 1806 of yacc.c  */
 #line 465 "dtc-parser.y"
     {
                        add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref));
                        (yyval.node) = (yyvsp[(2) - (2)].node);
-               ;}
+               }
     break;
 
 
 
-/* Line 1455 of yacc.c  */
-#line 2124 "dtc-parser.tab.c"
+/* Line 1806 of yacc.c  */
+#line 2154 "dtc-parser.tab.c"
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -2150,6 +2191,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -2157,37 +2202,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-         {
-           YYSIZE_T yyalloc = 2 * yysize;
-           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-             yyalloc = YYSTACK_ALLOC_MAXIMUM;
-           if (yymsg != yymsgbuf)
-             YYSTACK_FREE (yymsg);
-           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-           if (yymsg)
-             yymsg_alloc = yyalloc;
-           else
-             {
-               yymsg = yymsgbuf;
-               yymsg_alloc = sizeof yymsgbuf;
-             }
-         }
-
-       if (0 < yysize && yysize <= yymsg_alloc)
-         {
-           (void) yysyntax_error (yymsg, yystate, yychar);
-           yyerror (yymsg);
-         }
-       else
-         {
-           yyerror (YY_("syntax error"));
-           if (yysize != 0)
-             goto yyexhaustedlab;
-         }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -2246,7 +2290,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
        {
          yyn += YYTERROR;
          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -2305,8 +2349,13 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-                yytoken, &yylval);
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -2331,7 +2380,7 @@ yyreturn:
 
 
 
-/* Line 1675 of yacc.c  */
+/* Line 2067 of yacc.c  */
 #line 471 "dtc-parser.y"
 
 
index 9d2dce4..25d3b88 100644 (file)
@@ -1,10 +1,8 @@
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* Bison interface for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -70,7 +68,7 @@
 typedef union YYSTYPE
 {
 
-/* Line 1676 of yacc.c  */
+/* Line 2068 of yacc.c  */
 #line 40 "dtc-parser.y"
 
        char *propnodename;
@@ -94,8 +92,8 @@ typedef union YYSTYPE
 
 
 
-/* Line 1676 of yacc.c  */
-#line 99 "dtc-parser.tab.h"
+/* Line 2068 of yacc.c  */
+#line 97 "dtc-parser.tab.h"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
index 48d382e..38cd69c 100644 (file)
@@ -303,10 +303,11 @@ do_resize:
                                }
                }
 
-               if (i < max_choice ||
-                   key == KEY_UP || key == KEY_DOWN ||
-                   key == '-' || key == '+' ||
-                   key == KEY_PPAGE || key == KEY_NPAGE) {
+               if (item_count() != 0 &&
+                   (i < max_choice ||
+                    key == KEY_UP || key == KEY_DOWN ||
+                    key == '-' || key == '+' ||
+                    key == KEY_PPAGE || key == KEY_NPAGE)) {
                        /* Remove highligt of current item */
                        print_item(scroll + choice, choice, FALSE);
 
index 387dc8d..a69cbd7 100644 (file)
@@ -670,11 +670,12 @@ static void conf(struct menu *menu, struct menu *active_menu)
                                  active_menu, &s_scroll);
                if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
                        break;
-               if (!item_activate_selected())
-                       continue;
-               if (!item_tag())
-                       continue;
-
+               if (item_count() != 0) {
+                       if (!item_activate_selected())
+                               continue;
+                       if (!item_tag())
+                               continue;
+               }
                submenu = item_data();
                active_menu = item_data();
                if (submenu)
index b5c7d90..fd3f018 100644 (file)
@@ -146,11 +146,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
                        struct menu *menu = current_entry;
 
                        while ((menu = menu->parent) != NULL) {
+                               struct expr *dup_expr;
+
                                if (!menu->visibility)
                                        continue;
+                               /*
+                                * Do not add a reference to the
+                                * menu's visibility expression but
+                                * use a copy of it.  Otherwise the
+                                * expression reduction functions
+                                * will modify expressions that have
+                                * multiple references which can
+                                * cause unwanted side effects.
+                                */
+                               dup_expr = expr_copy(menu->visibility);
+
                                prop->visible.expr
                                        = expr_alloc_and(prop->visible.expr,
-                                                        menu->visibility);
+                                                        dup_expr);
                        }
                }
 
index 8ab2951..d030818 100644 (file)
@@ -316,6 +316,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
 
                memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
                memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
+               atomic_inc(&selinux_xfrm_refcount);
                *new_ctxp = new_ctx;
        }
        return 0;
@@ -326,6 +327,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
  */
 void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 {
+       atomic_dec(&selinux_xfrm_refcount);
        kfree(ctx);
 }
 
@@ -335,17 +337,13 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
 {
        const struct task_security_struct *tsec = current_security();
-       int rc = 0;
 
-       if (ctx) {
-               rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
-                                 SECCLASS_ASSOCIATION,
-                                 ASSOCIATION__SETCONTEXT, NULL);
-               if (rc == 0)
-                       atomic_dec(&selinux_xfrm_refcount);
-       }
+       if (!ctx)
+               return 0;
 
-       return rc;
+       return avc_has_perm(tsec->sid, ctx->ctx_sid,
+                           SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
+                           NULL);
 }
 
 /*
@@ -370,8 +368,8 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
  */
 void selinux_xfrm_state_free(struct xfrm_state *x)
 {
-       struct xfrm_sec_ctx *ctx = x->security;
-       kfree(ctx);
+       atomic_dec(&selinux_xfrm_refcount);
+       kfree(x->security);
 }
 
  /*
@@ -381,17 +379,13 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
 {
        const struct task_security_struct *tsec = current_security();
        struct xfrm_sec_ctx *ctx = x->security;
-       int rc = 0;
 
-       if (ctx) {
-               rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
-                                 SECCLASS_ASSOCIATION,
-                                 ASSOCIATION__SETCONTEXT, NULL);
-               if (rc == 0)
-                       atomic_dec(&selinux_xfrm_refcount);
-       }
+       if (!ctx)
+               return 0;
 
-       return rc;
+       return avc_has_perm(tsec->sid, ctx->ctx_sid,
+                           SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
+                           NULL);
 }
 
 /*
index ccfa383..f928181 100644 (file)
@@ -1649,6 +1649,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
        }
        if (!snd_pcm_stream_linked(substream)) {
                substream->group = group;
+               group = NULL;
                spin_lock_init(&substream->group->lock);
                INIT_LIST_HEAD(&substream->group->substreams);
                list_add_tail(&substream->link_list, &substream->group->substreams);
@@ -1663,8 +1664,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
  _nolock:
        snd_card_unref(substream1->pcm->card);
        fput_light(file, fput_needed);
-       if (res < 0)
-               kfree(group);
+       kfree(group);
        return res;
 }
 
index ae85bbd..4b1524a 100644 (file)
@@ -788,6 +788,8 @@ static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable)
                return;
        if (codec->inv_eapd)
                enable = !enable;
+       if (spec->keep_eapd_on && !enable)
+               return;
        snd_hda_codec_update_cache(codec, pin, 0,
                                   AC_VERB_SET_EAPD_BTLENABLE,
                                   enable ? 0x02 : 0x00);
@@ -1938,17 +1940,7 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
  * independent HP controls
  */
 
-/* update HP auto-mute state too */
-static void update_hp_automute_hook(struct hda_codec *codec)
-{
-       struct hda_gen_spec *spec = codec->spec;
-
-       if (spec->hp_automute_hook)
-               spec->hp_automute_hook(codec, NULL);
-       else
-               snd_hda_gen_hp_automute(codec, NULL);
-}
-
+static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack);
 static int indep_hp_info(struct snd_kcontrol *kcontrol,
                         struct snd_ctl_elem_info *uinfo)
 {
@@ -2009,7 +2001,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol,
                else
                        *dacp = spec->alt_dac_nid;
 
-               update_hp_automute_hook(codec);
+               call_hp_automute(codec, NULL);
                ret = 1;
        }
  unlock:
@@ -2305,7 +2297,7 @@ static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force)
                else
                        val = PIN_HP;
                set_pin_target(codec, pin, val, true);
-               update_hp_automute_hook(codec);
+               call_hp_automute(codec, NULL);
        }
 }
 
@@ -2714,7 +2706,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol,
                        val = snd_hda_get_default_vref(codec, nid);
        }
        snd_hda_set_pin_ctl_cache(codec, nid, val);
-       update_hp_automute_hook(codec);
+       call_hp_automute(codec, NULL);
 
        return 1;
 }
@@ -3859,20 +3851,42 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
 }
 EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch);
 
-/* update jack retasking */
-static void update_automute_all(struct hda_codec *codec)
+/* call appropriate hooks */
+static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
        struct hda_gen_spec *spec = codec->spec;
+       if (spec->hp_automute_hook)
+               spec->hp_automute_hook(codec, jack);
+       else
+               snd_hda_gen_hp_automute(codec, jack);
+}
 
-       update_hp_automute_hook(codec);
+static void call_line_automute(struct hda_codec *codec,
+                              struct hda_jack_tbl *jack)
+{
+       struct hda_gen_spec *spec = codec->spec;
        if (spec->line_automute_hook)
-               spec->line_automute_hook(codec, NULL);
+               spec->line_automute_hook(codec, jack);
        else
-               snd_hda_gen_line_automute(codec, NULL);
+               snd_hda_gen_line_automute(codec, jack);
+}
+
+static void call_mic_autoswitch(struct hda_codec *codec,
+                               struct hda_jack_tbl *jack)
+{
+       struct hda_gen_spec *spec = codec->spec;
        if (spec->mic_autoswitch_hook)
-               spec->mic_autoswitch_hook(codec, NULL);
+               spec->mic_autoswitch_hook(codec, jack);
        else
-               snd_hda_gen_mic_autoswitch(codec, NULL);
+               snd_hda_gen_mic_autoswitch(codec, jack);
+}
+
+/* update jack retasking */
+static void update_automute_all(struct hda_codec *codec)
+{
+       call_hp_automute(codec, NULL);
+       call_line_automute(codec, NULL);
+       call_mic_autoswitch(codec, NULL);
 }
 
 /*
@@ -4009,9 +4023,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
                snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n",
                            nid);
                snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT,
-                                                   spec->hp_automute_hook ?
-                                                   spec->hp_automute_hook :
-                                                   snd_hda_gen_hp_automute);
+                                                   call_hp_automute);
                spec->detect_hp = 1;
        }
 
@@ -4024,9 +4036,7 @@ static int check_auto_mute_availability(struct hda_codec *codec)
                                snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid);
                                snd_hda_jack_detect_enable_callback(codec, nid,
                                                                    HDA_GEN_FRONT_EVENT,
-                                                                   spec->line_automute_hook ?
-                                                                   spec->line_automute_hook :
-                                                                   snd_hda_gen_line_automute);
+                                                                   call_line_automute);
                                spec->detect_lo = 1;
                        }
                spec->automute_lo_possible = spec->detect_hp;
@@ -4068,9 +4078,7 @@ static bool auto_mic_check_imux(struct hda_codec *codec)
                snd_hda_jack_detect_enable_callback(codec,
                                                    spec->am_entry[i].pin,
                                                    HDA_GEN_MIC_EVENT,
-                                                   spec->mic_autoswitch_hook ?
-                                                   spec->mic_autoswitch_hook :
-                                                   snd_hda_gen_mic_autoswitch);
+                                                   call_mic_autoswitch);
        return true;
 }
 
index 54e6651..7620031 100644 (file)
@@ -222,6 +222,7 @@ struct hda_gen_spec {
        unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
        unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
        unsigned int own_eapd_ctl:1; /* set EAPD by own function */
+       unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */
        unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */
        unsigned int indep_hp:1; /* independent HP supported */
        unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */
index 59d2e91..02e22b4 100644 (file)
@@ -3493,6 +3493,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
        SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -3530,6 +3532,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
index e0dadcf..e524554 100644 (file)
@@ -136,6 +136,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
                spec->codec_type = VT1708S;
        spec->no_pin_power_ctl = 1;
        spec->gen.indep_hp = 1;
+       spec->gen.keep_eapd_on = 1;
        spec->gen.pcm_playback_hook = via_playback_pcm_hook;
        return spec;
 }
@@ -231,9 +232,14 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
 
 static void set_widgets_power_state(struct hda_codec *codec)
 {
+#if 0 /* FIXME: the assumed connections don't match always with the
+       * actual routes by the generic parser, so better to disable
+       * the control for safety.
+       */
        struct via_spec *spec = codec->spec;
        if (spec->set_widgets_power_state)
                spec->set_widgets_power_state(codec);
+#endif
 }
 
 static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
@@ -478,7 +484,9 @@ static int via_suspend(struct hda_codec *codec)
                /* Fix pop noise on headphones */
                int i;
                for (i = 0; i < spec->gen.autocfg.hp_outs; i++)
-                       snd_hda_set_pin_ctl(codec, spec->gen.autocfg.hp_pins[i], 0);
+                       snd_hda_codec_write(codec, spec->gen.autocfg.hp_pins[i],
+                                           0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           0x00);
        }
 
        return 0;
index d59abe1..748e82d 100644 (file)
@@ -1341,7 +1341,8 @@ static int sis_chip_create(struct snd_card *card,
        if (rc)
                goto error_out;
 
-       if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) {
+       rc = pci_set_dma_mask(pci, DMA_BIT_MASK(30));
+       if (rc < 0) {
                dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA");
                goto error_out_enabled;
        }
index 9e675c7..45eeaa9 100644 (file)
@@ -51,6 +51,7 @@ source "sound/soc/pxa/Kconfig"
 source "sound/soc/samsung/Kconfig"
 source "sound/soc/s6000/Kconfig"
 source "sound/soc/sh/Kconfig"
+source "sound/soc/spear/Kconfig"
 source "sound/soc/tegra/Kconfig"
 source "sound/soc/txx9/Kconfig"
 source "sound/soc/ux500/Kconfig"
index 197b6ae..bc02614 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_SND_SOC) += pxa/
 obj-$(CONFIG_SND_SOC)  += samsung/
 obj-$(CONFIG_SND_SOC)  += s6000/
 obj-$(CONFIG_SND_SOC)  += sh/
+obj-$(CONFIG_SND_SOC)  += spear/
 obj-$(CONFIG_SND_SOC)  += tegra/
 obj-$(CONFIG_SND_SOC)  += txx9/
 obj-$(CONFIG_SND_SOC)  += ux500/
index 2d6fbd0..802717e 100644 (file)
@@ -38,8 +38,6 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 
-#include <linux/pinctrl/consumer.h>
-
 #include <linux/atmel-ssc.h>
 
 #include <sound/core.h>
@@ -203,15 +201,8 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
        struct device_node *codec_np, *cpu_np;
        struct clk *pllb;
        struct snd_soc_card *card = &snd_soc_at91sam9g20ek;
-       struct pinctrl *pinctrl;
        int ret;
 
-       pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-       if (IS_ERR(pinctrl)) {
-               dev_err(&pdev->dev, "Failed to request pinctrl for mck\n");
-               return PTR_ERR(pinctrl);
-       }
-
        if (!np) {
                if (!(machine_is_at91sam9g20ek() ||
                        machine_is_at91sam9g20ek_2mmc()))
index 16b88f5..54f74f8 100644 (file)
@@ -56,6 +56,23 @@ config SND_SOC_BFIN_EVAL_ADAV80X
          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
+       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
+       select SND_BF5XX_SOC_I2S
+       select SND_SOC_AD193X
+       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
@@ -72,33 +89,6 @@ config SND_BFIN_AD73311_SE
          Enter the GPIO used to control AD73311's SE pin. Acceptable
          values are 0 to 7
 
-config SND_BF5XX_TDM
-       tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
-       depends on (BLACKFIN && SND_SOC)
-       select SND_BF5XX_SOC_SPORT
-       help
-         Say Y or M if you want to add support for codecs attached to
-         the Blackfin SPORT (synchronous serial ports) interface in TDM
-         mode.
-         You will also need to select the audio interfaces to support below.
-
-config SND_BF5XX_SOC_AD1836
-       tristate "SoC AD1836 Audio support for BF5xx"
-       depends on SND_BF5XX_TDM
-       select SND_BF5XX_SOC_TDM
-       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_TDM
-       select SND_BF5XX_SOC_TDM
-       select SND_SOC_AD193X
-       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_AC97
        tristate "SoC AC97 Audio for the ADI BF5xx chip"
        depends on BLACKFIN
@@ -174,9 +164,6 @@ config SND_BF5XX_SOC_I2S
 config SND_BF6XX_SOC_I2S
        tristate
 
-config SND_BF5XX_SOC_TDM
-       tristate
-
 config SND_BF5XX_SOC_AC97
        tristate
 
index 6fea1f4..ad0a6e9 100644 (file)
@@ -1,23 +1,19 @@
 # Blackfin Platform Support
 snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
 snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
-snd-bf5xx-tdm-objs := bf5xx-tdm-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
-snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o
 
 obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
 obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
-obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.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
-obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o
 
 # Blackfin Machine Support
 snd-ad1836-objs := bf5xx-ad1836.o
index 7e2f360..53f8408 100644 (file)
@@ -39,7 +39,6 @@
 
 #include <asm/dma.h>
 
-#include "bf5xx-ac97-pcm.h"
 #include "bf5xx-ac97.h"
 #include "bf5xx-sport.h"
 
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.h b/sound/soc/blackfin/bf5xx-ac97-pcm.h
deleted file mode 100644 (file)
index d324d58..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/sound/arm/bf5xx-ac97-pcm.h -- ALSA PCM interface for the Blackfin
- *
- * Copyright 2007 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.
- */
-
-#ifndef _BF5XX_AC97_PCM_H
-#define _BF5XX_AC97_PCM_H
-
-struct bf5xx_pcm_dma_params {
-       char *name;                     /* stream identifier */
-};
-
-struct bf5xx_gpio {
-       u32 sys;
-       u32 rx;
-       u32 tx;
-       u32 clk;
-       u32 frm;
-};
-
-#endif
index 4902173..c66bef8 100644 (file)
@@ -231,9 +231,9 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
                return 0;
 
 #if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-       ret = sport_set_multichannel(sport, 16, 0x3FF, 1);
+       ret = sport_set_multichannel(sport, 16, 0x3FF, 0x3FF, 1);
 #else
-       ret = sport_set_multichannel(sport, 16, 0x1F, 1);
+       ret = sport_set_multichannel(sport, 16, 0x1F, 0x1F, 1);
 #endif
        if (ret) {
                pr_err("SPORT is busy!\n");
@@ -311,9 +311,9 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
 
        /*SPORT works in TDM mode to simulate AC97 transfers*/
 #if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
-       ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
+       ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 0x3FF, 1);
 #else
-       ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
+       ret = sport_set_multichannel(sport_handle, 16, 0x1F, 0x1F, 1);
 #endif
        if (ret) {
                pr_err("SPORT is busy!\n");
index d23f4b0..8fcfc4e 100644 (file)
 
 #include "../codecs/ad1836.h"
 
-#include "bf5xx-tdm-pcm.h"
-#include "bf5xx-tdm.h"
-
 static struct snd_soc_card bf5xx_ad1836;
 
-static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+static int bf5xx_ad1836_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
        int ret = 0;
@@ -49,13 +44,13 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
        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;
 }
 
-static struct snd_soc_ops bf5xx_ad1836_ops = {
-       .hw_params = bf5xx_ad1836_hw_params,
-};
-
 #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
                                SND_SOC_DAIFMT_CBM_CFM)
 
@@ -63,9 +58,9 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai = {
        .name = "ad1836",
        .stream_name = "AD1836",
        .codec_dai_name = "ad1836-hifi",
-       .platform_name = "bfin-tdm-pcm-audio",
-       .ops = &bf5xx_ad1836_ops,
+       .platform_name = "bfin-i2s-pcm-audio",
        .dai_fmt = BF5XX_AD1836_DAIFMT,
+       .init = bf5xx_ad1836_init,
 };
 
 static struct snd_soc_card bf5xx_ad1836 = {
index 0e55e9f..603ad1f 100644 (file)
 
 #include "../codecs/ad193x.h"
 
-#include "bf5xx-tdm-pcm.h"
-#include "bf5xx-tdm.h"
-
 static struct snd_soc_card bf5xx_ad193x;
 
-static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+static int bf5xx_ad193x_link_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       unsigned int clk = 0;
-       unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
-       int ret = 0;
-
-       switch (params_rate(params)) {
-       case 48000:
-               clk = 24576000;
-               break;
-       }
+       int ret;
 
        /* set the codec system clock for DAC and ADC */
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
-               SND_SOC_CLOCK_IN);
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 24576000, SND_SOC_CLOCK_IN);
        if (ret < 0)
                return ret;
 
@@ -71,9 +57,7 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       /* 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);
+       ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFF, 0xFF, 8, 32);
        if (ret < 0)
                return ret;
 
@@ -83,30 +67,26 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
 #define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
                                SND_SOC_DAIFMT_CBM_CFM)
 
-static struct snd_soc_ops bf5xx_ad193x_ops = {
-       .hw_params = bf5xx_ad193x_hw_params,
-};
-
 static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
        {
                .name = "ad193x",
                .stream_name = "AD193X",
-               .cpu_dai_name = "bfin-tdm.0",
+               .cpu_dai_name = "bfin-i2s.0",
                .codec_dai_name ="ad193x-hifi",
-               .platform_name = "bfin-tdm-pcm-audio",
+               .platform_name = "bfin-i2s-pcm-audio",
                .codec_name = "spi0.5",
-               .ops = &bf5xx_ad193x_ops,
                .dai_fmt = BF5XX_AD193X_DAIFMT,
+               .init = bf5xx_ad193x_link_init,
        },
        {
                .name = "ad193x",
                .stream_name = "AD193X",
-               .cpu_dai_name = "bfin-tdm.1",
+               .cpu_dai_name = "bfin-i2s.1",
                .codec_dai_name ="ad193x-hifi",
-               .platform_name = "bfin-tdm-pcm-audio",
+               .platform_name = "bfin-i2s-pcm-audio",
                .codec_name = "spi0.5",
-               .ops = &bf5xx_ad193x_ops,
                .dai_fmt = BF5XX_AD193X_DAIFMT,
+               .init = bf5xx_ad193x_link_init,
        },
 };
 
index b30f88b..3450e8f 100644 (file)
@@ -48,7 +48,6 @@
 
 #include "../codecs/ad1980.h"
 
-#include "bf5xx-ac97-pcm.h"
 #include "bf5xx-ac97.h"
 
 static struct snd_soc_card bf5xx_board;
index 61cc91d..786bbdd 100644 (file)
@@ -45,7 +45,6 @@
 
 #include "../codecs/ad73311.h"
 #include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
 
 #if CONFIG_SND_BF5XX_SPORT_NUM == 0
 #define bfin_write_SPORT_TCR1  bfin_write_SPORT0_TCR1
index 262c1de..9cb4a80 100644 (file)
@@ -39,8 +39,8 @@
 
 #include <asm/dma.h>
 
-#include "bf5xx-i2s-pcm.h"
 #include "bf5xx-sport.h"
+#include "bf5xx-i2s-pcm.h"
 
 static void bf5xx_dma_irq(void *data)
 {
@@ -50,7 +50,6 @@ static void bf5xx_dma_irq(void *data)
 
 static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
        .info                   = SNDRV_PCM_INFO_INTERLEAVED |
-                                  SNDRV_PCM_INFO_MMAP |
                                   SNDRV_PCM_INFO_MMAP_VALID |
                                   SNDRV_PCM_INFO_BLOCK_TRANSFER,
        .formats                = SNDRV_PCM_FMTBIT_S16_LE |
@@ -67,10 +66,16 @@ static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
 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;
-       snd_pcm_lib_malloc_pages(substream, size);
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       unsigned int buffer_size = params_buffer_bytes(params);
+       struct bf5xx_i2s_pcm_data *dma_data;
 
-       return 0;
+       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)
@@ -82,9 +87,16 @@ static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
 
 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) {
@@ -131,10 +143,15 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 
 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);
@@ -151,6 +168,8 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
                diff = 0;
 
        frames = bytes_to_frames(substream->runtime, diff);
+       if (dma_data->tdm_mode)
+               frames = frames * runtime->channels / 8;
 
        return frames;
 }
@@ -162,11 +181,18 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
        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);
@@ -202,6 +228,88 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
        return 0 ;
 }
 
+static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
+       snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t 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) {
+               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 += frames_to_bytes(runtime, pos);
+               } else {
+                       src = runtime->dma_area;
+                       src += frames_to_bytes(runtime, pos);
+                       dst = buf;
+               }
+
+               memcpy(dst, src, frames_to_bytes(runtime, count));
+       }
+
+       return 0;
+}
+
+static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
+       int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t 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, size;
+
+       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+       if (dma_data->tdm_mode) {
+               offset = pos * 8 * sample_size;
+               size = count * 8 * sample_size;
+       } else {
+               offset = frames_to_bytes(runtime, pos);
+               size = frames_to_bytes(runtime, count);
+       }
+
+       snd_pcm_format_set_silence(runtime->format, buf + offset, size);
+
+       return 0;
+}
+
 static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
        .open           = bf5xx_pcm_open,
        .ioctl          = snd_pcm_lib_ioctl,
@@ -211,57 +319,16 @@ static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
        .trigger        = bf5xx_pcm_trigger,
        .pointer        = bf5xx_pcm_pointer,
        .mmap           = bf5xx_pcm_mmap,
+       .copy           = bf5xx_pcm_copy,
+       .silence        = bf5xx_pcm_silence,
 };
 
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       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;
-
-       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 - 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);
-
-       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;
-
-       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;
-       }
-}
-
 static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
 
 static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_card *card = rtd->card->snd_card;
-       struct snd_pcm *pcm = rtd->pcm;
-       int ret = 0;
+       size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
 
        pr_debug("%s enter\n", __func__);
        if (!card->dev->dma_mask)
@@ -269,27 +336,13 @@ static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
        if (!card->dev->coherent_dma_mask)
                card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
-       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;
+       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,
-       .pcm_free       = bf5xx_pcm_free_dma_buffers,
 };
 
 static int bfin_i2s_soc_platform_probe(struct platform_device *pdev)
index 0c2c5a6..1f04352 100644 (file)
@@ -1,26 +1,17 @@
 /*
- * linux/sound/arm/bf5xx-i2s-pcm.h -- ALSA PCM interface for the Blackfin
- *
- * Copyright 2007 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.
  */
 
-#ifndef _BF5XX_I2S_PCM_H
-#define _BF5XX_I2S_PCM_H
+#ifndef _BF5XX_TDM_PCM_H
+#define _BF5XX_TDM_PCM_H
 
-struct bf5xx_pcm_dma_params {
-       char *name;                     /* stream identifier */
-};
+#define BFIN_TDM_DAI_MAX_SLOTS 8
 
-struct bf5xx_gpio {
-       u32 sys;
-       u32 rx;
-       u32 tx;
-       u32 clk;
-       u32 frm;
+struct bf5xx_i2s_pcm_data {
+       unsigned int map[BFIN_TDM_DAI_MAX_SLOTS];
+       bool tdm_mode;
 };
 
 #endif
index dd0c2a4..9a174fc 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/gpio.h>
 
 #include "bf5xx-sport.h"
+#include "bf5xx-i2s-pcm.h"
 
 struct bf5xx_i2s_port {
        u16 tcr1;
@@ -49,6 +50,13 @@ struct bf5xx_i2s_port {
        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,
@@ -74,7 +82,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                ret = -EINVAL;
                break;
        default:
-               printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
+               dev_err(cpu_dai->dev, "%s: Unknown DAI format type\n",
+                       __func__);
                ret = -EINVAL;
                break;
        }
@@ -88,7 +97,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                ret = -EINVAL;
                break;
        default:
-               printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
+               dev_err(cpu_dai->dev, "%s: Unknown DAI master type\n",
+                       __func__);
                ret = -EINVAL;
                break;
        }
@@ -141,14 +151,14 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
                ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
                                      bf5xx_i2s->rcr2, 0, 0);
                if (ret) {
-                       pr_err("SPORT is busy!\n");
+                       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) {
-                       pr_err("SPORT is busy!\n");
+                       dev_err(dai->dev, "SPORT is busy!\n");
                        return -EBUSY;
                }
        }
@@ -162,18 +172,76 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
        struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
        struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
 
-       pr_debug("%s enter\n", __func__);
+       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);
 
-       pr_debug("%s : sport %d\n", __func__, dai->id);
+       dev_dbg(dai->dev, "%s : sport %d\n", __func__, dai->id);
 
        if (dai->capture_active)
                sport_rx_stop(sport_handle);
@@ -188,23 +256,24 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
        struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
        int ret;
 
-       pr_debug("%s : sport %d\n", __func__, dai->id);
+       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) {
-               pr_err("SPORT is busy!\n");
+               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) {
-               pr_err("SPORT is busy!\n");
+               dev_err(dai->dev, "SPORT is busy!\n");
                return -EBUSY;
        }
 
-       return 0;
+       return sport_set_multichannel(sport_handle, bf5xx_i2s->slots,
+                       bf5xx_i2s->tx_mask, bf5xx_i2s->rx_mask, 0);
 }
 
 #else
@@ -212,6 +281,23 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
 #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 | \
@@ -224,22 +310,25 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
         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,
+       .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 = 1,
-               .channels_max = 2,
+               .channels_min = 2,
+               .channels_max = 8,
                .rates = BF5XX_I2S_RATES,
                .formats = BF5XX_I2S_FORMATS,},
        .capture = {
-               .channels_min = 1,
-               .channels_max = 2,
+               .channels_min = 2,
+               .channels_max = 8,
                .rates = BF5XX_I2S_RATES,
                .formats = BF5XX_I2S_FORMATS,},
        .ops = &bf5xx_i2s_dai_ops,
@@ -255,7 +344,7 @@ static int bf5xx_i2s_probe(struct platform_device *pdev)
        int ret;
 
        /* configure SPORT for I2S */
-       sport_handle = sport_init(pdev, 4, 2 * sizeof(u32),
+       sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
                sizeof(struct bf5xx_i2s_port));
        if (!sport_handle)
                return -ENODEV;
@@ -264,7 +353,7 @@ static int bf5xx_i2s_probe(struct platform_device *pdev)
        ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component,
                                         &bf5xx_i2s_dai, 1);
        if (ret) {
-               pr_err("Failed to register DAI: %d\n", ret);
+               dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
                sport_done(sport_handle);
                return ret;
        }
@@ -276,7 +365,7 @@ static int bf5xx_i2s_remove(struct platform_device *pdev)
 {
        struct sport_device *sport_handle = platform_get_drvdata(pdev);
 
-       pr_debug("%s enter\n", __func__);
+       dev_dbg(&pdev->dev, "%s enter\n", __func__);
 
        snd_soc_unregister_component(&pdev->dev);
        sport_done(sport_handle);
index 2fd9f2a..6953512 100644 (file)
 /* 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 mask, int packed)
+               int tdm_count, u32 tx_mask, u32 rx_mask, int packed)
 {
-       pr_debug("%s tdm_count=%d mask:0x%08x packed=%d\n", __func__,
-                       tdm_count, mask, 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;
@@ -65,8 +65,8 @@ int sport_set_multichannel(struct sport_device *sport,
                sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
                                (packed ? (MCDTXPE|MCDRXPE) : 0);
 
-               sport->regs->mtcs0 = mask;
-               sport->regs->mrcs0 = mask;
+               sport->regs->mtcs0 = tx_mask;
+               sport->regs->mrcs0 = rx_mask;
                sport->regs->mtcs1 = 0;
                sport->regs->mrcs1 = 0;
                sport->regs->mtcs2 = 0;
index 5ab60bd..9fc2192 100644 (file)
@@ -128,7 +128,7 @@ void sport_done(struct sport_device *sport);
 /* 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 mask, int packed);
+               u32 tx_mask, u32 rx_mask, int packed);
 
 int sport_config_rx(struct sport_device *sport,
                unsigned int rcr1, unsigned int rcr2,
index 7dbeef1..9c19ccc 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/gpio.h>
 #include "../codecs/ssm2602.h"
 #include "bf5xx-sport.h"
-#include "bf5xx-i2s-pcm.h"
 
 static struct snd_soc_card bf5xx_ssm2602;
 
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
deleted file mode 100644 (file)
index 0e6b888..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-tdm-pcm.c
- * Author:       Barry Song <Barry.Song@analog.com>
- *
- * Created:      Tue June 06 2009
- * Description:  DMA driver for tdm codec
- *
- * Modified:
- *               Copyright 2009 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-tdm-pcm.h"
-#include "bf5xx-tdm.h"
-#include "bf5xx-sport.h"
-
-#define PCM_BUFFER_MAX  0x8000
-#define FRAGMENT_SIZE_MIN  (4*1024)
-#define FRAGMENTS_MIN  2
-#define FRAGMENTS_MAX  32
-
-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_BLOCK_TRANSFER |
-               SNDRV_PCM_INFO_RESUME),
-       .formats =          SNDRV_PCM_FMTBIT_S32_LE,
-       .rates =            SNDRV_PCM_RATE_48000,
-       .channels_min =     2,
-       .channels_max =     8,
-       .buffer_bytes_max = PCM_BUFFER_MAX,
-       .period_bytes_min = FRAGMENT_SIZE_MIN,
-       .period_bytes_max = PCM_BUFFER_MAX/2,
-       .periods_min =      FRAGMENTS_MIN,
-       .periods_max =      FRAGMENTS_MAX,
-};
-
-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;
-       snd_pcm_lib_malloc_pages(substream, size * 4);
-
-       return 0;
-}
-
-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_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
-
-       fragsize_bytes /= runtime->channels;
-       /* inflate the fragsize to match the dma width of SPORT */
-       fragsize_bytes *= 8;
-
-       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, fragsize_bytes);
-       } else {
-               sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
-               sport_config_rx_dma(sport, runtime->dma_area,
-                       runtime->periods, fragsize_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;
-
-       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_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       unsigned int diff;
-       snd_pcm_uframes_t frames;
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               diff = sport_curr_offset_tx(sport);
-               frames = diff / (8*4); /* 32 bytes per frame */
-       } else {
-               diff = sport_curr_offset_rx(sport);
-               frames = diff / (8*4);
-       }
-       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;
-
-       int ret = 0;
-
-       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) {
-               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");
-               ret = -ENODEV;
-       }
-out:
-       return ret;
-}
-
-static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
-       snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-       struct bf5xx_tdm_port *tdm_port = sport->private_data;
-       unsigned int *src;
-       unsigned int *dst;
-       int i;
-
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               src = buf;
-               dst = (unsigned int *)substream->runtime->dma_area;
-
-               dst += pos * 8;
-               while (count--) {
-                       for (i = 0; i < substream->runtime->channels; i++)
-                               *(dst + tdm_port->tx_map[i]) = *src++;
-                       dst += 8;
-               }
-       } else {
-               src = (unsigned int *)substream->runtime->dma_area;
-               dst = buf;
-
-               src += pos * 8;
-               while (count--) {
-                       for (i = 0; i < substream->runtime->channels; i++)
-                               *dst++ = *(src + tdm_port->rx_map[i]);
-                       src += 8;
-               }
-       }
-
-       return 0;
-}
-
-static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
-       int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
-{
-       unsigned char *buf = substream->runtime->dma_area;
-       buf += pos * 8 * 4;
-       memset(buf, '\0', count * 8 * 4);
-
-       return 0;
-}
-
-
-struct snd_pcm_ops bf5xx_pcm_tdm_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,
-       .copy           = bf5xx_pcm_copy,
-       .silence        = bf5xx_pcm_silence,
-};
-
-static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       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;
-
-       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 * 4,
-               &buf->addr, GFP_KERNEL);
-       if (!buf->area) {
-               pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
-               return -ENOMEM;
-       }
-       buf->bytes = size;
-
-       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;
-
-       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;
-       }
-}
-
-static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       struct snd_pcm *pcm = rtd->pcm;
-       int ret = 0;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &bf5xx_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
-       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_tdm_soc_platform = {
-       .ops        = &bf5xx_pcm_tdm_ops,
-       .pcm_new        = bf5xx_pcm_tdm_new,
-       .pcm_free       = bf5xx_pcm_free_dma_buffers,
-};
-
-static int bf5xx_soc_platform_probe(struct platform_device *pdev)
-{
-       return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
-}
-
-static int bf5xx_soc_platform_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_platform(&pdev->dev);
-       return 0;
-}
-
-static struct platform_driver bfin_tdm_driver = {
-       .driver = {
-                       .name = "bfin-tdm-pcm-audio",
-                       .owner = THIS_MODULE,
-       },
-
-       .probe = bf5xx_soc_platform_probe,
-       .remove = bf5xx_soc_platform_remove,
-};
-
-module_platform_driver(bfin_tdm_driver);
-
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.h b/sound/soc/blackfin/bf5xx-tdm-pcm.h
deleted file mode 100644 (file)
index 7f8cc01..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-tdm-pcm.h -- ALSA PCM interface for the Blackfin
- *
- * Copyright 2009 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.
- */
-
-#ifndef _BF5XX_TDM_PCM_H
-#define _BF5XX_TDM_PCM_H
-
-struct bf5xx_pcm_dma_params {
-       char *name;                     /* stream identifier */
-};
-
-#endif
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
deleted file mode 100644 (file)
index 69e9a3e..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * File:         sound/soc/blackfin/bf5xx-tdm.c
- * Author:       Barry Song <Barry.Song@analog.com>
- *
- * Created:      Thurs June 04 2009
- * Description:  Blackfin I2S(TDM) CPU DAI driver
- *              Even though TDM mode can be as part of I2S DAI, but there
- *              are so much difference in configuration and data flow,
- *              it's very ugly to integrate I2S and TDM into a module
- *
- * Modified:
- *               Copyright 2009 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 <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-tdm.h"
-
-static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-       unsigned int fmt)
-{
-       int ret = 0;
-
-       /* interface format:support TDM,slave mode */
-       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-       case SND_SOC_DAIFMT_DSP_A:
-               break;
-       default:
-               printk(KERN_ERR "%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:
-               printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-static int bf5xx_tdm_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_tdm_port *bf5xx_tdm = sport_handle->private_data;
-       int ret = 0;
-
-       bf5xx_tdm->tcr2 &= ~0x1f;
-       bf5xx_tdm->rcr2 &= ~0x1f;
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S32_LE:
-               bf5xx_tdm->tcr2 |= 31;
-               bf5xx_tdm->rcr2 |= 31;
-               sport_handle->wdsize = 4;
-               break;
-               /* at present, we only support 32bit transfer */
-       default:
-               pr_err("not supported PCM format yet\n");
-               return -EINVAL;
-               break;
-       }
-
-       if (!bf5xx_tdm->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.
-                */
-               ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1,
-                       bf5xx_tdm->rcr2, 0, 0);
-               if (ret) {
-                       pr_err("SPORT is busy!\n");
-                       return -EBUSY;
-               }
-
-               ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1,
-                       bf5xx_tdm->tcr2, 0, 0);
-               if (ret) {
-                       pr_err("SPORT is busy!\n");
-                       return -EBUSY;
-               }
-
-               bf5xx_tdm->configured = 1;
-       }
-
-       return 0;
-}
-
-static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
-       struct snd_soc_dai *dai)
-{
-       struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
-       struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
-
-       /* No active stream, SPORT is allowed to be configured again. */
-       if (!dai->active)
-               bf5xx_tdm->configured = 0;
-}
-
-static int bf5xx_tdm_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_tdm_port *bf5xx_tdm = sport_handle->private_data;
-       int i;
-       unsigned int slot;
-       unsigned int tx_mapped = 0, rx_mapped = 0;
-
-       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_tdm->tx_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_tdm->rx_map[i] = slot;
-                       rx_mapped |= 1 << slot;
-               } else
-                       return -EINVAL;
-       }
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
-{
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-       if (dai->playback_active)
-               sport_tx_stop(sport);
-       if (dai->capture_active)
-               sport_rx_stop(sport);
-
-       /* isolate sync/clock pins from codec while sports resume */
-       peripheral_free_list(sport->pin_req);
-
-       return 0;
-}
-
-static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
-{
-       int ret;
-       struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
-
-       ret = sport_set_multichannel(sport, 8, 0xFF, 1);
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-       }
-
-       ret = sport_config_rx(sport, 0, 0x1F, 0, 0);
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-       }
-
-       ret = sport_config_tx(sport, 0, 0x1F, 0, 0);
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-       }
-
-       peripheral_request_list(sport->pin_req, "soc-audio");
-
-       return 0;
-}
-
-#else
-#define bf5xx_tdm_suspend      NULL
-#define bf5xx_tdm_resume       NULL
-#endif
-
-static const struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
-       .hw_params      = bf5xx_tdm_hw_params,
-       .set_fmt        = bf5xx_tdm_set_dai_fmt,
-       .shutdown       = bf5xx_tdm_shutdown,
-       .set_channel_map   = bf5xx_tdm_set_channel_map,
-};
-
-static struct snd_soc_dai_driver bf5xx_tdm_dai = {
-       .suspend = bf5xx_tdm_suspend,
-       .resume = bf5xx_tdm_resume,
-       .playback = {
-               .channels_min = 2,
-               .channels_max = 8,
-               .rates = SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE,},
-       .capture = {
-               .channels_min = 2,
-               .channels_max = 8,
-               .rates = SNDRV_PCM_RATE_48000,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE,},
-       .ops = &bf5xx_tdm_dai_ops,
-};
-
-static const struct snd_soc_component_driver bf5xx_tdm_component = {
-       .name           = "bf5xx-tdm",
-};
-
-static int bfin_tdm_probe(struct platform_device *pdev)
-{
-       struct sport_device *sport_handle;
-       int ret;
-
-       /* configure SPORT for TDM */
-       sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
-               sizeof(struct bf5xx_tdm_port));
-       if (!sport_handle)
-               return -ENODEV;
-
-       /* SPORT works in TDM mode */
-       ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-               goto sport_config_err;
-       }
-
-       ret = sport_config_rx(sport_handle, 0, 0x1F, 0, 0);
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-               goto sport_config_err;
-       }
-
-       ret = sport_config_tx(sport_handle, 0, 0x1F, 0, 0);
-       if (ret) {
-               pr_err("SPORT is busy!\n");
-               ret = -EBUSY;
-               goto sport_config_err;
-       }
-
-       ret = snd_soc_register_component(&pdev->dev, &bf5xx_tdm_component,
-                                        &bf5xx_tdm_dai, 1);
-       if (ret) {
-               pr_err("Failed to register DAI: %d\n", ret);
-               goto sport_config_err;
-       }
-
-       return 0;
-
-sport_config_err:
-       sport_done(sport_handle);
-       return ret;
-}
-
-static int bfin_tdm_remove(struct platform_device *pdev)
-{
-       struct sport_device *sport_handle = platform_get_drvdata(pdev);
-
-       snd_soc_unregister_component(&pdev->dev);
-       sport_done(sport_handle);
-
-       return 0;
-}
-
-static struct platform_driver bfin_tdm_driver = {
-       .probe  = bfin_tdm_probe,
-       .remove = bfin_tdm_remove,
-       .driver = {
-               .name   = "bfin-tdm",
-               .owner  = THIS_MODULE,
-       },
-};
-
-module_platform_driver(bfin_tdm_driver);
-
-/* Module information */
-MODULE_AUTHOR("Barry Song");
-MODULE_DESCRIPTION("TDM driver for ADI Blackfin");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
deleted file mode 100644 (file)
index e986a3e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * sound/soc/blackfin/bf5xx-tdm.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_TDM_H
-#define _BF5XX_TDM_H
-
-#define BFIN_TDM_DAI_MAX_SLOTS 8
-struct bf5xx_tdm_port {
-       u16 tcr1;
-       u16 rcr1;
-       u16 tcr2;
-       u16 rcr2;
-       unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS];
-       unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS];
-       int configured;
-};
-
-#endif
index 88143db..2c20f01 100644 (file)
@@ -1,7 +1,7 @@
 config SND_EP93XX_SOC
        tristate "SoC Audio support for the Cirrus Logic EP93xx series"
        depends on ARCH_EP93XX && SND_SOC
-       select SND_SOC_DMAENGINE_PCM
+       select SND_SOC_GENERIC_DMAENGINE_PCM
        help
          Say Y or M if you want to add support for codecs attached to
          the EP93xx I2S or AC97 interfaces.
index 7798fbd..3f4f888 100644 (file)
@@ -314,22 +314,15 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int ep93xx_ac97_startup(struct snd_pcm_substream *substream,
-                              struct snd_soc_dai *dai)
+static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai)
 {
-       struct ep93xx_dma_data *dma_data;
+       dai->playback_dma_data = &ep93xx_ac97_pcm_out;
+       dai->capture_dma_data = &ep93xx_ac97_pcm_in;
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dma_data = &ep93xx_ac97_pcm_out;
-       else
-               dma_data = &ep93xx_ac97_pcm_in;
-
-       snd_soc_dai_set_dma_data(dai, substream, dma_data);
        return 0;
 }
 
 static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
-       .startup        = ep93xx_ac97_startup,
        .trigger        = ep93xx_ac97_trigger,
 };
 
@@ -337,6 +330,7 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = {
        .name           = "ep93xx-ac97",
        .id             = 0,
        .ac97_control   = 1,
+       .probe          = ep93xx_ac97_dai_probe,
        .playback       = {
                .stream_name    = "AC97 Playback",
                .channels_min   = 2,
@@ -403,7 +397,6 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
        return 0;
 
 fail:
-       platform_set_drvdata(pdev, NULL);
        ep93xx_ac97_info = NULL;
        dev_set_drvdata(&pdev->dev, NULL);
        return ret;
@@ -418,7 +411,6 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
        /* disable the AC97 controller */
        ep93xx_ac97_write_reg(info, AC97GCR, 0);
 
-       platform_set_drvdata(pdev, NULL);
        ep93xx_ac97_info = NULL;
        dev_set_drvdata(&pdev->dev, NULL);
 
index 5c1102e..17ad70b 100644 (file)
@@ -60,11 +60,10 @@ struct ep93xx_i2s_info {
        struct clk                      *mclk;
        struct clk                      *sclk;
        struct clk                      *lrclk;
-       struct ep93xx_dma_data          *dma_data;
        void __iomem                    *regs;
 };
 
-struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
+static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
        [SNDRV_PCM_STREAM_PLAYBACK] = {
                .name           = "i2s-pcm-out",
                .port           = EP93XX_DMA_I2S1,
@@ -139,15 +138,11 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
        }
 }
 
-static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
-                             struct snd_soc_dai *dai)
+static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       dai->playback_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK];
+       dai->capture_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE];
 
-       snd_soc_dai_set_dma_data(cpu_dai, substream,
-                                &info->dma_data[substream->stream]);
        return 0;
 }
 
@@ -338,7 +333,6 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
 #endif
 
 static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
-       .startup        = ep93xx_i2s_startup,
        .shutdown       = ep93xx_i2s_shutdown,
        .hw_params      = ep93xx_i2s_hw_params,
        .set_sysclk     = ep93xx_i2s_set_sysclk,
@@ -349,6 +343,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
 
 static struct snd_soc_dai_driver ep93xx_i2s_dai = {
        .symmetric_rates= 1,
+       .probe          = ep93xx_i2s_dai_probe,
        .suspend        = ep93xx_i2s_suspend,
        .resume         = ep93xx_i2s_resume,
        .playback       = {
@@ -407,7 +402,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
        }
 
        dev_set_drvdata(&pdev->dev, info);
-       info->dma_data = ep93xx_i2s_dma_data;
 
        err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
                                         &ep93xx_i2s_dai, 1);
index 4880326..0e9f56e 100644 (file)
 
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/device.h>
-#include <linux/slab.h>
+#include <linux/platform_device.h>
 #include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
 
-#include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/dmaengine_pcm.h>
 
 #include <linux/platform_data/dma-ep93xx.h>
-#include <mach/hardware.h>
-#include <mach/ep93xx-regs.h>
 
 static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
        .info                   = (SNDRV_PCM_INFO_MMAP          |
@@ -63,134 +57,24 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
        return false;
 }
 
-static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
-       snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
-
-       return snd_dmaengine_pcm_open_request_chan(substream,
-                       ep93xx_pcm_dma_filter,
-                       snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
-}
-
-static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
-{
-       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
-       return 0;
-}
-
-static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-       snd_pcm_set_runtime_buffer(substream, NULL);
-       return 0;
-}
-
-static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
-                          struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-
-       return dma_mmap_writecombine(substream->pcm->card->dev, vma,
-                                    runtime->dma_area,
-                                    runtime->dma_addr,
-                                    runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops ep93xx_pcm_ops = {
-       .open           = ep93xx_pcm_open,
-       .close          = snd_dmaengine_pcm_close_release_chan,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = ep93xx_pcm_hw_params,
-       .hw_free        = ep93xx_pcm_hw_free,
-       .trigger        = snd_dmaengine_pcm_trigger,
-       .pointer        = snd_dmaengine_pcm_pointer_no_residue,
-       .mmap           = ep93xx_pcm_mmap,
-};
-
-static int ep93xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-       size_t size = ep93xx_pcm_hardware.buffer_bytes_max;
-
-       buf->dev.type = SNDRV_DMA_TYPE_DEV;
-       buf->dev.dev = pcm->card->dev;
-       buf->private_data = NULL;
-       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
-                                          &buf->addr, GFP_KERNEL);
-       buf->bytes = size;
-
-       return (buf->area == NULL) ? -ENOMEM : 0;
-}
-
-static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-
-       for (stream = 0; stream < 2; stream++) {                
-               substream = pcm->streams[stream].substream;
-               if (!substream)
-                       continue;
-               
-               buf = &substream->dma_buffer;
-               if (!buf->area)
-                       continue;
-
-               dma_free_writecombine(pcm->card->dev, buf->bytes, buf->area,
-                                     buf->addr);
-               buf->area = NULL;
-       }
-}
-
-static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       struct snd_pcm *pcm = rtd->pcm;
-       int ret = 0;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &ep93xx_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
-       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
-               ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
-                                       SNDRV_PCM_STREAM_PLAYBACK);
-               if (ret)
-                       return ret;
-       }
-
-       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-               ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
-                                       SNDRV_PCM_STREAM_CAPTURE);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static struct snd_soc_platform_driver ep93xx_soc_platform = {
-       .ops            = &ep93xx_pcm_ops,
-       .pcm_new        = &ep93xx_pcm_new,
-       .pcm_free       = &ep93xx_pcm_free_dma_buffers,
+static const struct snd_dmaengine_pcm_config ep93xx_dmaengine_pcm_config = {
+       .pcm_hardware = &ep93xx_pcm_hardware,
+       .compat_filter_fn = ep93xx_pcm_dma_filter,
+       .prealloc_buffer_size = 131072,
 };
 
 static int ep93xx_soc_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform);
+       return snd_dmaengine_pcm_register(&pdev->dev,
+               &ep93xx_dmaengine_pcm_config,
+               SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
+               SND_DMAENGINE_PCM_FLAG_NO_DT |
+               SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
 
 static int ep93xx_soc_platform_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_platform(&pdev->dev);
+       snd_dmaengine_pcm_unregister(&pdev->dev);
        return 0;
 }
 
index 60159c0..1382f3f 100644 (file)
@@ -1444,7 +1444,7 @@ static int pm860x_codec_probe(struct platform_device *pdev)
                res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
                if (!res) {
                        dev_err(&pdev->dev, "Failed to get IRQ resources\n");
-                       goto out;
+                       return -EINVAL;
                }
                pm860x->irq[i] = res->start + chip->irq_base;
                strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);
@@ -1454,19 +1454,14 @@ static int pm860x_codec_probe(struct platform_device *pdev)
                                     pm860x_dai, ARRAY_SIZE(pm860x_dai));
        if (ret) {
                dev_err(&pdev->dev, "Failed to register codec\n");
-               goto out;
+               return -EINVAL;
        }
        return ret;
-
-out:
-       platform_set_drvdata(pdev, NULL);
-       return -EINVAL;
 }
 
 static int pm860x_codec_remove(struct platform_device *pdev)
 {
        snd_soc_unregister_codec(&pdev->dev);
-       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
index 2f45f00..badb6fb 100644 (file)
@@ -19,7 +19,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_AD1980 if SND_SOC_AC97_BUS
        select SND_SOC_AD73311
        select SND_SOC_ADAU1373 if I2C
-       select SND_SOC_ADAV80X
+       select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI
        select SND_SOC_ADS117X
        select SND_SOC_AK4104 if SPI_MASTER
        select SND_SOC_AK4535 if I2C
@@ -40,7 +40,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_DA7213 if I2C
        select SND_SOC_DA732X if I2C
        select SND_SOC_DA9055 if I2C
-       select SND_SOC_DFBMCS320
+       select SND_SOC_BT_SCO
        select SND_SOC_ISABELLE if I2C
        select SND_SOC_JZ4740_CODEC
        select SND_SOC_LM4857 if I2C
@@ -53,13 +53,15 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_MAX9877 if I2C
        select SND_SOC_MC13783 if MFD_MC13XXX
        select SND_SOC_ML26124 if I2C
-       select SND_SOC_OMAP_HDMI_CODEC if OMAP4_DSS_HDMI
+       select SND_SOC_HDMI_CODEC
        select SND_SOC_PCM3008
        select SND_SOC_RT5631 if I2C
+       select SND_SOC_RT5640 if I2C
        select SND_SOC_SGTL5000 if I2C
        select SND_SOC_SI476X if MFD_SI476X_CORE
        select SND_SOC_SN95031 if INTEL_SCU_IPC
        select SND_SOC_SPDIF
+       select SND_SOC_SSM2518 if I2C
        select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
        select SND_SOC_STA32X if I2C
        select SND_SOC_STA529 if I2C
@@ -263,7 +265,7 @@ config SND_SOC_DA732X
 config SND_SOC_DA9055
        tristate
 
-config SND_SOC_DFBMCS320
+config SND_SOC_BT_SCO
        tristate
 
 config SND_SOC_DMIC
@@ -287,7 +289,7 @@ config SND_SOC_MAX98095
 config SND_SOC_MAX9850
        tristate
 
-config SND_SOC_OMAP_HDMI_CODEC
+config SND_SOC_HDMI_CODEC
        tristate
 
 config SND_SOC_PCM3008
@@ -296,6 +298,9 @@ config SND_SOC_PCM3008
 config SND_SOC_RT5631
        tristate
 
+config SND_SOC_RT5640
+       tristate
+
 #Freescale sgtl5000 codec
 config SND_SOC_SGTL5000
        tristate
@@ -313,6 +318,9 @@ config SND_SOC_SN95031
 config SND_SOC_SPDIF
        tristate
 
+config SND_SOC_SSM2518
+       tristate
+
 config SND_SOC_SSM2602
        tristate
 
index b9e41c9..70fd806 100644 (file)
@@ -27,7 +27,7 @@ snd-soc-da7210-objs := da7210.o
 snd-soc-da7213-objs := da7213.o
 snd-soc-da732x-objs := da732x.o
 snd-soc-da9055-objs := da9055.o
-snd-soc-dfbmcs320-objs := dfbmcs320.o
+snd-soc-bt-sco-objs := bt-sco.o
 snd-soc-dmic-objs := dmic.o
 snd-soc-isabelle-objs := isabelle.o
 snd-soc-jz4740-codec-objs := jz4740.o
@@ -41,17 +41,19 @@ snd-soc-max98095-objs := max98095.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
 snd-soc-ml26124-objs := ml26124.o
-snd-soc-omap-hdmi-codec-objs := omap-hdmi.o
+snd-soc-hdmi-codec-objs := hdmi.o
 snd-soc-pcm3008-objs := pcm3008.o
 snd-soc-rt5631-objs := rt5631.o
+snd-soc-rt5640-objs := rt5640.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
 snd-soc-sigmadsp-objs := sigmadsp.o
 snd-soc-si476x-objs := si476x.o
 snd-soc-sn95031-objs := sn95031.o
-snd-soc-spdif-tx-objs := spdif_transciever.o
+snd-soc-spdif-tx-objs := spdif_transmitter.o
 snd-soc-spdif-rx-objs := spdif_receiver.o
+snd-soc-ssm2518-objs := ssm2518.o
 snd-soc-ssm2602-objs := ssm2602.o
 snd-soc-sta32x-objs := sta32x.o
 snd-soc-sta529-objs := sta529.o
@@ -154,7 +156,7 @@ obj-$(CONFIG_SND_SOC_DA7210)        += snd-soc-da7210.o
 obj-$(CONFIG_SND_SOC_DA7213)   += snd-soc-da7213.o
 obj-$(CONFIG_SND_SOC_DA732X)   += snd-soc-da732x.o
 obj-$(CONFIG_SND_SOC_DA9055)   += snd-soc-da9055.o
-obj-$(CONFIG_SND_SOC_DFBMCS320)        += snd-soc-dfbmcs320.o
+obj-$(CONFIG_SND_SOC_BT_SCO)   += snd-soc-bt-sco.o
 obj-$(CONFIG_SND_SOC_DMIC)     += snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
 obj-$(CONFIG_SND_SOC_JZ4740_CODEC)     += snd-soc-jz4740-codec.o
@@ -168,14 +170,16 @@ obj-$(CONFIG_SND_SOC_MAX98095)    += snd-soc-max98095.o
 obj-$(CONFIG_SND_SOC_MAX9850)  += snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)  += snd-soc-mc13783.o
 obj-$(CONFIG_SND_SOC_ML26124)  += snd-soc-ml26124.o
-obj-$(CONFIG_SND_SOC_OMAP_HDMI_CODEC) += snd-soc-omap-hdmi-codec.o
+obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
 obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
 obj-$(CONFIG_SND_SOC_RT5631)   += snd-soc-rt5631.o
+obj-$(CONFIG_SND_SOC_RT5640)   += snd-soc-rt5640.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.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_SSM2518)  += snd-soc-ssm2518.o
 obj-$(CONFIG_SND_SOC_SSM2602)  += snd-soc-ssm2602.o
 obj-$(CONFIG_SND_SOC_STA32X)   += snd-soc-sta32x.o
 obj-$(CONFIG_SND_SOC_STA529)   += snd-soc-sta529.o
index a153b16..b8ba0ad 100644 (file)
@@ -1496,6 +1496,12 @@ static const char * const enum_ad_to_slot_map[] = {"AD_OUT1",
                                        "AD_OUT7",
                                        "AD_OUT8",
                                        "zeroes",
+                                       "zeroes",
+                                       "zeroes",
+                                       "zeroes",
+                                       "tristate",
+                                       "tristate",
+                                       "tristate",
                                        "tristate"};
 static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map,
                        AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT,
@@ -2230,7 +2236,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
                int slots, int slot_width)
 {
        struct snd_soc_codec *codec = dai->codec;
-       unsigned int val, mask, slots_active;
+       unsigned int val, mask, slot, slots_active;
 
        mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
                BIT(AB8500_DIGIFCONF2_IF0WL1);
@@ -2286,27 +2292,34 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
        snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
 
        /* Setup TDM DA according to active tx slots */
+
+       if (tx_mask & ~0xff)
+               return -EINVAL;
+
        mask = AB8500_DASLOTCONFX_SLTODAX_MASK;
+       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__,
                slots_active);
+
        switch (slots_active) {
        case 0:
                break;
        case 1:
-               /* Slot 9 -> DA_IN1 & DA_IN3 */
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11);
+               slot = find_first_bit((unsigned long *)&tx_mask, 32);
+               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);
                break;
        case 2:
-               /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11);
-               snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11);
-
+               slot = find_first_bit((unsigned long *)&tx_mask, 32);
+               snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot);
+               snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot);
+               slot = find_next_bit((unsigned long *)&tx_mask, 32, slot + 1);
+               snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot);
+               snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot);
                break;
        case 8:
                dev_dbg(dai->codec->dev,
@@ -2321,25 +2334,36 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
        }
 
        /* Setup TDM AD according to active RX-slots */
+
+       if (rx_mask & ~0xff)
+               return -EINVAL;
+
+       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__,
                slots_active);
+
        switch (slots_active) {
        case 0:
                break;
        case 1:
-               /* AD_OUT3 -> slot 0 & 1 */
-               snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL,
-                               AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
-                               AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD);
+               slot = find_first_bit((unsigned long *)&rx_mask, 32);
+               snd_soc_update_bits(codec, AB8500_ADSLOTSEL(slot),
+                               AB8500_MASK_SLOT(slot),
+                               AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
                break;
        case 2:
-               /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
+               slot = find_first_bit((unsigned long *)&rx_mask, 32);
                snd_soc_update_bits(codec,
-                               AB8500_ADSLOTSEL1,
-                               AB8500_MASK_ALL,
-                               AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
-                               AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD);
+                               AB8500_ADSLOTSEL(slot),
+                               AB8500_MASK_SLOT(slot),
+                               AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
+               slot = find_next_bit((unsigned long *)&rx_mask, 32, slot + 1);
+               snd_soc_update_bits(codec,
+                               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,
@@ -2356,6 +2380,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
        return 0;
 }
 
+static const struct snd_soc_dai_ops ab8500_codec_ops = {
+       .set_fmt = ab8500_codec_set_dai_fmt,
+       .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
+};
+
 static struct snd_soc_dai_driver ab8500_codec_dai[] = {
        {
                .name = "ab8500-codec-dai.0",
@@ -2367,12 +2396,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
                        .rates = AB8500_SUPPORTED_RATE,
                        .formats = AB8500_SUPPORTED_FMT,
                },
-               .ops = (struct snd_soc_dai_ops[]) {
-                       {
-                               .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
-                               .set_fmt = ab8500_codec_set_dai_fmt,
-                       }
-               },
+               .ops = &ab8500_codec_ops,
                .symmetric_rates = 1
        },
        {
@@ -2385,12 +2409,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
                        .rates = AB8500_SUPPORTED_RATE,
                        .formats = AB8500_SUPPORTED_FMT,
                },
-               .ops = (struct snd_soc_dai_ops[]) {
-                       {
-                               .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
-                               .set_fmt = ab8500_codec_set_dai_fmt,
-                       }
-               },
+               .ops = &ab8500_codec_ops,
                .symmetric_rates = 1
        }
 };
index 306d0bc..e2e5442 100644 (file)
 #define AB8500_SUPPORTED_RATE                  (SNDRV_PCM_RATE_48000)
 #define AB8500_SUPPORTED_FMT                   (SNDRV_PCM_FMTBIT_S16_LE)
 
+/* AB8500 interface slot offset definitions */
+
+#define AB8500_AD_DATA0_OFFSET 0
+#define AB8500_DA_DATA0_OFFSET 8
+#define AB8500_AD_DATA1_OFFSET 16
+#define AB8500_DA_DATA1_OFFSET 24
+
 /* AB8500 audio bank (0x0d) register definitions */
 
 #define AB8500_POWERUP                         0x00
@@ -73,6 +80,7 @@
 #define AB8500_ADSLOTSEL14                     0x2C
 #define AB8500_ADSLOTSEL15                     0x2D
 #define AB8500_ADSLOTSEL16                     0x2E
+#define AB8500_ADSLOTSEL(slot)                 (AB8500_ADSLOTSEL1 + (slot >> 1))
 #define AB8500_ADSLOTHIZCTRL1                  0x2F
 #define AB8500_ADSLOTHIZCTRL2                  0x30
 #define AB8500_ADSLOTHIZCTRL3                  0x31
 #define AB8500_CACHEREGNUM                     (AB8500_LAST_REG + 1)
 
 #define AB8500_MASK_ALL                                0xFF
+#define AB8500_MASK_SLOT(slot)                 ((slot & 1) ? 0xF0 : 0x0F)
 #define AB8500_MASK_NONE                       0x00
 
 /* AB8500_POWERUP */
 #define AB8500_DIGIFCONF4_IF1WL0               0
 
 /* AB8500_ADSLOTSELX */
-#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD  0x00
-#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD  0x10
-#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD  0x20
-#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD  0x30
-#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD  0x40
-#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD  0x50
-#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD  0x60
-#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD  0x70
-#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD   0x80
-#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0
-#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
-#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01
-#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02
-#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03
-#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04
-#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05
-#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06
-#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07
-#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN  0x08
-#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN        0x0F
+#define AB8500_AD_OUT1 0x0
+#define AB8500_AD_OUT2 0x1
+#define AB8500_AD_OUT3 0x2
+#define AB8500_AD_OUT4 0x3
+#define AB8500_AD_OUT5 0x4
+#define AB8500_AD_OUT6 0x5
+#define AB8500_AD_OUT7 0x6
+#define AB8500_AD_OUT8 0x7
+#define AB8500_ZEROES  0x8
+#define AB8500_TRISTATE        0xF
 #define AB8500_ADSLOTSELX_EVEN_SHIFT           0
 #define AB8500_ADSLOTSELX_ODD_SHIFT            4
+#define AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(out, slot)    \
+       ((out) << (((slot) & 1) ? \
+        AB8500_ADSLOTSELX_ODD_SHIFT : AB8500_ADSLOTSELX_EVEN_SHIFT))
 
 /* AB8500_ADSLOTHIZCTRL1 */
 /* AB8500_ADSLOTHIZCTRL2 */
index dafdbe8..b6b1a77 100644 (file)
@@ -13,6 +13,9 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -87,6 +90,7 @@
 #define ADAU1701_FIRMWARE "adau1701.bin"
 
 struct adau1701 {
+       int gpio_nreset;
        unsigned int dai_fmt;
 };
 
@@ -180,9 +184,37 @@ static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg)
        return value;
 }
 
-static int adau1701_load_firmware(struct snd_soc_codec *codec)
+static void adau1701_reset(struct snd_soc_codec *codec)
 {
-       return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE);
+       struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
+
+       if (!gpio_is_valid(adau1701->gpio_nreset))
+               return;
+
+       gpio_set_value(adau1701->gpio_nreset, 0);
+       /* minimum reset time is 20ns */
+       udelay(1);
+       gpio_set_value(adau1701->gpio_nreset, 1);
+       /* power-up time may be as long as 85ms */
+       mdelay(85);
+}
+
+static int adau1701_init(struct snd_soc_codec *codec)
+{
+       int ret;
+       struct i2c_client *client = to_i2c_client(codec->dev);
+
+       adau1701_reset(codec);
+
+       ret = process_sigma_firmware(client, ADAU1701_FIRMWARE);
+       if (ret) {
+               dev_warn(codec->dev, "Failed to load firmware\n");
+               return ret;
+       }
+
+       snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
+
+       return 0;
 }
 
 static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
@@ -452,17 +484,24 @@ static struct snd_soc_dai_driver adau1701_dai = {
        .symmetric_rates = 1,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id adau1701_dt_ids[] = {
+       { .compatible = "adi,adau1701", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
+#endif
+
 static int adau1701_probe(struct snd_soc_codec *codec)
 {
        int ret;
 
        codec->control_data = to_i2c_client(codec->dev);
 
-       ret = adau1701_load_firmware(codec);
+       ret = adau1701_init(codec);
        if (ret)
-               dev_warn(codec->dev, "Failed to load firmware\n");
+               return ret;
 
-       snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
        snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
 
        return 0;
@@ -493,12 +532,29 @@ static int adau1701_i2c_probe(struct i2c_client *client,
                              const struct i2c_device_id *id)
 {
        struct adau1701 *adau1701;
+       struct device *dev = &client->dev;
+       int gpio_nreset = -EINVAL;
        int ret;
 
-       adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL);
+       adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
        if (!adau1701)
                return -ENOMEM;
 
+       if (dev->of_node) {
+               gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
+               if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
+                       return gpio_nreset;
+       }
+
+       if (gpio_is_valid(gpio_nreset)) {
+               ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
+                                           "ADAU1701 Reset");
+               if (ret < 0)
+                       return ret;
+       }
+
+       adau1701->gpio_nreset = gpio_nreset;
+
        i2c_set_clientdata(client, adau1701);
        ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
                        &adau1701_dai, 1);
@@ -521,6 +577,7 @@ static struct i2c_driver adau1701_i2c_driver = {
        .driver = {
                .name   = "adau1701",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(adau1701_dt_ids),
        },
        .probe          = adau1701_i2c_probe,
        .remove         = adau1701_i2c_remove,
index 389f232..de62581 100644 (file)
@@ -1198,6 +1198,13 @@ const struct snd_soc_dai_ops arizona_dai_ops = {
 };
 EXPORT_SYMBOL_GPL(arizona_dai_ops);
 
+const struct snd_soc_dai_ops arizona_simple_dai_ops = {
+       .startup = arizona_startup,
+       .hw_params = arizona_hw_params_rate,
+       .set_sysclk = arizona_dai_set_sysclk,
+};
+EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
+
 int arizona_init_dai(struct arizona_priv *priv, int id)
 {
        struct arizona_dai_priv *dai_priv = &priv->dai[id];
index af39f10..b60b08c 100644 (file)
@@ -57,7 +57,7 @@
 #define ARIZONA_CLK_98MHZ  5
 #define ARIZONA_CLK_147MHZ 6
 
-#define ARIZONA_MAX_DAI  4
+#define ARIZONA_MAX_DAI  6
 #define ARIZONA_MAX_ADSP 4
 
 struct arizona;
@@ -213,6 +213,7 @@ extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                              int source, unsigned int freq, int dir);
 
 extern const struct snd_soc_dai_ops arizona_dai_ops;
+extern const struct snd_soc_dai_ops arizona_simple_dai_ops;
 
 #define ARIZONA_FLL_NAME_LEN 20
 
similarity index 53%
rename from sound/soc/codecs/dfbmcs320.c
rename to sound/soc/codecs/bt-sco.c
index 4f4f7f4..a081d9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Driver for the DFBM-CS320 bluetooth module
+ * Driver for generic Bluetooth SCO link
  * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -15,8 +15,8 @@
 
 #include <sound/soc.h>
 
-static struct snd_soc_dai_driver dfbmcs320_dai = {
-       .name = "dfbmcs320-pcm",
+static struct snd_soc_dai_driver bt_sco_dai = {
+       .name = "bt-sco-pcm",
        .playback = {
                .channels_min = 1,
                .channels_max = 1,
@@ -31,32 +31,41 @@ static struct snd_soc_dai_driver dfbmcs320_dai = {
        },
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
+static struct snd_soc_codec_driver soc_codec_dev_bt_sco;
 
-static int dfbmcs320_probe(struct platform_device *pdev)
+static int bt_sco_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
-                       &dfbmcs320_dai, 1);
+       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_bt_sco,
+                       &bt_sco_dai, 1);
 }
 
-static int dfbmcs320_remove(struct platform_device *pdev)
+static int bt_sco_remove(struct platform_device *pdev)
 {
        snd_soc_unregister_codec(&pdev->dev);
 
        return 0;
 }
 
-static struct platform_driver dfmcs320_driver = {
+static struct platform_device_id bt_sco_driver_ids[] = {
+       {
+               .name           = "dfbmcs320",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
+
+static struct platform_driver bt_sco_driver = {
        .driver = {
-               .name = "dfbmcs320",
+               .name = "bt-sco",
                .owner = THIS_MODULE,
        },
-       .probe = dfbmcs320_probe,
-       .remove = dfbmcs320_remove,
+       .probe = bt_sco_probe,
+       .remove = bt_sco_remove,
+       .id_table = bt_sco_driver_ids,
 };
 
-module_platform_driver(dfmcs320_driver);
+module_platform_driver(bt_sco_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
+MODULE_DESCRIPTION("ASoC generic bluethooth sco link driver");
 MODULE_LICENSE("GPL");
index 0f6f481..987f728 100644 (file)
@@ -86,7 +86,7 @@ static const struct reg_default cs42l52_reg_defaults[] = {
        { CS42L52_BEEP_VOL, 0x00 },     /* r1D Beep Volume off Time */
        { CS42L52_BEEP_TONE_CTL, 0x00 },        /* r1E Beep Tone Cfg. */
        { CS42L52_TONE_CTL, 0x00 },     /* r1F Tone Ctl */
-       { CS42L52_MASTERA_VOL, 0x88 },  /* r20 Master A Volume */
+       { CS42L52_MASTERA_VOL, 0x00 },  /* r20 Master A Volume */
        { CS42L52_MASTERB_VOL, 0x00 },  /* r21 Master B Volume */
        { CS42L52_HPA_VOL, 0x00 },      /* r22 Headphone A Volume */
        { CS42L52_HPB_VOL, 0x00 },      /* r23 Headphone B Volume */
@@ -193,6 +193,8 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);
 
 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
 
+static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0);
+
 static const unsigned int limiter_tlv[] = {
        TLV_DB_RANGE_HEAD(2),
        0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
@@ -225,7 +227,7 @@ static const char * const mic_bias_level_text[] = {
 };
 
 static const struct soc_enum mic_bias_level_enum =
-       SOC_ENUM_SINGLE(CS42L52_IFACE_CTL1, 0,
+       SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0,
                        ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
 
 static const char * const cs42l52_mic_text[] = { "Single", "Differential" };
@@ -260,7 +262,7 @@ static const char * const hp_gain_num_text[] = {
 };
 
 static const struct soc_enum hp_gain_enum =
-       SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 4,
+       SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5,
                ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text);
 
 static const char * const beep_pitch_text[] = {
@@ -413,7 +415,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
        SOC_ENUM("Headphone Analog Gain", hp_gain_enum),
 
        SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL,
-                             CS42L52_SPKB_VOL, 7, 0x1, 0xff, hl_tlv),
+                             CS42L52_SPKB_VOL, 0, 0x1, 0xff, hl_tlv),
 
        SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL,
                              CS42L52_PASSTHRUB_VOL, 6, 0x18, 0x90, pga_tlv),
@@ -441,7 +443,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
 
        SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume",
                            CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL,
-                               6, 0x7f, 0x19, hl_tlv),
+                               0, 0x7f, 0x19, mix_tlv),
        SOC_DOUBLE_R("PCM Mixer Switch",
                     CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, 7, 1, 1),
 
index 60985c0..4277012 100644 (file)
 #define CS42L52_PB_CTL1_INV_PCMA               (1 << 2)
 #define CS42L52_PB_CTL1_MSTB_MUTE              (1 << 1)
 #define CS42L52_PB_CTL1_MSTA_MUTE              (1 << 0)
-#define CS42L52_PB_CTL1_MUTE_MASK              0xFFFD
+#define CS42L52_PB_CTL1_MUTE_MASK              0x03
 #define CS42L52_PB_CTL1_MUTE                   3
 #define CS42L52_PB_CTL1_UNMUTE                 0
 
similarity index 69%
rename from sound/soc/codecs/omap-hdmi.c
rename to sound/soc/codecs/hdmi.c
index 529d064..2bcae2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ALSA SoC codec driver for HDMI audio on OMAP processors.
+ * ALSA SoC codec driver for HDMI audio codecs.
  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
  * Author: Ricardo Neri <ricardo.neri@ti.com>
  *
 
 #define DRV_NAME "hdmi-audio-codec"
 
-static struct snd_soc_codec_driver omap_hdmi_codec;
+static struct snd_soc_codec_driver hdmi_codec;
 
-static struct snd_soc_dai_driver omap_hdmi_codec_dai = {
-       .name = "omap-hdmi-hifi",
+static struct snd_soc_dai_driver hdmi_codec_dai = {
+       .name = "hdmi-hifi",
        .playback = {
                .channels_min = 2,
                .channels_max = 8,
@@ -39,31 +39,31 @@ static struct snd_soc_dai_driver omap_hdmi_codec_dai = {
        },
 };
 
-static int omap_hdmi_codec_probe(struct platform_device *pdev)
+static int hdmi_codec_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_codec(&pdev->dev, &omap_hdmi_codec,
-                       &omap_hdmi_codec_dai, 1);
+       return snd_soc_register_codec(&pdev->dev, &hdmi_codec,
+                       &hdmi_codec_dai, 1);
 }
 
-static int omap_hdmi_codec_remove(struct platform_device *pdev)
+static int hdmi_codec_remove(struct platform_device *pdev)
 {
        snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
-static struct platform_driver omap_hdmi_codec_driver = {
+static struct platform_driver hdmi_codec_driver = {
        .driver         = {
                .name   = DRV_NAME,
                .owner  = THIS_MODULE,
        },
 
-       .probe          = omap_hdmi_codec_probe,
-       .remove         = omap_hdmi_codec_remove,
+       .probe          = hdmi_codec_probe,
+       .remove         = hdmi_codec_remove,
 };
 
-module_platform_driver(omap_hdmi_codec_driver);
+module_platform_driver(hdmi_codec_driver);
 
 MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
-MODULE_DESCRIPTION("ASoC OMAP HDMI codec driver");
+MODULE_DESCRIPTION("ASoC generic HDMI codec driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRV_NAME);
index 5f607b3..bcebd1a 100644 (file)
@@ -384,8 +384,6 @@ static int jz4740_codec_remove(struct platform_device *pdev)
 {
        snd_soc_unregister_codec(&pdev->dev);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index ce0d364..ad5313f 100644 (file)
@@ -857,6 +857,14 @@ static const struct soc_enum mic2_mux_enum =
 static const struct snd_kcontrol_new max98090_mic2_mux =
        SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum);
 
+static const char *dmic_mux_text[] = { "ADC", "DMIC" };
+
+static const struct soc_enum dmic_mux_enum =
+       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dmic_mux_text), dmic_mux_text);
+
+static const struct snd_kcontrol_new max98090_dmic_mux =
+       SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum);
+
 static const char *max98090_micpre_text[] = { "Off", "On" };
 
 static const struct soc_enum max98090_pa1en_enum =
@@ -1144,6 +1152,9 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
        SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM,
                0, 0, &max98090_mic2_mux),
 
+       SND_SOC_DAPM_VIRT_MUX("DMIC Mux", SND_SOC_NOPM,
+               0, 0, &max98090_dmic_mux),
+
        SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL,
                M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event,
                SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -1336,11 +1347,14 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
        {"ADCL", NULL, "SHDN"},
        {"ADCR", NULL, "SHDN"},
 
-       {"LBENL Mux", "Normal", "ADCL"},
-       {"LBENL Mux", "Normal", "DMICL"},
+       {"DMIC Mux", "ADC", "ADCL"},
+       {"DMIC Mux", "ADC", "ADCR"},
+       {"DMIC Mux", "DMIC", "DMICL"},
+       {"DMIC Mux", "DMIC", "DMICR"},
+
+       {"LBENL Mux", "Normal", "DMIC Mux"},
        {"LBENL Mux", "Loopback", "LTENL Mux"},
-       {"LBENR Mux", "Normal", "ADCR"},
-       {"LBENR Mux", "Normal", "DMICR"},
+       {"LBENR Mux", "Normal", "DMIC Mux"},
        {"LBENR Mux", "Loopback", "LTENR Mux"},
 
        {"AIFOUTL", NULL, "LBENL Mux"},
@@ -2233,7 +2247,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
        dev_dbg(codec->dev, "irq = %d\n", max98090->irq);
 
        ret = request_threaded_irq(max98090->irq, NULL,
-               max98090_interrupt, IRQF_TRIGGER_FALLING,
+               max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                "max98090_interrupt", codec);
        if (ret < 0) {
                dev_err(codec->dev, "request_irq failed: %d\n",
@@ -2336,6 +2350,7 @@ static int max98090_i2c_remove(struct i2c_client *client)
        return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
 static int max98090_runtime_resume(struct device *dev)
 {
        struct max98090_priv *max98090 = dev_get_drvdata(dev);
@@ -2355,6 +2370,7 @@ static int max98090_runtime_suspend(struct device *dev)
 
        return 0;
 }
+#endif
 
 static const struct dev_pm_ops max98090_pm = {
        SET_RUNTIME_PM_OPS(max98090_runtime_suspend,
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
new file mode 100644 (file)
index 0000000..ce585e3
--- /dev/null
@@ -0,0 +1,2128 @@
+/*
+ * rt5640.c  --  RT5640 ALSA SoC audio codec driver
+ *
+ * Copyright 2011 Realtek Semiconductor Corp.
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "rt5640.h"
+
+#define RT5640_DEVICE_ID 0x6231
+
+#define RT5640_PR_RANGE_BASE (0xff + 1)
+#define RT5640_PR_SPACING 0x100
+
+#define RT5640_PR_BASE (RT5640_PR_RANGE_BASE + (0 * RT5640_PR_SPACING))
+
+static const struct regmap_range_cfg rt5640_ranges[] = {
+       { .name = "PR", .range_min = RT5640_PR_BASE,
+         .range_max = RT5640_PR_BASE + 0xb4,
+         .selector_reg = RT5640_PRIV_INDEX,
+         .selector_mask = 0xff,
+         .selector_shift = 0x0,
+         .window_start = RT5640_PRIV_DATA,
+         .window_len = 0x1, },
+};
+
+static struct reg_default init_list[] = {
+       {RT5640_PR_BASE + 0x3d, 0x3600},
+       {RT5640_PR_BASE + 0x1c, 0x0D21},
+       {RT5640_PR_BASE + 0x1b, 0x0000},
+       {RT5640_PR_BASE + 0x12, 0x0aa8},
+       {RT5640_PR_BASE + 0x14, 0x0aaa},
+       {RT5640_PR_BASE + 0x20, 0x6110},
+       {RT5640_PR_BASE + 0x21, 0xe0e0},
+       {RT5640_PR_BASE + 0x23, 0x1804},
+};
+#define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list)
+
+static const struct reg_default rt5640_reg[RT5640_VENDOR_ID2 + 1] = {
+       { 0x00, 0x000e },
+       { 0x01, 0xc8c8 },
+       { 0x02, 0xc8c8 },
+       { 0x03, 0xc8c8 },
+       { 0x04, 0x8000 },
+       { 0x0d, 0x0000 },
+       { 0x0e, 0x0000 },
+       { 0x0f, 0x0808 },
+       { 0x19, 0xafaf },
+       { 0x1a, 0xafaf },
+       { 0x1b, 0x0000 },
+       { 0x1c, 0x2f2f },
+       { 0x1d, 0x2f2f },
+       { 0x1e, 0x0000 },
+       { 0x27, 0x7060 },
+       { 0x28, 0x7070 },
+       { 0x29, 0x8080 },
+       { 0x2a, 0x5454 },
+       { 0x2b, 0x5454 },
+       { 0x2c, 0xaa00 },
+       { 0x2d, 0x0000 },
+       { 0x2e, 0xa000 },
+       { 0x2f, 0x0000 },
+       { 0x3b, 0x0000 },
+       { 0x3c, 0x007f },
+       { 0x3d, 0x0000 },
+       { 0x3e, 0x007f },
+       { 0x45, 0xe000 },
+       { 0x46, 0x003e },
+       { 0x47, 0x003e },
+       { 0x48, 0xf800 },
+       { 0x49, 0x3800 },
+       { 0x4a, 0x0004 },
+       { 0x4c, 0xfc00 },
+       { 0x4d, 0x0000 },
+       { 0x4f, 0x01ff },
+       { 0x50, 0x0000 },
+       { 0x51, 0x0000 },
+       { 0x52, 0x01ff },
+       { 0x53, 0xf000 },
+       { 0x61, 0x0000 },
+       { 0x62, 0x0000 },
+       { 0x63, 0x00c0 },
+       { 0x64, 0x0000 },
+       { 0x65, 0x0000 },
+       { 0x66, 0x0000 },
+       { 0x6a, 0x0000 },
+       { 0x6c, 0x0000 },
+       { 0x70, 0x8000 },
+       { 0x71, 0x8000 },
+       { 0x72, 0x8000 },
+       { 0x73, 0x1114 },
+       { 0x74, 0x0c00 },
+       { 0x75, 0x1d00 },
+       { 0x80, 0x0000 },
+       { 0x81, 0x0000 },
+       { 0x82, 0x0000 },
+       { 0x83, 0x0000 },
+       { 0x84, 0x0000 },
+       { 0x85, 0x0008 },
+       { 0x89, 0x0000 },
+       { 0x8a, 0x0000 },
+       { 0x8b, 0x0600 },
+       { 0x8c, 0x0228 },
+       { 0x8d, 0xa000 },
+       { 0x8e, 0x0004 },
+       { 0x8f, 0x1100 },
+       { 0x90, 0x0646 },
+       { 0x91, 0x0c00 },
+       { 0x92, 0x0000 },
+       { 0x93, 0x3000 },
+       { 0xb0, 0x2080 },
+       { 0xb1, 0x0000 },
+       { 0xb4, 0x2206 },
+       { 0xb5, 0x1f00 },
+       { 0xb6, 0x0000 },
+       { 0xb8, 0x034b },
+       { 0xb9, 0x0066 },
+       { 0xba, 0x000b },
+       { 0xbb, 0x0000 },
+       { 0xbc, 0x0000 },
+       { 0xbd, 0x0000 },
+       { 0xbe, 0x0000 },
+       { 0xbf, 0x0000 },
+       { 0xc0, 0x0400 },
+       { 0xc2, 0x0000 },
+       { 0xc4, 0x0000 },
+       { 0xc5, 0x0000 },
+       { 0xc6, 0x2000 },
+       { 0xc8, 0x0000 },
+       { 0xc9, 0x0000 },
+       { 0xca, 0x0000 },
+       { 0xcb, 0x0000 },
+       { 0xcc, 0x0000 },
+       { 0xcf, 0x0013 },
+       { 0xd0, 0x0680 },
+       { 0xd1, 0x1c17 },
+       { 0xd2, 0x8c00 },
+       { 0xd3, 0xaa20 },
+       { 0xd6, 0x0400 },
+       { 0xd9, 0x0809 },
+       { 0xfe, 0x10ec },
+       { 0xff, 0x6231 },
+};
+
+static int rt5640_reset(struct snd_soc_codec *codec)
+{
+       return snd_soc_write(codec, RT5640_RESET, 0);
+}
+
+static bool rt5640_volatile_register(struct device *dev, unsigned int reg)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(rt5640_ranges); i++)
+               if ((reg >= rt5640_ranges[i].window_start &&
+                    reg <= rt5640_ranges[i].window_start +
+                    rt5640_ranges[i].window_len) ||
+                   (reg >= rt5640_ranges[i].range_min &&
+                    reg <= rt5640_ranges[i].range_max))
+                       return true;
+
+       switch (reg) {
+       case RT5640_RESET:
+       case RT5640_ASRC_5:
+       case RT5640_EQ_CTRL1:
+       case RT5640_DRC_AGC_1:
+       case RT5640_ANC_CTRL1:
+       case RT5640_IRQ_CTRL2:
+       case RT5640_INT_IRQ_ST:
+       case RT5640_DSP_CTRL2:
+       case RT5640_DSP_CTRL3:
+       case RT5640_PRIV_INDEX:
+       case RT5640_PRIV_DATA:
+       case RT5640_PGM_REG_ARR1:
+       case RT5640_PGM_REG_ARR3:
+       case RT5640_VENDOR_ID:
+       case RT5640_VENDOR_ID1:
+       case RT5640_VENDOR_ID2:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool rt5640_readable_register(struct device *dev, unsigned int reg)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(rt5640_ranges); i++)
+               if ((reg >= rt5640_ranges[i].window_start &&
+                    reg <= rt5640_ranges[i].window_start +
+                    rt5640_ranges[i].window_len) ||
+                   (reg >= rt5640_ranges[i].range_min &&
+                    reg <= rt5640_ranges[i].range_max))
+                       return true;
+
+       switch (reg) {
+       case RT5640_RESET:
+       case RT5640_SPK_VOL:
+       case RT5640_HP_VOL:
+       case RT5640_OUTPUT:
+       case RT5640_MONO_OUT:
+       case RT5640_IN1_IN2:
+       case RT5640_IN3_IN4:
+       case RT5640_INL_INR_VOL:
+       case RT5640_DAC1_DIG_VOL:
+       case RT5640_DAC2_DIG_VOL:
+       case RT5640_DAC2_CTRL:
+       case RT5640_ADC_DIG_VOL:
+       case RT5640_ADC_DATA:
+       case RT5640_ADC_BST_VOL:
+       case RT5640_STO_ADC_MIXER:
+       case RT5640_MONO_ADC_MIXER:
+       case RT5640_AD_DA_MIXER:
+       case RT5640_STO_DAC_MIXER:
+       case RT5640_MONO_DAC_MIXER:
+       case RT5640_DIG_MIXER:
+       case RT5640_DSP_PATH1:
+       case RT5640_DSP_PATH2:
+       case RT5640_DIG_INF_DATA:
+       case RT5640_REC_L1_MIXER:
+       case RT5640_REC_L2_MIXER:
+       case RT5640_REC_R1_MIXER:
+       case RT5640_REC_R2_MIXER:
+       case RT5640_HPO_MIXER:
+       case RT5640_SPK_L_MIXER:
+       case RT5640_SPK_R_MIXER:
+       case RT5640_SPO_L_MIXER:
+       case RT5640_SPO_R_MIXER:
+       case RT5640_SPO_CLSD_RATIO:
+       case RT5640_MONO_MIXER:
+       case RT5640_OUT_L1_MIXER:
+       case RT5640_OUT_L2_MIXER:
+       case RT5640_OUT_L3_MIXER:
+       case RT5640_OUT_R1_MIXER:
+       case RT5640_OUT_R2_MIXER:
+       case RT5640_OUT_R3_MIXER:
+       case RT5640_LOUT_MIXER:
+       case RT5640_PWR_DIG1:
+       case RT5640_PWR_DIG2:
+       case RT5640_PWR_ANLG1:
+       case RT5640_PWR_ANLG2:
+       case RT5640_PWR_MIXER:
+       case RT5640_PWR_VOL:
+       case RT5640_PRIV_INDEX:
+       case RT5640_PRIV_DATA:
+       case RT5640_I2S1_SDP:
+       case RT5640_I2S2_SDP:
+       case RT5640_ADDA_CLK1:
+       case RT5640_ADDA_CLK2:
+       case RT5640_DMIC:
+       case RT5640_GLB_CLK:
+       case RT5640_PLL_CTRL1:
+       case RT5640_PLL_CTRL2:
+       case RT5640_ASRC_1:
+       case RT5640_ASRC_2:
+       case RT5640_ASRC_3:
+       case RT5640_ASRC_4:
+       case RT5640_ASRC_5:
+       case RT5640_HP_OVCD:
+       case RT5640_CLS_D_OVCD:
+       case RT5640_CLS_D_OUT:
+       case RT5640_DEPOP_M1:
+       case RT5640_DEPOP_M2:
+       case RT5640_DEPOP_M3:
+       case RT5640_CHARGE_PUMP:
+       case RT5640_PV_DET_SPK_G:
+       case RT5640_MICBIAS:
+       case RT5640_EQ_CTRL1:
+       case RT5640_EQ_CTRL2:
+       case RT5640_WIND_FILTER:
+       case RT5640_DRC_AGC_1:
+       case RT5640_DRC_AGC_2:
+       case RT5640_DRC_AGC_3:
+       case RT5640_SVOL_ZC:
+       case RT5640_ANC_CTRL1:
+       case RT5640_ANC_CTRL2:
+       case RT5640_ANC_CTRL3:
+       case RT5640_JD_CTRL:
+       case RT5640_ANC_JD:
+       case RT5640_IRQ_CTRL1:
+       case RT5640_IRQ_CTRL2:
+       case RT5640_INT_IRQ_ST:
+       case RT5640_GPIO_CTRL1:
+       case RT5640_GPIO_CTRL2:
+       case RT5640_GPIO_CTRL3:
+       case RT5640_DSP_CTRL1:
+       case RT5640_DSP_CTRL2:
+       case RT5640_DSP_CTRL3:
+       case RT5640_DSP_CTRL4:
+       case RT5640_PGM_REG_ARR1:
+       case RT5640_PGM_REG_ARR2:
+       case RT5640_PGM_REG_ARR3:
+       case RT5640_PGM_REG_ARR4:
+       case RT5640_PGM_REG_ARR5:
+       case RT5640_SCB_FUNC:
+       case RT5640_SCB_CTRL:
+       case RT5640_BASE_BACK:
+       case RT5640_MP3_PLUS1:
+       case RT5640_MP3_PLUS2:
+       case RT5640_3D_HP:
+       case RT5640_ADJ_HPF:
+       case RT5640_HP_CALIB_AMP_DET:
+       case RT5640_HP_CALIB2:
+       case RT5640_SV_ZCD1:
+       case RT5640_SV_ZCD2:
+       case RT5640_DUMMY1:
+       case RT5640_DUMMY2:
+       case RT5640_DUMMY3:
+       case RT5640_VENDOR_ID:
+       case RT5640_VENDOR_ID1:
+       case RT5640_VENDOR_ID2:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
+
+/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
+static unsigned int bst_tlv[] = {
+       TLV_DB_RANGE_HEAD(7),
+       0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+       1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+       2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
+       3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
+       6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
+       7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
+       8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
+};
+
+/* Interface data select */
+static const char * const rt5640_data_select[] = {
+       "Normal", "left copy to right", "right copy to left", "Swap"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5640_if1_dac_enum, RT5640_DIG_INF_DATA,
+                               RT5640_IF1_DAC_SEL_SFT, rt5640_data_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5640_if1_adc_enum, RT5640_DIG_INF_DATA,
+                               RT5640_IF1_ADC_SEL_SFT, rt5640_data_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5640_if2_dac_enum, RT5640_DIG_INF_DATA,
+                               RT5640_IF2_DAC_SEL_SFT, rt5640_data_select);
+
+static const SOC_ENUM_SINGLE_DECL(rt5640_if2_adc_enum, RT5640_DIG_INF_DATA,
+                               RT5640_IF2_ADC_SEL_SFT, rt5640_data_select);
+
+/* Class D speaker gain ratio */
+static const char * const rt5640_clsd_spk_ratio[] = {"1.66x", "1.83x", "1.94x",
+       "2x", "2.11x", "2.22x", "2.33x", "2.44x", "2.55x", "2.66x", "2.77x"};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_clsd_spk_ratio_enum, RT5640_CLS_D_OUT,
+       RT5640_CLSD_RATIO_SFT, rt5640_clsd_spk_ratio);
+
+static const struct snd_kcontrol_new rt5640_snd_controls[] = {
+       /* Speaker Output Volume */
+       SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL,
+               RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL,
+               RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
+       SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL,
+               RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
+       /* Headphone Output Volume */
+       SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL,
+               RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL,
+               RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
+       SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL,
+               RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
+       /* OUTPUT Control */
+       SOC_DOUBLE("OUT Playback Switch", RT5640_OUTPUT,
+               RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE("OUT Channel Switch", RT5640_OUTPUT,
+               RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
+       SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT,
+               RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
+       /* MONO Output Control */
+       SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT,
+                               RT5640_L_MUTE_SFT, 1, 1),
+       /* DAC Digital Volume */
+       SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL,
+               RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1),
+       SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL,
+                       RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
+                       175, 0, dac_vol_tlv),
+       SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL,
+                       RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
+                       175, 0, dac_vol_tlv),
+       /* IN1/IN2 Control */
+       SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2,
+               RT5640_BST_SFT1, 8, 0, bst_tlv),
+       SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4,
+               RT5640_BST_SFT2, 8, 0, bst_tlv),
+       /* INL/INR Volume Control */
+       SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL,
+                       RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT,
+                       31, 1, in_vol_tlv),
+       /* ADC Digital Volume Control */
+       SOC_DOUBLE("ADC Capture Switch", RT5640_ADC_DIG_VOL,
+               RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE_TLV("ADC Capture Volume", RT5640_ADC_DIG_VOL,
+                       RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
+                       127, 0, adc_vol_tlv),
+       SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5640_ADC_DATA,
+                       RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
+                       127, 0, adc_vol_tlv),
+       /* ADC Boost Volume Control */
+       SOC_DOUBLE_TLV("ADC Boost Gain", RT5640_ADC_BST_VOL,
+                       RT5640_ADC_L_BST_SFT, RT5640_ADC_R_BST_SFT,
+                       3, 0, adc_bst_tlv),
+       /* Class D speaker gain ratio */
+       SOC_ENUM("Class D SPK Ratio Control", rt5640_clsd_spk_ratio_enum),
+
+       SOC_ENUM("ADC IF1 Data Switch", rt5640_if1_adc_enum),
+       SOC_ENUM("DAC IF1 Data Switch", rt5640_if1_dac_enum),
+       SOC_ENUM("ADC IF2 Data Switch", rt5640_if2_adc_enum),
+       SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum),
+};
+
+/**
+ * set_dmic_clk - Set parameter of dmic.
+ *
+ * @w: DAPM widget.
+ * @kcontrol: The kcontrol of this widget.
+ * @event: Event id.
+ *
+ * Choose dmic clock between 1MHz and 3MHz.
+ * It is better for clock to approximate 3MHz.
+ */
+static int set_dmic_clk(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       int div[] = {2, 3, 4, 6, 8, 12};
+       int idx = -EINVAL, i;
+       int rate, red, bound, temp;
+
+       rate = rt5640->sysclk;
+       red = 3000000 * 12;
+       for (i = 0; i < ARRAY_SIZE(div); i++) {
+               bound = div[i] * 3000000;
+               if (rate > bound)
+                       continue;
+               temp = bound - rate;
+               if (temp < red) {
+                       red = temp;
+                       idx = i;
+               }
+       }
+       if (idx < 0)
+               dev_err(codec->dev, "Failed to set DMIC clock\n");
+       else
+               snd_soc_update_bits(codec, RT5640_DMIC, RT5640_DMIC_CLK_MASK,
+                                       idx << RT5640_DMIC_CLK_SFT);
+       return idx;
+}
+
+static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
+                        struct snd_soc_dapm_widget *sink)
+{
+       unsigned int val;
+
+       val = snd_soc_read(source->codec, RT5640_GLB_CLK);
+       val &= RT5640_SCLK_SRC_MASK;
+       if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T)
+               return 1;
+       else
+               return 0;
+}
+
+/* Digital Mixer */
+static const struct snd_kcontrol_new rt5640_sto_adc_l_mix[] = {
+       SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER,
+                       RT5640_M_ADC_L1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ADC2 Switch", RT5640_STO_ADC_MIXER,
+                       RT5640_M_ADC_L2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_sto_adc_r_mix[] = {
+       SOC_DAPM_SINGLE("ADC1 Switch", RT5640_STO_ADC_MIXER,
+                       RT5640_M_ADC_R1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ADC2 Switch", RT5640_STO_ADC_MIXER,
+                       RT5640_M_ADC_R2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_mono_adc_l_mix[] = {
+       SOC_DAPM_SINGLE("ADC1 Switch", RT5640_MONO_ADC_MIXER,
+                       RT5640_M_MONO_ADC_L1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ADC2 Switch", RT5640_MONO_ADC_MIXER,
+                       RT5640_M_MONO_ADC_L2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_mono_adc_r_mix[] = {
+       SOC_DAPM_SINGLE("ADC1 Switch", RT5640_MONO_ADC_MIXER,
+                       RT5640_M_MONO_ADC_R1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ADC2 Switch", RT5640_MONO_ADC_MIXER,
+                       RT5640_M_MONO_ADC_R2_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_dac_l_mix[] = {
+       SOC_DAPM_SINGLE("Stereo ADC Switch", RT5640_AD_DA_MIXER,
+                       RT5640_M_ADCMIX_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INF1 Switch", RT5640_AD_DA_MIXER,
+                       RT5640_M_IF1_DAC_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_dac_r_mix[] = {
+       SOC_DAPM_SINGLE("Stereo ADC Switch", RT5640_AD_DA_MIXER,
+                       RT5640_M_ADCMIX_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INF1 Switch", RT5640_AD_DA_MIXER,
+                       RT5640_M_IF1_DAC_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_sto_dac_l_mix[] = {
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER,
+                       RT5640_M_DAC_L1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER,
+                       RT5640_M_DAC_L2_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ANC Switch", RT5640_STO_DAC_MIXER,
+                       RT5640_M_ANC_DAC_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = {
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER,
+                       RT5640_M_DAC_R1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER,
+                       RT5640_M_DAC_R2_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ANC Switch", RT5640_STO_DAC_MIXER,
+                       RT5640_M_ANC_DAC_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = {
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER,
+                       RT5640_M_DAC_L1_MONO_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_DAC_MIXER,
+                       RT5640_M_DAC_L2_MONO_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_DAC_MIXER,
+                       RT5640_M_DAC_R2_MONO_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_mono_dac_r_mix[] = {
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_MONO_DAC_MIXER,
+                       RT5640_M_DAC_R1_MONO_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_DAC_MIXER,
+                       RT5640_M_DAC_R2_MONO_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_DAC_MIXER,
+                       RT5640_M_DAC_L2_MONO_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_dig_l_mix[] = {
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_DIG_MIXER,
+                       RT5640_M_STO_L_DAC_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_DIG_MIXER,
+                       RT5640_M_DAC_L2_DAC_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_dig_r_mix[] = {
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_DIG_MIXER,
+                       RT5640_M_STO_R_DAC_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_DIG_MIXER,
+                       RT5640_M_DAC_R2_DAC_R_SFT, 1, 1),
+};
+
+/* Analog Input Mixer */
+static const struct snd_kcontrol_new rt5640_rec_l_mix[] = {
+       SOC_DAPM_SINGLE("HPOL Switch", RT5640_REC_L2_MIXER,
+                       RT5640_M_HP_L_RM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER,
+                       RT5640_M_IN_L_RM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER,
+                       RT5640_M_BST4_RM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER,
+                       RT5640_M_BST1_RM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUT MIXL Switch", RT5640_REC_L2_MIXER,
+                       RT5640_M_OM_L_RM_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_rec_r_mix[] = {
+       SOC_DAPM_SINGLE("HPOR Switch", RT5640_REC_R2_MIXER,
+                       RT5640_M_HP_R_RM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER,
+                       RT5640_M_IN_R_RM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER,
+                       RT5640_M_BST4_RM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER,
+                       RT5640_M_BST1_RM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUT MIXR Switch", RT5640_REC_R2_MIXER,
+                       RT5640_M_OM_R_RM_R_SFT, 1, 1),
+};
+
+/* Analog Output Mixer */
+static const struct snd_kcontrol_new rt5640_spk_l_mix[] = {
+       SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_SPK_L_MIXER,
+                       RT5640_M_RM_L_SM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INL Switch", RT5640_SPK_L_MIXER,
+                       RT5640_M_IN_L_SM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_SPK_L_MIXER,
+                       RT5640_M_DAC_L1_SM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_SPK_L_MIXER,
+                       RT5640_M_DAC_L2_SM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUT MIXL Switch", RT5640_SPK_L_MIXER,
+                       RT5640_M_OM_L_SM_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_spk_r_mix[] = {
+       SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_SPK_R_MIXER,
+                       RT5640_M_RM_R_SM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INR Switch", RT5640_SPK_R_MIXER,
+                       RT5640_M_IN_R_SM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPK_R_MIXER,
+                       RT5640_M_DAC_R1_SM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_SPK_R_MIXER,
+                       RT5640_M_DAC_R2_SM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUT MIXR Switch", RT5640_SPK_R_MIXER,
+                       RT5640_M_OM_R_SM_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_out_l_mix[] = {
+       SOC_DAPM_SINGLE("SPK MIXL Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_SM_L_OM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_BST1_OM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_IN_L_OM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_RM_L_OM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_DAC_R2_OM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_DAC_L2_OM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER,
+                       RT5640_M_DAC_L1_OM_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_out_r_mix[] = {
+       SOC_DAPM_SINGLE("SPK MIXR Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_SM_L_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_BST4_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_BST1_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_IN_R_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_RM_R_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_DAC_L2_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_DAC_R2_OM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER,
+                       RT5640_M_DAC_R1_OM_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_spo_l_mix[] = {
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER,
+                       RT5640_M_DAC_R1_SPM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_SPO_L_MIXER,
+                       RT5640_M_DAC_L1_SPM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("SPKVOL R Switch", RT5640_SPO_L_MIXER,
+                       RT5640_M_SV_R_SPM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("SPKVOL L Switch", RT5640_SPO_L_MIXER,
+                       RT5640_M_SV_L_SPM_L_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_SPO_L_MIXER,
+                       RT5640_M_BST1_SPM_L_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_spo_r_mix[] = {
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_R_MIXER,
+                       RT5640_M_DAC_R1_SPM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("SPKVOL R Switch", RT5640_SPO_R_MIXER,
+                       RT5640_M_SV_R_SPM_R_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_SPO_R_MIXER,
+                       RT5640_M_BST1_SPM_R_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_hpo_mix[] = {
+       SOC_DAPM_SINGLE("HPO MIX DAC2 Switch", RT5640_HPO_MIXER,
+                       RT5640_M_DAC2_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5640_HPO_MIXER,
+                       RT5640_M_DAC1_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5640_HPO_MIXER,
+                       RT5640_M_HPVOL_HM_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_lout_mix[] = {
+       SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER,
+                       RT5640_M_DAC_L1_LM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_LOUT_MIXER,
+                       RT5640_M_DAC_R1_LM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUTVOL L Switch", RT5640_LOUT_MIXER,
+                       RT5640_M_OV_L_LM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUTVOL R Switch", RT5640_LOUT_MIXER,
+                       RT5640_M_OV_R_LM_SFT, 1, 1),
+};
+
+static const struct snd_kcontrol_new rt5640_mono_mix[] = {
+       SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_MONO_MIXER,
+                       RT5640_M_DAC_R2_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_MONO_MIXER,
+                       RT5640_M_DAC_L2_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUTVOL R Switch", RT5640_MONO_MIXER,
+                       RT5640_M_OV_R_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("OUTVOL L Switch", RT5640_MONO_MIXER,
+                       RT5640_M_OV_L_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("BST1 Switch", RT5640_MONO_MIXER,
+                       RT5640_M_BST1_MM_SFT, 1, 1),
+};
+
+/* INL/R source */
+static const char * const rt5640_inl_src[] = {
+       "IN2P", "MONOP"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_inl_enum, RT5640_INL_INR_VOL,
+       RT5640_INL_SEL_SFT, rt5640_inl_src);
+
+static const struct snd_kcontrol_new rt5640_inl_mux =
+       SOC_DAPM_ENUM("INL source", rt5640_inl_enum);
+
+static const char * const rt5640_inr_src[] = {
+       "IN2N", "MONON"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_inr_enum, RT5640_INL_INR_VOL,
+       RT5640_INR_SEL_SFT, rt5640_inr_src);
+
+static const struct snd_kcontrol_new rt5640_inr_mux =
+       SOC_DAPM_ENUM("INR source", rt5640_inr_enum);
+
+/* Stereo ADC source */
+static const char * const rt5640_stereo_adc1_src[] = {
+       "DIG MIX", "ADC"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_stereo_adc1_enum, RT5640_STO_ADC_MIXER,
+       RT5640_ADC_1_SRC_SFT, rt5640_stereo_adc1_src);
+
+static const struct snd_kcontrol_new rt5640_sto_adc_1_mux =
+       SOC_DAPM_ENUM("Stereo ADC1 Mux", rt5640_stereo_adc1_enum);
+
+static const char * const rt5640_stereo_adc2_src[] = {
+       "DMIC1", "DMIC2", "DIG MIX"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_stereo_adc2_enum, RT5640_STO_ADC_MIXER,
+       RT5640_ADC_2_SRC_SFT, rt5640_stereo_adc2_src);
+
+static const struct snd_kcontrol_new rt5640_sto_adc_2_mux =
+       SOC_DAPM_ENUM("Stereo ADC2 Mux", rt5640_stereo_adc2_enum);
+
+/* Mono ADC source */
+static const char * const rt5640_mono_adc_l1_src[] = {
+       "Mono DAC MIXL", "ADCL"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_mono_adc_l1_enum, RT5640_MONO_ADC_MIXER,
+       RT5640_MONO_ADC_L1_SRC_SFT, rt5640_mono_adc_l1_src);
+
+static const struct snd_kcontrol_new rt5640_mono_adc_l1_mux =
+       SOC_DAPM_ENUM("Mono ADC1 left source", rt5640_mono_adc_l1_enum);
+
+static const char * const rt5640_mono_adc_l2_src[] = {
+       "DMIC L1", "DMIC L2", "Mono DAC MIXL"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_mono_adc_l2_enum, RT5640_MONO_ADC_MIXER,
+       RT5640_MONO_ADC_L2_SRC_SFT, rt5640_mono_adc_l2_src);
+
+static const struct snd_kcontrol_new rt5640_mono_adc_l2_mux =
+       SOC_DAPM_ENUM("Mono ADC2 left source", rt5640_mono_adc_l2_enum);
+
+static const char * const rt5640_mono_adc_r1_src[] = {
+       "Mono DAC MIXR", "ADCR"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_mono_adc_r1_enum, RT5640_MONO_ADC_MIXER,
+       RT5640_MONO_ADC_R1_SRC_SFT, rt5640_mono_adc_r1_src);
+
+static const struct snd_kcontrol_new rt5640_mono_adc_r1_mux =
+       SOC_DAPM_ENUM("Mono ADC1 right source", rt5640_mono_adc_r1_enum);
+
+static const char * const rt5640_mono_adc_r2_src[] = {
+       "DMIC R1", "DMIC R2", "Mono DAC MIXR"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_mono_adc_r2_enum, RT5640_MONO_ADC_MIXER,
+       RT5640_MONO_ADC_R2_SRC_SFT, rt5640_mono_adc_r2_src);
+
+static const struct snd_kcontrol_new rt5640_mono_adc_r2_mux =
+       SOC_DAPM_ENUM("Mono ADC2 right source", rt5640_mono_adc_r2_enum);
+
+/* DAC2 channel source */
+static const char * const rt5640_dac_l2_src[] = {
+       "IF2", "Base L/R"
+};
+
+static int rt5640_dac_l2_values[] = {
+       0,
+       3,
+};
+
+static const SOC_VALUE_ENUM_SINGLE_DECL(
+       rt5640_dac_l2_enum, RT5640_DSP_PATH2, RT5640_DAC_L2_SEL_SFT,
+       0x3, rt5640_dac_l2_src, rt5640_dac_l2_values);
+
+static const struct snd_kcontrol_new rt5640_dac_l2_mux =
+       SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum);
+
+static const char * const rt5640_dac_r2_src[] = {
+       "IF2",
+};
+
+static int rt5640_dac_r2_values[] = {
+       0,
+};
+
+static const SOC_VALUE_ENUM_SINGLE_DECL(
+       rt5640_dac_r2_enum, RT5640_DSP_PATH2, RT5640_DAC_R2_SEL_SFT,
+       0x3, rt5640_dac_r2_src, rt5640_dac_r2_values);
+
+static const struct snd_kcontrol_new rt5640_dac_r2_mux =
+       SOC_DAPM_ENUM("DAC2 right channel source", rt5640_dac_r2_enum);
+
+/* digital interface and iis interface map */
+static const char * const rt5640_dai_iis_map[] = {
+       "1:1|2:2", "1:2|2:1", "1:1|2:1", "1:2|2:2"
+};
+
+static int rt5640_dai_iis_map_values[] = {
+       0,
+       5,
+       6,
+       7,
+};
+
+static const SOC_VALUE_ENUM_SINGLE_DECL(
+       rt5640_dai_iis_map_enum, RT5640_I2S1_SDP, RT5640_I2S_IF_SFT,
+       0x7, rt5640_dai_iis_map, rt5640_dai_iis_map_values);
+
+static const struct snd_kcontrol_new rt5640_dai_mux =
+       SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum);
+
+/* SDI select */
+static const char * const rt5640_sdi_sel[] = {
+       "IF1", "IF2"
+};
+
+static const SOC_ENUM_SINGLE_DECL(
+       rt5640_sdi_sel_enum, RT5640_I2S2_SDP,
+       RT5640_I2S2_SDI_SFT, rt5640_sdi_sel);
+
+static const struct snd_kcontrol_new rt5640_sdi_mux =
+       SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
+
+static int spk_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
+                                       0x0001, 0x0001);
+               regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
+                                       0xf000, 0xf000);
+               break;
+
+       case SND_SOC_DAPM_PRE_PMD:
+               regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
+                                       0xf000, 0x0000);
+               regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
+                                       0x0001, 0x0000);
+               break;
+
+       default:
+               return 0;
+       }
+       return 0;
+}
+
+static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               snd_soc_update_bits(codec, RT5640_GPIO_CTRL1,
+                       RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK,
+                       RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA);
+               snd_soc_update_bits(codec, RT5640_DMIC,
+                       RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK |
+                       RT5640_DMIC_1_DP_MASK,
+                       RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING |
+                       RT5640_DMIC_1_DP_IN1P);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
+static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               snd_soc_update_bits(codec, RT5640_GPIO_CTRL1,
+                       RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK,
+                       RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA);
+               snd_soc_update_bits(codec, RT5640_DMIC,
+                       RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK |
+                       RT5640_DMIC_2_DP_MASK,
+                       RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING |
+                       RT5640_DMIC_2_DP_IN1N);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
+static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
+       SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
+                       RT5640_PWR_PLL_BIT, 0, NULL, 0),
+       /* Input Side */
+       /* micbias */
+       SND_SOC_DAPM_SUPPLY("LDO2", RT5640_PWR_ANLG1,
+                       RT5640_PWR_LDO2_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5640_PWR_ANLG2,
+                       RT5640_PWR_MB1_BIT, 0, NULL, 0),
+       /* Input Lines */
+       SND_SOC_DAPM_INPUT("DMIC1"),
+       SND_SOC_DAPM_INPUT("DMIC2"),
+       SND_SOC_DAPM_INPUT("IN1P"),
+       SND_SOC_DAPM_INPUT("IN1N"),
+       SND_SOC_DAPM_INPUT("IN2P"),
+       SND_SOC_DAPM_INPUT("IN2N"),
+       SND_SOC_DAPM_PGA("DMIC L1", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("DMIC R1", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("DMIC L2", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("DMIC R2", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
+               set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
+       SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC,
+               RT5640_DMIC_1_EN_SFT, 0, rt5640_set_dmic1_event,
+               SND_SOC_DAPM_PRE_PMU),
+       SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC,
+               RT5640_DMIC_2_EN_SFT, 0, rt5640_set_dmic2_event,
+               SND_SOC_DAPM_PRE_PMU),
+       /* Boost */
+       SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2,
+               RT5640_PWR_BST1_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2,
+               RT5640_PWR_BST4_BIT, 0, NULL, 0),
+       /* Input Volume */
+       SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL,
+               RT5640_PWR_IN_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("INR VOL", RT5640_PWR_VOL,
+               RT5640_PWR_IN_R_BIT, 0, NULL, 0),
+       /* IN Mux */
+       SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt5640_inl_mux),
+       SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt5640_inr_mux),
+       /* REC Mixer */
+       SND_SOC_DAPM_MIXER("RECMIXL", RT5640_PWR_MIXER, RT5640_PWR_RM_L_BIT, 0,
+                       rt5640_rec_l_mix, ARRAY_SIZE(rt5640_rec_l_mix)),
+       SND_SOC_DAPM_MIXER("RECMIXR", RT5640_PWR_MIXER, RT5640_PWR_RM_R_BIT, 0,
+                       rt5640_rec_r_mix, ARRAY_SIZE(rt5640_rec_r_mix)),
+       /* ADCs */
+       SND_SOC_DAPM_ADC("ADC L", NULL, RT5640_PWR_DIG1,
+                       RT5640_PWR_ADC_L_BIT, 0),
+       SND_SOC_DAPM_ADC("ADC R", NULL, RT5640_PWR_DIG1,
+                       RT5640_PWR_ADC_R_BIT, 0),
+       /* ADC Mux */
+       SND_SOC_DAPM_MUX("Stereo ADC L2 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_sto_adc_2_mux),
+       SND_SOC_DAPM_MUX("Stereo ADC R2 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_sto_adc_2_mux),
+       SND_SOC_DAPM_MUX("Stereo ADC L1 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_sto_adc_1_mux),
+       SND_SOC_DAPM_MUX("Stereo ADC R1 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_sto_adc_1_mux),
+       SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_mono_adc_l2_mux),
+       SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_mono_adc_l1_mux),
+       SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_mono_adc_r1_mux),
+       SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_mono_adc_r2_mux),
+       /* ADC Mixer */
+       SND_SOC_DAPM_SUPPLY("Stereo Filter", RT5640_PWR_DIG2,
+               RT5640_PWR_ADC_SF_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("Stereo ADC MIXL", SND_SOC_NOPM, 0, 0,
+               rt5640_sto_adc_l_mix, ARRAY_SIZE(rt5640_sto_adc_l_mix)),
+       SND_SOC_DAPM_MIXER("Stereo ADC MIXR", SND_SOC_NOPM, 0, 0,
+               rt5640_sto_adc_r_mix, ARRAY_SIZE(rt5640_sto_adc_r_mix)),
+       SND_SOC_DAPM_SUPPLY("Mono Left Filter", RT5640_PWR_DIG2,
+               RT5640_PWR_ADC_MF_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
+               rt5640_mono_adc_l_mix, ARRAY_SIZE(rt5640_mono_adc_l_mix)),
+       SND_SOC_DAPM_SUPPLY("Mono Right Filter", RT5640_PWR_DIG2,
+               RT5640_PWR_ADC_MF_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
+               rt5640_mono_adc_r_mix, ARRAY_SIZE(rt5640_mono_adc_r_mix)),
+
+       /* Digital Interface */
+       SND_SOC_DAPM_SUPPLY("I2S1", RT5640_PWR_DIG1,
+               RT5640_PWR_I2S1_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("I2S2", RT5640_PWR_DIG1,
+               RT5640_PWR_I2S2_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF2 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IF2 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
+       /* Digital Interface Select */
+       SND_SOC_DAPM_MUX("DAI1 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("DAI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("DAI1 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("DAI1 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("SDI1 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_sdi_mux),
+       SND_SOC_DAPM_MUX("DAI2 RX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("DAI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("DAI2 IF1 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("DAI2 IF2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dai_mux),
+       SND_SOC_DAPM_MUX("SDI2 TX Mux", SND_SOC_NOPM, 0, 0, &rt5640_sdi_mux),
+       /* Audio Interface */
+       SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
+       /* Audio DSP */
+       SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
+       /* ANC */
+       SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       /* Output Side */
+       /* DAC mixer before sound effect  */
+       SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
+               rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)),
+       SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
+               rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)),
+       /* DAC2 channel Mux */
+       SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_dac_l2_mux),
+       SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0,
+                               &rt5640_dac_r2_mux),
+       /* DAC Mixer */
+       SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
+               rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)),
+       SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
+               rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)),
+       SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
+               rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)),
+       SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
+               rt5640_mono_dac_r_mix, ARRAY_SIZE(rt5640_mono_dac_r_mix)),
+       SND_SOC_DAPM_MIXER("DIG MIXL", SND_SOC_NOPM, 0, 0,
+               rt5640_dig_l_mix, ARRAY_SIZE(rt5640_dig_l_mix)),
+       SND_SOC_DAPM_MIXER("DIG MIXR", SND_SOC_NOPM, 0, 0,
+               rt5640_dig_r_mix, ARRAY_SIZE(rt5640_dig_r_mix)),
+       /* DACs */
+       SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1,
+                       RT5640_PWR_DAC_L1_BIT, 0),
+       SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1,
+                       RT5640_PWR_DAC_L2_BIT, 0),
+       SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1,
+                       RT5640_PWR_DAC_R1_BIT, 0),
+       SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1,
+                       RT5640_PWR_DAC_R2_BIT, 0),
+       /* SPK/OUT Mixer */
+       SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
+               0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
+       SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT,
+               0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)),
+       SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
+               0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)),
+       SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,
+               0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)),
+       /* Ouput Volume */
+       SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL,
+               RT5640_PWR_SV_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("SPKVOL R", RT5640_PWR_VOL,
+               RT5640_PWR_SV_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("OUTVOL L", RT5640_PWR_VOL,
+               RT5640_PWR_OV_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("OUTVOL R", RT5640_PWR_VOL,
+               RT5640_PWR_OV_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("HPOVOL L", RT5640_PWR_VOL,
+               RT5640_PWR_HV_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("HPOVOL R", RT5640_PWR_VOL,
+               RT5640_PWR_HV_R_BIT, 0, NULL, 0),
+       /* SPO/HPO/LOUT/Mono Mixer */
+       SND_SOC_DAPM_MIXER("SPOL MIX", SND_SOC_NOPM, 0,
+               0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)),
+       SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0,
+               0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)),
+       SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0,
+               rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
+       SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0,
+               rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)),
+       SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0,
+               rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)),
+       SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0,
+               rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
+       SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
+               RT5640_PWR_MA_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1,
+               SND_SOC_NOPM, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1,
+               RT5640_PWR_HP_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1,
+               RT5640_PWR_HP_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1,
+               SND_SOC_NOPM, 0, spk_event,
+               SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+       /* Output Lines */
+       SND_SOC_DAPM_OUTPUT("SPOLP"),
+       SND_SOC_DAPM_OUTPUT("SPOLN"),
+       SND_SOC_DAPM_OUTPUT("SPORP"),
+       SND_SOC_DAPM_OUTPUT("SPORN"),
+       SND_SOC_DAPM_OUTPUT("HPOL"),
+       SND_SOC_DAPM_OUTPUT("HPOR"),
+       SND_SOC_DAPM_OUTPUT("LOUTL"),
+       SND_SOC_DAPM_OUTPUT("LOUTR"),
+       SND_SOC_DAPM_OUTPUT("MONOP"),
+       SND_SOC_DAPM_OUTPUT("MONON"),
+};
+
+static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
+       {"IN1P", NULL, "LDO2"},
+       {"IN2P", NULL, "LDO2"},
+
+       {"DMIC L1", NULL, "DMIC1"},
+       {"DMIC R1", NULL, "DMIC1"},
+       {"DMIC L2", NULL, "DMIC2"},
+       {"DMIC R2", NULL, "DMIC2"},
+
+       {"BST1", NULL, "IN1P"},
+       {"BST1", NULL, "IN1N"},
+       {"BST2", NULL, "IN2P"},
+       {"BST2", NULL, "IN2N"},
+
+       {"INL VOL", NULL, "IN2P"},
+       {"INR VOL", NULL, "IN2N"},
+
+       {"RECMIXL", "HPOL Switch", "HPOL"},
+       {"RECMIXL", "INL Switch", "INL VOL"},
+       {"RECMIXL", "BST2 Switch", "BST2"},
+       {"RECMIXL", "BST1 Switch", "BST1"},
+       {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"},
+
+       {"RECMIXR", "HPOR Switch", "HPOR"},
+       {"RECMIXR", "INR Switch", "INR VOL"},
+       {"RECMIXR", "BST2 Switch", "BST2"},
+       {"RECMIXR", "BST1 Switch", "BST1"},
+       {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"},
+
+       {"ADC L", NULL, "RECMIXL"},
+       {"ADC R", NULL, "RECMIXR"},
+
+       {"DMIC L1", NULL, "DMIC CLK"},
+       {"DMIC L1", NULL, "DMIC1 Power"},
+       {"DMIC R1", NULL, "DMIC CLK"},
+       {"DMIC R1", NULL, "DMIC1 Power"},
+       {"DMIC L2", NULL, "DMIC CLK"},
+       {"DMIC L2", NULL, "DMIC2 Power"},
+       {"DMIC R2", NULL, "DMIC CLK"},
+       {"DMIC R2", NULL, "DMIC2 Power"},
+
+       {"Stereo ADC L2 Mux", "DMIC1", "DMIC L1"},
+       {"Stereo ADC L2 Mux", "DMIC2", "DMIC L2"},
+       {"Stereo ADC L2 Mux", "DIG MIX", "DIG MIXL"},
+       {"Stereo ADC L1 Mux", "ADC", "ADC L"},
+       {"Stereo ADC L1 Mux", "DIG MIX", "DIG MIXL"},
+
+       {"Stereo ADC R1 Mux", "ADC", "ADC R"},
+       {"Stereo ADC R1 Mux", "DIG MIX", "DIG MIXR"},
+       {"Stereo ADC R2 Mux", "DMIC1", "DMIC R1"},
+       {"Stereo ADC R2 Mux", "DMIC2", "DMIC R2"},
+       {"Stereo ADC R2 Mux", "DIG MIX", "DIG MIXR"},
+
+       {"Mono ADC L2 Mux", "DMIC L1", "DMIC L1"},
+       {"Mono ADC L2 Mux", "DMIC L2", "DMIC L2"},
+       {"Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL"},
+       {"Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL"},
+       {"Mono ADC L1 Mux", "ADCL", "ADC L"},
+
+       {"Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR"},
+       {"Mono ADC R1 Mux", "ADCR", "ADC R"},
+       {"Mono ADC R2 Mux", "DMIC R1", "DMIC R1"},
+       {"Mono ADC R2 Mux", "DMIC R2", "DMIC R2"},
+       {"Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR"},
+
+       {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"},
+       {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"},
+       {"Stereo ADC MIXL", NULL, "Stereo Filter"},
+       {"Stereo Filter", NULL, "PLL1", check_sysclk1_source},
+
+       {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"},
+       {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"},
+       {"Stereo ADC MIXR", NULL, "Stereo Filter"},
+       {"Stereo Filter", NULL, "PLL1", check_sysclk1_source},
+
+       {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"},
+       {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"},
+       {"Mono ADC MIXL", NULL, "Mono Left Filter"},
+       {"Mono Left Filter", NULL, "PLL1", check_sysclk1_source},
+
+       {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"},
+       {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"},
+       {"Mono ADC MIXR", NULL, "Mono Right Filter"},
+       {"Mono Right Filter", NULL, "PLL1", check_sysclk1_source},
+
+       {"IF2 ADC L", NULL, "Mono ADC MIXL"},
+       {"IF2 ADC R", NULL, "Mono ADC MIXR"},
+       {"IF1 ADC L", NULL, "Stereo ADC MIXL"},
+       {"IF1 ADC R", NULL, "Stereo ADC MIXR"},
+
+       {"IF1 ADC", NULL, "I2S1"},
+       {"IF1 ADC", NULL, "IF1 ADC L"},
+       {"IF1 ADC", NULL, "IF1 ADC R"},
+       {"IF2 ADC", NULL, "I2S2"},
+       {"IF2 ADC", NULL, "IF2 ADC L"},
+       {"IF2 ADC", NULL, "IF2 ADC R"},
+
+       {"DAI1 TX Mux", "1:1|2:2", "IF1 ADC"},
+       {"DAI1 TX Mux", "1:2|2:1", "IF2 ADC"},
+       {"DAI1 IF1 Mux", "1:1|2:1", "IF1 ADC"},
+       {"DAI1 IF2 Mux", "1:1|2:1", "IF2 ADC"},
+       {"SDI1 TX Mux", "IF1", "DAI1 IF1 Mux"},
+       {"SDI1 TX Mux", "IF2", "DAI1 IF2 Mux"},
+
+       {"DAI2 TX Mux", "1:2|2:1", "IF1 ADC"},
+       {"DAI2 TX Mux", "1:1|2:2", "IF2 ADC"},
+       {"DAI2 IF1 Mux", "1:2|2:2", "IF1 ADC"},
+       {"DAI2 IF2 Mux", "1:2|2:2", "IF2 ADC"},
+       {"SDI2 TX Mux", "IF1", "DAI2 IF1 Mux"},
+       {"SDI2 TX Mux", "IF2", "DAI2 IF2 Mux"},
+
+       {"AIF1TX", NULL, "DAI1 TX Mux"},
+       {"AIF1TX", NULL, "SDI1 TX Mux"},
+       {"AIF2TX", NULL, "DAI2 TX Mux"},
+       {"AIF2TX", NULL, "SDI2 TX Mux"},
+
+       {"DAI1 RX Mux", "1:1|2:2", "AIF1RX"},
+       {"DAI1 RX Mux", "1:1|2:1", "AIF1RX"},
+       {"DAI1 RX Mux", "1:2|2:1", "AIF2RX"},
+       {"DAI1 RX Mux", "1:2|2:2", "AIF2RX"},
+
+       {"DAI2 RX Mux", "1:2|2:1", "AIF1RX"},
+       {"DAI2 RX Mux", "1:1|2:1", "AIF1RX"},
+       {"DAI2 RX Mux", "1:1|2:2", "AIF2RX"},
+       {"DAI2 RX Mux", "1:2|2:2", "AIF2RX"},
+
+       {"IF1 DAC", NULL, "I2S1"},
+       {"IF1 DAC", NULL, "DAI1 RX Mux"},
+       {"IF2 DAC", NULL, "I2S2"},
+       {"IF2 DAC", NULL, "DAI2 RX Mux"},
+
+       {"IF1 DAC L", NULL, "IF1 DAC"},
+       {"IF1 DAC R", NULL, "IF1 DAC"},
+       {"IF2 DAC L", NULL, "IF2 DAC"},
+       {"IF2 DAC R", NULL, "IF2 DAC"},
+
+       {"DAC MIXL", "Stereo ADC Switch", "Stereo ADC MIXL"},
+       {"DAC MIXL", "INF1 Switch", "IF1 DAC L"},
+       {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"},
+       {"DAC MIXR", "INF1 Switch", "IF1 DAC R"},
+
+       {"ANC", NULL, "Stereo ADC MIXL"},
+       {"ANC", NULL, "Stereo ADC MIXR"},
+
+       {"Audio DSP", NULL, "DAC MIXL"},
+       {"Audio DSP", NULL, "DAC MIXR"},
+
+       {"DAC L2 Mux", "IF2", "IF2 DAC L"},
+       {"DAC L2 Mux", "Base L/R", "Audio DSP"},
+
+       {"DAC R2 Mux", "IF2", "IF2 DAC R"},
+
+       {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
+       {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
+       {"Stereo DAC MIXL", "ANC Switch", "ANC"},
+       {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
+       {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
+       {"Stereo DAC MIXR", "ANC Switch", "ANC"},
+
+       {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
+       {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
+       {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"},
+       {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
+       {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"},
+       {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"},
+
+       {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"},
+       {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"},
+       {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"},
+       {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"},
+
+       {"DAC L1", NULL, "Stereo DAC MIXL"},
+       {"DAC L1", NULL, "PLL1", check_sysclk1_source},
+       {"DAC R1", NULL, "Stereo DAC MIXR"},
+       {"DAC R1", NULL, "PLL1", check_sysclk1_source},
+       {"DAC L2", NULL, "Mono DAC MIXL"},
+       {"DAC L2", NULL, "PLL1", check_sysclk1_source},
+       {"DAC R2", NULL, "Mono DAC MIXR"},
+       {"DAC R2", NULL, "PLL1", check_sysclk1_source},
+
+       {"SPK MIXL", "REC MIXL Switch", "RECMIXL"},
+       {"SPK MIXL", "INL Switch", "INL VOL"},
+       {"SPK MIXL", "DAC L1 Switch", "DAC L1"},
+       {"SPK MIXL", "DAC L2 Switch", "DAC L2"},
+       {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"},
+       {"SPK MIXR", "REC MIXR Switch", "RECMIXR"},
+       {"SPK MIXR", "INR Switch", "INR VOL"},
+       {"SPK MIXR", "DAC R1 Switch", "DAC R1"},
+       {"SPK MIXR", "DAC R2 Switch", "DAC R2"},
+       {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"},
+
+       {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"},
+       {"OUT MIXL", "BST1 Switch", "BST1"},
+       {"OUT MIXL", "INL Switch", "INL VOL"},
+       {"OUT MIXL", "REC MIXL Switch", "RECMIXL"},
+       {"OUT MIXL", "DAC R2 Switch", "DAC R2"},
+       {"OUT MIXL", "DAC L2 Switch", "DAC L2"},
+       {"OUT MIXL", "DAC L1 Switch", "DAC L1"},
+
+       {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"},
+       {"OUT MIXR", "BST2 Switch", "BST2"},
+       {"OUT MIXR", "BST1 Switch", "BST1"},
+       {"OUT MIXR", "INR Switch", "INR VOL"},
+       {"OUT MIXR", "REC MIXR Switch", "RECMIXR"},
+       {"OUT MIXR", "DAC L2 Switch", "DAC L2"},
+       {"OUT MIXR", "DAC R2 Switch", "DAC R2"},
+       {"OUT MIXR", "DAC R1 Switch", "DAC R1"},
+
+       {"SPKVOL L", NULL, "SPK MIXL"},
+       {"SPKVOL R", NULL, "SPK MIXR"},
+       {"HPOVOL L", NULL, "OUT MIXL"},
+       {"HPOVOL R", NULL, "OUT MIXR"},
+       {"OUTVOL L", NULL, "OUT MIXL"},
+       {"OUTVOL R", NULL, "OUT MIXR"},
+
+       {"SPOL MIX", "DAC R1 Switch", "DAC R1"},
+       {"SPOL MIX", "DAC L1 Switch", "DAC L1"},
+       {"SPOL MIX", "SPKVOL R Switch", "SPKVOL R"},
+       {"SPOL MIX", "SPKVOL L Switch", "SPKVOL L"},
+       {"SPOL MIX", "BST1 Switch", "BST1"},
+       {"SPOR MIX", "DAC R1 Switch", "DAC R1"},
+       {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"},
+       {"SPOR MIX", "BST1 Switch", "BST1"},
+
+       {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
+       {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"},
+       {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"},
+       {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
+       {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"},
+       {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"},
+
+       {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
+       {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
+       {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"},
+       {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"},
+
+       {"Mono MIX", "DAC R2 Switch", "DAC R2"},
+       {"Mono MIX", "DAC L2 Switch", "DAC L2"},
+       {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"},
+       {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
+       {"Mono MIX", "BST1 Switch", "BST1"},
+
+       {"HP L Amp", NULL, "HPO MIX L"},
+       {"HP R Amp", NULL, "HPO MIX R"},
+
+       {"SPOLP", NULL, "SPOL MIX"},
+       {"SPOLN", NULL, "SPOL MIX"},
+       {"SPORP", NULL, "SPOR MIX"},
+       {"SPORN", NULL, "SPOR MIX"},
+
+       {"SPOLP", NULL, "Improve SPK Amp Drv"},
+       {"SPOLN", NULL, "Improve SPK Amp Drv"},
+       {"SPORP", NULL, "Improve SPK Amp Drv"},
+       {"SPORN", NULL, "Improve SPK Amp Drv"},
+
+       {"HPOL", NULL, "Improve HP Amp Drv"},
+       {"HPOR", NULL, "Improve HP Amp Drv"},
+
+       {"HPOL", NULL, "HP L Amp"},
+       {"HPOR", NULL, "HP R Amp"},
+       {"LOUTL", NULL, "LOUT MIX"},
+       {"LOUTR", NULL, "LOUT MIX"},
+       {"MONOP", NULL, "Mono MIX"},
+       {"MONON", NULL, "Mono MIX"},
+       {"MONOP", NULL, "Improve MONO Amp Drv"},
+};
+
+static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
+{
+       int ret = 0, val;
+
+       if (codec == NULL)
+               return -EINVAL;
+
+       val = snd_soc_read(codec, RT5640_I2S1_SDP);
+       val = (val & RT5640_I2S_IF_MASK) >> RT5640_I2S_IF_SFT;
+       switch (dai_id) {
+       case RT5640_AIF1:
+               switch (val) {
+               case RT5640_IF_123:
+               case RT5640_IF_132:
+                       ret |= RT5640_U_IF1;
+                       break;
+               case RT5640_IF_113:
+                       ret |= RT5640_U_IF1;
+               case RT5640_IF_312:
+               case RT5640_IF_213:
+                       ret |= RT5640_U_IF2;
+                       break;
+               }
+               break;
+
+       case RT5640_AIF2:
+               switch (val) {
+               case RT5640_IF_231:
+               case RT5640_IF_213:
+                       ret |= RT5640_U_IF1;
+                       break;
+               case RT5640_IF_223:
+                       ret |= RT5640_U_IF1;
+               case RT5640_IF_123:
+               case RT5640_IF_321:
+                       ret |= RT5640_U_IF2;
+                       break;
+               }
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+static int get_clk_info(int sclk, int rate)
+{
+       int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
+
+       if (sclk <= 0 || rate <= 0)
+               return -EINVAL;
+
+       rate = rate << 8;
+       for (i = 0; i < ARRAY_SIZE(pd); i++)
+               if (sclk == rate * pd[i])
+                       return i;
+
+       return -EINVAL;
+}
+
+static int rt5640_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 rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       unsigned int val_len = 0, val_clk, mask_clk, dai_sel;
+       int pre_div, bclk_ms, frame_size;
+
+       rt5640->lrck[dai->id] = params_rate(params);
+       pre_div = get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
+       if (pre_div < 0) {
+               dev_err(codec->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);
+               return frame_size;
+       }
+       if (frame_size > 32)
+               bclk_ms = 1;
+       else
+               bclk_ms = 0;
+       rt5640->bclk[dai->id] = rt5640->lrck[dai->id] * (32 << bclk_ms);
+
+       dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
+               rt5640->bclk[dai->id], rt5640->lrck[dai->id]);
+       dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
+                               bclk_ms, pre_div, dai->id);
+
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               val_len |= RT5640_I2S_DL_20;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               val_len |= RT5640_I2S_DL_24;
+               break;
+       case SNDRV_PCM_FORMAT_S8:
+               val_len |= RT5640_I2S_DL_8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dai_sel = get_sdp_info(codec, dai->id);
+       if (dai_sel < 0) {
+               dev_err(codec->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,
+                       RT5640_I2S_DL_MASK, val_len);
+               snd_soc_update_bits(codec, 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,
+                       RT5640_I2S_DL_MASK, val_len);
+               snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);
+       }
+
+       return 0;
+}
+
+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);
+       unsigned int reg_val = 0, dai_sel;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               rt5640->master[dai->id] = 1;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               reg_val |= RT5640_I2S_MS_S;
+               rt5640->master[dai->id] = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               reg_val |= RT5640_I2S_BP_INV;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               reg_val |= RT5640_I2S_DF_LEFT;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               reg_val |= RT5640_I2S_DF_PCM_A;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               reg_val  |= RT5640_I2S_DF_PCM_B;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dai_sel = get_sdp_info(codec, dai->id);
+       if (dai_sel < 0) {
+               dev_err(codec->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,
+                       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,
+                       RT5640_I2S_MS_MASK | RT5640_I2S_BP_MASK |
+                       RT5640_I2S_DF_MASK, reg_val);
+       }
+
+       return 0;
+}
+
+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);
+       unsigned int reg_val = 0;
+
+       if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src)
+               return 0;
+
+       switch (clk_id) {
+       case RT5640_SCLK_S_MCLK:
+               reg_val |= RT5640_SCLK_SRC_MCLK;
+               break;
+       case RT5640_SCLK_S_PLL1:
+               reg_val |= RT5640_SCLK_SRC_PLL1;
+               break;
+       case RT5640_SCLK_S_PLL1_TK:
+               reg_val |= RT5640_SCLK_SRC_PLL1T;
+               break;
+       case RT5640_SCLK_S_RCCLK:
+               reg_val |= RT5640_SCLK_SRC_RCCLK;
+               break;
+       default:
+               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               return -EINVAL;
+       }
+       snd_soc_update_bits(codec, RT5640_GLB_CLK,
+               RT5640_SCLK_SRC_MASK, reg_val);
+       rt5640->sysclk = freq;
+       rt5640->sysclk_src = clk_id;
+
+       dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
+       return 0;
+}
+
+/**
+ * rt5640_pll_calc - Calculate PLL M/N/K code.
+ * @freq_in: external clock provided to codec.
+ * @freq_out: target clock which codec works on.
+ * @pll_code: Pointer to structure with M, N, K and bypass flag.
+ *
+ * Calculate M/N/K code to configure PLL for codec. And K is assigned to 2
+ * which make calculation more efficiently.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5640_pll_calc(const unsigned int freq_in,
+       const unsigned int freq_out, struct rt5640_pll_code *pll_code)
+{
+       int max_n = RT5640_PLL_N_MAX, max_m = RT5640_PLL_M_MAX;
+       int n = 0, m = 0, red, n_t, m_t, in_t, out_t;
+       int red_t = abs(freq_out - freq_in);
+       bool bypass = false;
+
+       if (RT5640_PLL_INP_MAX < freq_in || RT5640_PLL_INP_MIN > freq_in)
+               return -EINVAL;
+
+       for (n_t = 0; n_t <= max_n; n_t++) {
+               in_t = (freq_in >> 1) + (freq_in >> 2) * n_t;
+               if (in_t < 0)
+                       continue;
+               if (in_t == freq_out) {
+                       bypass = true;
+                       n = n_t;
+                       goto code_find;
+               }
+               for (m_t = 0; m_t <= max_m; m_t++) {
+                       out_t = in_t / (m_t + 2);
+                       red = abs(out_t - freq_out);
+                       if (red < red_t) {
+                               n = n_t;
+                               m = m_t;
+                               if (red == 0)
+                                       goto code_find;
+                               red_t = red;
+                       }
+               }
+       }
+       pr_debug("Only get approximation about PLL\n");
+
+code_find:
+       pll_code->m_bp = bypass;
+       pll_code->m_code = m;
+       pll_code->n_code = n;
+       pll_code->k_code = 2;
+       return 0;
+}
+
+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 rt5640_pll_code *pll_code = &rt5640->pll_code;
+       int ret, dai_sel;
+
+       if (source == rt5640->pll_src && freq_in == rt5640->pll_in &&
+           freq_out == rt5640->pll_out)
+               return 0;
+
+       if (!freq_in || !freq_out) {
+               dev_dbg(codec->dev, "PLL disabled\n");
+
+               rt5640->pll_in = 0;
+               rt5640->pll_out = 0;
+               snd_soc_update_bits(codec, 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,
+                       RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK);
+               break;
+       case RT5640_PLL1_S_BCLK1:
+       case RT5640_PLL1_S_BCLK2:
+               dai_sel = get_sdp_info(codec, dai->id);
+               if (dai_sel < 0) {
+                       dev_err(codec->dev,
+                               "Failed to get sdp info: %d\n", dai_sel);
+                       return -EINVAL;
+               }
+               if (dai_sel & RT5640_U_IF1) {
+                       snd_soc_update_bits(codec, RT5640_GLB_CLK,
+                               RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1);
+               }
+               if (dai_sel & RT5640_U_IF2) {
+                       snd_soc_update_bits(codec, RT5640_GLB_CLK,
+                               RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2);
+               }
+               break;
+       default:
+               dev_err(codec->dev, "Unknown PLL source %d\n", source);
+               return -EINVAL;
+       }
+
+       ret = rt5640_pll_calc(freq_in, freq_out, pll_code);
+       if (ret < 0) {
+               dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
+               return ret;
+       }
+
+       dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code->m_bp,
+               (pll_code->m_bp ? 0 : pll_code->m_code), pll_code->n_code);
+
+       snd_soc_write(codec, RT5640_PLL_CTRL1,
+               pll_code->n_code << RT5640_PLL_N_SFT | pll_code->k_code);
+       snd_soc_write(codec, 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);
+
+       rt5640->pll_in = freq_in;
+       rt5640->pll_out = freq_out;
+       rt5640->pll_src = source;
+
+       return 0;
+}
+
+static int rt5640_set_bias_level(struct snd_soc_codec *codec,
+                       enum snd_soc_bias_level level)
+{
+       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       switch (level) {
+       case SND_SOC_BIAS_STANDBY:
+               if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
+                       regcache_cache_only(rt5640->regmap, false);
+                       snd_soc_update_bits(codec, 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);
+                       mdelay(10);
+                       snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+                               RT5640_PWR_FV1 | RT5640_PWR_FV2,
+                               RT5640_PWR_FV1 | RT5640_PWR_FV2);
+                       regcache_sync(rt5640->regmap);
+                       snd_soc_update_bits(codec, RT5640_DUMMY1,
+                                               0x0301, 0x0301);
+                       snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+                                               0x001d, 0x0019);
+                       snd_soc_update_bits(codec, RT5640_DEPOP_M2,
+                                               0x2000, 0x2000);
+                       snd_soc_update_bits(codec, 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);
+               break;
+
+       default:
+               break;
+       }
+       codec->dapm.bias_level = level;
+
+       return 0;
+}
+
+static int rt5640_probe(struct snd_soc_codec *codec)
+{
+       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+       int ret;
+
+       rt5640->codec = codec;
+       codec->control_data = rt5640->regmap;
+
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
+
+       codec->dapm.idle_bias_off = 1;
+       rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
+       snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019);
+       snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000);
+       snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
+       snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
+
+       return 0;
+}
+
+static int rt5640_remove(struct snd_soc_codec *codec)
+{
+       rt5640_reset(codec);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int rt5640_suspend(struct snd_soc_codec *codec)
+{
+       struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
+
+       rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       rt5640_reset(codec);
+       regcache_cache_only(rt5640->regmap, true);
+       regcache_mark_dirty(rt5640->regmap);
+
+       return 0;
+}
+
+static int rt5640_resume(struct snd_soc_codec *codec)
+{
+       rt5640_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       return 0;
+}
+#else
+#define rt5640_suspend NULL
+#define rt5640_resume NULL
+#endif
+
+#define RT5640_STEREO_RATES SNDRV_PCM_RATE_8000_96000
+#define RT5640_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+                       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
+
+static const struct snd_soc_dai_ops rt5640_aif_dai_ops = {
+       .hw_params = rt5640_hw_params,
+       .set_fmt = rt5640_set_dai_fmt,
+       .set_sysclk = rt5640_set_dai_sysclk,
+       .set_pll = rt5640_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver rt5640_dai[] = {
+       {
+               .name = "rt5640-aif1",
+               .id = RT5640_AIF1,
+               .playback = {
+                       .stream_name = "AIF1 Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = RT5640_STEREO_RATES,
+                       .formats = RT5640_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "AIF1 Capture",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = RT5640_STEREO_RATES,
+                       .formats = RT5640_FORMATS,
+               },
+               .ops = &rt5640_aif_dai_ops,
+       },
+       {
+               .name = "rt5640-aif2",
+               .id = RT5640_AIF2,
+               .playback = {
+                       .stream_name = "AIF2 Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = RT5640_STEREO_RATES,
+                       .formats = RT5640_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "AIF2 Capture",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = RT5640_STEREO_RATES,
+                       .formats = RT5640_FORMATS,
+               },
+               .ops = &rt5640_aif_dai_ops,
+       },
+};
+
+static 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,
+       .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 regmap_config rt5640_regmap = {
+       .reg_bits = 8,
+       .val_bits = 16,
+
+       .max_register = RT5640_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5640_ranges) *
+                                              RT5640_PR_SPACING),
+       .volatile_reg = rt5640_volatile_register,
+       .readable_reg = rt5640_readable_register,
+
+       .cache_type = REGCACHE_RBTREE,
+       .reg_defaults = rt5640_reg,
+       .num_reg_defaults = ARRAY_SIZE(rt5640_reg),
+       .ranges = rt5640_ranges,
+       .num_ranges = ARRAY_SIZE(rt5640_ranges),
+};
+
+static const struct i2c_device_id rt5640_i2c_id[] = {
+       { "rt5640", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id);
+
+static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
+{
+       rt5640->pdata.in1_diff = of_property_read_bool(np,
+                                       "realtek,in1-differential");
+       rt5640->pdata.in2_diff = of_property_read_bool(np,
+                                       "realtek,in2-differential");
+
+       rt5640->pdata.ldo1_en = of_get_named_gpio(np,
+                                       "realtek,ldo1-en-gpios", 0);
+       /*
+        * LDO1_EN is optional (it may be statically tied on the board).
+        * -ENOENT means that the property doesn't exist, i.e. there is no
+        * GPIO, so is not an error. Any other error code means the property
+        * exists, but could not be parsed.
+        */
+       if (!gpio_is_valid(rt5640->pdata.ldo1_en) &&
+                       (rt5640->pdata.ldo1_en != -ENOENT))
+               return rt5640->pdata.ldo1_en;
+
+       return 0;
+}
+
+static int rt5640_i2c_probe(struct i2c_client *i2c,
+                   const struct i2c_device_id *id)
+{
+       struct rt5640_platform_data *pdata = dev_get_platdata(&i2c->dev);
+       struct rt5640_priv *rt5640;
+       int ret;
+       unsigned int val;
+
+       rt5640 = devm_kzalloc(&i2c->dev,
+                               sizeof(struct rt5640_priv),
+                               GFP_KERNEL);
+       if (NULL == rt5640)
+               return -ENOMEM;
+       i2c_set_clientdata(i2c, rt5640);
+
+       if (pdata) {
+               rt5640->pdata = *pdata;
+               /*
+                * Translate zero'd out (default) pdata value to an invalid
+                * GPIO ID. This makes the pdata and DT paths consistent in
+                * terms of the value left in this field when no GPIO is
+                * specified, but means we can't actually use GPIO 0.
+                */
+               if (!rt5640->pdata.ldo1_en)
+                       rt5640->pdata.ldo1_en = -EINVAL;
+       } else if (i2c->dev.of_node) {
+               ret = rt5640_parse_dt(rt5640, i2c->dev.of_node);
+               if (ret)
+                       return ret;
+       } else
+               rt5640->pdata.ldo1_en = -EINVAL;
+
+       rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap);
+       if (IS_ERR(rt5640->regmap)) {
+               ret = PTR_ERR(rt5640->regmap);
+               dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
+
+       if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
+               ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en,
+                                           GPIOF_OUT_INIT_HIGH,
+                                           "RT5640 LDO1_EN");
+               if (ret < 0) {
+                       dev_err(&i2c->dev, "Failed to request LDO1_EN %d: %d\n",
+                               rt5640->pdata.ldo1_en, ret);
+                       return ret;
+               }
+               msleep(400);
+       }
+
+       regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val);
+       if ((val != RT5640_DEVICE_ID)) {
+               dev_err(&i2c->dev,
+                       "Device with ID register %x is not rt5640/39\n", val);
+               return -ENODEV;
+       }
+
+       regmap_write(rt5640->regmap, RT5640_RESET, 0);
+
+       ret = regmap_register_patch(rt5640->regmap, init_list,
+                                   ARRAY_SIZE(init_list));
+       if (ret != 0)
+               dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
+
+       if (rt5640->pdata.in1_diff)
+               regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
+                                       RT5640_IN_DF1, RT5640_IN_DF1);
+
+       if (rt5640->pdata.in2_diff)
+               regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
+                                       RT5640_IN_DF2, RT5640_IN_DF2);
+
+       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
+                       rt5640_dai, ARRAY_SIZE(rt5640_dai));
+       if (ret < 0)
+               goto err;
+
+       return 0;
+err:
+       return ret;
+}
+
+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",
+               .owner = THIS_MODULE,
+       },
+       .probe = rt5640_i2c_probe,
+       .remove   = rt5640_i2c_remove,
+       .id_table = rt5640_i2c_id,
+};
+module_i2c_driver(rt5640_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC RT5640 driver");
+MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
new file mode 100644 (file)
index 0000000..c48286d
--- /dev/null
@@ -0,0 +1,2092 @@
+/*
+ * rt5640.h  --  RT5640 ALSA SoC audio driver
+ *
+ * Copyright 2011 Realtek Microelectronics
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _RT5640_H
+#define _RT5640_H
+
+#include <sound/rt5640.h>
+
+/* Info */
+#define RT5640_RESET                           0x00
+#define RT5640_VENDOR_ID                       0xfd
+#define RT5640_VENDOR_ID1                      0xfe
+#define RT5640_VENDOR_ID2                      0xff
+/*  I/O - Output */
+#define RT5640_SPK_VOL                         0x01
+#define RT5640_HP_VOL                          0x02
+#define RT5640_OUTPUT                          0x03
+#define RT5640_MONO_OUT                                0x04
+/* I/O - Input */
+#define RT5640_IN1_IN2                         0x0d
+#define RT5640_IN3_IN4                         0x0e
+#define RT5640_INL_INR_VOL                     0x0f
+/* I/O - ADC/DAC/DMIC */
+#define RT5640_DAC1_DIG_VOL                    0x19
+#define RT5640_DAC2_DIG_VOL                    0x1a
+#define RT5640_DAC2_CTRL                       0x1b
+#define RT5640_ADC_DIG_VOL                     0x1c
+#define RT5640_ADC_DATA                                0x1d
+#define RT5640_ADC_BST_VOL                     0x1e
+/* Mixer - D-D */
+#define RT5640_STO_ADC_MIXER                   0x27
+#define RT5640_MONO_ADC_MIXER                  0x28
+#define RT5640_AD_DA_MIXER                     0x29
+#define RT5640_STO_DAC_MIXER                   0x2a
+#define RT5640_MONO_DAC_MIXER                  0x2b
+#define RT5640_DIG_MIXER                       0x2c
+#define RT5640_DSP_PATH1                       0x2d
+#define RT5640_DSP_PATH2                       0x2e
+#define RT5640_DIG_INF_DATA                    0x2f
+/* Mixer - ADC */
+#define RT5640_REC_L1_MIXER                    0x3b
+#define RT5640_REC_L2_MIXER                    0x3c
+#define RT5640_REC_R1_MIXER                    0x3d
+#define RT5640_REC_R2_MIXER                    0x3e
+/* Mixer - DAC */
+#define RT5640_HPO_MIXER                       0x45
+#define RT5640_SPK_L_MIXER                     0x46
+#define RT5640_SPK_R_MIXER                     0x47
+#define RT5640_SPO_L_MIXER                     0x48
+#define RT5640_SPO_R_MIXER                     0x49
+#define RT5640_SPO_CLSD_RATIO                  0x4a
+#define RT5640_MONO_MIXER                      0x4c
+#define RT5640_OUT_L1_MIXER                    0x4d
+#define RT5640_OUT_L2_MIXER                    0x4e
+#define RT5640_OUT_L3_MIXER                    0x4f
+#define RT5640_OUT_R1_MIXER                    0x50
+#define RT5640_OUT_R2_MIXER                    0x51
+#define RT5640_OUT_R3_MIXER                    0x52
+#define RT5640_LOUT_MIXER                      0x53
+/* Power */
+#define RT5640_PWR_DIG1                                0x61
+#define RT5640_PWR_DIG2                                0x62
+#define RT5640_PWR_ANLG1                       0x63
+#define RT5640_PWR_ANLG2                       0x64
+#define RT5640_PWR_MIXER                       0x65
+#define RT5640_PWR_VOL                         0x66
+/* Private Register Control */
+#define RT5640_PRIV_INDEX                      0x6a
+#define RT5640_PRIV_DATA                       0x6c
+/* Format - ADC/DAC */
+#define RT5640_I2S1_SDP                                0x70
+#define RT5640_I2S2_SDP                                0x71
+#define RT5640_ADDA_CLK1                       0x73
+#define RT5640_ADDA_CLK2                       0x74
+#define RT5640_DMIC                            0x75
+/* Function - Analog */
+#define RT5640_GLB_CLK                         0x80
+#define RT5640_PLL_CTRL1                       0x81
+#define RT5640_PLL_CTRL2                       0x82
+#define RT5640_ASRC_1                          0x83
+#define RT5640_ASRC_2                          0x84
+#define RT5640_ASRC_3                          0x85
+#define RT5640_ASRC_4                          0x89
+#define RT5640_ASRC_5                          0x8a
+#define RT5640_HP_OVCD                         0x8b
+#define RT5640_CLS_D_OVCD                      0x8c
+#define RT5640_CLS_D_OUT                       0x8d
+#define RT5640_DEPOP_M1                                0x8e
+#define RT5640_DEPOP_M2                                0x8f
+#define RT5640_DEPOP_M3                                0x90
+#define RT5640_CHARGE_PUMP                     0x91
+#define RT5640_PV_DET_SPK_G                    0x92
+#define RT5640_MICBIAS                         0x93
+/* Function - Digital */
+#define RT5640_EQ_CTRL1                                0xb0
+#define RT5640_EQ_CTRL2                                0xb1
+#define RT5640_WIND_FILTER                     0xb2
+#define RT5640_DRC_AGC_1                       0xb4
+#define RT5640_DRC_AGC_2                       0xb5
+#define RT5640_DRC_AGC_3                       0xb6
+#define RT5640_SVOL_ZC                         0xb7
+#define RT5640_ANC_CTRL1                       0xb8
+#define RT5640_ANC_CTRL2                       0xb9
+#define RT5640_ANC_CTRL3                       0xba
+#define RT5640_JD_CTRL                         0xbb
+#define RT5640_ANC_JD                          0xbc
+#define RT5640_IRQ_CTRL1                       0xbd
+#define RT5640_IRQ_CTRL2                       0xbe
+#define RT5640_INT_IRQ_ST                      0xbf
+#define RT5640_GPIO_CTRL1                      0xc0
+#define RT5640_GPIO_CTRL2                      0xc1
+#define RT5640_GPIO_CTRL3                      0xc2
+#define RT5640_DSP_CTRL1                       0xc4
+#define RT5640_DSP_CTRL2                       0xc5
+#define RT5640_DSP_CTRL3                       0xc6
+#define RT5640_DSP_CTRL4                       0xc7
+#define RT5640_PGM_REG_ARR1                    0xc8
+#define RT5640_PGM_REG_ARR2                    0xc9
+#define RT5640_PGM_REG_ARR3                    0xca
+#define RT5640_PGM_REG_ARR4                    0xcb
+#define RT5640_PGM_REG_ARR5                    0xcc
+#define RT5640_SCB_FUNC                                0xcd
+#define RT5640_SCB_CTRL                                0xce
+#define RT5640_BASE_BACK                       0xcf
+#define RT5640_MP3_PLUS1                       0xd0
+#define RT5640_MP3_PLUS2                       0xd1
+#define RT5640_3D_HP                           0xd2
+#define RT5640_ADJ_HPF                         0xd3
+#define RT5640_HP_CALIB_AMP_DET                        0xd6
+#define RT5640_HP_CALIB2                       0xd7
+#define RT5640_SV_ZCD1                         0xd9
+#define RT5640_SV_ZCD2                         0xda
+/* Dummy Register */
+#define RT5640_DUMMY1                          0xfa
+#define RT5640_DUMMY2                          0xfb
+#define RT5640_DUMMY3                          0xfc
+
+
+/* Index of Codec Private Register definition */
+#define RT5640_3D_SPK                          0x63
+#define RT5640_WND_1                           0x6c
+#define RT5640_WND_2                           0x6d
+#define RT5640_WND_3                           0x6e
+#define RT5640_WND_4                           0x6f
+#define RT5640_WND_5                           0x70
+#define RT5640_WND_8                           0x73
+#define RT5640_DIP_SPK_INF                     0x75
+#define RT5640_EQ_BW_LOP                       0xa0
+#define RT5640_EQ_GN_LOP                       0xa1
+#define RT5640_EQ_FC_BP1                       0xa2
+#define RT5640_EQ_BW_BP1                       0xa3
+#define RT5640_EQ_GN_BP1                       0xa4
+#define RT5640_EQ_FC_BP2                       0xa5
+#define RT5640_EQ_BW_BP2                       0xa6
+#define RT5640_EQ_GN_BP2                       0xa7
+#define RT5640_EQ_FC_BP3                       0xa8
+#define RT5640_EQ_BW_BP3                       0xa9
+#define RT5640_EQ_GN_BP3                       0xaa
+#define RT5640_EQ_FC_BP4                       0xab
+#define RT5640_EQ_BW_BP4                       0xac
+#define RT5640_EQ_GN_BP4                       0xad
+#define RT5640_EQ_FC_HIP1                      0xae
+#define RT5640_EQ_GN_HIP1                      0xaf
+#define RT5640_EQ_FC_HIP2                      0xb0
+#define RT5640_EQ_BW_HIP2                      0xb1
+#define RT5640_EQ_GN_HIP2                      0xb2
+#define RT5640_EQ_PRE_VOL                      0xb3
+#define RT5640_EQ_PST_VOL                      0xb4
+
+/* global definition */
+#define RT5640_L_MUTE                          (0x1 << 15)
+#define RT5640_L_MUTE_SFT                      15
+#define RT5640_VOL_L_MUTE                      (0x1 << 14)
+#define RT5640_VOL_L_SFT                       14
+#define RT5640_R_MUTE                          (0x1 << 7)
+#define RT5640_R_MUTE_SFT                      7
+#define RT5640_VOL_R_MUTE                      (0x1 << 6)
+#define RT5640_VOL_R_SFT                       6
+#define RT5640_L_VOL_MASK                      (0x3f << 8)
+#define RT5640_L_VOL_SFT                       8
+#define RT5640_R_VOL_MASK                      (0x3f)
+#define RT5640_R_VOL_SFT                       0
+
+/* IN1 and IN2 Control (0x0d) */
+/* IN3 and IN4 Control (0x0e) */
+#define RT5640_BST_SFT1                                12
+#define RT5640_BST_SFT2                                8
+#define RT5640_IN_DF1                          (0x1 << 7)
+#define RT5640_IN_SFT1                         7
+#define RT5640_IN_DF2                          (0x1 << 6)
+#define RT5640_IN_SFT2                         6
+
+/* INL and INR Volume Control (0x0f) */
+#define RT5640_INL_SEL_MASK                    (0x1 << 15)
+#define RT5640_INL_SEL_SFT                     15
+#define RT5640_INL_SEL_IN4P                    (0x0 << 15)
+#define RT5640_INL_SEL_MONOP                   (0x1 << 15)
+#define RT5640_INL_VOL_MASK                    (0x1f << 8)
+#define RT5640_INL_VOL_SFT                     8
+#define RT5640_INR_SEL_MASK                    (0x1 << 7)
+#define RT5640_INR_SEL_SFT                     7
+#define RT5640_INR_SEL_IN4N                    (0x0 << 7)
+#define RT5640_INR_SEL_MONON                   (0x1 << 7)
+#define RT5640_INR_VOL_MASK                    (0x1f)
+#define RT5640_INR_VOL_SFT                     0
+
+/* DAC1 Digital Volume (0x19) */
+#define RT5640_DAC_L1_VOL_MASK                 (0xff << 8)
+#define RT5640_DAC_L1_VOL_SFT                  8
+#define RT5640_DAC_R1_VOL_MASK                 (0xff)
+#define RT5640_DAC_R1_VOL_SFT                  0
+
+/* DAC2 Digital Volume (0x1a) */
+#define RT5640_DAC_L2_VOL_MASK                 (0xff << 8)
+#define RT5640_DAC_L2_VOL_SFT                  8
+#define RT5640_DAC_R2_VOL_MASK                 (0xff)
+#define RT5640_DAC_R2_VOL_SFT                  0
+
+/* DAC2 Control (0x1b) */
+#define RT5640_M_DAC_L2_VOL                    (0x1 << 13)
+#define RT5640_M_DAC_L2_VOL_SFT                        13
+#define RT5640_M_DAC_R2_VOL                    (0x1 << 12)
+#define RT5640_M_DAC_R2_VOL_SFT                        12
+
+/* ADC Digital Volume Control (0x1c) */
+#define RT5640_ADC_L_VOL_MASK                  (0x7f << 8)
+#define RT5640_ADC_L_VOL_SFT                   8
+#define RT5640_ADC_R_VOL_MASK                  (0x7f)
+#define RT5640_ADC_R_VOL_SFT                   0
+
+/* Mono ADC Digital Volume Control (0x1d) */
+#define RT5640_MONO_ADC_L_VOL_MASK             (0x7f << 8)
+#define RT5640_MONO_ADC_L_VOL_SFT              8
+#define RT5640_MONO_ADC_R_VOL_MASK             (0x7f)
+#define RT5640_MONO_ADC_R_VOL_SFT              0
+
+/* ADC Boost Volume Control (0x1e) */
+#define RT5640_ADC_L_BST_MASK                  (0x3 << 14)
+#define RT5640_ADC_L_BST_SFT                   14
+#define RT5640_ADC_R_BST_MASK                  (0x3 << 12)
+#define RT5640_ADC_R_BST_SFT                   12
+#define RT5640_ADC_COMP_MASK                   (0x3 << 10)
+#define RT5640_ADC_COMP_SFT                    10
+
+/* Stereo ADC Mixer Control (0x27) */
+#define RT5640_M_ADC_L1                                (0x1 << 14)
+#define RT5640_M_ADC_L1_SFT                    14
+#define RT5640_M_ADC_L2                                (0x1 << 13)
+#define RT5640_M_ADC_L2_SFT                    13
+#define RT5640_ADC_1_SRC_MASK                  (0x1 << 12)
+#define RT5640_ADC_1_SRC_SFT                   12
+#define RT5640_ADC_1_SRC_ADC                   (0x1 << 12)
+#define RT5640_ADC_1_SRC_DACMIX                        (0x0 << 12)
+#define RT5640_ADC_2_SRC_MASK                  (0x3 << 10)
+#define RT5640_ADC_2_SRC_SFT                   10
+#define RT5640_ADC_2_SRC_DMIC1                 (0x0 << 10)
+#define RT5640_ADC_2_SRC_DMIC2                 (0x1 << 10)
+#define RT5640_ADC_2_SRC_DACMIX                        (0x2 << 10)
+#define RT5640_M_ADC_R1                                (0x1 << 6)
+#define RT5640_M_ADC_R1_SFT                    6
+#define RT5640_M_ADC_R2                                (0x1 << 5)
+#define RT5640_M_ADC_R2_SFT                    5
+
+/* Mono ADC Mixer Control (0x28) */
+#define RT5640_M_MONO_ADC_L1                   (0x1 << 14)
+#define RT5640_M_MONO_ADC_L1_SFT               14
+#define RT5640_M_MONO_ADC_L2                   (0x1 << 13)
+#define RT5640_M_MONO_ADC_L2_SFT               13
+#define RT5640_MONO_ADC_L1_SRC_MASK            (0x1 << 12)
+#define RT5640_MONO_ADC_L1_SRC_SFT             12
+#define RT5640_MONO_ADC_L1_SRC_DACMIXL         (0x0 << 12)
+#define RT5640_MONO_ADC_L1_SRC_ADCL            (0x1 << 12)
+#define RT5640_MONO_ADC_L2_SRC_MASK            (0x3 << 10)
+#define RT5640_MONO_ADC_L2_SRC_SFT             10
+#define RT5640_MONO_ADC_L2_SRC_DMIC_L1         (0x0 << 10)
+#define RT5640_MONO_ADC_L2_SRC_DMIC_L2         (0x1 << 10)
+#define RT5640_MONO_ADC_L2_SRC_DACMIXL         (0x2 << 10)
+#define RT5640_M_MONO_ADC_R1                   (0x1 << 6)
+#define RT5640_M_MONO_ADC_R1_SFT               6
+#define RT5640_M_MONO_ADC_R2                   (0x1 << 5)
+#define RT5640_M_MONO_ADC_R2_SFT               5
+#define RT5640_MONO_ADC_R1_SRC_MASK            (0x1 << 4)
+#define RT5640_MONO_ADC_R1_SRC_SFT             4
+#define RT5640_MONO_ADC_R1_SRC_ADCR            (0x1 << 4)
+#define RT5640_MONO_ADC_R1_SRC_DACMIXR         (0x0 << 4)
+#define RT5640_MONO_ADC_R2_SRC_MASK            (0x3 << 2)
+#define RT5640_MONO_ADC_R2_SRC_SFT             2
+#define RT5640_MONO_ADC_R2_SRC_DMIC_R1         (0x0 << 2)
+#define RT5640_MONO_ADC_R2_SRC_DMIC_R2         (0x1 << 2)
+#define RT5640_MONO_ADC_R2_SRC_DACMIXR         (0x2 << 2)
+
+/* ADC Mixer to DAC Mixer Control (0x29) */
+#define RT5640_M_ADCMIX_L                      (0x1 << 15)
+#define RT5640_M_ADCMIX_L_SFT                  15
+#define RT5640_M_IF1_DAC_L                     (0x1 << 14)
+#define RT5640_M_IF1_DAC_L_SFT                 14
+#define RT5640_M_ADCMIX_R                      (0x1 << 7)
+#define RT5640_M_ADCMIX_R_SFT                  7
+#define RT5640_M_IF1_DAC_R                     (0x1 << 6)
+#define RT5640_M_IF1_DAC_R_SFT                 6
+
+/* Stereo DAC Mixer Control (0x2a) */
+#define RT5640_M_DAC_L1                                (0x1 << 14)
+#define RT5640_M_DAC_L1_SFT                    14
+#define RT5640_DAC_L1_STO_L_VOL_MASK           (0x1 << 13)
+#define RT5640_DAC_L1_STO_L_VOL_SFT            13
+#define RT5640_M_DAC_L2                                (0x1 << 12)
+#define RT5640_M_DAC_L2_SFT                    12
+#define RT5640_DAC_L2_STO_L_VOL_MASK           (0x1 << 11)
+#define RT5640_DAC_L2_STO_L_VOL_SFT            11
+#define RT5640_M_ANC_DAC_L                     (0x1 << 10)
+#define RT5640_M_ANC_DAC_L_SFT                 10
+#define RT5640_M_DAC_R1                                (0x1 << 6)
+#define RT5640_M_DAC_R1_SFT                    6
+#define RT5640_DAC_R1_STO_R_VOL_MASK           (0x1 << 5)
+#define RT5640_DAC_R1_STO_R_VOL_SFT            5
+#define RT5640_M_DAC_R2                                (0x1 << 4)
+#define RT5640_M_DAC_R2_SFT                    4
+#define RT5640_DAC_R2_STO_R_VOL_MASK           (0x1 << 3)
+#define RT5640_DAC_R2_STO_R_VOL_SFT            3
+#define RT5640_M_ANC_DAC_R                     (0x1 << 2)
+#define RT5640_M_ANC_DAC_R_SFT         2
+
+/* Mono DAC Mixer Control (0x2b) */
+#define RT5640_M_DAC_L1_MONO_L                 (0x1 << 14)
+#define RT5640_M_DAC_L1_MONO_L_SFT             14
+#define RT5640_DAC_L1_MONO_L_VOL_MASK          (0x1 << 13)
+#define RT5640_DAC_L1_MONO_L_VOL_SFT           13
+#define RT5640_M_DAC_L2_MONO_L                 (0x1 << 12)
+#define RT5640_M_DAC_L2_MONO_L_SFT             12
+#define RT5640_DAC_L2_MONO_L_VOL_MASK          (0x1 << 11)
+#define RT5640_DAC_L2_MONO_L_VOL_SFT           11
+#define RT5640_M_DAC_R2_MONO_L                 (0x1 << 10)
+#define RT5640_M_DAC_R2_MONO_L_SFT             10
+#define RT5640_DAC_R2_MONO_L_VOL_MASK          (0x1 << 9)
+#define RT5640_DAC_R2_MONO_L_VOL_SFT           9
+#define RT5640_M_DAC_R1_MONO_R                 (0x1 << 6)
+#define RT5640_M_DAC_R1_MONO_R_SFT             6
+#define RT5640_DAC_R1_MONO_R_VOL_MASK          (0x1 << 5)
+#define RT5640_DAC_R1_MONO_R_VOL_SFT           5
+#define RT5640_M_DAC_R2_MONO_R                 (0x1 << 4)
+#define RT5640_M_DAC_R2_MONO_R_SFT             4
+#define RT5640_DAC_R2_MONO_R_VOL_MASK          (0x1 << 3)
+#define RT5640_DAC_R2_MONO_R_VOL_SFT           3
+#define RT5640_M_DAC_L2_MONO_R                 (0x1 << 2)
+#define RT5640_M_DAC_L2_MONO_R_SFT             2
+#define RT5640_DAC_L2_MONO_R_VOL_MASK          (0x1 << 1)
+#define RT5640_DAC_L2_MONO_R_VOL_SFT           1
+
+/* Digital Mixer Control (0x2c) */
+#define RT5640_M_STO_L_DAC_L                   (0x1 << 15)
+#define RT5640_M_STO_L_DAC_L_SFT               15
+#define RT5640_STO_L_DAC_L_VOL_MASK            (0x1 << 14)
+#define RT5640_STO_L_DAC_L_VOL_SFT             14
+#define RT5640_M_DAC_L2_DAC_L                  (0x1 << 13)
+#define RT5640_M_DAC_L2_DAC_L_SFT              13
+#define RT5640_DAC_L2_DAC_L_VOL_MASK           (0x1 << 12)
+#define RT5640_DAC_L2_DAC_L_VOL_SFT            12
+#define RT5640_M_STO_R_DAC_R                   (0x1 << 11)
+#define RT5640_M_STO_R_DAC_R_SFT               11
+#define RT5640_STO_R_DAC_R_VOL_MASK            (0x1 << 10)
+#define RT5640_STO_R_DAC_R_VOL_SFT             10
+#define RT5640_M_DAC_R2_DAC_R                  (0x1 << 9)
+#define RT5640_M_DAC_R2_DAC_R_SFT              9
+#define RT5640_DAC_R2_DAC_R_VOL_MASK           (0x1 << 8)
+#define RT5640_DAC_R2_DAC_R_VOL_SFT            8
+
+/* DSP Path Control 1 (0x2d) */
+#define RT5640_RXDP_SRC_MASK                   (0x1 << 15)
+#define RT5640_RXDP_SRC_SFT                    15
+#define RT5640_RXDP_SRC_NOR                    (0x0 << 15)
+#define RT5640_RXDP_SRC_DIV3                   (0x1 << 15)
+#define RT5640_TXDP_SRC_MASK                   (0x1 << 14)
+#define RT5640_TXDP_SRC_SFT                    14
+#define RT5640_TXDP_SRC_NOR                    (0x0 << 14)
+#define RT5640_TXDP_SRC_DIV3                   (0x1 << 14)
+
+/* DSP Path Control 2 (0x2e) */
+#define RT5640_DAC_L2_SEL_MASK                 (0x3 << 14)
+#define RT5640_DAC_L2_SEL_SFT                  14
+#define RT5640_DAC_L2_SEL_IF2                  (0x0 << 14)
+#define RT5640_DAC_L2_SEL_IF3                  (0x1 << 14)
+#define RT5640_DAC_L2_SEL_TXDC                 (0x2 << 14)
+#define RT5640_DAC_L2_SEL_BASS                 (0x3 << 14)
+#define RT5640_DAC_R2_SEL_MASK                 (0x3 << 12)
+#define RT5640_DAC_R2_SEL_SFT                  12
+#define RT5640_DAC_R2_SEL_IF2                  (0x0 << 12)
+#define RT5640_DAC_R2_SEL_IF3                  (0x1 << 12)
+#define RT5640_DAC_R2_SEL_TXDC                 (0x2 << 12)
+#define RT5640_IF2_ADC_L_SEL_MASK              (0x1 << 11)
+#define RT5640_IF2_ADC_L_SEL_SFT               11
+#define RT5640_IF2_ADC_L_SEL_TXDP              (0x0 << 11)
+#define RT5640_IF2_ADC_L_SEL_PASS              (0x1 << 11)
+#define RT5640_IF2_ADC_R_SEL_MASK              (0x1 << 10)
+#define RT5640_IF2_ADC_R_SEL_SFT               10
+#define RT5640_IF2_ADC_R_SEL_TXDP              (0x0 << 10)
+#define RT5640_IF2_ADC_R_SEL_PASS              (0x1 << 10)
+#define RT5640_RXDC_SEL_MASK                   (0x3 << 8)
+#define RT5640_RXDC_SEL_SFT                    8
+#define RT5640_RXDC_SEL_NOR                    (0x0 << 8)
+#define RT5640_RXDC_SEL_L2R                    (0x1 << 8)
+#define RT5640_RXDC_SEL_R2L                    (0x2 << 8)
+#define RT5640_RXDC_SEL_SWAP                   (0x3 << 8)
+#define RT5640_RXDP_SEL_MASK                   (0x3 << 6)
+#define RT5640_RXDP_SEL_SFT                    6
+#define RT5640_RXDP_SEL_NOR                    (0x0 << 6)
+#define RT5640_RXDP_SEL_L2R                    (0x1 << 6)
+#define RT5640_RXDP_SEL_R2L                    (0x2 << 6)
+#define RT5640_RXDP_SEL_SWAP                   (0x3 << 6)
+#define RT5640_TXDC_SEL_MASK                   (0x3 << 4)
+#define RT5640_TXDC_SEL_SFT                    4
+#define RT5640_TXDC_SEL_NOR                    (0x0 << 4)
+#define RT5640_TXDC_SEL_L2R                    (0x1 << 4)
+#define RT5640_TXDC_SEL_R2L                    (0x2 << 4)
+#define RT5640_TXDC_SEL_SWAP                   (0x3 << 4)
+#define RT5640_TXDP_SEL_MASK                   (0x3 << 2)
+#define RT5640_TXDP_SEL_SFT                    2
+#define RT5640_TXDP_SEL_NOR                    (0x0 << 2)
+#define RT5640_TXDP_SEL_L2R                    (0x1 << 2)
+#define RT5640_TXDP_SEL_R2L                    (0x2 << 2)
+#define RT5640_TRXDP_SEL_SWAP                  (0x3 << 2)
+
+/* Digital Interface Data Control (0x2f) */
+#define RT5640_IF1_DAC_SEL_MASK                        (0x3 << 14)
+#define RT5640_IF1_DAC_SEL_SFT                 14
+#define RT5640_IF1_DAC_SEL_NOR                 (0x0 << 14)
+#define RT5640_IF1_DAC_SEL_L2R                 (0x1 << 14)
+#define RT5640_IF1_DAC_SEL_R2L                 (0x2 << 14)
+#define RT5640_IF1_DAC_SEL_SWAP                        (0x3 << 14)
+#define RT5640_IF1_ADC_SEL_MASK                        (0x3 << 12)
+#define RT5640_IF1_ADC_SEL_SFT                 12
+#define RT5640_IF1_ADC_SEL_NOR                 (0x0 << 12)
+#define RT5640_IF1_ADC_SEL_L2R                 (0x1 << 12)
+#define RT5640_IF1_ADC_SEL_R2L                 (0x2 << 12)
+#define RT5640_IF1_ADC_SEL_SWAP                        (0x3 << 12)
+#define RT5640_IF2_DAC_SEL_MASK                        (0x3 << 10)
+#define RT5640_IF2_DAC_SEL_SFT                 10
+#define RT5640_IF2_DAC_SEL_NOR                 (0x0 << 10)
+#define RT5640_IF2_DAC_SEL_L2R                 (0x1 << 10)
+#define RT5640_IF2_DAC_SEL_R2L                 (0x2 << 10)
+#define RT5640_IF2_DAC_SEL_SWAP                        (0x3 << 10)
+#define RT5640_IF2_ADC_SEL_MASK                        (0x3 << 8)
+#define RT5640_IF2_ADC_SEL_SFT                 8
+#define RT5640_IF2_ADC_SEL_NOR                 (0x0 << 8)
+#define RT5640_IF2_ADC_SEL_L2R                 (0x1 << 8)
+#define RT5640_IF2_ADC_SEL_R2L                 (0x2 << 8)
+#define RT5640_IF2_ADC_SEL_SWAP                        (0x3 << 8)
+#define RT5640_IF3_DAC_SEL_MASK                        (0x3 << 6)
+#define RT5640_IF3_DAC_SEL_SFT                 6
+#define RT5640_IF3_DAC_SEL_NOR                 (0x0 << 6)
+#define RT5640_IF3_DAC_SEL_L2R                 (0x1 << 6)
+#define RT5640_IF3_DAC_SEL_R2L                 (0x2 << 6)
+#define RT5640_IF3_DAC_SEL_SWAP                        (0x3 << 6)
+#define RT5640_IF3_ADC_SEL_MASK                        (0x3 << 4)
+#define RT5640_IF3_ADC_SEL_SFT                 4
+#define RT5640_IF3_ADC_SEL_NOR                 (0x0 << 4)
+#define RT5640_IF3_ADC_SEL_L2R                 (0x1 << 4)
+#define RT5640_IF3_ADC_SEL_R2L                 (0x2 << 4)
+#define RT5640_IF3_ADC_SEL_SWAP                        (0x3 << 4)
+
+/* REC Left Mixer Control 1 (0x3b) */
+#define RT5640_G_HP_L_RM_L_MASK                        (0x7 << 13)
+#define RT5640_G_HP_L_RM_L_SFT                 13
+#define RT5640_G_IN_L_RM_L_MASK                        (0x7 << 10)
+#define RT5640_G_IN_L_RM_L_SFT                 10
+#define RT5640_G_BST4_RM_L_MASK                        (0x7 << 7)
+#define RT5640_G_BST4_RM_L_SFT                 7
+#define RT5640_G_BST3_RM_L_MASK                        (0x7 << 4)
+#define RT5640_G_BST3_RM_L_SFT                 4
+#define RT5640_G_BST2_RM_L_MASK                        (0x7 << 1)
+#define RT5640_G_BST2_RM_L_SFT                 1
+
+/* REC Left Mixer Control 2 (0x3c) */
+#define RT5640_G_BST1_RM_L_MASK                        (0x7 << 13)
+#define RT5640_G_BST1_RM_L_SFT                 13
+#define RT5640_G_OM_L_RM_L_MASK                        (0x7 << 10)
+#define RT5640_G_OM_L_RM_L_SFT                 10
+#define RT5640_M_HP_L_RM_L                     (0x1 << 6)
+#define RT5640_M_HP_L_RM_L_SFT                 6
+#define RT5640_M_IN_L_RM_L                     (0x1 << 5)
+#define RT5640_M_IN_L_RM_L_SFT                 5
+#define RT5640_M_BST4_RM_L                     (0x1 << 4)
+#define RT5640_M_BST4_RM_L_SFT                 4
+#define RT5640_M_BST3_RM_L                     (0x1 << 3)
+#define RT5640_M_BST3_RM_L_SFT                 3
+#define RT5640_M_BST2_RM_L                     (0x1 << 2)
+#define RT5640_M_BST2_RM_L_SFT                 2
+#define RT5640_M_BST1_RM_L                     (0x1 << 1)
+#define RT5640_M_BST1_RM_L_SFT                 1
+#define RT5640_M_OM_L_RM_L                     (0x1)
+#define RT5640_M_OM_L_RM_L_SFT                 0
+
+/* REC Right Mixer Control 1 (0x3d) */
+#define RT5640_G_HP_R_RM_R_MASK                        (0x7 << 13)
+#define RT5640_G_HP_R_RM_R_SFT                 13
+#define RT5640_G_IN_R_RM_R_MASK                        (0x7 << 10)
+#define RT5640_G_IN_R_RM_R_SFT                 10
+#define RT5640_G_BST4_RM_R_MASK                        (0x7 << 7)
+#define RT5640_G_BST4_RM_R_SFT                 7
+#define RT5640_G_BST3_RM_R_MASK                        (0x7 << 4)
+#define RT5640_G_BST3_RM_R_SFT                 4
+#define RT5640_G_BST2_RM_R_MASK                        (0x7 << 1)
+#define RT5640_G_BST2_RM_R_SFT                 1
+
+/* REC Right Mixer Control 2 (0x3e) */
+#define RT5640_G_BST1_RM_R_MASK                        (0x7 << 13)
+#define RT5640_G_BST1_RM_R_SFT                 13
+#define RT5640_G_OM_R_RM_R_MASK                        (0x7 << 10)
+#define RT5640_G_OM_R_RM_R_SFT                 10
+#define RT5640_M_HP_R_RM_R                     (0x1 << 6)
+#define RT5640_M_HP_R_RM_R_SFT                 6
+#define RT5640_M_IN_R_RM_R                     (0x1 << 5)
+#define RT5640_M_IN_R_RM_R_SFT                 5
+#define RT5640_M_BST4_RM_R                     (0x1 << 4)
+#define RT5640_M_BST4_RM_R_SFT                 4
+#define RT5640_M_BST3_RM_R                     (0x1 << 3)
+#define RT5640_M_BST3_RM_R_SFT                 3
+#define RT5640_M_BST2_RM_R                     (0x1 << 2)
+#define RT5640_M_BST2_RM_R_SFT                 2
+#define RT5640_M_BST1_RM_R                     (0x1 << 1)
+#define RT5640_M_BST1_RM_R_SFT                 1
+#define RT5640_M_OM_R_RM_R                     (0x1)
+#define RT5640_M_OM_R_RM_R_SFT                 0
+
+/* HPMIX Control (0x45) */
+#define RT5640_M_DAC2_HM                       (0x1 << 15)
+#define RT5640_M_DAC2_HM_SFT                   15
+#define RT5640_M_DAC1_HM                       (0x1 << 14)
+#define RT5640_M_DAC1_HM_SFT                   14
+#define RT5640_M_HPVOL_HM                      (0x1 << 13)
+#define RT5640_M_HPVOL_HM_SFT                  13
+#define RT5640_G_HPOMIX_MASK                   (0x1 << 12)
+#define RT5640_G_HPOMIX_SFT                    12
+
+/* SPK Left Mixer Control (0x46) */
+#define RT5640_G_RM_L_SM_L_MASK                        (0x3 << 14)
+#define RT5640_G_RM_L_SM_L_SFT                 14
+#define RT5640_G_IN_L_SM_L_MASK                        (0x3 << 12)
+#define RT5640_G_IN_L_SM_L_SFT                 12
+#define RT5640_G_DAC_L1_SM_L_MASK              (0x3 << 10)
+#define RT5640_G_DAC_L1_SM_L_SFT               10
+#define RT5640_G_DAC_L2_SM_L_MASK              (0x3 << 8)
+#define RT5640_G_DAC_L2_SM_L_SFT               8
+#define RT5640_G_OM_L_SM_L_MASK                        (0x3 << 6)
+#define RT5640_G_OM_L_SM_L_SFT                 6
+#define RT5640_M_RM_L_SM_L                     (0x1 << 5)
+#define RT5640_M_RM_L_SM_L_SFT                 5
+#define RT5640_M_IN_L_SM_L                     (0x1 << 4)
+#define RT5640_M_IN_L_SM_L_SFT                 4
+#define RT5640_M_DAC_L1_SM_L                   (0x1 << 3)
+#define RT5640_M_DAC_L1_SM_L_SFT               3
+#define RT5640_M_DAC_L2_SM_L                   (0x1 << 2)
+#define RT5640_M_DAC_L2_SM_L_SFT               2
+#define RT5640_M_OM_L_SM_L                     (0x1 << 1)
+#define RT5640_M_OM_L_SM_L_SFT         1
+
+/* SPK Right Mixer Control (0x47) */
+#define RT5640_G_RM_R_SM_R_MASK                        (0x3 << 14)
+#define RT5640_G_RM_R_SM_R_SFT                 14
+#define RT5640_G_IN_R_SM_R_MASK                        (0x3 << 12)
+#define RT5640_G_IN_R_SM_R_SFT                 12
+#define RT5640_G_DAC_R1_SM_R_MASK              (0x3 << 10)
+#define RT5640_G_DAC_R1_SM_R_SFT               10
+#define RT5640_G_DAC_R2_SM_R_MASK              (0x3 << 8)
+#define RT5640_G_DAC_R2_SM_R_SFT               8
+#define RT5640_G_OM_R_SM_R_MASK                        (0x3 << 6)
+#define RT5640_G_OM_R_SM_R_SFT                 6
+#define RT5640_M_RM_R_SM_R                     (0x1 << 5)
+#define RT5640_M_RM_R_SM_R_SFT                 5
+#define RT5640_M_IN_R_SM_R                     (0x1 << 4)
+#define RT5640_M_IN_R_SM_R_SFT                 4
+#define RT5640_M_DAC_R1_SM_R                   (0x1 << 3)
+#define RT5640_M_DAC_R1_SM_R_SFT               3
+#define RT5640_M_DAC_R2_SM_R                   (0x1 << 2)
+#define RT5640_M_DAC_R2_SM_R_SFT               2
+#define RT5640_M_OM_R_SM_R                     (0x1 << 1)
+#define RT5640_M_OM_R_SM_R_SFT                 1
+
+/* SPOLMIX Control (0x48) */
+#define RT5640_M_DAC_R1_SPM_L                  (0x1 << 15)
+#define RT5640_M_DAC_R1_SPM_L_SFT              15
+#define RT5640_M_DAC_L1_SPM_L                  (0x1 << 14)
+#define RT5640_M_DAC_L1_SPM_L_SFT              14
+#define RT5640_M_SV_R_SPM_L                    (0x1 << 13)
+#define RT5640_M_SV_R_SPM_L_SFT                        13
+#define RT5640_M_SV_L_SPM_L                    (0x1 << 12)
+#define RT5640_M_SV_L_SPM_L_SFT                        12
+#define RT5640_M_BST1_SPM_L                    (0x1 << 11)
+#define RT5640_M_BST1_SPM_L_SFT                        11
+
+/* SPORMIX Control (0x49) */
+#define RT5640_M_DAC_R1_SPM_R                  (0x1 << 13)
+#define RT5640_M_DAC_R1_SPM_R_SFT              13
+#define RT5640_M_SV_R_SPM_R                    (0x1 << 12)
+#define RT5640_M_SV_R_SPM_R_SFT                        12
+#define RT5640_M_BST1_SPM_R                    (0x1 << 11)
+#define RT5640_M_BST1_SPM_R_SFT                        11
+
+/* SPOLMIX / SPORMIX Ratio Control (0x4a) */
+#define RT5640_SPO_CLSD_RATIO_MASK             (0x7)
+#define RT5640_SPO_CLSD_RATIO_SFT              0
+
+/* Mono Output Mixer Control (0x4c) */
+#define RT5640_M_DAC_R2_MM                     (0x1 << 15)
+#define RT5640_M_DAC_R2_MM_SFT                 15
+#define RT5640_M_DAC_L2_MM                     (0x1 << 14)
+#define RT5640_M_DAC_L2_MM_SFT                 14
+#define RT5640_M_OV_R_MM                       (0x1 << 13)
+#define RT5640_M_OV_R_MM_SFT                   13
+#define RT5640_M_OV_L_MM                       (0x1 << 12)
+#define RT5640_M_OV_L_MM_SFT                   12
+#define RT5640_M_BST1_MM                       (0x1 << 11)
+#define RT5640_M_BST1_MM_SFT                   11
+#define RT5640_G_MONOMIX_MASK                  (0x1 << 10)
+#define RT5640_G_MONOMIX_SFT                   10
+
+/* Output Left Mixer Control 1 (0x4d) */
+#define RT5640_G_BST3_OM_L_MASK                        (0x7 << 13)
+#define RT5640_G_BST3_OM_L_SFT                 13
+#define RT5640_G_BST2_OM_L_MASK                        (0x7 << 10)
+#define RT5640_G_BST2_OM_L_SFT                 10
+#define RT5640_G_BST1_OM_L_MASK                        (0x7 << 7)
+#define RT5640_G_BST1_OM_L_SFT                 7
+#define RT5640_G_IN_L_OM_L_MASK                        (0x7 << 4)
+#define RT5640_G_IN_L_OM_L_SFT                 4
+#define RT5640_G_RM_L_OM_L_MASK                        (0x7 << 1)
+#define RT5640_G_RM_L_OM_L_SFT                 1
+
+/* Output Left Mixer Control 2 (0x4e) */
+#define RT5640_G_DAC_R2_OM_L_MASK              (0x7 << 13)
+#define RT5640_G_DAC_R2_OM_L_SFT               13
+#define RT5640_G_DAC_L2_OM_L_MASK              (0x7 << 10)
+#define RT5640_G_DAC_L2_OM_L_SFT               10
+#define RT5640_G_DAC_L1_OM_L_MASK              (0x7 << 7)
+#define RT5640_G_DAC_L1_OM_L_SFT               7
+
+/* Output Left Mixer Control 3 (0x4f) */
+#define RT5640_M_SM_L_OM_L                     (0x1 << 8)
+#define RT5640_M_SM_L_OM_L_SFT                 8
+#define RT5640_M_BST3_OM_L                     (0x1 << 7)
+#define RT5640_M_BST3_OM_L_SFT                 7
+#define RT5640_M_BST2_OM_L                     (0x1 << 6)
+#define RT5640_M_BST2_OM_L_SFT                 6
+#define RT5640_M_BST1_OM_L                     (0x1 << 5)
+#define RT5640_M_BST1_OM_L_SFT                 5
+#define RT5640_M_IN_L_OM_L                     (0x1 << 4)
+#define RT5640_M_IN_L_OM_L_SFT                 4
+#define RT5640_M_RM_L_OM_L                     (0x1 << 3)
+#define RT5640_M_RM_L_OM_L_SFT                 3
+#define RT5640_M_DAC_R2_OM_L                   (0x1 << 2)
+#define RT5640_M_DAC_R2_OM_L_SFT               2
+#define RT5640_M_DAC_L2_OM_L                   (0x1 << 1)
+#define RT5640_M_DAC_L2_OM_L_SFT               1
+#define RT5640_M_DAC_L1_OM_L                   (0x1)
+#define RT5640_M_DAC_L1_OM_L_SFT               0
+
+/* Output Right Mixer Control 1 (0x50) */
+#define RT5640_G_BST4_OM_R_MASK                        (0x7 << 13)
+#define RT5640_G_BST4_OM_R_SFT                 13
+#define RT5640_G_BST2_OM_R_MASK                        (0x7 << 10)
+#define RT5640_G_BST2_OM_R_SFT                 10
+#define RT5640_G_BST1_OM_R_MASK                        (0x7 << 7)
+#define RT5640_G_BST1_OM_R_SFT                 7
+#define RT5640_G_IN_R_OM_R_MASK                        (0x7 << 4)
+#define RT5640_G_IN_R_OM_R_SFT                 4
+#define RT5640_G_RM_R_OM_R_MASK                        (0x7 << 1)
+#define RT5640_G_RM_R_OM_R_SFT                 1
+
+/* Output Right Mixer Control 2 (0x51) */
+#define RT5640_G_DAC_L2_OM_R_MASK              (0x7 << 13)
+#define RT5640_G_DAC_L2_OM_R_SFT               13
+#define RT5640_G_DAC_R2_OM_R_MASK              (0x7 << 10)
+#define RT5640_G_DAC_R2_OM_R_SFT               10
+#define RT5640_G_DAC_R1_OM_R_MASK              (0x7 << 7)
+#define RT5640_G_DAC_R1_OM_R_SFT               7
+
+/* Output Right Mixer Control 3 (0x52) */
+#define RT5640_M_SM_L_OM_R                     (0x1 << 8)
+#define RT5640_M_SM_L_OM_R_SFT                 8
+#define RT5640_M_BST4_OM_R                     (0x1 << 7)
+#define RT5640_M_BST4_OM_R_SFT                 7
+#define RT5640_M_BST2_OM_R                     (0x1 << 6)
+#define RT5640_M_BST2_OM_R_SFT                 6
+#define RT5640_M_BST1_OM_R                     (0x1 << 5)
+#define RT5640_M_BST1_OM_R_SFT                 5
+#define RT5640_M_IN_R_OM_R                     (0x1 << 4)
+#define RT5640_M_IN_R_OM_R_SFT                 4
+#define RT5640_M_RM_R_OM_R                     (0x1 << 3)
+#define RT5640_M_RM_R_OM_R_SFT                 3
+#define RT5640_M_DAC_L2_OM_R                   (0x1 << 2)
+#define RT5640_M_DAC_L2_OM_R_SFT               2
+#define RT5640_M_DAC_R2_OM_R                   (0x1 << 1)
+#define RT5640_M_DAC_R2_OM_R_SFT               1
+#define RT5640_M_DAC_R1_OM_R                   (0x1)
+#define RT5640_M_DAC_R1_OM_R_SFT               0
+
+/* LOUT Mixer Control (0x53) */
+#define RT5640_M_DAC_L1_LM                     (0x1 << 15)
+#define RT5640_M_DAC_L1_LM_SFT                 15
+#define RT5640_M_DAC_R1_LM                     (0x1 << 14)
+#define RT5640_M_DAC_R1_LM_SFT                 14
+#define RT5640_M_OV_L_LM                       (0x1 << 13)
+#define RT5640_M_OV_L_LM_SFT                   13
+#define RT5640_M_OV_R_LM                       (0x1 << 12)
+#define RT5640_M_OV_R_LM_SFT                   12
+#define RT5640_G_LOUTMIX_MASK                  (0x1 << 11)
+#define RT5640_G_LOUTMIX_SFT                   11
+
+/* Power Management for Digital 1 (0x61) */
+#define RT5640_PWR_I2S1                                (0x1 << 15)
+#define RT5640_PWR_I2S1_BIT                    15
+#define RT5640_PWR_I2S2                                (0x1 << 14)
+#define RT5640_PWR_I2S2_BIT                    14
+#define RT5640_PWR_DAC_L1                      (0x1 << 12)
+#define RT5640_PWR_DAC_L1_BIT                  12
+#define RT5640_PWR_DAC_R1                      (0x1 << 11)
+#define RT5640_PWR_DAC_R1_BIT                  11
+#define RT5640_PWR_DAC_L2                      (0x1 << 7)
+#define RT5640_PWR_DAC_L2_BIT                  7
+#define RT5640_PWR_DAC_R2                      (0x1 << 6)
+#define RT5640_PWR_DAC_R2_BIT                  6
+#define RT5640_PWR_ADC_L                       (0x1 << 2)
+#define RT5640_PWR_ADC_L_BIT                   2
+#define RT5640_PWR_ADC_R                       (0x1 << 1)
+#define RT5640_PWR_ADC_R_BIT                   1
+#define RT5640_PWR_CLS_D                       (0x1)
+#define RT5640_PWR_CLS_D_BIT                   0
+
+/* Power Management for Digital 2 (0x62) */
+#define RT5640_PWR_ADC_SF                      (0x1 << 15)
+#define RT5640_PWR_ADC_SF_BIT                  15
+#define RT5640_PWR_ADC_MF_L                    (0x1 << 14)
+#define RT5640_PWR_ADC_MF_L_BIT                        14
+#define RT5640_PWR_ADC_MF_R                    (0x1 << 13)
+#define RT5640_PWR_ADC_MF_R_BIT                        13
+#define RT5640_PWR_I2S_DSP                     (0x1 << 12)
+#define RT5640_PWR_I2S_DSP_BIT                 12
+
+/* Power Management for Analog 1 (0x63) */
+#define RT5640_PWR_VREF1                       (0x1 << 15)
+#define RT5640_PWR_VREF1_BIT                   15
+#define RT5640_PWR_FV1                         (0x1 << 14)
+#define RT5640_PWR_FV1_BIT                     14
+#define RT5640_PWR_MB                          (0x1 << 13)
+#define RT5640_PWR_MB_BIT                      13
+#define RT5640_PWR_LM                          (0x1 << 12)
+#define RT5640_PWR_LM_BIT                      12
+#define RT5640_PWR_BG                          (0x1 << 11)
+#define RT5640_PWR_BG_BIT                      11
+#define RT5640_PWR_MM                          (0x1 << 10)
+#define RT5640_PWR_MM_BIT                      10
+#define RT5640_PWR_MA                          (0x1 << 8)
+#define RT5640_PWR_MA_BIT                      8
+#define RT5640_PWR_HP_L                                (0x1 << 7)
+#define RT5640_PWR_HP_L_BIT                    7
+#define RT5640_PWR_HP_R                                (0x1 << 6)
+#define RT5640_PWR_HP_R_BIT                    6
+#define RT5640_PWR_HA                          (0x1 << 5)
+#define RT5640_PWR_HA_BIT                      5
+#define RT5640_PWR_VREF2                       (0x1 << 4)
+#define RT5640_PWR_VREF2_BIT                   4
+#define RT5640_PWR_FV2                         (0x1 << 3)
+#define RT5640_PWR_FV2_BIT                     3
+#define RT5640_PWR_LDO2                                (0x1 << 2)
+#define RT5640_PWR_LDO2_BIT                    2
+
+/* Power Management for Analog 2 (0x64) */
+#define RT5640_PWR_BST1                                (0x1 << 15)
+#define RT5640_PWR_BST1_BIT                    15
+#define RT5640_PWR_BST2                                (0x1 << 14)
+#define RT5640_PWR_BST2_BIT                    14
+#define RT5640_PWR_BST3                                (0x1 << 13)
+#define RT5640_PWR_BST3_BIT                    13
+#define RT5640_PWR_BST4                                (0x1 << 12)
+#define RT5640_PWR_BST4_BIT                    12
+#define RT5640_PWR_MB1                         (0x1 << 11)
+#define RT5640_PWR_MB1_BIT                     11
+#define RT5640_PWR_PLL                         (0x1 << 9)
+#define RT5640_PWR_PLL_BIT                     9
+
+/* Power Management for Mixer (0x65) */
+#define RT5640_PWR_OM_L                                (0x1 << 15)
+#define RT5640_PWR_OM_L_BIT                    15
+#define RT5640_PWR_OM_R                                (0x1 << 14)
+#define RT5640_PWR_OM_R_BIT                    14
+#define RT5640_PWR_SM_L                                (0x1 << 13)
+#define RT5640_PWR_SM_L_BIT                    13
+#define RT5640_PWR_SM_R                                (0x1 << 12)
+#define RT5640_PWR_SM_R_BIT                    12
+#define RT5640_PWR_RM_L                                (0x1 << 11)
+#define RT5640_PWR_RM_L_BIT                    11
+#define RT5640_PWR_RM_R                                (0x1 << 10)
+#define RT5640_PWR_RM_R_BIT                    10
+
+/* Power Management for Volume (0x66) */
+#define RT5640_PWR_SV_L                                (0x1 << 15)
+#define RT5640_PWR_SV_L_BIT                    15
+#define RT5640_PWR_SV_R                                (0x1 << 14)
+#define RT5640_PWR_SV_R_BIT                    14
+#define RT5640_PWR_OV_L                                (0x1 << 13)
+#define RT5640_PWR_OV_L_BIT                    13
+#define RT5640_PWR_OV_R                                (0x1 << 12)
+#define RT5640_PWR_OV_R_BIT                    12
+#define RT5640_PWR_HV_L                                (0x1 << 11)
+#define RT5640_PWR_HV_L_BIT                    11
+#define RT5640_PWR_HV_R                                (0x1 << 10)
+#define RT5640_PWR_HV_R_BIT                    10
+#define RT5640_PWR_IN_L                                (0x1 << 9)
+#define RT5640_PWR_IN_L_BIT                    9
+#define RT5640_PWR_IN_R                                (0x1 << 8)
+#define RT5640_PWR_IN_R_BIT                    8
+
+/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71 0x72) */
+#define RT5640_I2S_MS_MASK                     (0x1 << 15)
+#define RT5640_I2S_MS_SFT                      15
+#define RT5640_I2S_MS_M                                (0x0 << 15)
+#define RT5640_I2S_MS_S                                (0x1 << 15)
+#define RT5640_I2S_IF_MASK                     (0x7 << 12)
+#define RT5640_I2S_IF_SFT                      12
+#define RT5640_I2S_O_CP_MASK                   (0x3 << 10)
+#define RT5640_I2S_O_CP_SFT                    10
+#define RT5640_I2S_O_CP_OFF                    (0x0 << 10)
+#define RT5640_I2S_O_CP_U_LAW                  (0x1 << 10)
+#define RT5640_I2S_O_CP_A_LAW                  (0x2 << 10)
+#define RT5640_I2S_I_CP_MASK                   (0x3 << 8)
+#define RT5640_I2S_I_CP_SFT                    8
+#define RT5640_I2S_I_CP_OFF                    (0x0 << 8)
+#define RT5640_I2S_I_CP_U_LAW                  (0x1 << 8)
+#define RT5640_I2S_I_CP_A_LAW                  (0x2 << 8)
+#define RT5640_I2S_BP_MASK                     (0x1 << 7)
+#define RT5640_I2S_BP_SFT                      7
+#define RT5640_I2S_BP_NOR                      (0x0 << 7)
+#define RT5640_I2S_BP_INV                      (0x1 << 7)
+#define RT5640_I2S_DL_MASK                     (0x3 << 2)
+#define RT5640_I2S_DL_SFT                      2
+#define RT5640_I2S_DL_16                       (0x0 << 2)
+#define RT5640_I2S_DL_20                       (0x1 << 2)
+#define RT5640_I2S_DL_24                       (0x2 << 2)
+#define RT5640_I2S_DL_8                                (0x3 << 2)
+#define RT5640_I2S_DF_MASK                     (0x3)
+#define RT5640_I2S_DF_SFT                      0
+#define RT5640_I2S_DF_I2S                      (0x0)
+#define RT5640_I2S_DF_LEFT                     (0x1)
+#define RT5640_I2S_DF_PCM_A                    (0x2)
+#define RT5640_I2S_DF_PCM_B                    (0x3)
+
+/* I2S2 Audio Serial Data Port Control (0x71) */
+#define RT5640_I2S2_SDI_MASK                   (0x1 << 6)
+#define RT5640_I2S2_SDI_SFT                    6
+#define RT5640_I2S2_SDI_I2S1                   (0x0 << 6)
+#define RT5640_I2S2_SDI_I2S2                   (0x1 << 6)
+
+/* ADC/DAC Clock Control 1 (0x73) */
+#define RT5640_I2S_BCLK_MS1_MASK               (0x1 << 15)
+#define RT5640_I2S_BCLK_MS1_SFT                        15
+#define RT5640_I2S_BCLK_MS1_32                 (0x0 << 15)
+#define RT5640_I2S_BCLK_MS1_64                 (0x1 << 15)
+#define RT5640_I2S_PD1_MASK                    (0x7 << 12)
+#define RT5640_I2S_PD1_SFT                     12
+#define RT5640_I2S_PD1_1                       (0x0 << 12)
+#define RT5640_I2S_PD1_2                       (0x1 << 12)
+#define RT5640_I2S_PD1_3                       (0x2 << 12)
+#define RT5640_I2S_PD1_4                       (0x3 << 12)
+#define RT5640_I2S_PD1_6                       (0x4 << 12)
+#define RT5640_I2S_PD1_8                       (0x5 << 12)
+#define RT5640_I2S_PD1_12                      (0x6 << 12)
+#define RT5640_I2S_PD1_16                      (0x7 << 12)
+#define RT5640_I2S_BCLK_MS2_MASK               (0x1 << 11)
+#define RT5640_I2S_BCLK_MS2_SFT                        11
+#define RT5640_I2S_BCLK_MS2_32                 (0x0 << 11)
+#define RT5640_I2S_BCLK_MS2_64                 (0x1 << 11)
+#define RT5640_I2S_PD2_MASK                    (0x7 << 8)
+#define RT5640_I2S_PD2_SFT                     8
+#define RT5640_I2S_PD2_1                       (0x0 << 8)
+#define RT5640_I2S_PD2_2                       (0x1 << 8)
+#define RT5640_I2S_PD2_3                       (0x2 << 8)
+#define RT5640_I2S_PD2_4                       (0x3 << 8)
+#define RT5640_I2S_PD2_6                       (0x4 << 8)
+#define RT5640_I2S_PD2_8                       (0x5 << 8)
+#define RT5640_I2S_PD2_12                      (0x6 << 8)
+#define RT5640_I2S_PD2_16                      (0x7 << 8)
+#define RT5640_I2S_BCLK_MS3_MASK               (0x1 << 7)
+#define RT5640_I2S_BCLK_MS3_SFT                        7
+#define RT5640_I2S_BCLK_MS3_32                 (0x0 << 7)
+#define RT5640_I2S_BCLK_MS3_64                 (0x1 << 7)
+#define RT5640_I2S_PD3_MASK                    (0x7 << 4)
+#define RT5640_I2S_PD3_SFT                     4
+#define RT5640_I2S_PD3_1                       (0x0 << 4)
+#define RT5640_I2S_PD3_2                       (0x1 << 4)
+#define RT5640_I2S_PD3_3                       (0x2 << 4)
+#define RT5640_I2S_PD3_4                       (0x3 << 4)
+#define RT5640_I2S_PD3_6                       (0x4 << 4)
+#define RT5640_I2S_PD3_8                       (0x5 << 4)
+#define RT5640_I2S_PD3_12                      (0x6 << 4)
+#define RT5640_I2S_PD3_16                      (0x7 << 4)
+#define RT5640_DAC_OSR_MASK                    (0x3 << 2)
+#define RT5640_DAC_OSR_SFT                     2
+#define RT5640_DAC_OSR_128                     (0x0 << 2)
+#define RT5640_DAC_OSR_64                      (0x1 << 2)
+#define RT5640_DAC_OSR_32                      (0x2 << 2)
+#define RT5640_DAC_OSR_16                      (0x3 << 2)
+#define RT5640_ADC_OSR_MASK                    (0x3)
+#define RT5640_ADC_OSR_SFT                     0
+#define RT5640_ADC_OSR_128                     (0x0)
+#define RT5640_ADC_OSR_64                      (0x1)
+#define RT5640_ADC_OSR_32                      (0x2)
+#define RT5640_ADC_OSR_16                      (0x3)
+
+/* ADC/DAC Clock Control 2 (0x74) */
+#define RT5640_DAC_L_OSR_MASK                  (0x3 << 14)
+#define RT5640_DAC_L_OSR_SFT                   14
+#define RT5640_DAC_L_OSR_128                   (0x0 << 14)
+#define RT5640_DAC_L_OSR_64                    (0x1 << 14)
+#define RT5640_DAC_L_OSR_32                    (0x2 << 14)
+#define RT5640_DAC_L_OSR_16                    (0x3 << 14)
+#define RT5640_ADC_R_OSR_MASK                  (0x3 << 12)
+#define RT5640_ADC_R_OSR_SFT                   12
+#define RT5640_ADC_R_OSR_128                   (0x0 << 12)
+#define RT5640_ADC_R_OSR_64                    (0x1 << 12)
+#define RT5640_ADC_R_OSR_32                    (0x2 << 12)
+#define RT5640_ADC_R_OSR_16                    (0x3 << 12)
+#define RT5640_DAHPF_EN                                (0x1 << 11)
+#define RT5640_DAHPF_EN_SFT                    11
+#define RT5640_ADHPF_EN                                (0x1 << 10)
+#define RT5640_ADHPF_EN_SFT                    10
+
+/* Digital Microphone Control (0x75) */
+#define RT5640_DMIC_1_EN_MASK                  (0x1 << 15)
+#define RT5640_DMIC_1_EN_SFT                   15
+#define RT5640_DMIC_1_DIS                      (0x0 << 15)
+#define RT5640_DMIC_1_EN                       (0x1 << 15)
+#define RT5640_DMIC_2_EN_MASK                  (0x1 << 14)
+#define RT5640_DMIC_2_EN_SFT                   14
+#define RT5640_DMIC_2_DIS                      (0x0 << 14)
+#define RT5640_DMIC_2_EN                       (0x1 << 14)
+#define RT5640_DMIC_1L_LH_MASK                 (0x1 << 13)
+#define RT5640_DMIC_1L_LH_SFT                  13
+#define RT5640_DMIC_1L_LH_FALLING              (0x0 << 13)
+#define RT5640_DMIC_1L_LH_RISING               (0x1 << 13)
+#define RT5640_DMIC_1R_LH_MASK                 (0x1 << 12)
+#define RT5640_DMIC_1R_LH_SFT                  12
+#define RT5640_DMIC_1R_LH_FALLING              (0x0 << 12)
+#define RT5640_DMIC_1R_LH_RISING               (0x1 << 12)
+#define RT5640_DMIC_1_DP_MASK                  (0x1 << 11)
+#define RT5640_DMIC_1_DP_SFT                   11
+#define RT5640_DMIC_1_DP_GPIO3                 (0x0 << 11)
+#define RT5640_DMIC_1_DP_IN1P                  (0x1 << 11)
+#define RT5640_DMIC_2_DP_MASK                  (0x1 << 10)
+#define RT5640_DMIC_2_DP_SFT                   10
+#define RT5640_DMIC_2_DP_GPIO4                 (0x0 << 10)
+#define RT5640_DMIC_2_DP_IN1N                  (0x1 << 10)
+#define RT5640_DMIC_2L_LH_MASK                 (0x1 << 9)
+#define RT5640_DMIC_2L_LH_SFT                  9
+#define RT5640_DMIC_2L_LH_FALLING              (0x0 << 9)
+#define RT5640_DMIC_2L_LH_RISING               (0x1 << 9)
+#define RT5640_DMIC_2R_LH_MASK                 (0x1 << 8)
+#define RT5640_DMIC_2R_LH_SFT                  8
+#define RT5640_DMIC_2R_LH_FALLING              (0x0 << 8)
+#define RT5640_DMIC_2R_LH_RISING               (0x1 << 8)
+#define RT5640_DMIC_CLK_MASK                   (0x7 << 5)
+#define RT5640_DMIC_CLK_SFT                    5
+
+/* Global Clock Control (0x80) */
+#define RT5640_SCLK_SRC_MASK                   (0x3 << 14)
+#define RT5640_SCLK_SRC_SFT                    14
+#define RT5640_SCLK_SRC_MCLK                   (0x0 << 14)
+#define RT5640_SCLK_SRC_PLL1                   (0x1 << 14)
+#define RT5640_SCLK_SRC_PLL1T                  (0x2 << 14)
+#define RT5640_SCLK_SRC_RCCLK                  (0x3 << 14) /* 15MHz */
+#define RT5640_PLL1_SRC_MASK                   (0x3 << 12)
+#define RT5640_PLL1_SRC_SFT                    12
+#define RT5640_PLL1_SRC_MCLK                   (0x0 << 12)
+#define RT5640_PLL1_SRC_BCLK1                  (0x1 << 12)
+#define RT5640_PLL1_SRC_BCLK2                  (0x2 << 12)
+#define RT5640_PLL1_SRC_BCLK3                  (0x3 << 12)
+#define RT5640_PLL1_PD_MASK                    (0x1 << 3)
+#define RT5640_PLL1_PD_SFT                     3
+#define RT5640_PLL1_PD_1                       (0x0 << 3)
+#define RT5640_PLL1_PD_2                       (0x1 << 3)
+
+#define RT5640_PLL_INP_MAX                     40000000
+#define RT5640_PLL_INP_MIN                     256000
+/* PLL M/N/K Code Control 1 (0x81) */
+#define RT5640_PLL_N_MAX                       0x1ff
+#define RT5640_PLL_N_MASK                      (RT5640_PLL_N_MAX << 7)
+#define RT5640_PLL_N_SFT                       7
+#define RT5640_PLL_K_MAX                       0x1f
+#define RT5640_PLL_K_MASK                      (RT5640_PLL_K_MAX)
+#define RT5640_PLL_K_SFT                       0
+
+/* PLL M/N/K Code Control 2 (0x82) */
+#define RT5640_PLL_M_MAX                       0xf
+#define RT5640_PLL_M_MASK                      (RT5640_PLL_M_MAX << 12)
+#define RT5640_PLL_M_SFT                       12
+#define RT5640_PLL_M_BP                                (0x1 << 11)
+#define RT5640_PLL_M_BP_SFT                    11
+
+/* ASRC Control 1 (0x83) */
+#define RT5640_STO_T_MASK                      (0x1 << 15)
+#define RT5640_STO_T_SFT                       15
+#define RT5640_STO_T_SCLK                      (0x0 << 15)
+#define RT5640_STO_T_LRCK1                     (0x1 << 15)
+#define RT5640_M1_T_MASK                       (0x1 << 14)
+#define RT5640_M1_T_SFT                                14
+#define RT5640_M1_T_I2S2                       (0x0 << 14)
+#define RT5640_M1_T_I2S2_D3                    (0x1 << 14)
+#define RT5640_I2S2_F_MASK                     (0x1 << 12)
+#define RT5640_I2S2_F_SFT                      12
+#define RT5640_I2S2_F_I2S2_D2                  (0x0 << 12)
+#define RT5640_I2S2_F_I2S1_TCLK                        (0x1 << 12)
+#define RT5640_DMIC_1_M_MASK                   (0x1 << 9)
+#define RT5640_DMIC_1_M_SFT                    9
+#define RT5640_DMIC_1_M_NOR                    (0x0 << 9)
+#define RT5640_DMIC_1_M_ASYN                   (0x1 << 9)
+#define RT5640_DMIC_2_M_MASK                   (0x1 << 8)
+#define RT5640_DMIC_2_M_SFT                    8
+#define RT5640_DMIC_2_M_NOR                    (0x0 << 8)
+#define RT5640_DMIC_2_M_ASYN                   (0x1 << 8)
+
+/* ASRC Control 2 (0x84) */
+#define RT5640_MDA_L_M_MASK                    (0x1 << 15)
+#define RT5640_MDA_L_M_SFT                     15
+#define RT5640_MDA_L_M_NOR                     (0x0 << 15)
+#define RT5640_MDA_L_M_ASYN                    (0x1 << 15)
+#define RT5640_MDA_R_M_MASK                    (0x1 << 14)
+#define RT5640_MDA_R_M_SFT                     14
+#define RT5640_MDA_R_M_NOR                     (0x0 << 14)
+#define RT5640_MDA_R_M_ASYN                    (0x1 << 14)
+#define RT5640_MAD_L_M_MASK                    (0x1 << 13)
+#define RT5640_MAD_L_M_SFT                     13
+#define RT5640_MAD_L_M_NOR                     (0x0 << 13)
+#define RT5640_MAD_L_M_ASYN                    (0x1 << 13)
+#define RT5640_MAD_R_M_MASK                    (0x1 << 12)
+#define RT5640_MAD_R_M_SFT                     12
+#define RT5640_MAD_R_M_NOR                     (0x0 << 12)
+#define RT5640_MAD_R_M_ASYN                    (0x1 << 12)
+#define RT5640_ADC_M_MASK                      (0x1 << 11)
+#define RT5640_ADC_M_SFT                       11
+#define RT5640_ADC_M_NOR                       (0x0 << 11)
+#define RT5640_ADC_M_ASYN                      (0x1 << 11)
+#define RT5640_STO_DAC_M_MASK                  (0x1 << 5)
+#define RT5640_STO_DAC_M_SFT                   5
+#define RT5640_STO_DAC_M_NOR                   (0x0 << 5)
+#define RT5640_STO_DAC_M_ASYN                  (0x1 << 5)
+#define RT5640_I2S1_R_D_MASK                   (0x1 << 4)
+#define RT5640_I2S1_R_D_SFT                    4
+#define RT5640_I2S1_R_D_DIS                    (0x0 << 4)
+#define RT5640_I2S1_R_D_EN                     (0x1 << 4)
+#define RT5640_I2S2_R_D_MASK                   (0x1 << 3)
+#define RT5640_I2S2_R_D_SFT                    3
+#define RT5640_I2S2_R_D_DIS                    (0x0 << 3)
+#define RT5640_I2S2_R_D_EN                     (0x1 << 3)
+#define RT5640_PRE_SCLK_MASK                   (0x3)
+#define RT5640_PRE_SCLK_SFT                    0
+#define RT5640_PRE_SCLK_512                    (0x0)
+#define RT5640_PRE_SCLK_1024                   (0x1)
+#define RT5640_PRE_SCLK_2048                   (0x2)
+
+/* ASRC Control 3 (0x85) */
+#define RT5640_I2S1_RATE_MASK                  (0xf << 12)
+#define RT5640_I2S1_RATE_SFT                   12
+#define RT5640_I2S2_RATE_MASK                  (0xf << 8)
+#define RT5640_I2S2_RATE_SFT                   8
+
+/* ASRC Control 4 (0x89) */
+#define RT5640_I2S1_PD_MASK                    (0x7 << 12)
+#define RT5640_I2S1_PD_SFT                     12
+#define RT5640_I2S2_PD_MASK                    (0x7 << 8)
+#define RT5640_I2S2_PD_SFT                     8
+
+/* HPOUT Over Current Detection (0x8b) */
+#define RT5640_HP_OVCD_MASK                    (0x1 << 10)
+#define RT5640_HP_OVCD_SFT                     10
+#define RT5640_HP_OVCD_DIS                     (0x0 << 10)
+#define RT5640_HP_OVCD_EN                      (0x1 << 10)
+#define RT5640_HP_OC_TH_MASK                   (0x3 << 8)
+#define RT5640_HP_OC_TH_SFT                    8
+#define RT5640_HP_OC_TH_90                     (0x0 << 8)
+#define RT5640_HP_OC_TH_105                    (0x1 << 8)
+#define RT5640_HP_OC_TH_120                    (0x2 << 8)
+#define RT5640_HP_OC_TH_135                    (0x3 << 8)
+
+/* Class D Over Current Control (0x8c) */
+#define RT5640_CLSD_OC_MASK                    (0x1 << 9)
+#define RT5640_CLSD_OC_SFT                     9
+#define RT5640_CLSD_OC_PU                      (0x0 << 9)
+#define RT5640_CLSD_OC_PD                      (0x1 << 9)
+#define RT5640_AUTO_PD_MASK                    (0x1 << 8)
+#define RT5640_AUTO_PD_SFT                     8
+#define RT5640_AUTO_PD_DIS                     (0x0 << 8)
+#define RT5640_AUTO_PD_EN                      (0x1 << 8)
+#define RT5640_CLSD_OC_TH_MASK                 (0x3f)
+#define RT5640_CLSD_OC_TH_SFT                  0
+
+/* Class D Output Control (0x8d) */
+#define RT5640_CLSD_RATIO_MASK                 (0xf << 12)
+#define RT5640_CLSD_RATIO_SFT                  12
+#define RT5640_CLSD_OM_MASK                    (0x1 << 11)
+#define RT5640_CLSD_OM_SFT                     11
+#define RT5640_CLSD_OM_MONO                    (0x0 << 11)
+#define RT5640_CLSD_OM_STO                     (0x1 << 11)
+#define RT5640_CLSD_SCH_MASK                   (0x1 << 10)
+#define RT5640_CLSD_SCH_SFT                    10
+#define RT5640_CLSD_SCH_L                      (0x0 << 10)
+#define RT5640_CLSD_SCH_S                      (0x1 << 10)
+
+/* Depop Mode Control 1 (0x8e) */
+#define RT5640_SMT_TRIG_MASK                   (0x1 << 15)
+#define RT5640_SMT_TRIG_SFT                    15
+#define RT5640_SMT_TRIG_DIS                    (0x0 << 15)
+#define RT5640_SMT_TRIG_EN                     (0x1 << 15)
+#define RT5640_HP_L_SMT_MASK                   (0x1 << 9)
+#define RT5640_HP_L_SMT_SFT                    9
+#define RT5640_HP_L_SMT_DIS                    (0x0 << 9)
+#define RT5640_HP_L_SMT_EN                     (0x1 << 9)
+#define RT5640_HP_R_SMT_MASK                   (0x1 << 8)
+#define RT5640_HP_R_SMT_SFT                    8
+#define RT5640_HP_R_SMT_DIS                    (0x0 << 8)
+#define RT5640_HP_R_SMT_EN                     (0x1 << 8)
+#define RT5640_HP_CD_PD_MASK                   (0x1 << 7)
+#define RT5640_HP_CD_PD_SFT                    7
+#define RT5640_HP_CD_PD_DIS                    (0x0 << 7)
+#define RT5640_HP_CD_PD_EN                     (0x1 << 7)
+#define RT5640_RSTN_MASK                       (0x1 << 6)
+#define RT5640_RSTN_SFT                                6
+#define RT5640_RSTN_DIS                                (0x0 << 6)
+#define RT5640_RSTN_EN                         (0x1 << 6)
+#define RT5640_RSTP_MASK                       (0x1 << 5)
+#define RT5640_RSTP_SFT                                5
+#define RT5640_RSTP_DIS                                (0x0 << 5)
+#define RT5640_RSTP_EN                         (0x1 << 5)
+#define RT5640_HP_CO_MASK                      (0x1 << 4)
+#define RT5640_HP_CO_SFT                       4
+#define RT5640_HP_CO_DIS                       (0x0 << 4)
+#define RT5640_HP_CO_EN                                (0x1 << 4)
+#define RT5640_HP_CP_MASK                      (0x1 << 3)
+#define RT5640_HP_CP_SFT                       3
+#define RT5640_HP_CP_PD                                (0x0 << 3)
+#define RT5640_HP_CP_PU                                (0x1 << 3)
+#define RT5640_HP_SG_MASK                      (0x1 << 2)
+#define RT5640_HP_SG_SFT                       2
+#define RT5640_HP_SG_DIS                       (0x0 << 2)
+#define RT5640_HP_SG_EN                                (0x1 << 2)
+#define RT5640_HP_DP_MASK                      (0x1 << 1)
+#define RT5640_HP_DP_SFT                       1
+#define RT5640_HP_DP_PD                                (0x0 << 1)
+#define RT5640_HP_DP_PU                                (0x1 << 1)
+#define RT5640_HP_CB_MASK                      (0x1)
+#define RT5640_HP_CB_SFT                       0
+#define RT5640_HP_CB_PD                                (0x0)
+#define RT5640_HP_CB_PU                                (0x1)
+
+/* Depop Mode Control 2 (0x8f) */
+#define RT5640_DEPOP_MASK                      (0x1 << 13)
+#define RT5640_DEPOP_SFT                       13
+#define RT5640_DEPOP_AUTO                      (0x0 << 13)
+#define RT5640_DEPOP_MAN                       (0x1 << 13)
+#define RT5640_RAMP_MASK                       (0x1 << 12)
+#define RT5640_RAMP_SFT                                12
+#define RT5640_RAMP_DIS                                (0x0 << 12)
+#define RT5640_RAMP_EN                         (0x1 << 12)
+#define RT5640_BPS_MASK                                (0x1 << 11)
+#define RT5640_BPS_SFT                         11
+#define RT5640_BPS_DIS                         (0x0 << 11)
+#define RT5640_BPS_EN                          (0x1 << 11)
+#define RT5640_FAST_UPDN_MASK                  (0x1 << 10)
+#define RT5640_FAST_UPDN_SFT                   10
+#define RT5640_FAST_UPDN_DIS                   (0x0 << 10)
+#define RT5640_FAST_UPDN_EN                    (0x1 << 10)
+#define RT5640_MRES_MASK                       (0x3 << 8)
+#define RT5640_MRES_SFT                                8
+#define RT5640_MRES_15MO                       (0x0 << 8)
+#define RT5640_MRES_25MO                       (0x1 << 8)
+#define RT5640_MRES_35MO                       (0x2 << 8)
+#define RT5640_MRES_45MO                       (0x3 << 8)
+#define RT5640_VLO_MASK                                (0x1 << 7)
+#define RT5640_VLO_SFT                         7
+#define RT5640_VLO_3V                          (0x0 << 7)
+#define RT5640_VLO_32V                         (0x1 << 7)
+#define RT5640_DIG_DP_MASK                     (0x1 << 6)
+#define RT5640_DIG_DP_SFT                      6
+#define RT5640_DIG_DP_DIS                      (0x0 << 6)
+#define RT5640_DIG_DP_EN                       (0x1 << 6)
+#define RT5640_DP_TH_MASK                      (0x3 << 4)
+#define RT5640_DP_TH_SFT                       4
+
+/* Depop Mode Control 3 (0x90) */
+#define RT5640_CP_SYS_MASK                     (0x7 << 12)
+#define RT5640_CP_SYS_SFT                      12
+#define RT5640_CP_FQ1_MASK                     (0x7 << 8)
+#define RT5640_CP_FQ1_SFT                      8
+#define RT5640_CP_FQ2_MASK                     (0x7 << 4)
+#define RT5640_CP_FQ2_SFT                      4
+#define RT5640_CP_FQ3_MASK                     (0x7)
+#define RT5640_CP_FQ3_SFT                      0
+
+/* HPOUT charge pump (0x91) */
+#define RT5640_OSW_L_MASK                      (0x1 << 11)
+#define RT5640_OSW_L_SFT                       11
+#define RT5640_OSW_L_DIS                       (0x0 << 11)
+#define RT5640_OSW_L_EN                                (0x1 << 11)
+#define RT5640_OSW_R_MASK                      (0x1 << 10)
+#define RT5640_OSW_R_SFT                       10
+#define RT5640_OSW_R_DIS                       (0x0 << 10)
+#define RT5640_OSW_R_EN                                (0x1 << 10)
+#define RT5640_PM_HP_MASK                      (0x3 << 8)
+#define RT5640_PM_HP_SFT                       8
+#define RT5640_PM_HP_LV                                (0x0 << 8)
+#define RT5640_PM_HP_MV                                (0x1 << 8)
+#define RT5640_PM_HP_HV                                (0x2 << 8)
+#define RT5640_IB_HP_MASK                      (0x3 << 6)
+#define RT5640_IB_HP_SFT                       6
+#define RT5640_IB_HP_125IL                     (0x0 << 6)
+#define RT5640_IB_HP_25IL                      (0x1 << 6)
+#define RT5640_IB_HP_5IL                       (0x2 << 6)
+#define RT5640_IB_HP_1IL                       (0x3 << 6)
+
+/* PV detection and SPK gain control (0x92) */
+#define RT5640_PVDD_DET_MASK                   (0x1 << 15)
+#define RT5640_PVDD_DET_SFT                    15
+#define RT5640_PVDD_DET_DIS                    (0x0 << 15)
+#define RT5640_PVDD_DET_EN                     (0x1 << 15)
+#define RT5640_SPK_AG_MASK                     (0x1 << 14)
+#define RT5640_SPK_AG_SFT                      14
+#define RT5640_SPK_AG_DIS                      (0x0 << 14)
+#define RT5640_SPK_AG_EN                       (0x1 << 14)
+
+/* Micbias Control (0x93) */
+#define RT5640_MIC1_BS_MASK                    (0x1 << 15)
+#define RT5640_MIC1_BS_SFT                     15
+#define RT5640_MIC1_BS_9AV                     (0x0 << 15)
+#define RT5640_MIC1_BS_75AV                    (0x1 << 15)
+#define RT5640_MIC2_BS_MASK                    (0x1 << 14)
+#define RT5640_MIC2_BS_SFT                     14
+#define RT5640_MIC2_BS_9AV                     (0x0 << 14)
+#define RT5640_MIC2_BS_75AV                    (0x1 << 14)
+#define RT5640_MIC1_CLK_MASK                   (0x1 << 13)
+#define RT5640_MIC1_CLK_SFT                    13
+#define RT5640_MIC1_CLK_DIS                    (0x0 << 13)
+#define RT5640_MIC1_CLK_EN                     (0x1 << 13)
+#define RT5640_MIC2_CLK_MASK                   (0x1 << 12)
+#define RT5640_MIC2_CLK_SFT                    12
+#define RT5640_MIC2_CLK_DIS                    (0x0 << 12)
+#define RT5640_MIC2_CLK_EN                     (0x1 << 12)
+#define RT5640_MIC1_OVCD_MASK                  (0x1 << 11)
+#define RT5640_MIC1_OVCD_SFT                   11
+#define RT5640_MIC1_OVCD_DIS                   (0x0 << 11)
+#define RT5640_MIC1_OVCD_EN                    (0x1 << 11)
+#define RT5640_MIC1_OVTH_MASK                  (0x3 << 9)
+#define RT5640_MIC1_OVTH_SFT                   9
+#define RT5640_MIC1_OVTH_600UA                 (0x0 << 9)
+#define RT5640_MIC1_OVTH_1500UA                        (0x1 << 9)
+#define RT5640_MIC1_OVTH_2000UA                        (0x2 << 9)
+#define RT5640_MIC2_OVCD_MASK                  (0x1 << 8)
+#define RT5640_MIC2_OVCD_SFT                   8
+#define RT5640_MIC2_OVCD_DIS                   (0x0 << 8)
+#define RT5640_MIC2_OVCD_EN                    (0x1 << 8)
+#define RT5640_MIC2_OVTH_MASK                  (0x3 << 6)
+#define RT5640_MIC2_OVTH_SFT                   6
+#define RT5640_MIC2_OVTH_600UA                 (0x0 << 6)
+#define RT5640_MIC2_OVTH_1500UA                        (0x1 << 6)
+#define RT5640_MIC2_OVTH_2000UA                        (0x2 << 6)
+#define RT5640_PWR_MB_MASK                     (0x1 << 5)
+#define RT5640_PWR_MB_SFT                      5
+#define RT5640_PWR_MB_PD                       (0x0 << 5)
+#define RT5640_PWR_MB_PU                       (0x1 << 5)
+#define RT5640_PWR_CLK25M_MASK                 (0x1 << 4)
+#define RT5640_PWR_CLK25M_SFT                  4
+#define RT5640_PWR_CLK25M_PD                   (0x0 << 4)
+#define RT5640_PWR_CLK25M_PU                   (0x1 << 4)
+
+/* EQ Control 1 (0xb0) */
+#define RT5640_EQ_SRC_MASK                     (0x1 << 15)
+#define RT5640_EQ_SRC_SFT                      15
+#define RT5640_EQ_SRC_DAC                      (0x0 << 15)
+#define RT5640_EQ_SRC_ADC                      (0x1 << 15)
+#define RT5640_EQ_UPD                          (0x1 << 14)
+#define RT5640_EQ_UPD_BIT                      14
+#define RT5640_EQ_CD_MASK                      (0x1 << 13)
+#define RT5640_EQ_CD_SFT                       13
+#define RT5640_EQ_CD_DIS                       (0x0 << 13)
+#define RT5640_EQ_CD_EN                                (0x1 << 13)
+#define RT5640_EQ_DITH_MASK                    (0x3 << 8)
+#define RT5640_EQ_DITH_SFT                     8
+#define RT5640_EQ_DITH_NOR                     (0x0 << 8)
+#define RT5640_EQ_DITH_LSB                     (0x1 << 8)
+#define RT5640_EQ_DITH_LSB_1                   (0x2 << 8)
+#define RT5640_EQ_DITH_LSB_2                   (0x3 << 8)
+
+/* EQ Control 2 (0xb1) */
+#define RT5640_EQ_HPF1_M_MASK                  (0x1 << 8)
+#define RT5640_EQ_HPF1_M_SFT                   8
+#define RT5640_EQ_HPF1_M_HI                    (0x0 << 8)
+#define RT5640_EQ_HPF1_M_1ST                   (0x1 << 8)
+#define RT5640_EQ_LPF1_M_MASK                  (0x1 << 7)
+#define RT5640_EQ_LPF1_M_SFT                   7
+#define RT5640_EQ_LPF1_M_LO                    (0x0 << 7)
+#define RT5640_EQ_LPF1_M_1ST                   (0x1 << 7)
+#define RT5640_EQ_HPF2_MASK                    (0x1 << 6)
+#define RT5640_EQ_HPF2_SFT                     6
+#define RT5640_EQ_HPF2_DIS                     (0x0 << 6)
+#define RT5640_EQ_HPF2_EN                      (0x1 << 6)
+#define RT5640_EQ_HPF1_MASK                    (0x1 << 5)
+#define RT5640_EQ_HPF1_SFT                     5
+#define RT5640_EQ_HPF1_DIS                     (0x0 << 5)
+#define RT5640_EQ_HPF1_EN                      (0x1 << 5)
+#define RT5640_EQ_BPF4_MASK                    (0x1 << 4)
+#define RT5640_EQ_BPF4_SFT                     4
+#define RT5640_EQ_BPF4_DIS                     (0x0 << 4)
+#define RT5640_EQ_BPF4_EN                      (0x1 << 4)
+#define RT5640_EQ_BPF3_MASK                    (0x1 << 3)
+#define RT5640_EQ_BPF3_SFT                     3
+#define RT5640_EQ_BPF3_DIS                     (0x0 << 3)
+#define RT5640_EQ_BPF3_EN                      (0x1 << 3)
+#define RT5640_EQ_BPF2_MASK                    (0x1 << 2)
+#define RT5640_EQ_BPF2_SFT                     2
+#define RT5640_EQ_BPF2_DIS                     (0x0 << 2)
+#define RT5640_EQ_BPF2_EN                      (0x1 << 2)
+#define RT5640_EQ_BPF1_MASK                    (0x1 << 1)
+#define RT5640_EQ_BPF1_SFT                     1
+#define RT5640_EQ_BPF1_DIS                     (0x0 << 1)
+#define RT5640_EQ_BPF1_EN                      (0x1 << 1)
+#define RT5640_EQ_LPF_MASK                     (0x1)
+#define RT5640_EQ_LPF_SFT                      0
+#define RT5640_EQ_LPF_DIS                      (0x0)
+#define RT5640_EQ_LPF_EN                       (0x1)
+
+/* Memory Test (0xb2) */
+#define RT5640_MT_MASK                         (0x1 << 15)
+#define RT5640_MT_SFT                          15
+#define RT5640_MT_DIS                          (0x0 << 15)
+#define RT5640_MT_EN                           (0x1 << 15)
+
+/* DRC/AGC Control 1 (0xb4) */
+#define RT5640_DRC_AGC_P_MASK                  (0x1 << 15)
+#define RT5640_DRC_AGC_P_SFT                   15
+#define RT5640_DRC_AGC_P_DAC                   (0x0 << 15)
+#define RT5640_DRC_AGC_P_ADC                   (0x1 << 15)
+#define RT5640_DRC_AGC_MASK                    (0x1 << 14)
+#define RT5640_DRC_AGC_SFT                     14
+#define RT5640_DRC_AGC_DIS                     (0x0 << 14)
+#define RT5640_DRC_AGC_EN                      (0x1 << 14)
+#define RT5640_DRC_AGC_UPD                     (0x1 << 13)
+#define RT5640_DRC_AGC_UPD_BIT                 13
+#define RT5640_DRC_AGC_AR_MASK                 (0x1f << 8)
+#define RT5640_DRC_AGC_AR_SFT                  8
+#define RT5640_DRC_AGC_R_MASK                  (0x7 << 5)
+#define RT5640_DRC_AGC_R_SFT                   5
+#define RT5640_DRC_AGC_R_48K                   (0x1 << 5)
+#define RT5640_DRC_AGC_R_96K                   (0x2 << 5)
+#define RT5640_DRC_AGC_R_192K                  (0x3 << 5)
+#define RT5640_DRC_AGC_R_441K                  (0x5 << 5)
+#define RT5640_DRC_AGC_R_882K                  (0x6 << 5)
+#define RT5640_DRC_AGC_R_1764K                 (0x7 << 5)
+#define RT5640_DRC_AGC_RC_MASK                 (0x1f)
+#define RT5640_DRC_AGC_RC_SFT                  0
+
+/* DRC/AGC Control 2 (0xb5) */
+#define RT5640_DRC_AGC_POB_MASK                        (0x3f << 8)
+#define RT5640_DRC_AGC_POB_SFT                 8
+#define RT5640_DRC_AGC_CP_MASK                 (0x1 << 7)
+#define RT5640_DRC_AGC_CP_SFT                  7
+#define RT5640_DRC_AGC_CP_DIS                  (0x0 << 7)
+#define RT5640_DRC_AGC_CP_EN                   (0x1 << 7)
+#define RT5640_DRC_AGC_CPR_MASK                        (0x3 << 5)
+#define RT5640_DRC_AGC_CPR_SFT                 5
+#define RT5640_DRC_AGC_CPR_1_1                 (0x0 << 5)
+#define RT5640_DRC_AGC_CPR_1_2                 (0x1 << 5)
+#define RT5640_DRC_AGC_CPR_1_3                 (0x2 << 5)
+#define RT5640_DRC_AGC_CPR_1_4                 (0x3 << 5)
+#define RT5640_DRC_AGC_PRB_MASK                        (0x1f)
+#define RT5640_DRC_AGC_PRB_SFT                 0
+
+/* DRC/AGC Control 3 (0xb6) */
+#define RT5640_DRC_AGC_NGB_MASK                        (0xf << 12)
+#define RT5640_DRC_AGC_NGB_SFT                 12
+#define RT5640_DRC_AGC_TAR_MASK                        (0x1f << 7)
+#define RT5640_DRC_AGC_TAR_SFT                 7
+#define RT5640_DRC_AGC_NG_MASK                 (0x1 << 6)
+#define RT5640_DRC_AGC_NG_SFT                  6
+#define RT5640_DRC_AGC_NG_DIS                  (0x0 << 6)
+#define RT5640_DRC_AGC_NG_EN                   (0x1 << 6)
+#define RT5640_DRC_AGC_NGH_MASK                        (0x1 << 5)
+#define RT5640_DRC_AGC_NGH_SFT                 5
+#define RT5640_DRC_AGC_NGH_DIS                 (0x0 << 5)
+#define RT5640_DRC_AGC_NGH_EN                  (0x1 << 5)
+#define RT5640_DRC_AGC_NGT_MASK                        (0x1f)
+#define RT5640_DRC_AGC_NGT_SFT                 0
+
+/* ANC Control 1 (0xb8) */
+#define RT5640_ANC_M_MASK                      (0x1 << 15)
+#define RT5640_ANC_M_SFT                       15
+#define RT5640_ANC_M_NOR                       (0x0 << 15)
+#define RT5640_ANC_M_REV                       (0x1 << 15)
+#define RT5640_ANC_MASK                                (0x1 << 14)
+#define RT5640_ANC_SFT                         14
+#define RT5640_ANC_DIS                         (0x0 << 14)
+#define RT5640_ANC_EN                          (0x1 << 14)
+#define RT5640_ANC_MD_MASK                     (0x3 << 12)
+#define RT5640_ANC_MD_SFT                      12
+#define RT5640_ANC_MD_DIS                      (0x0 << 12)
+#define RT5640_ANC_MD_67MS                     (0x1 << 12)
+#define RT5640_ANC_MD_267MS                    (0x2 << 12)
+#define RT5640_ANC_MD_1067MS                   (0x3 << 12)
+#define RT5640_ANC_SN_MASK                     (0x1 << 11)
+#define RT5640_ANC_SN_SFT                      11
+#define RT5640_ANC_SN_DIS                      (0x0 << 11)
+#define RT5640_ANC_SN_EN                       (0x1 << 11)
+#define RT5640_ANC_CLK_MASK                    (0x1 << 10)
+#define RT5640_ANC_CLK_SFT                     10
+#define RT5640_ANC_CLK_ANC                     (0x0 << 10)
+#define RT5640_ANC_CLK_REG                     (0x1 << 10)
+#define RT5640_ANC_ZCD_MASK                    (0x3 << 8)
+#define RT5640_ANC_ZCD_SFT                     8
+#define RT5640_ANC_ZCD_DIS                     (0x0 << 8)
+#define RT5640_ANC_ZCD_T1                      (0x1 << 8)
+#define RT5640_ANC_ZCD_T2                      (0x2 << 8)
+#define RT5640_ANC_ZCD_WT                      (0x3 << 8)
+#define RT5640_ANC_CS_MASK                     (0x1 << 7)
+#define RT5640_ANC_CS_SFT                      7
+#define RT5640_ANC_CS_DIS                      (0x0 << 7)
+#define RT5640_ANC_CS_EN                       (0x1 << 7)
+#define RT5640_ANC_SW_MASK                     (0x1 << 6)
+#define RT5640_ANC_SW_SFT                      6
+#define RT5640_ANC_SW_NOR                      (0x0 << 6)
+#define RT5640_ANC_SW_AUTO                     (0x1 << 6)
+#define RT5640_ANC_CO_L_MASK                   (0x3f)
+#define RT5640_ANC_CO_L_SFT                    0
+
+/* ANC Control 2 (0xb6) */
+#define RT5640_ANC_FG_R_MASK                   (0xf << 12)
+#define RT5640_ANC_FG_R_SFT                    12
+#define RT5640_ANC_FG_L_MASK                   (0xf << 8)
+#define RT5640_ANC_FG_L_SFT                    8
+#define RT5640_ANC_CG_R_MASK                   (0xf << 4)
+#define RT5640_ANC_CG_R_SFT                    4
+#define RT5640_ANC_CG_L_MASK                   (0xf)
+#define RT5640_ANC_CG_L_SFT                    0
+
+/* ANC Control 3 (0xb6) */
+#define RT5640_ANC_CD_MASK                     (0x1 << 6)
+#define RT5640_ANC_CD_SFT                      6
+#define RT5640_ANC_CD_BOTH                     (0x0 << 6)
+#define RT5640_ANC_CD_IND                      (0x1 << 6)
+#define RT5640_ANC_CO_R_MASK                   (0x3f)
+#define RT5640_ANC_CO_R_SFT                    0
+
+/* Jack Detect Control (0xbb) */
+#define RT5640_JD_MASK                         (0x7 << 13)
+#define RT5640_JD_SFT                          13
+#define RT5640_JD_DIS                          (0x0 << 13)
+#define RT5640_JD_GPIO1                                (0x1 << 13)
+#define RT5640_JD_JD1_IN4P                     (0x2 << 13)
+#define RT5640_JD_JD2_IN4N                     (0x3 << 13)
+#define RT5640_JD_GPIO2                                (0x4 << 13)
+#define RT5640_JD_GPIO3                                (0x5 << 13)
+#define RT5640_JD_GPIO4                                (0x6 << 13)
+#define RT5640_JD_HP_MASK                      (0x1 << 11)
+#define RT5640_JD_HP_SFT                       11
+#define RT5640_JD_HP_DIS                       (0x0 << 11)
+#define RT5640_JD_HP_EN                                (0x1 << 11)
+#define RT5640_JD_HP_TRG_MASK                  (0x1 << 10)
+#define RT5640_JD_HP_TRG_SFT                   10
+#define RT5640_JD_HP_TRG_LO                    (0x0 << 10)
+#define RT5640_JD_HP_TRG_HI                    (0x1 << 10)
+#define RT5640_JD_SPL_MASK                     (0x1 << 9)
+#define RT5640_JD_SPL_SFT                      9
+#define RT5640_JD_SPL_DIS                      (0x0 << 9)
+#define RT5640_JD_SPL_EN                       (0x1 << 9)
+#define RT5640_JD_SPL_TRG_MASK                 (0x1 << 8)
+#define RT5640_JD_SPL_TRG_SFT                  8
+#define RT5640_JD_SPL_TRG_LO                   (0x0 << 8)
+#define RT5640_JD_SPL_TRG_HI                   (0x1 << 8)
+#define RT5640_JD_SPR_MASK                     (0x1 << 7)
+#define RT5640_JD_SPR_SFT                      7
+#define RT5640_JD_SPR_DIS                      (0x0 << 7)
+#define RT5640_JD_SPR_EN                       (0x1 << 7)
+#define RT5640_JD_SPR_TRG_MASK                 (0x1 << 6)
+#define RT5640_JD_SPR_TRG_SFT                  6
+#define RT5640_JD_SPR_TRG_LO                   (0x0 << 6)
+#define RT5640_JD_SPR_TRG_HI                   (0x1 << 6)
+#define RT5640_JD_MO_MASK                      (0x1 << 5)
+#define RT5640_JD_MO_SFT                       5
+#define RT5640_JD_MO_DIS                       (0x0 << 5)
+#define RT5640_JD_MO_EN                                (0x1 << 5)
+#define RT5640_JD_MO_TRG_MASK                  (0x1 << 4)
+#define RT5640_JD_MO_TRG_SFT                   4
+#define RT5640_JD_MO_TRG_LO                    (0x0 << 4)
+#define RT5640_JD_MO_TRG_HI                    (0x1 << 4)
+#define RT5640_JD_LO_MASK                      (0x1 << 3)
+#define RT5640_JD_LO_SFT                       3
+#define RT5640_JD_LO_DIS                       (0x0 << 3)
+#define RT5640_JD_LO_EN                                (0x1 << 3)
+#define RT5640_JD_LO_TRG_MASK                  (0x1 << 2)
+#define RT5640_JD_LO_TRG_SFT                   2
+#define RT5640_JD_LO_TRG_LO                    (0x0 << 2)
+#define RT5640_JD_LO_TRG_HI                    (0x1 << 2)
+#define RT5640_JD1_IN4P_MASK                   (0x1 << 1)
+#define RT5640_JD1_IN4P_SFT                    1
+#define RT5640_JD1_IN4P_DIS                    (0x0 << 1)
+#define RT5640_JD1_IN4P_EN                     (0x1 << 1)
+#define RT5640_JD2_IN4N_MASK                   (0x1)
+#define RT5640_JD2_IN4N_SFT                    0
+#define RT5640_JD2_IN4N_DIS                    (0x0)
+#define RT5640_JD2_IN4N_EN                     (0x1)
+
+/* Jack detect for ANC (0xbc) */
+#define RT5640_ANC_DET_MASK                    (0x3 << 4)
+#define RT5640_ANC_DET_SFT                     4
+#define RT5640_ANC_DET_DIS                     (0x0 << 4)
+#define RT5640_ANC_DET_MB1                     (0x1 << 4)
+#define RT5640_ANC_DET_MB2                     (0x2 << 4)
+#define RT5640_ANC_DET_JD                      (0x3 << 4)
+#define RT5640_AD_TRG_MASK                     (0x1 << 3)
+#define RT5640_AD_TRG_SFT                      3
+#define RT5640_AD_TRG_LO                       (0x0 << 3)
+#define RT5640_AD_TRG_HI                       (0x1 << 3)
+#define RT5640_ANCM_DET_MASK                   (0x3 << 4)
+#define RT5640_ANCM_DET_SFT                    4
+#define RT5640_ANCM_DET_DIS                    (0x0 << 4)
+#define RT5640_ANCM_DET_MB1                    (0x1 << 4)
+#define RT5640_ANCM_DET_MB2                    (0x2 << 4)
+#define RT5640_ANCM_DET_JD                     (0x3 << 4)
+#define RT5640_AMD_TRG_MASK                    (0x1 << 3)
+#define RT5640_AMD_TRG_SFT                     3
+#define RT5640_AMD_TRG_LO                      (0x0 << 3)
+#define RT5640_AMD_TRG_HI                      (0x1 << 3)
+
+/* IRQ Control 1 (0xbd) */
+#define RT5640_IRQ_JD_MASK                     (0x1 << 15)
+#define RT5640_IRQ_JD_SFT                      15
+#define RT5640_IRQ_JD_BP                       (0x0 << 15)
+#define RT5640_IRQ_JD_NOR                      (0x1 << 15)
+#define RT5640_IRQ_OT_MASK                     (0x1 << 14)
+#define RT5640_IRQ_OT_SFT                      14
+#define RT5640_IRQ_OT_BP                       (0x0 << 14)
+#define RT5640_IRQ_OT_NOR                      (0x1 << 14)
+#define RT5640_JD_STKY_MASK                    (0x1 << 13)
+#define RT5640_JD_STKY_SFT                     13
+#define RT5640_JD_STKY_DIS                     (0x0 << 13)
+#define RT5640_JD_STKY_EN                      (0x1 << 13)
+#define RT5640_OT_STKY_MASK                    (0x1 << 12)
+#define RT5640_OT_STKY_SFT                     12
+#define RT5640_OT_STKY_DIS                     (0x0 << 12)
+#define RT5640_OT_STKY_EN                      (0x1 << 12)
+#define RT5640_JD_P_MASK                       (0x1 << 11)
+#define RT5640_JD_P_SFT                                11
+#define RT5640_JD_P_NOR                                (0x0 << 11)
+#define RT5640_JD_P_INV                                (0x1 << 11)
+#define RT5640_OT_P_MASK                       (0x1 << 10)
+#define RT5640_OT_P_SFT                                10
+#define RT5640_OT_P_NOR                                (0x0 << 10)
+#define RT5640_OT_P_INV                                (0x1 << 10)
+
+/* IRQ Control 2 (0xbe) */
+#define RT5640_IRQ_MB1_OC_MASK                 (0x1 << 15)
+#define RT5640_IRQ_MB1_OC_SFT                  15
+#define RT5640_IRQ_MB1_OC_BP                   (0x0 << 15)
+#define RT5640_IRQ_MB1_OC_NOR                  (0x1 << 15)
+#define RT5640_IRQ_MB2_OC_MASK                 (0x1 << 14)
+#define RT5640_IRQ_MB2_OC_SFT                  14
+#define RT5640_IRQ_MB2_OC_BP                   (0x0 << 14)
+#define RT5640_IRQ_MB2_OC_NOR                  (0x1 << 14)
+#define RT5640_MB1_OC_STKY_MASK                        (0x1 << 11)
+#define RT5640_MB1_OC_STKY_SFT                 11
+#define RT5640_MB1_OC_STKY_DIS                 (0x0 << 11)
+#define RT5640_MB1_OC_STKY_EN                  (0x1 << 11)
+#define RT5640_MB2_OC_STKY_MASK                        (0x1 << 10)
+#define RT5640_MB2_OC_STKY_SFT                 10
+#define RT5640_MB2_OC_STKY_DIS                 (0x0 << 10)
+#define RT5640_MB2_OC_STKY_EN                  (0x1 << 10)
+#define RT5640_MB1_OC_P_MASK                   (0x1 << 7)
+#define RT5640_MB1_OC_P_SFT                    7
+#define RT5640_MB1_OC_P_NOR                    (0x0 << 7)
+#define RT5640_MB1_OC_P_INV                    (0x1 << 7)
+#define RT5640_MB2_OC_P_MASK                   (0x1 << 6)
+#define RT5640_MB2_OC_P_SFT                    6
+#define RT5640_MB2_OC_P_NOR                    (0x0 << 6)
+#define RT5640_MB2_OC_P_INV                    (0x1 << 6)
+#define RT5640_MB1_OC_CLR                      (0x1 << 3)
+#define RT5640_MB1_OC_CLR_SFT                  3
+#define RT5640_MB2_OC_CLR                      (0x1 << 2)
+#define RT5640_MB2_OC_CLR_SFT                  2
+
+/* GPIO Control 1 (0xc0) */
+#define RT5640_GP1_PIN_MASK                    (0x1 << 15)
+#define RT5640_GP1_PIN_SFT                     15
+#define RT5640_GP1_PIN_GPIO1                   (0x0 << 15)
+#define RT5640_GP1_PIN_IRQ                     (0x1 << 15)
+#define RT5640_GP2_PIN_MASK                    (0x1 << 14)
+#define RT5640_GP2_PIN_SFT                     14
+#define RT5640_GP2_PIN_GPIO2                   (0x0 << 14)
+#define RT5640_GP2_PIN_DMIC1_SCL               (0x1 << 14)
+#define RT5640_GP3_PIN_MASK                    (0x3 << 12)
+#define RT5640_GP3_PIN_SFT                     12
+#define RT5640_GP3_PIN_GPIO3                   (0x0 << 12)
+#define RT5640_GP3_PIN_DMIC1_SDA               (0x1 << 12)
+#define RT5640_GP3_PIN_IRQ                     (0x2 << 12)
+#define RT5640_GP4_PIN_MASK                    (0x1 << 11)
+#define RT5640_GP4_PIN_SFT                     11
+#define RT5640_GP4_PIN_GPIO4                   (0x0 << 11)
+#define RT5640_GP4_PIN_DMIC2_SDA               (0x1 << 11)
+#define RT5640_DP_SIG_MASK                     (0x1 << 10)
+#define RT5640_DP_SIG_SFT                      10
+#define RT5640_DP_SIG_TEST                     (0x0 << 10)
+#define RT5640_DP_SIG_AP                       (0x1 << 10)
+#define RT5640_GPIO_M_MASK                     (0x1 << 9)
+#define RT5640_GPIO_M_SFT                      9
+#define RT5640_GPIO_M_FLT                      (0x0 << 9)
+#define RT5640_GPIO_M_PH                       (0x1 << 9)
+
+/* GPIO Control 3 (0xc2) */
+#define RT5640_GP4_PF_MASK                     (0x1 << 11)
+#define RT5640_GP4_PF_SFT                      11
+#define RT5640_GP4_PF_IN                       (0x0 << 11)
+#define RT5640_GP4_PF_OUT                      (0x1 << 11)
+#define RT5640_GP4_OUT_MASK                    (0x1 << 10)
+#define RT5640_GP4_OUT_SFT                     10
+#define RT5640_GP4_OUT_LO                      (0x0 << 10)
+#define RT5640_GP4_OUT_HI                      (0x1 << 10)
+#define RT5640_GP4_P_MASK                      (0x1 << 9)
+#define RT5640_GP4_P_SFT                       9
+#define RT5640_GP4_P_NOR                       (0x0 << 9)
+#define RT5640_GP4_P_INV                       (0x1 << 9)
+#define RT5640_GP3_PF_MASK                     (0x1 << 8)
+#define RT5640_GP3_PF_SFT                      8
+#define RT5640_GP3_PF_IN                       (0x0 << 8)
+#define RT5640_GP3_PF_OUT                      (0x1 << 8)
+#define RT5640_GP3_OUT_MASK                    (0x1 << 7)
+#define RT5640_GP3_OUT_SFT                     7
+#define RT5640_GP3_OUT_LO                      (0x0 << 7)
+#define RT5640_GP3_OUT_HI                      (0x1 << 7)
+#define RT5640_GP3_P_MASK                      (0x1 << 6)
+#define RT5640_GP3_P_SFT                       6
+#define RT5640_GP3_P_NOR                       (0x0 << 6)
+#define RT5640_GP3_P_INV                       (0x1 << 6)
+#define RT5640_GP2_PF_MASK                     (0x1 << 5)
+#define RT5640_GP2_PF_SFT                      5
+#define RT5640_GP2_PF_IN                       (0x0 << 5)
+#define RT5640_GP2_PF_OUT                      (0x1 << 5)
+#define RT5640_GP2_OUT_MASK                    (0x1 << 4)
+#define RT5640_GP2_OUT_SFT                     4
+#define RT5640_GP2_OUT_LO                      (0x0 << 4)
+#define RT5640_GP2_OUT_HI                      (0x1 << 4)
+#define RT5640_GP2_P_MASK                      (0x1 << 3)
+#define RT5640_GP2_P_SFT                       3
+#define RT5640_GP2_P_NOR                       (0x0 << 3)
+#define RT5640_GP2_P_INV                       (0x1 << 3)
+#define RT5640_GP1_PF_MASK                     (0x1 << 2)
+#define RT5640_GP1_PF_SFT                      2
+#define RT5640_GP1_PF_IN                       (0x0 << 2)
+#define RT5640_GP1_PF_OUT                      (0x1 << 2)
+#define RT5640_GP1_OUT_MASK                    (0x1 << 1)
+#define RT5640_GP1_OUT_SFT                     1
+#define RT5640_GP1_OUT_LO                      (0x0 << 1)
+#define RT5640_GP1_OUT_HI                      (0x1 << 1)
+#define RT5640_GP1_P_MASK                      (0x1)
+#define RT5640_GP1_P_SFT                       0
+#define RT5640_GP1_P_NOR                       (0x0)
+#define RT5640_GP1_P_INV                       (0x1)
+
+/* FM34-500 Register Control 1 (0xc4) */
+#define RT5640_DSP_ADD_SFT                     0
+
+/* FM34-500 Register Control 2 (0xc5) */
+#define RT5640_DSP_DAT_SFT                     0
+
+/* FM34-500 Register Control 3 (0xc6) */
+#define RT5640_DSP_BUSY_MASK                   (0x1 << 15)
+#define RT5640_DSP_BUSY_BIT                    15
+#define RT5640_DSP_DS_MASK                     (0x1 << 14)
+#define RT5640_DSP_DS_SFT                      14
+#define RT5640_DSP_DS_FM3010                   (0x1 << 14)
+#define RT5640_DSP_DS_TEMP                     (0x1 << 14)
+#define RT5640_DSP_CLK_MASK                    (0x3 << 12)
+#define RT5640_DSP_CLK_SFT                     12
+#define RT5640_DSP_CLK_384K                    (0x0 << 12)
+#define RT5640_DSP_CLK_192K                    (0x1 << 12)
+#define RT5640_DSP_CLK_96K                     (0x2 << 12)
+#define RT5640_DSP_CLK_64K                     (0x3 << 12)
+#define RT5640_DSP_PD_PIN_MASK                 (0x1 << 11)
+#define RT5640_DSP_PD_PIN_SFT                  11
+#define RT5640_DSP_PD_PIN_LO                   (0x0 << 11)
+#define RT5640_DSP_PD_PIN_HI                   (0x1 << 11)
+#define RT5640_DSP_RST_PIN_MASK                        (0x1 << 10)
+#define RT5640_DSP_RST_PIN_SFT                 10
+#define RT5640_DSP_RST_PIN_LO                  (0x0 << 10)
+#define RT5640_DSP_RST_PIN_HI                  (0x1 << 10)
+#define RT5640_DSP_R_EN                                (0x1 << 9)
+#define RT5640_DSP_R_EN_BIT                    9
+#define RT5640_DSP_W_EN                                (0x1 << 8)
+#define RT5640_DSP_W_EN_BIT                    8
+#define RT5640_DSP_CMD_MASK                    (0xff)
+#define RT5640_DSP_CMD_SFT                     0
+#define RT5640_DSP_CMD_MW                      (0x3B)  /* Memory Write */
+#define RT5640_DSP_CMD_MR                      (0x37)  /* Memory Read */
+#define RT5640_DSP_CMD_RR                      (0x60)  /* Register Read */
+#define RT5640_DSP_CMD_RW                      (0x68)  /* Register Write */
+
+/* Programmable Register Array Control 1 (0xc8) */
+#define RT5640_REG_SEQ_MASK                    (0xf << 12)
+#define RT5640_REG_SEQ_SFT                     12
+#define RT5640_SEQ1_ST_MASK                    (0x1 << 11) /*RO*/
+#define RT5640_SEQ1_ST_SFT                     11
+#define RT5640_SEQ1_ST_RUN                     (0x0 << 11)
+#define RT5640_SEQ1_ST_FIN                     (0x1 << 11)
+#define RT5640_SEQ2_ST_MASK                    (0x1 << 10) /*RO*/
+#define RT5640_SEQ2_ST_SFT                     10
+#define RT5640_SEQ2_ST_RUN                     (0x0 << 10)
+#define RT5640_SEQ2_ST_FIN                     (0x1 << 10)
+#define RT5640_REG_LV_MASK                     (0x1 << 9)
+#define RT5640_REG_LV_SFT                      9
+#define RT5640_REG_LV_MX                       (0x0 << 9)
+#define RT5640_REG_LV_PR                       (0x1 << 9)
+#define RT5640_SEQ_2_PT_MASK                   (0x1 << 8)
+#define RT5640_SEQ_2_PT_BIT                    8
+#define RT5640_REG_IDX_MASK                    (0xff)
+#define RT5640_REG_IDX_SFT                     0
+
+/* Programmable Register Array Control 2 (0xc9) */
+#define RT5640_REG_DAT_MASK                    (0xffff)
+#define RT5640_REG_DAT_SFT                     0
+
+/* Programmable Register Array Control 3 (0xca) */
+#define RT5640_SEQ_DLY_MASK                    (0xff << 8)
+#define RT5640_SEQ_DLY_SFT                     8
+#define RT5640_PROG_MASK                       (0x1 << 7)
+#define RT5640_PROG_SFT                                7
+#define RT5640_PROG_DIS                                (0x0 << 7)
+#define RT5640_PROG_EN                         (0x1 << 7)
+#define RT5640_SEQ1_PT_RUN                     (0x1 << 6)
+#define RT5640_SEQ1_PT_RUN_BIT                 6
+#define RT5640_SEQ2_PT_RUN                     (0x1 << 5)
+#define RT5640_SEQ2_PT_RUN_BIT                 5
+
+/* Programmable Register Array Control 4 (0xcb) */
+#define RT5640_SEQ1_START_MASK                 (0xf << 8)
+#define RT5640_SEQ1_START_SFT                  8
+#define RT5640_SEQ1_END_MASK                   (0xf)
+#define RT5640_SEQ1_END_SFT                    0
+
+/* Programmable Register Array Control 5 (0xcc) */
+#define RT5640_SEQ2_START_MASK                 (0xf << 8)
+#define RT5640_SEQ2_START_SFT                  8
+#define RT5640_SEQ2_END_MASK                   (0xf)
+#define RT5640_SEQ2_END_SFT                    0
+
+/* Scramble Function (0xcd) */
+#define RT5640_SCB_KEY_MASK                    (0xff)
+#define RT5640_SCB_KEY_SFT                     0
+
+/* Scramble Control (0xce) */
+#define RT5640_SCB_SWAP_MASK                   (0x1 << 15)
+#define RT5640_SCB_SWAP_SFT                    15
+#define RT5640_SCB_SWAP_DIS                    (0x0 << 15)
+#define RT5640_SCB_SWAP_EN                     (0x1 << 15)
+#define RT5640_SCB_MASK                                (0x1 << 14)
+#define RT5640_SCB_SFT                         14
+#define RT5640_SCB_DIS                         (0x0 << 14)
+#define RT5640_SCB_EN                          (0x1 << 14)
+
+/* Baseback Control (0xcf) */
+#define RT5640_BB_MASK                         (0x1 << 15)
+#define RT5640_BB_SFT                          15
+#define RT5640_BB_DIS                          (0x0 << 15)
+#define RT5640_BB_EN                           (0x1 << 15)
+#define RT5640_BB_CT_MASK                      (0x7 << 12)
+#define RT5640_BB_CT_SFT                       12
+#define RT5640_BB_CT_A                         (0x0 << 12)
+#define RT5640_BB_CT_B                         (0x1 << 12)
+#define RT5640_BB_CT_C                         (0x2 << 12)
+#define RT5640_BB_CT_D                         (0x3 << 12)
+#define RT5640_M_BB_L_MASK                     (0x1 << 9)
+#define RT5640_M_BB_L_SFT                      9
+#define RT5640_M_BB_R_MASK                     (0x1 << 8)
+#define RT5640_M_BB_R_SFT                      8
+#define RT5640_M_BB_HPF_L_MASK                 (0x1 << 7)
+#define RT5640_M_BB_HPF_L_SFT                  7
+#define RT5640_M_BB_HPF_R_MASK                 (0x1 << 6)
+#define RT5640_M_BB_HPF_R_SFT                  6
+#define RT5640_G_BB_BST_MASK                   (0x3f)
+#define RT5640_G_BB_BST_SFT                    0
+
+/* MP3 Plus Control 1 (0xd0) */
+#define RT5640_M_MP3_L_MASK                    (0x1 << 15)
+#define RT5640_M_MP3_L_SFT                     15
+#define RT5640_M_MP3_R_MASK                    (0x1 << 14)
+#define RT5640_M_MP3_R_SFT                     14
+#define RT5640_M_MP3_MASK                      (0x1 << 13)
+#define RT5640_M_MP3_SFT                       13
+#define RT5640_M_MP3_DIS                       (0x0 << 13)
+#define RT5640_M_MP3_EN                                (0x1 << 13)
+#define RT5640_EG_MP3_MASK                     (0x1f << 8)
+#define RT5640_EG_MP3_SFT                      8
+#define RT5640_MP3_HLP_MASK                    (0x1 << 7)
+#define RT5640_MP3_HLP_SFT                     7
+#define RT5640_MP3_HLP_DIS                     (0x0 << 7)
+#define RT5640_MP3_HLP_EN                      (0x1 << 7)
+#define RT5640_M_MP3_ORG_L_MASK                        (0x1 << 6)
+#define RT5640_M_MP3_ORG_L_SFT                 6
+#define RT5640_M_MP3_ORG_R_MASK                        (0x1 << 5)
+#define RT5640_M_MP3_ORG_R_SFT                 5
+
+/* MP3 Plus Control 2 (0xd1) */
+#define RT5640_MP3_WT_MASK                     (0x1 << 13)
+#define RT5640_MP3_WT_SFT                      13
+#define RT5640_MP3_WT_1_4                      (0x0 << 13)
+#define RT5640_MP3_WT_1_2                      (0x1 << 13)
+#define RT5640_OG_MP3_MASK                     (0x1f << 8)
+#define RT5640_OG_MP3_SFT                      8
+#define RT5640_HG_MP3_MASK                     (0x3f)
+#define RT5640_HG_MP3_SFT                      0
+
+/* 3D HP Control 1 (0xd2) */
+#define RT5640_3D_CF_MASK                      (0x1 << 15)
+#define RT5640_3D_CF_SFT                       15
+#define RT5640_3D_CF_DIS                       (0x0 << 15)
+#define RT5640_3D_CF_EN                                (0x1 << 15)
+#define RT5640_3D_HP_MASK                      (0x1 << 14)
+#define RT5640_3D_HP_SFT                       14
+#define RT5640_3D_HP_DIS                       (0x0 << 14)
+#define RT5640_3D_HP_EN                                (0x1 << 14)
+#define RT5640_3D_BT_MASK                      (0x1 << 13)
+#define RT5640_3D_BT_SFT                       13
+#define RT5640_3D_BT_DIS                       (0x0 << 13)
+#define RT5640_3D_BT_EN                                (0x1 << 13)
+#define RT5640_3D_1F_MIX_MASK                  (0x3 << 11)
+#define RT5640_3D_1F_MIX_SFT                   11
+#define RT5640_3D_HP_M_MASK                    (0x1 << 10)
+#define RT5640_3D_HP_M_SFT                     10
+#define RT5640_3D_HP_M_SUR                     (0x0 << 10)
+#define RT5640_3D_HP_M_FRO                     (0x1 << 10)
+#define RT5640_M_3D_HRTF_MASK                  (0x1 << 9)
+#define RT5640_M_3D_HRTF_SFT                   9
+#define RT5640_M_3D_D2H_MASK                   (0x1 << 8)
+#define RT5640_M_3D_D2H_SFT                    8
+#define RT5640_M_3D_D2R_MASK                   (0x1 << 7)
+#define RT5640_M_3D_D2R_SFT                    7
+#define RT5640_M_3D_REVB_MASK                  (0x1 << 6)
+#define RT5640_M_3D_REVB_SFT                   6
+
+/* Adjustable high pass filter control 1 (0xd3) */
+#define RT5640_2ND_HPF_MASK                    (0x1 << 15)
+#define RT5640_2ND_HPF_SFT                     15
+#define RT5640_2ND_HPF_DIS                     (0x0 << 15)
+#define RT5640_2ND_HPF_EN                      (0x1 << 15)
+#define RT5640_HPF_CF_L_MASK                   (0x7 << 12)
+#define RT5640_HPF_CF_L_SFT                    12
+#define RT5640_1ST_HPF_MASK                    (0x1 << 11)
+#define RT5640_1ST_HPF_SFT                     11
+#define RT5640_1ST_HPF_DIS                     (0x0 << 11)
+#define RT5640_1ST_HPF_EN                      (0x1 << 11)
+#define RT5640_HPF_CF_R_MASK                   (0x7 << 8)
+#define RT5640_HPF_CF_R_SFT                    8
+#define RT5640_ZD_T_MASK                       (0x3 << 6)
+#define RT5640_ZD_T_SFT                                6
+#define RT5640_ZD_F_MASK                       (0x3 << 4)
+#define RT5640_ZD_F_SFT                                4
+#define RT5640_ZD_F_IM                         (0x0 << 4)
+#define RT5640_ZD_F_ZC_IM                      (0x1 << 4)
+#define RT5640_ZD_F_ZC_IOD                     (0x2 << 4)
+#define RT5640_ZD_F_UN                         (0x3 << 4)
+
+/* HP calibration control and Amp detection (0xd6) */
+#define RT5640_SI_DAC_MASK                     (0x1 << 11)
+#define RT5640_SI_DAC_SFT                      11
+#define RT5640_SI_DAC_AUTO                     (0x0 << 11)
+#define RT5640_SI_DAC_TEST                     (0x1 << 11)
+#define RT5640_DC_CAL_M_MASK                   (0x1 << 10)
+#define RT5640_DC_CAL_M_SFT                    10
+#define RT5640_DC_CAL_M_CAL                    (0x0 << 10)
+#define RT5640_DC_CAL_M_NOR                    (0x1 << 10)
+#define RT5640_DC_CAL_MASK                     (0x1 << 9)
+#define RT5640_DC_CAL_SFT                      9
+#define RT5640_DC_CAL_DIS                      (0x0 << 9)
+#define RT5640_DC_CAL_EN                       (0x1 << 9)
+#define RT5640_HPD_RCV_MASK                    (0x7 << 6)
+#define RT5640_HPD_RCV_SFT                     6
+#define RT5640_HPD_PS_MASK                     (0x1 << 5)
+#define RT5640_HPD_PS_SFT                      5
+#define RT5640_HPD_PS_DIS                      (0x0 << 5)
+#define RT5640_HPD_PS_EN                       (0x1 << 5)
+#define RT5640_CAL_M_MASK                      (0x1 << 4)
+#define RT5640_CAL_M_SFT                       4
+#define RT5640_CAL_M_DEP                       (0x0 << 4)
+#define RT5640_CAL_M_CAL                       (0x1 << 4)
+#define RT5640_CAL_MASK                                (0x1 << 3)
+#define RT5640_CAL_SFT                         3
+#define RT5640_CAL_DIS                         (0x0 << 3)
+#define RT5640_CAL_EN                          (0x1 << 3)
+#define RT5640_CAL_TEST_MASK                   (0x1 << 2)
+#define RT5640_CAL_TEST_SFT                    2
+#define RT5640_CAL_TEST_DIS                    (0x0 << 2)
+#define RT5640_CAL_TEST_EN                     (0x1 << 2)
+#define RT5640_CAL_P_MASK                      (0x3)
+#define RT5640_CAL_P_SFT                       0
+#define RT5640_CAL_P_NONE                      (0x0)
+#define RT5640_CAL_P_CAL                       (0x1)
+#define RT5640_CAL_P_DAC_CAL                   (0x2)
+
+/* Soft volume and zero cross control 1 (0xd9) */
+#define RT5640_SV_MASK                         (0x1 << 15)
+#define RT5640_SV_SFT                          15
+#define RT5640_SV_DIS                          (0x0 << 15)
+#define RT5640_SV_EN                           (0x1 << 15)
+#define RT5640_SPO_SV_MASK                     (0x1 << 14)
+#define RT5640_SPO_SV_SFT                      14
+#define RT5640_SPO_SV_DIS                      (0x0 << 14)
+#define RT5640_SPO_SV_EN                       (0x1 << 14)
+#define RT5640_OUT_SV_MASK                     (0x1 << 13)
+#define RT5640_OUT_SV_SFT                      13
+#define RT5640_OUT_SV_DIS                      (0x0 << 13)
+#define RT5640_OUT_SV_EN                       (0x1 << 13)
+#define RT5640_HP_SV_MASK                      (0x1 << 12)
+#define RT5640_HP_SV_SFT                       12
+#define RT5640_HP_SV_DIS                       (0x0 << 12)
+#define RT5640_HP_SV_EN                                (0x1 << 12)
+#define RT5640_ZCD_DIG_MASK                    (0x1 << 11)
+#define RT5640_ZCD_DIG_SFT                     11
+#define RT5640_ZCD_DIG_DIS                     (0x0 << 11)
+#define RT5640_ZCD_DIG_EN                      (0x1 << 11)
+#define RT5640_ZCD_MASK                                (0x1 << 10)
+#define RT5640_ZCD_SFT                         10
+#define RT5640_ZCD_PD                          (0x0 << 10)
+#define RT5640_ZCD_PU                          (0x1 << 10)
+#define RT5640_M_ZCD_MASK                      (0x3f << 4)
+#define RT5640_M_ZCD_SFT                       4
+#define RT5640_M_ZCD_RM_L                      (0x1 << 9)
+#define RT5640_M_ZCD_RM_R                      (0x1 << 8)
+#define RT5640_M_ZCD_SM_L                      (0x1 << 7)
+#define RT5640_M_ZCD_SM_R                      (0x1 << 6)
+#define RT5640_M_ZCD_OM_L                      (0x1 << 5)
+#define RT5640_M_ZCD_OM_R                      (0x1 << 4)
+#define RT5640_SV_DLY_MASK                     (0xf)
+#define RT5640_SV_DLY_SFT                      0
+
+/* Soft volume and zero cross control 2 (0xda) */
+#define RT5640_ZCD_HP_MASK                     (0x1 << 15)
+#define RT5640_ZCD_HP_SFT                      15
+#define RT5640_ZCD_HP_DIS                      (0x0 << 15)
+#define RT5640_ZCD_HP_EN                       (0x1 << 15)
+
+
+/* Codec Private Register definition */
+/* 3D Speaker Control (0x63) */
+#define RT5640_3D_SPK_MASK                     (0x1 << 15)
+#define RT5640_3D_SPK_SFT                      15
+#define RT5640_3D_SPK_DIS                      (0x0 << 15)
+#define RT5640_3D_SPK_EN                       (0x1 << 15)
+#define RT5640_3D_SPK_M_MASK                   (0x3 << 13)
+#define RT5640_3D_SPK_M_SFT                    13
+#define RT5640_3D_SPK_CG_MASK                  (0x1f << 8)
+#define RT5640_3D_SPK_CG_SFT                   8
+#define RT5640_3D_SPK_SG_MASK                  (0x1f)
+#define RT5640_3D_SPK_SG_SFT                   0
+
+/* Wind Noise Detection Control 1 (0x6c) */
+#define RT5640_WND_MASK                                (0x1 << 15)
+#define RT5640_WND_SFT                         15
+#define RT5640_WND_DIS                         (0x0 << 15)
+#define RT5640_WND_EN                          (0x1 << 15)
+
+/* Wind Noise Detection Control 2 (0x6d) */
+#define RT5640_WND_FC_NW_MASK                  (0x3f << 10)
+#define RT5640_WND_FC_NW_SFT                   10
+#define RT5640_WND_FC_WK_MASK                  (0x3f << 4)
+#define RT5640_WND_FC_WK_SFT                   4
+
+/* Wind Noise Detection Control 3 (0x6e) */
+#define RT5640_HPF_FC_MASK                     (0x3f << 6)
+#define RT5640_HPF_FC_SFT                      6
+#define RT5640_WND_FC_ST_MASK                  (0x3f)
+#define RT5640_WND_FC_ST_SFT                   0
+
+/* Wind Noise Detection Control 4 (0x6f) */
+#define RT5640_WND_TH_LO_MASK                  (0x3ff)
+#define RT5640_WND_TH_LO_SFT                   0
+
+/* Wind Noise Detection Control 5 (0x70) */
+#define RT5640_WND_TH_HI_MASK                  (0x3ff)
+#define RT5640_WND_TH_HI_SFT                   0
+
+/* Wind Noise Detection Control 8 (0x73) */
+#define RT5640_WND_WIND_MASK                   (0x1 << 13) /* Read-Only */
+#define RT5640_WND_WIND_SFT                    13
+#define RT5640_WND_STRONG_MASK                 (0x1 << 12) /* Read-Only */
+#define RT5640_WND_STRONG_SFT                  12
+enum {
+       RT5640_NO_WIND,
+       RT5640_BREEZE,
+       RT5640_STORM,
+};
+
+/* Dipole Speaker Interface (0x75) */
+#define RT5640_DP_ATT_MASK                     (0x3 << 14)
+#define RT5640_DP_ATT_SFT                      14
+#define RT5640_DP_SPK_MASK                     (0x1 << 10)
+#define RT5640_DP_SPK_SFT                      10
+#define RT5640_DP_SPK_DIS                      (0x0 << 10)
+#define RT5640_DP_SPK_EN                       (0x1 << 10)
+
+/* EQ Pre Volume Control (0xb3) */
+#define RT5640_EQ_PRE_VOL_MASK                 (0xffff)
+#define RT5640_EQ_PRE_VOL_SFT                  0
+
+/* EQ Post Volume Control (0xb4) */
+#define RT5640_EQ_PST_VOL_MASK                 (0xffff)
+#define RT5640_EQ_PST_VOL_SFT                  0
+
+#define RT5640_NO_JACK         BIT(0)
+#define RT5640_HEADSET_DET     BIT(1)
+#define RT5640_HEADPHO_DET     BIT(2)
+
+/* System Clock Source */
+#define RT5640_SCLK_S_MCLK     0
+#define RT5640_SCLK_S_PLL1     1
+#define RT5640_SCLK_S_PLL1_TK  2
+#define RT5640_SCLK_S_RCCLK    3
+
+/* PLL1 Source */
+#define RT5640_PLL1_S_MCLK     0
+#define RT5640_PLL1_S_BCLK1    1
+#define RT5640_PLL1_S_BCLK2    2
+#define RT5640_PLL1_S_BCLK3    3
+
+
+enum {
+       RT5640_AIF1,
+       RT5640_AIF2,
+       RT5640_AIF3,
+       RT5640_AIFS,
+};
+
+enum {
+       RT5640_U_IF1 = 0x1,
+       RT5640_U_IF2 = 0x2,
+       RT5640_U_IF3 = 0x4,
+};
+
+enum {
+       RT5640_IF_123,
+       RT5640_IF_132,
+       RT5640_IF_312,
+       RT5640_IF_321,
+       RT5640_IF_231,
+       RT5640_IF_213,
+       RT5640_IF_113,
+       RT5640_IF_223,
+       RT5640_IF_ALL,
+};
+
+enum {
+       RT5640_DMIC_DIS,
+       RT5640_DMIC1,
+       RT5640_DMIC2,
+};
+
+struct rt5640_pll_code {
+       bool m_bp; /* Indicates bypass m code or not. */
+       int m_code;
+       int n_code;
+       int k_code;
+};
+
+struct rt5640_priv {
+       struct snd_soc_codec *codec;
+       struct rt5640_platform_data pdata;
+       struct regmap *regmap;
+
+       int sysclk;
+       int sysclk_src;
+       int lrck[RT5640_AIFS];
+       int bclk[RT5640_AIFS];
+       int master[RT5640_AIFS];
+
+       struct rt5640_pll_code pll_code;
+       int pll_src;
+       int pll_in;
+       int pll_out;
+
+       int dmic_en;
+};
+
+#endif
index 92bbfec..d441559 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/clk.h>
+#include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/consumer.h>
 #define SGTL5000_MAX_REG_OFFSET        0x013A
 
 /* default value of sgtl5000 registers */
-static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] =  {
-       [SGTL5000_CHIP_CLK_CTRL] = 0x0008,
-       [SGTL5000_CHIP_I2S_CTRL] = 0x0010,
-       [SGTL5000_CHIP_SSS_CTRL] = 0x0008,
-       [SGTL5000_CHIP_DAC_VOL] = 0x3c3c,
-       [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f,
-       [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818,
-       [SGTL5000_CHIP_ANA_CTRL] = 0x0111,
-       [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404,
-       [SGTL5000_CHIP_ANA_POWER] = 0x7060,
-       [SGTL5000_CHIP_PLL_CTRL] = 0x5000,
-       [SGTL5000_DAP_BASS_ENHANCE] = 0x0040,
-       [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f,
-       [SGTL5000_DAP_SURROUND] = 0x0040,
-       [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f,
-       [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f,
-       [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f,
-       [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f,
-       [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f,
-       [SGTL5000_DAP_MAIN_CHAN] = 0x8000,
-       [SGTL5000_DAP_AVC_CTRL] = 0x0510,
-       [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473,
-       [SGTL5000_DAP_AVC_ATTACK] = 0x0028,
-       [SGTL5000_DAP_AVC_DECAY] = 0x0050,
+static const struct reg_default sgtl5000_reg_defaults[] = {
+       { SGTL5000_CHIP_CLK_CTRL,               0x0008 },
+       { SGTL5000_CHIP_I2S_CTRL,               0x0010 },
+       { SGTL5000_CHIP_SSS_CTRL,               0x0008 },
+       { SGTL5000_CHIP_DAC_VOL,                0x3c3c },
+       { SGTL5000_CHIP_PAD_STRENGTH,           0x015f },
+       { SGTL5000_CHIP_ANA_HP_CTRL,            0x1818 },
+       { SGTL5000_CHIP_ANA_CTRL,               0x0111 },
+       { SGTL5000_CHIP_LINE_OUT_VOL,           0x0404 },
+       { SGTL5000_CHIP_ANA_POWER,              0x7060 },
+       { SGTL5000_CHIP_PLL_CTRL,               0x5000 },
+       { SGTL5000_DAP_BASS_ENHANCE,            0x0040 },
+       { SGTL5000_DAP_BASS_ENHANCE_CTRL,       0x051f },
+       { SGTL5000_DAP_SURROUND,                0x0040 },
+       { SGTL5000_DAP_EQ_BASS_BAND0,           0x002f },
+       { SGTL5000_DAP_EQ_BASS_BAND1,           0x002f },
+       { SGTL5000_DAP_EQ_BASS_BAND2,           0x002f },
+       { SGTL5000_DAP_EQ_BASS_BAND3,           0x002f },
+       { SGTL5000_DAP_EQ_BASS_BAND4,           0x002f },
+       { SGTL5000_DAP_MAIN_CHAN,               0x8000 },
+       { SGTL5000_DAP_AVC_CTRL,                0x0510 },
+       { SGTL5000_DAP_AVC_THRESHOLD,           0x1473 },
+       { SGTL5000_DAP_AVC_ATTACK,              0x0028 },
+       { SGTL5000_DAP_AVC_DECAY,               0x0050 },
 };
 
 /* regulator supplies for sgtl5000, VDDD is an optional external supply */
@@ -112,6 +113,8 @@ struct sgtl5000_priv {
        int fmt;        /* i2s data format */
        struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
        struct ldo_regulator *ldo;
+       struct regmap *regmap;
+       struct clk *mclk;
 };
 
 /*
@@ -151,12 +154,12 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
        switch (event) {
-       case SND_SOC_DAPM_PRE_PMU:
+       case SND_SOC_DAPM_POST_PMU:
                snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
                break;
 
-       case SND_SOC_DAPM_POST_PMD:
+       case SND_SOC_DAPM_PRE_PMD:
                snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
                        SGTL5000_VAG_POWERUP, 0);
                msleep(400);
@@ -217,12 +220,11 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
                                0, SGTL5000_CHIP_DIG_POWER,
                                1, 0),
 
-       SND_SOC_DAPM_SUPPLY("VAG_POWER", SGTL5000_CHIP_ANA_POWER, 7, 0,
-                           power_vag_event,
-                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
        SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
        SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
+
+       SND_SOC_DAPM_PRE("VAG_POWER_PRE", power_vag_event),
+       SND_SOC_DAPM_POST("VAG_POWER_POST", power_vag_event),
 };
 
 /* routes for sgtl5000 */
@@ -230,16 +232,13 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
        {"Capture Mux", "LINE_IN", "LINE_IN"},  /* line_in --> adc_mux */
        {"Capture Mux", "MIC_IN", "MIC_IN"},    /* mic_in --> adc_mux */
 
-       {"ADC", NULL, "VAG_POWER"},
        {"ADC", NULL, "Capture Mux"},           /* adc_mux --> adc */
        {"AIFOUT", NULL, "ADC"},                /* adc --> i2s_out */
 
-       {"DAC", NULL, "VAG_POWER"},
        {"DAC", NULL, "AIFIN"},                 /* i2s-->dac,skip audio mux */
        {"Headphone Mux", "DAC", "DAC"},        /* dac --> hp_mux */
        {"LO", NULL, "DAC"},                    /* dac --> line_out */
 
-       {"LINE_IN", NULL, "VAG_POWER"},
        {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
        {"HP", NULL, "Headphone Mux"},          /* hp_mux --> hp */
 
@@ -909,10 +908,25 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
                        if (ret)
                                return ret;
                        udelay(10);
+
+                       regcache_cache_only(sgtl5000->regmap, false);
+
+                       ret = regcache_sync(sgtl5000->regmap);
+                       if (ret != 0) {
+                               dev_err(codec->dev,
+                                       "Failed to restore cache: %d\n", ret);
+
+                               regcache_cache_only(sgtl5000->regmap, true);
+                               regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
+                                                      sgtl5000->supplies);
+
+                               return ret;
+                       }
                }
 
                break;
        case SND_SOC_BIAS_OFF:
+               regcache_cache_only(sgtl5000->regmap, true);
                regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
                                        sgtl5000->supplies);
                break;
@@ -958,17 +972,76 @@ static struct snd_soc_dai_driver sgtl5000_dai = {
        .symmetric_rates = 1,
 };
 
-static int sgtl5000_volatile_register(struct snd_soc_codec *codec,
-                                       unsigned int reg)
+static bool sgtl5000_volatile(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case SGTL5000_CHIP_ID:
        case SGTL5000_CHIP_ADCDAC_CTRL:
        case SGTL5000_CHIP_ANA_STATUS:
-               return 1;
+               return true;
        }
 
-       return 0;
+       return false;
+}
+
+static bool sgtl5000_readable(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case SGTL5000_CHIP_ID:
+       case SGTL5000_CHIP_DIG_POWER:
+       case SGTL5000_CHIP_CLK_CTRL:
+       case SGTL5000_CHIP_I2S_CTRL:
+       case SGTL5000_CHIP_SSS_CTRL:
+       case SGTL5000_CHIP_ADCDAC_CTRL:
+       case SGTL5000_CHIP_DAC_VOL:
+       case SGTL5000_CHIP_PAD_STRENGTH:
+       case SGTL5000_CHIP_ANA_ADC_CTRL:
+       case SGTL5000_CHIP_ANA_HP_CTRL:
+       case SGTL5000_CHIP_ANA_CTRL:
+       case SGTL5000_CHIP_LINREG_CTRL:
+       case SGTL5000_CHIP_REF_CTRL:
+       case SGTL5000_CHIP_MIC_CTRL:
+       case SGTL5000_CHIP_LINE_OUT_CTRL:
+       case SGTL5000_CHIP_LINE_OUT_VOL:
+       case SGTL5000_CHIP_ANA_POWER:
+       case SGTL5000_CHIP_PLL_CTRL:
+       case SGTL5000_CHIP_CLK_TOP_CTRL:
+       case SGTL5000_CHIP_ANA_STATUS:
+       case SGTL5000_CHIP_SHORT_CTRL:
+       case SGTL5000_CHIP_ANA_TEST2:
+       case SGTL5000_DAP_CTRL:
+       case SGTL5000_DAP_PEQ:
+       case SGTL5000_DAP_BASS_ENHANCE:
+       case SGTL5000_DAP_BASS_ENHANCE_CTRL:
+       case SGTL5000_DAP_AUDIO_EQ:
+       case SGTL5000_DAP_SURROUND:
+       case SGTL5000_DAP_FLT_COEF_ACCESS:
+       case SGTL5000_DAP_COEF_WR_B0_MSB:
+       case SGTL5000_DAP_COEF_WR_B0_LSB:
+       case SGTL5000_DAP_EQ_BASS_BAND0:
+       case SGTL5000_DAP_EQ_BASS_BAND1:
+       case SGTL5000_DAP_EQ_BASS_BAND2:
+       case SGTL5000_DAP_EQ_BASS_BAND3:
+       case SGTL5000_DAP_EQ_BASS_BAND4:
+       case SGTL5000_DAP_MAIN_CHAN:
+       case SGTL5000_DAP_MIX_CHAN:
+       case SGTL5000_DAP_AVC_CTRL:
+       case SGTL5000_DAP_AVC_THRESHOLD:
+       case SGTL5000_DAP_AVC_ATTACK:
+       case SGTL5000_DAP_AVC_DECAY:
+       case SGTL5000_DAP_COEF_WR_B1_MSB:
+       case SGTL5000_DAP_COEF_WR_B1_LSB:
+       case SGTL5000_DAP_COEF_WR_B2_MSB:
+       case SGTL5000_DAP_COEF_WR_B2_LSB:
+       case SGTL5000_DAP_COEF_WR_A1_MSB:
+       case SGTL5000_DAP_COEF_WR_A1_LSB:
+       case SGTL5000_DAP_COEF_WR_A2_MSB:
+       case SGTL5000_DAP_COEF_WR_A2_LSB:
+               return true;
+
+       default:
+               return false;
+       }
 }
 
 #ifdef CONFIG_SUSPEND
@@ -1214,7 +1287,7 @@ static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec)
 
 static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
 {
-       u16 reg;
+       int reg;
        int ret;
        int rev;
        int i;
@@ -1242,23 +1315,17 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
        /* wait for all power rails bring up */
        udelay(10);
 
-       /* read chip information */
-       reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
-       if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
-           SGTL5000_PARTID_PART_ID) {
-               dev_err(codec->dev,
-                       "Device with ID register %x is not a sgtl5000\n", reg);
-               ret = -ENODEV;
-               goto err_regulator_disable;
-       }
-
-       rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
-       dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev);
-
        /*
         * workaround for revision 0x11 and later,
         * roll back to use internal LDO
         */
+
+       ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
+       if (ret)
+               goto err_regulator_disable;
+
+       rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
+
        if (external_vddd && rev >= 0x11) {
                /* disable all regulator first */
                regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
@@ -1300,7 +1367,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
        struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
 
        /* setup i2c data ops */
-       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+       codec->control_data = sgtl5000->regmap;
+       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
@@ -1391,11 +1459,6 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
        .suspend = sgtl5000_suspend,
        .resume = sgtl5000_resume,
        .set_bias_level = sgtl5000_set_bias_level,
-       .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
-       .reg_word_size = sizeof(u16),
-       .reg_cache_step = 2,
-       .reg_cache_default = sgtl5000_regs,
-       .volatile_register = sgtl5000_volatile_register,
        .controls = sgtl5000_snd_controls,
        .num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
        .dapm_widgets = sgtl5000_dapm_widgets,
@@ -1404,28 +1467,114 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
        .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
 };
 
+static const struct regmap_config sgtl5000_regmap = {
+       .reg_bits = 16,
+       .val_bits = 16,
+
+       .max_register = SGTL5000_MAX_REG_OFFSET,
+       .volatile_reg = sgtl5000_volatile,
+       .readable_reg = sgtl5000_readable,
+
+       .cache_type = REGCACHE_RBTREE,
+       .reg_defaults = sgtl5000_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(sgtl5000_reg_defaults),
+};
+
+/*
+ * Write all the default values from sgtl5000_reg_defaults[] array into the
+ * sgtl5000 registers, to make sure we always start with the sane registers
+ * values as stated in the datasheet.
+ *
+ * Since sgtl5000 does not have a reset line, nor a reset command in software,
+ * we follow this approach to guarantee we always start from the default values
+ * and avoid problems like, not being able to probe after an audio playback
+ * followed by a system reset or a 'reboot' command in Linux
+ */
+static int sgtl5000_fill_defaults(struct sgtl5000_priv *sgtl5000)
+{
+       int i, ret, val, index;
+
+       for (i = 0; i < ARRAY_SIZE(sgtl5000_reg_defaults); i++) {
+               val = sgtl5000_reg_defaults[i].def;
+               index = sgtl5000_reg_defaults[i].reg;
+               ret = regmap_write(sgtl5000->regmap, index, val);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static int sgtl5000_i2c_probe(struct i2c_client *client,
                              const struct i2c_device_id *id)
 {
        struct sgtl5000_priv *sgtl5000;
-       int ret;
+       int ret, reg, rev;
 
        sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv),
                                                                GFP_KERNEL);
        if (!sgtl5000)
                return -ENOMEM;
 
+       sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap);
+       if (IS_ERR(sgtl5000->regmap)) {
+               ret = PTR_ERR(sgtl5000->regmap);
+               dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
+               return ret;
+       }
+
+       sgtl5000->mclk = devm_clk_get(&client->dev, NULL);
+       if (IS_ERR(sgtl5000->mclk)) {
+               ret = PTR_ERR(sgtl5000->mclk);
+               dev_err(&client->dev, "Failed to get mclock: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(sgtl5000->mclk);
+       if (ret)
+               return ret;
+
+       /* read chip information */
+       ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, &reg);
+       if (ret)
+               goto disable_clk;
+
+       if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
+           SGTL5000_PARTID_PART_ID) {
+               dev_err(&client->dev,
+                       "Device with ID register %x is not a sgtl5000\n", reg);
+               ret = -ENODEV;
+               goto disable_clk;
+       }
+
+       rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
+       dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev);
+
        i2c_set_clientdata(client, sgtl5000);
 
+       /* Ensure sgtl5000 will start with sane register values */
+       ret = sgtl5000_fill_defaults(sgtl5000);
+       if (ret)
+               goto disable_clk;
+
        ret = snd_soc_register_codec(&client->dev,
                        &sgtl5000_driver, &sgtl5000_dai, 1);
+       if (ret)
+               goto disable_clk;
+
+       return 0;
+
+disable_clk:
+       clk_disable_unprepare(sgtl5000->mclk);
        return ret;
 }
 
 static int sgtl5000_i2c_remove(struct i2c_client *client)
 {
-       snd_soc_unregister_codec(&client->dev);
+       struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
 
+       snd_soc_unregister_codec(&client->dev);
+       clk_disable_unprepare(sgtl5000->mclk);
        return 0;
 }
 
index 8a9f435..4b69229 100644 (file)
@@ -12,7 +12,7 @@
 #define _SGTL5000_H
 
 /*
- * Register values.
+ * Registers addresses
  */
 #define SGTL5000_CHIP_ID                       0x0000
 #define SGTL5000_CHIP_DIG_POWER                        0x0002
index d1ae869..dba26e6 100644 (file)
@@ -883,7 +883,7 @@ static int sn95031_codec_remove(struct snd_soc_codec *codec)
        return 0;
 }
 
-struct snd_soc_codec_driver sn95031_codec = {
+static struct snd_soc_codec_driver sn95031_codec = {
        .probe          = sn95031_codec_probe,
        .remove         = sn95031_codec_remove,
        .read           = sn95031_read,
index dd8d856..e9d7881 100644 (file)
@@ -21,6 +21,7 @@
 #include <sound/soc.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
+#include <linux/of.h>
 
 #define STUB_RATES     SNDRV_PCM_RATE_8000_192000
 #define STUB_FORMATS   (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -51,12 +52,21 @@ static int spdif_dir_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id spdif_dir_dt_ids[] = {
+       { .compatible = "linux,spdif-dir", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, spdif_dir_dt_ids);
+#endif
+
 static struct platform_driver spdif_dir_driver = {
        .probe          = spdif_dir_probe,
        .remove         = spdif_dir_remove,
        .driver         = {
                .name   = "spdif-dir",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(spdif_dir_dt_ids),
        },
 };
 
similarity index 88%
rename from sound/soc/codecs/spdif_transciever.c
rename to sound/soc/codecs/spdif_transmitter.c
index 112a49d..1828049 100644 (file)
@@ -20,6 +20,7 @@
 #include <sound/soc.h>
 #include <sound/pcm.h>
 #include <sound/initval.h>
+#include <linux/of.h>
 
 #define DRV_NAME "spdif-dit"
 
@@ -52,12 +53,21 @@ static int spdif_dit_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id spdif_dit_dt_ids[] = {
+       { .compatible = "linux,spdif-dit", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, spdif_dit_dt_ids);
+#endif
+
 static struct platform_driver spdif_dit_driver = {
        .probe          = spdif_dit_probe,
        .remove         = spdif_dit_remove,
        .driver         = {
                .name   = DRV_NAME,
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(spdif_dit_dt_ids),
        },
 };
 
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
new file mode 100644 (file)
index 0000000..95aed55
--- /dev/null
@@ -0,0 +1,856 @@
+/*
+ * SSM2518 amplifier audio driver
+ *
+ * Copyright 2013 Analog Devices Inc.
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_data/ssm2518.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "ssm2518.h"
+
+#define SSM2518_REG_POWER1             0x00
+#define SSM2518_REG_CLOCK              0x01
+#define SSM2518_REG_SAI_CTRL1          0x02
+#define SSM2518_REG_SAI_CTRL2          0x03
+#define SSM2518_REG_CHAN_MAP           0x04
+#define SSM2518_REG_LEFT_VOL           0x05
+#define SSM2518_REG_RIGHT_VOL          0x06
+#define SSM2518_REG_MUTE_CTRL          0x07
+#define SSM2518_REG_FAULT_CTRL         0x08
+#define SSM2518_REG_POWER2             0x09
+#define SSM2518_REG_DRC_1              0x0a
+#define SSM2518_REG_DRC_2              0x0b
+#define SSM2518_REG_DRC_3              0x0c
+#define SSM2518_REG_DRC_4              0x0d
+#define SSM2518_REG_DRC_5              0x0e
+#define SSM2518_REG_DRC_6              0x0f
+#define SSM2518_REG_DRC_7              0x10
+#define SSM2518_REG_DRC_8              0x11
+#define SSM2518_REG_DRC_9              0x12
+
+#define SSM2518_POWER1_RESET                   BIT(7)
+#define SSM2518_POWER1_NO_BCLK                 BIT(5)
+#define SSM2518_POWER1_MCS_MASK                        (0xf << 1)
+#define SSM2518_POWER1_MCS_64FS                        (0x0 << 1)
+#define SSM2518_POWER1_MCS_128FS               (0x1 << 1)
+#define SSM2518_POWER1_MCS_256FS               (0x2 << 1)
+#define SSM2518_POWER1_MCS_384FS               (0x3 << 1)
+#define SSM2518_POWER1_MCS_512FS               (0x4 << 1)
+#define SSM2518_POWER1_MCS_768FS               (0x5 << 1)
+#define SSM2518_POWER1_MCS_100FS               (0x6 << 1)
+#define SSM2518_POWER1_MCS_200FS               (0x7 << 1)
+#define SSM2518_POWER1_MCS_400FS               (0x8 << 1)
+#define SSM2518_POWER1_SPWDN                   BIT(0)
+
+#define SSM2518_CLOCK_ASR                      BIT(0)
+
+#define SSM2518_SAI_CTRL1_FMT_MASK             (0x3 << 5)
+#define SSM2518_SAI_CTRL1_FMT_I2S              (0x0 << 5)
+#define SSM2518_SAI_CTRL1_FMT_LJ               (0x1 << 5)
+#define SSM2518_SAI_CTRL1_FMT_RJ_24BIT         (0x2 << 5)
+#define SSM2518_SAI_CTRL1_FMT_RJ_16BIT         (0x3 << 5)
+
+#define SSM2518_SAI_CTRL1_SAI_MASK             (0x7 << 2)
+#define SSM2518_SAI_CTRL1_SAI_I2S              (0x0 << 2)
+#define SSM2518_SAI_CTRL1_SAI_TDM_2            (0x1 << 2)
+#define SSM2518_SAI_CTRL1_SAI_TDM_4            (0x2 << 2)
+#define SSM2518_SAI_CTRL1_SAI_TDM_8            (0x3 << 2)
+#define SSM2518_SAI_CTRL1_SAI_TDM_16           (0x4 << 2)
+#define SSM2518_SAI_CTRL1_SAI_MONO             (0x5 << 2)
+
+#define SSM2518_SAI_CTRL1_FS_MASK              (0x3)
+#define SSM2518_SAI_CTRL1_FS_8000_12000                (0x0)
+#define SSM2518_SAI_CTRL1_FS_16000_24000       (0x1)
+#define SSM2518_SAI_CTRL1_FS_32000_48000       (0x2)
+#define SSM2518_SAI_CTRL1_FS_64000_96000       (0x3)
+
+#define SSM2518_SAI_CTRL2_BCLK_INTERAL         BIT(7)
+#define SSM2518_SAI_CTRL2_LRCLK_PULSE          BIT(6)
+#define SSM2518_SAI_CTRL2_LRCLK_INVERT         BIT(5)
+#define SSM2518_SAI_CTRL2_MSB                  BIT(4)
+#define SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK      (0x3 << 2)
+#define SSM2518_SAI_CTRL2_SLOT_WIDTH_32                (0x0 << 2)
+#define SSM2518_SAI_CTRL2_SLOT_WIDTH_24                (0x1 << 2)
+#define SSM2518_SAI_CTRL2_SLOT_WIDTH_16                (0x2 << 2)
+#define SSM2518_SAI_CTRL2_BCLK_INVERT          BIT(1)
+
+#define SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET     4
+#define SSM2518_CHAN_MAP_RIGHT_SLOT_MASK       0xf0
+#define SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET      0
+#define SSM2518_CHAN_MAP_LEFT_SLOT_MASK                0x0f
+
+#define SSM2518_MUTE_CTRL_ANA_GAIN             BIT(5)
+#define SSM2518_MUTE_CTRL_MUTE_MASTER          BIT(0)
+
+#define SSM2518_POWER2_APWDN                   BIT(0)
+
+#define SSM2518_DAC_MUTE                       BIT(6)
+#define SSM2518_DAC_FS_MASK                    0x07
+#define SSM2518_DAC_FS_8000                    0x00
+#define SSM2518_DAC_FS_16000                   0x01
+#define SSM2518_DAC_FS_32000                   0x02
+#define SSM2518_DAC_FS_64000                   0x03
+#define SSM2518_DAC_FS_128000                  0x04
+
+struct ssm2518 {
+       struct regmap *regmap;
+       bool right_j;
+
+       unsigned int sysclk;
+       const struct snd_pcm_hw_constraint_list *constraints;
+
+       int enable_gpio;
+};
+
+static const struct reg_default ssm2518_reg_defaults[] = {
+       { 0x00, 0x05 },
+       { 0x01, 0x00 },
+       { 0x02, 0x02 },
+       { 0x03, 0x00 },
+       { 0x04, 0x10 },
+       { 0x05, 0x40 },
+       { 0x06, 0x40 },
+       { 0x07, 0x81 },
+       { 0x08, 0x0c },
+       { 0x09, 0x99 },
+       { 0x0a, 0x7c },
+       { 0x0b, 0x5b },
+       { 0x0c, 0x57 },
+       { 0x0d, 0x89 },
+       { 0x0e, 0x8c },
+       { 0x0f, 0x77 },
+       { 0x10, 0x26 },
+       { 0x11, 0x1c },
+       { 0x12, 0x97 },
+};
+
+static const DECLARE_TLV_DB_MINMAX_MUTE(ssm2518_vol_tlv, -7125, 2400);
+static const DECLARE_TLV_DB_SCALE(ssm2518_compressor_tlv, -3400, 200, 0);
+static const DECLARE_TLV_DB_SCALE(ssm2518_expander_tlv, -8100, 300, 0);
+static const DECLARE_TLV_DB_SCALE(ssm2518_noise_gate_tlv, -9600, 300, 0);
+static const DECLARE_TLV_DB_SCALE(ssm2518_post_drc_tlv, -2400, 300, 0);
+
+static const DECLARE_TLV_DB_RANGE(ssm2518_limiter_tlv,
+       0, 7, TLV_DB_SCALE_ITEM(-2200, 200, 0),
+       7, 15, TLV_DB_SCALE_ITEM(-800, 100, 0),
+);
+
+static const char * const ssm2518_drc_peak_detector_attack_time_text[] = {
+       "0 ms", "0.1 ms", "0.19 ms", "0.37 ms", "0.75 ms", "1.5 ms", "3 ms",
+       "6 ms", "12 ms", "24 ms", "48 ms", "96 ms", "192 ms", "384 ms",
+       "768 ms", "1536 ms",
+};
+
+static const char * const ssm2518_drc_peak_detector_release_time_text[] = {
+       "0 ms", "1.5 ms", "3 ms", "6 ms", "12 ms", "24 ms", "48 ms", "96 ms",
+       "192 ms", "384 ms", "768 ms", "1536 ms", "3072 ms", "6144 ms",
+       "12288 ms", "24576 ms"
+};
+
+static const char * const ssm2518_drc_hold_time_text[] = {
+       "0 ms", "0.67 ms", "1.33 ms", "2.67 ms", "5.33 ms", "10.66 ms",
+       "21.32 ms", "42.64 ms", "85.28 ms", "170.56 ms", "341.12 ms",
+       "682.24 ms", "1364 ms",
+};
+
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
+       SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
+       SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
+       SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
+       SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
+       SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
+       SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
+static const SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
+       SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
+
+static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
+       SOC_SINGLE("Playback De-emphasis Switch", SSM2518_REG_MUTE_CTRL,
+                       4, 1, 0),
+       SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2518_REG_LEFT_VOL,
+                       SSM2518_REG_RIGHT_VOL, 0, 0xff, 1, ssm2518_vol_tlv),
+       SOC_DOUBLE("Master Playback Switch", SSM2518_REG_MUTE_CTRL, 2, 1, 1, 1),
+
+       SOC_SINGLE("Amp Low Power Mode Switch", SSM2518_REG_POWER2, 4, 1, 0),
+       SOC_SINGLE("DAC Low Power Mode Switch", SSM2518_REG_POWER2, 3, 1, 0),
+
+       SOC_SINGLE("DRC Limiter Switch", SSM2518_REG_DRC_1, 5, 1, 0),
+       SOC_SINGLE("DRC Compressor Switch", SSM2518_REG_DRC_1, 4, 1, 0),
+       SOC_SINGLE("DRC Expander Switch", SSM2518_REG_DRC_1, 3, 1, 0),
+       SOC_SINGLE("DRC Noise Gate Switch", SSM2518_REG_DRC_1, 2, 1, 0),
+       SOC_DOUBLE("DRC Switch", SSM2518_REG_DRC_1, 0, 1, 1, 0),
+
+       SOC_SINGLE_TLV("DRC Limiter Threshold Volume",
+                       SSM2518_REG_DRC_3, 4, 15, 1, ssm2518_limiter_tlv),
+       SOC_SINGLE_TLV("DRC Compressor Lower Threshold Volume",
+                       SSM2518_REG_DRC_3, 0, 15, 1, ssm2518_compressor_tlv),
+       SOC_SINGLE_TLV("DRC Expander Upper Threshold Volume", SSM2518_REG_DRC_4,
+                       4, 15, 1, ssm2518_expander_tlv),
+       SOC_SINGLE_TLV("DRC Noise Gate Threshold Volume",
+                       SSM2518_REG_DRC_4, 0, 15, 1, ssm2518_noise_gate_tlv),
+       SOC_SINGLE_TLV("DRC Upper Output Threshold Volume",
+                       SSM2518_REG_DRC_5, 4, 15, 1, ssm2518_limiter_tlv),
+       SOC_SINGLE_TLV("DRC Lower Output Threshold Volume",
+                       SSM2518_REG_DRC_5, 0, 15, 1, ssm2518_noise_gate_tlv),
+       SOC_SINGLE_TLV("DRC Post Volume", SSM2518_REG_DRC_8,
+                       2, 15, 1, ssm2518_post_drc_tlv),
+
+       SOC_ENUM("DRC Peak Detector Attack Time",
+               ssm2518_drc_peak_detector_attack_time_enum),
+       SOC_ENUM("DRC Peak Detector Release Time",
+               ssm2518_drc_peak_detector_release_time_enum),
+       SOC_ENUM("DRC Attack Time", ssm2518_drc_attack_time_enum),
+       SOC_ENUM("DRC Decay Time", ssm2518_drc_decay_time_enum),
+       SOC_ENUM("DRC Hold Time", ssm2518_drc_hold_time_enum),
+       SOC_ENUM("DRC Noise Gate Hold Time",
+               ssm2518_drc_noise_gate_hold_time_enum),
+       SOC_ENUM("DRC RMS Averaging Time", ssm2518_drc_rms_averaging_time_enum),
+};
+
+static const struct snd_soc_dapm_widget ssm2518_dapm_widgets[] = {
+       SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SSM2518_REG_POWER2, 1, 1),
+       SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SSM2518_REG_POWER2, 2, 1),
+
+       SND_SOC_DAPM_OUTPUT("OUTL"),
+       SND_SOC_DAPM_OUTPUT("OUTR"),
+};
+
+static const struct snd_soc_dapm_route ssm2518_routes[] = {
+       { "OUTL", NULL, "DACL" },
+       { "OUTR", NULL, "DACR" },
+};
+
+struct ssm2518_mcs_lut {
+       unsigned int rate;
+       const unsigned int *sysclks;
+};
+
+static const unsigned int ssm2518_sysclks_2048000[] = {
+       2048000, 4096000, 8192000, 12288000, 16384000, 24576000,
+       3200000, 6400000, 12800000, 0
+};
+
+static const unsigned int ssm2518_sysclks_2822000[] = {
+       2822000, 5644800, 11289600, 16934400, 22579200, 33868800,
+       4410000, 8820000, 17640000, 0
+};
+
+static const unsigned int ssm2518_sysclks_3072000[] = {
+       3072000, 6144000, 12288000, 16384000, 24576000, 38864000,
+       4800000, 9600000, 19200000, 0
+};
+
+static const struct ssm2518_mcs_lut ssm2518_mcs_lut[] = {
+       { 8000,  ssm2518_sysclks_2048000, },
+       { 11025, ssm2518_sysclks_2822000, },
+       { 12000, ssm2518_sysclks_3072000, },
+       { 16000, ssm2518_sysclks_2048000, },
+       { 24000, ssm2518_sysclks_3072000, },
+       { 22050, ssm2518_sysclks_2822000, },
+       { 32000, ssm2518_sysclks_2048000, },
+       { 44100, ssm2518_sysclks_2822000, },
+       { 48000, ssm2518_sysclks_3072000, },
+       { 96000, ssm2518_sysclks_3072000, },
+};
+
+static const unsigned int ssm2518_rates_2048000[] = {
+       8000, 16000, 32000,
+};
+
+static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2048000 = {
+       .list = ssm2518_rates_2048000,
+       .count = ARRAY_SIZE(ssm2518_rates_2048000),
+};
+
+static const unsigned int ssm2518_rates_2822000[] = {
+       11025, 22050, 44100,
+};
+
+static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2822000 = {
+       .list = ssm2518_rates_2822000,
+       .count = ARRAY_SIZE(ssm2518_rates_2822000),
+};
+
+static const unsigned int ssm2518_rates_3072000[] = {
+       12000, 24000, 48000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list ssm2518_constraints_3072000 = {
+       .list = ssm2518_rates_3072000,
+       .count = ARRAY_SIZE(ssm2518_rates_3072000),
+};
+
+static const unsigned int ssm2518_rates_12288000[] = {
+       8000, 12000, 16000, 24000, 32000, 48000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
+       .list = ssm2518_rates_12288000,
+       .count = ARRAY_SIZE(ssm2518_rates_12288000),
+};
+
+static unsigned int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
+       unsigned int rate)
+{
+       const unsigned int *sysclks = NULL;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ssm2518_mcs_lut); i++) {
+               if (ssm2518_mcs_lut[i].rate == rate) {
+                       sysclks = ssm2518_mcs_lut[i].sysclks;
+                       break;
+               }
+       }
+
+       if (!sysclks)
+               return -EINVAL;
+
+       for (i = 0; sysclks[i]; i++) {
+               if (sysclks[i] == ssm2518->sysclk)
+                       return i;
+       }
+
+       return -EINVAL;
+}
+
+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);
+       unsigned int rate = params_rate(params);
+       unsigned int ctrl1, ctrl1_mask;
+       int mcs;
+       int ret;
+
+       mcs = ssm2518_lookup_mcs(ssm2518, rate);
+       if (mcs < 0)
+               return mcs;
+
+       ctrl1_mask = SSM2518_SAI_CTRL1_FS_MASK;
+
+       if (rate >= 8000 && rate <= 12000)
+               ctrl1 = SSM2518_SAI_CTRL1_FS_8000_12000;
+       else if (rate >= 16000 && rate <= 24000)
+               ctrl1 = SSM2518_SAI_CTRL1_FS_16000_24000;
+       else if (rate >= 32000 && rate <= 48000)
+               ctrl1 = SSM2518_SAI_CTRL1_FS_32000_48000;
+       else if (rate >= 64000 && rate <= 96000)
+               ctrl1 = SSM2518_SAI_CTRL1_FS_64000_96000;
+       else
+               return -EINVAL;
+
+       if (ssm2518->right_j) {
+               switch (params_format(params)) {
+               case SNDRV_PCM_FORMAT_S16_LE:
+                       ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_16BIT;
+                       break;
+               case SNDRV_PCM_FORMAT_S24_LE:
+                       ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               ctrl1_mask |= SSM2518_SAI_CTRL1_FMT_MASK;
+       }
+
+       /* Disable auto samplerate detection */
+       ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_CLOCK,
+                               SSM2518_CLOCK_ASR, SSM2518_CLOCK_ASR);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
+                               ctrl1_mask, ctrl1);
+       if (ret < 0)
+               return ret;
+
+       return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
+                               SSM2518_POWER1_MCS_MASK, mcs << 1);
+}
+
+static int ssm2518_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+       unsigned int val;
+
+       if (mute)
+               val = SSM2518_MUTE_CTRL_MUTE_MASTER;
+       else
+               val = 0;
+
+       return regmap_update_bits(ssm2518->regmap, SSM2518_REG_MUTE_CTRL,
+                       SSM2518_MUTE_CTRL_MUTE_MASTER, val);
+}
+
+static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+       unsigned int ctrl1 = 0, ctrl2 = 0;
+       bool invert_fclk;
+       int ret;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               invert_fclk = false;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
+               invert_fclk = false;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               invert_fclk = true;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
+               invert_fclk = true;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ssm2518->right_j = false;
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
+               invert_fclk = !invert_fclk;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
+               ssm2518->right_j = true;
+               invert_fclk = !invert_fclk;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
+               ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
+               invert_fclk = false;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
+               ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
+               invert_fclk = false;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (invert_fclk)
+               ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_INVERT;
+
+       ret = regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL1, ctrl1);
+       if (ret)
+               return ret;
+
+       return regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL2, ctrl2);
+}
+
+static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
+{
+       int ret = 0;
+
+       if (!enable) {
+               ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
+                       SSM2518_POWER1_SPWDN, SSM2518_POWER1_SPWDN);
+               regcache_mark_dirty(ssm2518->regmap);
+       }
+
+       if (gpio_is_valid(ssm2518->enable_gpio))
+               gpio_set_value(ssm2518->enable_gpio, enable);
+
+       regcache_cache_only(ssm2518->regmap, !enable);
+
+       if (enable) {
+               ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
+                       SSM2518_POWER1_SPWDN | SSM2518_POWER1_RESET, 0x00);
+               regcache_sync(ssm2518->regmap);
+       }
+
+       return ret;
+}
+
+static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
+       enum snd_soc_bias_level level)
+{
+       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+       int ret = 0;
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+                       ret = ssm2518_set_power(ssm2518, true);
+               break;
+       case SND_SOC_BIAS_OFF:
+               ret = ssm2518_set_power(ssm2518, false);
+               break;
+       }
+
+       if (ret)
+               return ret;
+
+       codec->dapm.bias_level = level;
+
+       return 0;
+}
+
+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);
+       unsigned int ctrl1, ctrl2;
+       int left_slot, right_slot;
+       int ret;
+
+       if (slots == 0)
+               return regmap_update_bits(ssm2518->regmap,
+                       SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
+                       SSM2518_SAI_CTRL1_SAI_I2S);
+
+       if (tx_mask == 0 || rx_mask != 0)
+               return -EINVAL;
+
+       if (slots == 1) {
+               if (tx_mask != 1)
+                       return -EINVAL;
+               left_slot = 0;
+               right_slot = 0;
+       } else {
+               /* We assume the left channel < right channel */
+               left_slot = ffs(tx_mask);
+               tx_mask &= ~(1 << tx_mask);
+               if (tx_mask == 0) {
+                       right_slot = left_slot;
+               } else {
+                       right_slot = ffs(tx_mask);
+                       tx_mask &= ~(1 << tx_mask);
+               }
+       }
+
+       if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+               return -EINVAL;
+
+       switch (width) {
+       case 16:
+               ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
+               break;
+       case 24:
+               ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
+               break;
+       case 32:
+               ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (slots) {
+       case 1:
+               ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
+               break;
+       case 2:
+               ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
+               break;
+       case 4:
+               ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
+               break;
+       case 8:
+               ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
+               break;
+       case 16:
+               ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
+               (left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
+               (right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
+               SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
+       if (ret)
+               return ret;
+
+       return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
+               SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
+}
+
+static int ssm2518_startup(struct snd_pcm_substream *substream,
+       struct snd_soc_dai *dai)
+{
+       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
+
+       if (ssm2518->constraints)
+               snd_pcm_hw_constraint_list(substream->runtime, 0,
+                               SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
+
+       return 0;
+}
+
+#define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
+                       SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
+
+static const struct snd_soc_dai_ops ssm2518_dai_ops = {
+       .startup = ssm2518_startup,
+       .hw_params      = ssm2518_hw_params,
+       .digital_mute   = ssm2518_mute,
+       .set_fmt        = ssm2518_set_dai_fmt,
+       .set_tdm_slot   = ssm2518_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver ssm2518_dai = {
+       .name = "ssm2518-hifi",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_96000,
+               .formats = SSM2518_FORMATS,
+       },
+       .ops = &ssm2518_dai_ops,
+};
+
+static int ssm2518_probe(struct snd_soc_codec *codec)
+{
+       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+       int ret;
+
+       codec->control_data = ssm2518->regmap;
+       ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
+
+       return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
+}
+
+static int ssm2518_remove(struct snd_soc_codec *codec)
+{
+       ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+       int source, unsigned int freq, int dir)
+{
+       struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
+       unsigned int val;
+
+       if (clk_id != SSM2518_SYSCLK)
+               return -EINVAL;
+
+       switch (source) {
+       case SSM2518_SYSCLK_SRC_MCLK:
+               val = 0;
+               break;
+       case SSM2518_SYSCLK_SRC_BCLK:
+               /* In this case the bitclock is used as the system clock, and
+                * the bitclock signal needs to be connected to the MCLK pin and
+                * the BCLK pin is left unconnected */
+               val = SSM2518_POWER1_NO_BCLK;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (freq) {
+       case 0:
+               ssm2518->constraints = NULL;
+               break;
+       case 2048000:
+       case 4096000:
+       case 8192000:
+       case 3200000:
+       case 6400000:
+       case 12800000:
+               ssm2518->constraints = &ssm2518_constraints_2048000;
+               break;
+       case 2822000:
+       case 5644800:
+       case 11289600:
+       case 16934400:
+       case 22579200:
+       case 33868800:
+       case 4410000:
+       case 8820000:
+       case 17640000:
+               ssm2518->constraints = &ssm2518_constraints_2822000;
+               break;
+       case 3072000:
+       case 6144000:
+       case 38864000:
+       case 4800000:
+       case 9600000:
+       case 19200000:
+               ssm2518->constraints = &ssm2518_constraints_3072000;
+               break;
+       case 12288000:
+       case 16384000:
+       case 24576000:
+               ssm2518->constraints = &ssm2518_constraints_12288000;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ssm2518->sysclk = freq;
+
+       return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
+                       SSM2518_POWER1_NO_BCLK, val);
+}
+
+static struct snd_soc_codec_driver ssm2518_codec_driver = {
+       .probe = ssm2518_probe,
+       .remove = ssm2518_remove,
+       .set_bias_level = ssm2518_set_bias_level,
+       .set_sysclk = ssm2518_set_sysclk,
+       .idle_bias_off = true,
+
+       .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 bool ssm2518_register_volatile(struct device *dev, unsigned int reg)
+{
+       return false;
+}
+
+static const struct regmap_config ssm2518_regmap_config = {
+       .val_bits = 8,
+       .reg_bits = 8,
+
+       .max_register = SSM2518_REG_DRC_9,
+       .volatile_reg = ssm2518_register_volatile,
+
+       .cache_type = REGCACHE_RBTREE,
+       .reg_defaults = ssm2518_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
+};
+
+static int ssm2518_i2c_probe(struct i2c_client *i2c,
+       const struct i2c_device_id *id)
+{
+       struct ssm2518_platform_data *pdata = i2c->dev.platform_data;
+       struct ssm2518 *ssm2518;
+       int ret;
+
+       ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
+       if (ssm2518 == NULL)
+               return -ENOMEM;
+
+       if (pdata) {
+               ssm2518->enable_gpio = pdata->enable_gpio;
+       } else if (i2c->dev.of_node) {
+               ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0);
+               if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT)
+                       return ssm2518->enable_gpio;
+       } else {
+               ssm2518->enable_gpio = -1;
+       }
+
+       if (gpio_is_valid(ssm2518->enable_gpio)) {
+               ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio,
+                               GPIOF_OUT_INIT_HIGH, "SSM2518 nSD");
+               if (ret)
+                       return ret;
+       }
+
+       i2c_set_clientdata(i2c, ssm2518);
+
+       ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
+       if (IS_ERR(ssm2518->regmap))
+               return PTR_ERR(ssm2518->regmap);
+
+       /*
+        * The reset bit is obviously volatile, but we need to be able to cache
+        * the other bits in the register, so we can't just mark the whole
+        * register as volatile. Since this is the only place where we'll ever
+        * touch the reset bit just bypass the cache for this operation.
+        */
+       regcache_cache_bypass(ssm2518->regmap, true);
+       ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
+                       SSM2518_POWER1_RESET);
+       regcache_cache_bypass(ssm2518->regmap, false);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
+                               SSM2518_POWER2_APWDN, 0x00);
+       if (ret)
+               return ret;
+
+       ret = ssm2518_set_power(ssm2518, false);
+       if (ret)
+               return ret;
+
+       return snd_soc_register_codec(&i2c->dev, &ssm2518_codec_driver,
+                       &ssm2518_dai, 1);
+}
+
+static int ssm2518_i2c_remove(struct i2c_client *client)
+{
+       snd_soc_unregister_codec(&client->dev);
+       return 0;
+}
+
+static const struct i2c_device_id ssm2518_i2c_ids[] = {
+       { "ssm2518", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
+
+static struct i2c_driver ssm2518_driver = {
+       .driver = {
+               .name = "ssm2518",
+               .owner = THIS_MODULE,
+       },
+       .probe = ssm2518_i2c_probe,
+       .remove = ssm2518_i2c_remove,
+       .id_table = ssm2518_i2c_ids,
+};
+module_i2c_driver(ssm2518_driver);
+
+MODULE_DESCRIPTION("ASoC SSM2518 driver");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2518.h b/sound/soc/codecs/ssm2518.h
new file mode 100644 (file)
index 0000000..62511d8
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * SSM2518 amplifier audio driver
+ *
+ * Copyright 2013 Analog Devices Inc.
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef __SND_SOC_CODECS_SSM2518_H__
+#define __SND_SOC_CODECS_SSM2518_H__
+
+#define SSM2518_SYSCLK 0
+
+enum ssm2518_sysclk_src {
+       SSM2518_SYSCLK_SRC_MCLK = 0,
+       SSM2518_SYSCLK_SRC_BCLK = 1,
+};
+
+#endif
index 65d09d6..1514bf8 100644 (file)
@@ -187,14 +187,14 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 
                        break;
                }
-
-               if (found)
-                       snd_soc_dapm_sync(widget->dapm);
        }
 
-       ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
-
        mutex_unlock(&widget->codec->mutex);
+
+       if (found)
+               snd_soc_dapm_sync(widget->dapm);
+
+       ret = snd_soc_update_bits_locked(widget->codec, reg, val_mask, val);
        return ret;
 }
 
index e895d39..282fd23 100644 (file)
@@ -814,7 +814,20 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
 
 SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]),
 SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]),
-SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]),
+SOC_VALUE_ENUM("EPOUT OSR", wm5102_hpout_osr[2]),
+
+SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE,
+          ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0),
+SOC_DOUBLE("HPOUT2 DRE Switch", ARIZONA_DRE_ENABLE,
+          ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0),
+SOC_SINGLE("EPOUT DRE Switch", ARIZONA_DRE_ENABLE,
+          ARIZONA_DRE3L_ENA_SHIFT, 1, 0),
+
+SOC_SINGLE("DRE Threshold", ARIZONA_DRE_CONTROL_2,
+          ARIZONA_DRE_T_LOW_SHIFT, 63, 0),
+
+SOC_SINGLE("DRE Low Level ABS", ARIZONA_DRE_CONTROL_3,
+          ARIZONA_DRE_LOW_LEVEL_ABS_SHIFT, 15, 0),
 
 SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
 SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
@@ -852,6 +865,15 @@ ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
 
 ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
+
+ARIZONA_MIXER_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
 };
 
 ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
@@ -898,6 +920,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
 
+ARIZONA_MIXER_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX7, ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX8, ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE);
+
 ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
@@ -1117,10 +1148,61 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
 SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
                    ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
 
+SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX8_ENA_SHIFT, 0),
+
 ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
 
 SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA, 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,
@@ -1188,6 +1270,15 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
 ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
 ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
 
+ARIZONA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
+ARIZONA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
+ARIZONA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
+ARIZONA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
+ARIZONA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
+ARIZONA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
+ARIZONA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
+ARIZONA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
+
 ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
 ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
 ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
@@ -1248,6 +1339,14 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"),
        { name, "AIF2RX2", "AIF2RX2" }, \
        { name, "AIF3RX1", "AIF3RX1" }, \
        { name, "AIF3RX2", "AIF3RX2" }, \
+       { name, "SLIMRX1", "SLIMRX1" }, \
+       { name, "SLIMRX2", "SLIMRX2" }, \
+       { name, "SLIMRX3", "SLIMRX3" }, \
+       { name, "SLIMRX4", "SLIMRX4" }, \
+       { name, "SLIMRX5", "SLIMRX5" }, \
+       { name, "SLIMRX6", "SLIMRX6" }, \
+       { name, "SLIMRX7", "SLIMRX7" }, \
+       { name, "SLIMRX8", "SLIMRX8" }, \
        { name, "EQ1", "EQ1" }, \
        { name, "EQ2", "EQ2" }, \
        { name, "EQ3", "EQ3" }, \
@@ -1303,10 +1402,21 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
        { "OUT5L", NULL, "SYSCLK" },
        { "OUT5R", NULL, "SYSCLK" },
 
+       { "IN1L", NULL, "SYSCLK" },
+       { "IN1R", NULL, "SYSCLK" },
+       { "IN2L", NULL, "SYSCLK" },
+       { "IN2R", NULL, "SYSCLK" },
+       { "IN3L", NULL, "SYSCLK" },
+       { "IN3R", NULL, "SYSCLK" },
+
        { "MICBIAS1", NULL, "MICVDD" },
        { "MICBIAS2", NULL, "MICVDD" },
        { "MICBIAS3", NULL, "MICVDD" },
 
+       { "Noise Generator", NULL, "SYSCLK" },
+       { "Tone Generator 1", NULL, "SYSCLK" },
+       { "Tone Generator 2", NULL, "SYSCLK" },
+
        { "Noise Generator", NULL, "NOISE" },
        { "Tone Generator 1", NULL, "TONE" },
        { "Tone Generator 2", NULL, "TONE" },
@@ -1344,13 +1454,41 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
        { "AIF3RX1", NULL, "AIF3 Playback" },
        { "AIF3RX2", NULL, "AIF3 Playback" },
 
+       { "Slim1 Capture", NULL, "SLIMTX1" },
+       { "Slim1 Capture", NULL, "SLIMTX2" },
+       { "Slim1 Capture", NULL, "SLIMTX3" },
+       { "Slim1 Capture", NULL, "SLIMTX4" },
+
+       { "SLIMRX1", NULL, "Slim1 Playback" },
+       { "SLIMRX2", NULL, "Slim1 Playback" },
+       { "SLIMRX3", NULL, "Slim1 Playback" },
+       { "SLIMRX4", NULL, "Slim1 Playback" },
+
+       { "Slim2 Capture", NULL, "SLIMTX5" },
+       { "Slim2 Capture", NULL, "SLIMTX6" },
+
+       { "SLIMRX5", NULL, "Slim2 Playback" },
+       { "SLIMRX6", NULL, "Slim2 Playback" },
+
+       { "Slim3 Capture", NULL, "SLIMTX7" },
+       { "Slim3 Capture", NULL, "SLIMTX8" },
+
+       { "SLIMRX7", NULL, "Slim3 Playback" },
+       { "SLIMRX8", NULL, "Slim3 Playback" },
+
        { "AIF1 Playback", NULL, "SYSCLK" },
        { "AIF2 Playback", NULL, "SYSCLK" },
        { "AIF3 Playback", NULL, "SYSCLK" },
+       { "Slim1 Playback", NULL, "SYSCLK" },
+       { "Slim2 Playback", NULL, "SYSCLK" },
+       { "Slim3 Playback", NULL, "SYSCLK" },
 
        { "AIF1 Capture", NULL, "SYSCLK" },
        { "AIF2 Capture", NULL, "SYSCLK" },
        { "AIF3 Capture", NULL, "SYSCLK" },
+       { "Slim1 Capture", NULL, "SYSCLK" },
+       { "Slim2 Capture", NULL, "SYSCLK" },
+       { "Slim3 Capture", NULL, "SYSCLK" },
 
        { "IN1L PGA", NULL, "IN1L" },
        { "IN1R PGA", NULL, "IN1R" },
@@ -1407,6 +1545,15 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
        ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
        ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
 
+       ARIZONA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
+       ARIZONA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
+       ARIZONA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
+       ARIZONA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
+       ARIZONA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
+       ARIZONA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
+       ARIZONA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
+       ARIZONA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
+
        ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
        ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
        ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
@@ -1559,6 +1706,63 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
                .ops = &arizona_dai_ops,
                .symmetric_rates = 1,
        },
+       {
+               .name = "wm5102-slim1",
+               .id = 4,
+               .playback = {
+                       .stream_name = "Slim1 Playback",
+                       .channels_min = 1,
+                       .channels_max = 4,
+                       .rates = WM5102_RATES,
+                       .formats = WM5102_FORMATS,
+               },
+               .capture = {
+                        .stream_name = "Slim1 Capture",
+                        .channels_min = 1,
+                        .channels_max = 4,
+                        .rates = WM5102_RATES,
+                        .formats = WM5102_FORMATS,
+                },
+               .ops = &arizona_simple_dai_ops,
+       },
+       {
+               .name = "wm5102-slim2",
+               .id = 5,
+               .playback = {
+                       .stream_name = "Slim2 Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = WM5102_RATES,
+                       .formats = WM5102_FORMATS,
+               },
+               .capture = {
+                        .stream_name = "Slim2 Capture",
+                        .channels_min = 1,
+                        .channels_max = 2,
+                        .rates = WM5102_RATES,
+                        .formats = WM5102_FORMATS,
+                },
+               .ops = &arizona_simple_dai_ops,
+       },
+       {
+               .name = "wm5102-slim3",
+               .id = 6,
+               .playback = {
+                       .stream_name = "Slim3 Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = WM5102_RATES,
+                       .formats = WM5102_FORMATS,
+               },
+               .capture = {
+                        .stream_name = "Slim3 Capture",
+                        .channels_min = 1,
+                        .channels_max = 2,
+                        .rates = WM5102_RATES,
+                        .formats = WM5102_FORMATS,
+                },
+               .ops = &arizona_simple_dai_ops,
+       },
 };
 
 static int wm5102_codec_probe(struct snd_soc_codec *codec)
index 731884e..2e7cb4b 100644 (file)
@@ -190,7 +190,7 @@ ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("DSP4L", ARIZONA_DSP4LMIX_INPUT_1_SOURCE),
-ARIZONA_MIXER_CONTROLS("DSP5R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP4R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE),
 
 ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
@@ -309,6 +309,15 @@ ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
 
 ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
+
+ARIZONA_MIXER_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
 };
 
 ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
@@ -360,6 +369,15 @@ ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
 
+ARIZONA_MIXER_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX7, ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(SLIMTX8, ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE);
+
 ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
 ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
@@ -503,7 +521,8 @@ SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
                 NULL, 0),
 
 SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
-                      ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5110_aec_loopback_mux),
+                      ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
+                      &wm5110_aec_loopback_mux),
 
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
                     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
@@ -549,6 +568,56 @@ SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
 SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
                    ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
 
+SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
+                   ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
+                   ARIZONA_SLIMRX8_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX6_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX7_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
+                    ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
+                    ARIZONA_SLIMTX8_ENA_SHIFT, 0),
+
 SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
                     ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
 SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
@@ -639,6 +708,15 @@ ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
 ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
 ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
 
+ARIZONA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
+ARIZONA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
+ARIZONA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
+ARIZONA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
+ARIZONA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
+ARIZONA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
+ARIZONA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
+ARIZONA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
+
 ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
 ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
 ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
@@ -689,6 +767,14 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"),
        { name, "AIF2RX2", "AIF2RX2" }, \
        { name, "AIF3RX1", "AIF3RX1" }, \
        { name, "AIF3RX2", "AIF3RX2" }, \
+       { name, "SLIMRX1", "SLIMRX1" }, \
+       { name, "SLIMRX2", "SLIMRX2" }, \
+       { name, "SLIMRX3", "SLIMRX3" }, \
+       { name, "SLIMRX4", "SLIMRX4" }, \
+       { name, "SLIMRX5", "SLIMRX5" }, \
+       { name, "SLIMRX6", "SLIMRX6" }, \
+       { name, "SLIMRX7", "SLIMRX7" }, \
+       { name, "SLIMRX8", "SLIMRX8" }, \
        { name, "EQ1", "EQ1" }, \
        { name, "EQ2", "EQ2" }, \
        { name, "EQ3", "EQ3" }, \
@@ -735,10 +821,23 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "OUT6L", NULL, "SYSCLK" },
        { "OUT6R", NULL, "SYSCLK" },
 
+       { "IN1L", NULL, "SYSCLK" },
+       { "IN1R", NULL, "SYSCLK" },
+       { "IN2L", NULL, "SYSCLK" },
+       { "IN2R", NULL, "SYSCLK" },
+       { "IN3L", NULL, "SYSCLK" },
+       { "IN3R", NULL, "SYSCLK" },
+       { "IN4L", NULL, "SYSCLK" },
+       { "IN4R", NULL, "SYSCLK" },
+
        { "MICBIAS1", NULL, "MICVDD" },
        { "MICBIAS2", NULL, "MICVDD" },
        { "MICBIAS3", NULL, "MICVDD" },
 
+       { "Noise Generator", NULL, "SYSCLK" },
+       { "Tone Generator 1", NULL, "SYSCLK" },
+       { "Tone Generator 2", NULL, "SYSCLK" },
+
        { "Noise Generator", NULL, "NOISE" },
        { "Tone Generator 1", NULL, "TONE" },
        { "Tone Generator 2", NULL, "TONE" },
@@ -776,13 +875,41 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        { "AIF3RX1", NULL, "AIF3 Playback" },
        { "AIF3RX2", NULL, "AIF3 Playback" },
 
+       { "Slim1 Capture", NULL, "SLIMTX1" },
+       { "Slim1 Capture", NULL, "SLIMTX2" },
+       { "Slim1 Capture", NULL, "SLIMTX3" },
+       { "Slim1 Capture", NULL, "SLIMTX4" },
+
+       { "SLIMRX1", NULL, "Slim1 Playback" },
+       { "SLIMRX2", NULL, "Slim1 Playback" },
+       { "SLIMRX3", NULL, "Slim1 Playback" },
+       { "SLIMRX4", NULL, "Slim1 Playback" },
+
+       { "Slim2 Capture", NULL, "SLIMTX5" },
+       { "Slim2 Capture", NULL, "SLIMTX6" },
+
+       { "SLIMRX5", NULL, "Slim2 Playback" },
+       { "SLIMRX6", NULL, "Slim2 Playback" },
+
+       { "Slim3 Capture", NULL, "SLIMTX7" },
+       { "Slim3 Capture", NULL, "SLIMTX8" },
+
+       { "SLIMRX7", NULL, "Slim3 Playback" },
+       { "SLIMRX8", NULL, "Slim3 Playback" },
+
        { "AIF1 Playback", NULL, "SYSCLK" },
        { "AIF2 Playback", NULL, "SYSCLK" },
        { "AIF3 Playback", NULL, "SYSCLK" },
+       { "Slim1 Playback", NULL, "SYSCLK" },
+       { "Slim2 Playback", NULL, "SYSCLK" },
+       { "Slim3 Playback", NULL, "SYSCLK" },
 
        { "AIF1 Capture", NULL, "SYSCLK" },
        { "AIF2 Capture", NULL, "SYSCLK" },
        { "AIF3 Capture", NULL, "SYSCLK" },
+       { "Slim1 Capture", NULL, "SYSCLK" },
+       { "Slim2 Capture", NULL, "SYSCLK" },
+       { "Slim3 Capture", NULL, "SYSCLK" },
 
        { "IN1L PGA", NULL, "IN1L" },
        { "IN1R PGA", NULL, "IN1R" },
@@ -828,6 +955,15 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
        ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
        ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
 
+       ARIZONA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
+       ARIZONA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
+       ARIZONA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
+       ARIZONA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
+       ARIZONA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
+       ARIZONA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
+       ARIZONA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
+       ARIZONA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
+
        ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
        ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
        ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
@@ -962,6 +1098,63 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
                .ops = &arizona_dai_ops,
                .symmetric_rates = 1,
        },
+       {
+               .name = "wm5110-slim1",
+               .id = 4,
+               .playback = {
+                       .stream_name = "Slim1 Playback",
+                       .channels_min = 1,
+                       .channels_max = 4,
+                       .rates = WM5110_RATES,
+                       .formats = WM5110_FORMATS,
+               },
+               .capture = {
+                        .stream_name = "Slim1 Capture",
+                        .channels_min = 1,
+                        .channels_max = 4,
+                        .rates = WM5110_RATES,
+                        .formats = WM5110_FORMATS,
+                },
+               .ops = &arizona_simple_dai_ops,
+       },
+       {
+               .name = "wm5110-slim2",
+               .id = 5,
+               .playback = {
+                       .stream_name = "Slim2 Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = WM5110_RATES,
+                       .formats = WM5110_FORMATS,
+               },
+               .capture = {
+                        .stream_name = "Slim2 Capture",
+                        .channels_min = 1,
+                        .channels_max = 2,
+                        .rates = WM5110_RATES,
+                        .formats = WM5110_FORMATS,
+                },
+               .ops = &arizona_simple_dai_ops,
+       },
+       {
+               .name = "wm5110-slim3",
+               .id = 6,
+               .playback = {
+                       .stream_name = "Slim3 Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = WM5110_RATES,
+                       .formats = WM5110_FORMATS,
+               },
+               .capture = {
+                        .stream_name = "Slim3 Capture",
+                        .channels_min = 1,
+                        .channels_max = 2,
+                        .rates = WM5110_RATES,
+                        .formats = WM5110_FORMATS,
+                },
+               .ops = &arizona_simple_dai_ops,
+       },
 };
 
 static int wm5110_codec_probe(struct snd_soc_codec *codec)
@@ -976,6 +1169,8 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
        if (ret != 0)
                return ret;
 
+       arizona_init_spk(codec);
+
        snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
 
        priv->core.arizona->dapm = &codec->dapm;
index e971028..4b7915b 100644 (file)
@@ -1600,7 +1600,6 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
                            struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       u16 *reg_cache = codec->reg_cache;
        int ret;
 
        /* Apply the update (if any) */
@@ -1609,16 +1608,19 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
                return 0;
 
        /* If the left PGA is enabled hit that VU bit... */
-       if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTL_PGA_ENA)
-               return snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
-                                    reg_cache[WM8962_HPOUTL_VOLUME]);
+       ret = snd_soc_read(codec, WM8962_PWR_MGMT_2);
+       if (ret & WM8962_HPOUTL_PGA_ENA) {
+               snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
+                             snd_soc_read(codec, WM8962_HPOUTL_VOLUME));
+               return 1;
+       }
 
        /* ...otherwise the right.  The VU is stereo. */
-       if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTR_PGA_ENA)
-               return snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
-                                    reg_cache[WM8962_HPOUTR_VOLUME]);
+       if (ret & WM8962_HPOUTR_PGA_ENA)
+               snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
+                             snd_soc_read(codec, WM8962_HPOUTR_VOLUME));
 
-       return 0;
+       return 1;
 }
 
 /* The VU bits for the speakers are in a different register to the mute
@@ -3374,7 +3376,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
        int ret;
        struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
        struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
-       u16 *reg_cache = codec->reg_cache;
        int i, trigger, irq_pol;
        bool dmicclk, dmicdat;
 
@@ -3432,8 +3433,9 @@ static int wm8962_probe(struct snd_soc_codec *codec)
 
                /* Put the speakers into mono mode? */
                if (pdata->spk_mono)
-                       reg_cache[WM8962_CLASS_D_CONTROL_2]
-                               |= WM8962_SPK_MONO;
+                       snd_soc_update_bits(codec, WM8962_CLASS_D_CONTROL_2,
+                               WM8962_SPK_MONO_MASK, WM8962_SPK_MONO);
+
 
                /* Micbias setup, detection enable and detection
                 * threasholds. */
@@ -3721,6 +3723,17 @@ static int wm8962_runtime_resume(struct device *dev)
 
        regcache_sync(wm8962->regmap);
 
+       regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
+                          WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
+                          WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
+
+       /* Bias enable at 2*5k (fast start-up) */
+       regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
+                          WM8962_BIAS_ENA | WM8962_VMID_SEL_MASK,
+                          WM8962_BIAS_ENA | 0x180);
+
+       msleep(5);
+
        return 0;
 }
 
index 1eb152c..29e95f9 100644 (file)
@@ -383,6 +383,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        int drc = wm8994_get_drc(kcontrol->id.name);
 
+       if (drc < 0)
+               return drc;
        ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
 
        return 0;
@@ -488,6 +490,9 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
 
+       if (block < 0)
+               return block;
+
        ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
 
        return 0;
@@ -1031,7 +1036,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
 {
        struct snd_soc_codec *codec = w->codec;
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-       struct wm8994 *control = codec->control_data;
+       struct wm8994 *control = wm8994->wm8994;
        int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
        int i;
        int dac;
@@ -3831,8 +3836,14 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
                                ret);
                } else if (!(ret & WM1811_JACKDET_LVL)) {
                        dev_dbg(codec->dev, "Ignoring removed jack\n");
-                       return IRQ_HANDLED;
+                       goto out;
                }
+       } else if (!(reg & WM8958_MICD_STS)) {
+               snd_soc_jack_report(wm8994->micdet[0].jack, 0,
+                                   SND_JACK_MECHANICAL | SND_JACK_HEADSET |
+                                   wm8994->btn_mask);
+               wm8994->mic_detecting = true;
+               goto out;
        }
 
        if (wm8994->mic_detecting)
index 3470b64..05252ac 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -215,6 +216,36 @@ static struct {
        [WM_ADSP_FW_RX_ANC] =  { .file = "rx-anc" },
 };
 
+struct wm_coeff_ctl_ops {
+       int (*xget)(struct snd_kcontrol *kcontrol,
+                   struct snd_ctl_elem_value *ucontrol);
+       int (*xput)(struct snd_kcontrol *kcontrol,
+                   struct snd_ctl_elem_value *ucontrol);
+       int (*xinfo)(struct snd_kcontrol *kcontrol,
+                    struct snd_ctl_elem_info *uinfo);
+};
+
+struct wm_coeff {
+       struct device *dev;
+       struct list_head ctl_list;
+       struct regmap *regmap;
+};
+
+struct wm_coeff_ctl {
+       const char *name;
+       struct snd_card *card;
+       struct wm_adsp_alg_region region;
+       struct wm_coeff_ctl_ops ops;
+       struct wm_adsp *adsp;
+       void *private;
+       unsigned int enabled:1;
+       struct list_head list;
+       void *cache;
+       size_t len;
+       unsigned int set:1;
+       struct snd_kcontrol *kcontrol;
+};
+
 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
@@ -279,7 +310,7 @@ static const struct soc_enum wm_adsp2_rate_enum[] = {
                              ARIZONA_DSP1_RATE_SHIFT, 0xf,
                              ARIZONA_RATE_ENUM_SIZE,
                              arizona_rate_text, arizona_rate_val),
-       SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
+       SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
                              ARIZONA_DSP1_RATE_SHIFT, 0xf,
                              ARIZONA_RATE_ENUM_SIZE,
                              arizona_rate_text, arizona_rate_val),
@@ -334,6 +365,181 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region,
        }
 }
 
+static int wm_coeff_info(struct snd_kcontrol *kcontrol,
+                        struct snd_ctl_elem_info *uinfo)
+{
+       struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
+
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+       uinfo->count = ctl->len;
+       return 0;
+}
+
+static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
+                                 const void *buf, size_t len)
+{
+       struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
+       struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
+       struct wm_adsp_alg_region *region = &ctl->region;
+       const struct wm_adsp_region *mem;
+       struct wm_adsp *adsp = ctl->adsp;
+       void *scratch;
+       int ret;
+       unsigned int reg;
+
+       mem = wm_adsp_find_region(adsp, region->type);
+       if (!mem) {
+               adsp_err(adsp, "No base for region %x\n",
+                        region->type);
+               return -EINVAL;
+       }
+
+       reg = ctl->region.base;
+       reg = wm_adsp_region_to_reg(mem, reg);
+
+       scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA);
+       if (!scratch)
+               return -ENOMEM;
+
+       ret = regmap_raw_write(wm_coeff->regmap, reg, scratch,
+                              ctl->len);
+       if (ret) {
+               adsp_err(adsp, "Failed to write %zu bytes to %x\n",
+                        ctl->len, reg);
+               kfree(scratch);
+               return ret;
+       }
+
+       kfree(scratch);
+
+       return 0;
+}
+
+static int wm_coeff_put(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
+       char *p = ucontrol->value.bytes.data;
+
+       memcpy(ctl->cache, p, ctl->len);
+
+       if (!ctl->enabled) {
+               ctl->set = 1;
+               return 0;
+       }
+
+       return wm_coeff_write_control(kcontrol, p, ctl->len);
+}
+
+static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
+                                void *buf, size_t len)
+{
+       struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
+       struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
+       struct wm_adsp_alg_region *region = &ctl->region;
+       const struct wm_adsp_region *mem;
+       struct wm_adsp *adsp = ctl->adsp;
+       void *scratch;
+       int ret;
+       unsigned int reg;
+
+       mem = wm_adsp_find_region(adsp, region->type);
+       if (!mem) {
+               adsp_err(adsp, "No base for region %x\n",
+                        region->type);
+               return -EINVAL;
+       }
+
+       reg = ctl->region.base;
+       reg = wm_adsp_region_to_reg(mem, reg);
+
+       scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA);
+       if (!scratch)
+               return -ENOMEM;
+
+       ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len);
+       if (ret) {
+               adsp_err(adsp, "Failed to read %zu bytes from %x\n",
+                        ctl->len, reg);
+               kfree(scratch);
+               return ret;
+       }
+
+       memcpy(buf, scratch, ctl->len);
+       kfree(scratch);
+
+       return 0;
+}
+
+static int wm_coeff_get(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
+       char *p = ucontrol->value.bytes.data;
+
+       memcpy(p, ctl->cache, ctl->len);
+       return 0;
+}
+
+static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff,
+                                struct wm_coeff_ctl *ctl,
+                                const struct snd_kcontrol_new *kctl)
+{
+       int ret;
+       struct snd_kcontrol *kcontrol;
+
+       kcontrol = snd_ctl_new1(kctl, wm_coeff);
+       ret = snd_ctl_add(ctl->card, kcontrol);
+       if (ret < 0) {
+               dev_err(wm_coeff->dev, "Failed to add %s: %d\n",
+                       kctl->name, ret);
+               return ret;
+       }
+       ctl->kcontrol = kcontrol;
+       return 0;
+}
+
+struct wmfw_ctl_work {
+       struct wm_coeff *wm_coeff;
+       struct wm_coeff_ctl *ctl;
+       struct work_struct work;
+};
+
+static int wmfw_add_ctl(struct wm_coeff *wm_coeff,
+                       struct wm_coeff_ctl *ctl)
+{
+       struct snd_kcontrol_new *kcontrol;
+       int ret;
+
+       if (!wm_coeff || !ctl || !ctl->name || !ctl->card)
+               return -EINVAL;
+
+       kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
+       if (!kcontrol)
+               return -ENOMEM;
+       kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+
+       kcontrol->name = ctl->name;
+       kcontrol->info = wm_coeff_info;
+       kcontrol->get = wm_coeff_get;
+       kcontrol->put = wm_coeff_put;
+       kcontrol->private_value = (unsigned long)ctl;
+
+       ret = wm_coeff_add_kcontrol(wm_coeff,
+                                   ctl, kcontrol);
+       if (ret < 0)
+               goto err_kcontrol;
+
+       kfree(kcontrol);
+
+       list_add(&ctl->list, &wm_coeff->ctl_list);
+       return 0;
+
+err_kcontrol:
+       kfree(kcontrol);
+       return ret;
+}
+
 static int wm_adsp_load(struct wm_adsp *dsp)
 {
        LIST_HEAD(buf_list);
@@ -547,7 +753,157 @@ out:
        return ret;
 }
 
-static int wm_adsp_setup_algs(struct wm_adsp *dsp)
+static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff)
+{
+       struct wm_coeff_ctl *ctl;
+       int ret;
+
+       list_for_each_entry(ctl, &wm_coeff->ctl_list,
+                           list) {
+               if (!ctl->enabled || ctl->set)
+                       continue;
+               ret = wm_coeff_read_control(ctl->kcontrol,
+                                           ctl->cache,
+                                           ctl->len);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff)
+{
+       struct wm_coeff_ctl *ctl;
+       int ret;
+
+       list_for_each_entry(ctl, &wm_coeff->ctl_list,
+                           list) {
+               if (!ctl->enabled)
+                       continue;
+               if (ctl->set) {
+                       ret = wm_coeff_write_control(ctl->kcontrol,
+                                                    ctl->cache,
+                                                    ctl->len);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+static void wm_adsp_ctl_work(struct work_struct *work)
+{
+       struct wmfw_ctl_work *ctl_work = container_of(work,
+                                                     struct wmfw_ctl_work,
+                                                     work);
+
+       wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl);
+       kfree(ctl_work);
+}
+
+static int wm_adsp_create_control(struct snd_soc_codec *codec,
+                                 const struct wm_adsp_alg_region *region)
+
+{
+       struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
+       struct wm_coeff_ctl *ctl;
+       struct wmfw_ctl_work *ctl_work;
+       char *name;
+       char *region_name;
+       int ret;
+
+       name = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!name)
+               return -ENOMEM;
+
+       switch (region->type) {
+       case WMFW_ADSP1_PM:
+               region_name = "PM";
+               break;
+       case WMFW_ADSP1_DM:
+               region_name = "DM";
+               break;
+       case WMFW_ADSP2_XM:
+               region_name = "XM";
+               break;
+       case WMFW_ADSP2_YM:
+               region_name = "YM";
+               break;
+       case WMFW_ADSP1_ZM:
+               region_name = "ZM";
+               break;
+       default:
+               ret = -EINVAL;
+               goto err_name;
+       }
+
+       snprintf(name, PAGE_SIZE, "DSP%d %s %x",
+                dsp->num, region_name, region->alg);
+
+       list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
+                           list) {
+               if (!strcmp(ctl->name, name)) {
+                       if (!ctl->enabled)
+                               ctl->enabled = 1;
+                       goto found;
+               }
+       }
+
+       ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
+       if (!ctl) {
+               ret = -ENOMEM;
+               goto err_name;
+       }
+       ctl->region = *region;
+       ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL);
+       if (!ctl->name) {
+               ret = -ENOMEM;
+               goto err_ctl;
+       }
+       ctl->enabled = 1;
+       ctl->set = 0;
+       ctl->ops.xget = wm_coeff_get;
+       ctl->ops.xput = wm_coeff_put;
+       ctl->card = codec->card->snd_card;
+       ctl->adsp = dsp;
+
+       ctl->len = region->len;
+       ctl->cache = kzalloc(ctl->len, GFP_KERNEL);
+       if (!ctl->cache) {
+               ret = -ENOMEM;
+               goto err_ctl_name;
+       }
+
+       ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL);
+       if (!ctl_work) {
+               ret = -ENOMEM;
+               goto err_ctl_cache;
+       }
+
+       ctl_work->wm_coeff = dsp->wm_coeff;
+       ctl_work->ctl = ctl;
+       INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
+       schedule_work(&ctl_work->work);
+
+found:
+       kfree(name);
+
+       return 0;
+
+err_ctl_cache:
+       kfree(ctl->cache);
+err_ctl_name:
+       kfree(ctl->name);
+err_ctl:
+       kfree(ctl);
+err_name:
+       kfree(name);
+       return ret;
+}
+
+static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
 {
        struct regmap *regmap = dsp->regmap;
        struct wmfw_adsp1_id_hdr adsp1_id;
@@ -730,7 +1086,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
                        region->type = WMFW_ADSP1_DM;
                        region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
                        region->base = be32_to_cpu(adsp1_alg[i].dm);
+                       region->len = 0;
                        list_add_tail(&region->list, &dsp->alg_regions);
+                       if (i + 1 < algs) {
+                               region->len = be32_to_cpu(adsp1_alg[i + 1].dm);
+                               region->len -= be32_to_cpu(adsp1_alg[i].dm);
+                               wm_adsp_create_control(codec, region);
+                       } else {
+                               adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
+                                         be32_to_cpu(adsp1_alg[i].alg.id));
+                       }
 
                        region = kzalloc(sizeof(*region), GFP_KERNEL);
                        if (!region)
@@ -738,7 +1103,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
                        region->type = WMFW_ADSP1_ZM;
                        region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
                        region->base = be32_to_cpu(adsp1_alg[i].zm);
+                       region->len = 0;
                        list_add_tail(&region->list, &dsp->alg_regions);
+                       if (i + 1 < algs) {
+                               region->len = be32_to_cpu(adsp1_alg[i + 1].zm);
+                               region->len -= be32_to_cpu(adsp1_alg[i].zm);
+                               wm_adsp_create_control(codec, region);
+                       } else {
+                               adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
+                                         be32_to_cpu(adsp1_alg[i].alg.id));
+                       }
                        break;
 
                case WMFW_ADSP2:
@@ -758,7 +1132,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
                        region->type = WMFW_ADSP2_XM;
                        region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
                        region->base = be32_to_cpu(adsp2_alg[i].xm);
+                       region->len = 0;
                        list_add_tail(&region->list, &dsp->alg_regions);
+                       if (i + 1 < algs) {
+                               region->len = be32_to_cpu(adsp2_alg[i + 1].xm);
+                               region->len -= be32_to_cpu(adsp2_alg[i].xm);
+                               wm_adsp_create_control(codec, region);
+                       } else {
+                               adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
+                                         be32_to_cpu(adsp2_alg[i].alg.id));
+                       }
 
                        region = kzalloc(sizeof(*region), GFP_KERNEL);
                        if (!region)
@@ -766,7 +1149,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
                        region->type = WMFW_ADSP2_YM;
                        region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
                        region->base = be32_to_cpu(adsp2_alg[i].ym);
+                       region->len = 0;
                        list_add_tail(&region->list, &dsp->alg_regions);
+                       if (i + 1 < algs) {
+                               region->len = be32_to_cpu(adsp2_alg[i + 1].ym);
+                               region->len -= be32_to_cpu(adsp2_alg[i].ym);
+                               wm_adsp_create_control(codec, region);
+                       } else {
+                               adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
+                                         be32_to_cpu(adsp2_alg[i].alg.id));
+                       }
 
                        region = kzalloc(sizeof(*region), GFP_KERNEL);
                        if (!region)
@@ -774,7 +1166,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
                        region->type = WMFW_ADSP2_ZM;
                        region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
                        region->base = be32_to_cpu(adsp2_alg[i].zm);
+                       region->len = 0;
                        list_add_tail(&region->list, &dsp->alg_regions);
+                       if (i + 1 < algs) {
+                               region->len = be32_to_cpu(adsp2_alg[i + 1].zm);
+                               region->len -= be32_to_cpu(adsp2_alg[i].zm);
+                               wm_adsp_create_control(codec, region);
+                       } else {
+                               adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
+                                         be32_to_cpu(adsp2_alg[i].alg.id));
+                       }
                        break;
                }
        }
@@ -986,6 +1387,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
        struct snd_soc_codec *codec = w->codec;
        struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
        struct wm_adsp *dsp = &dsps[w->shift];
+       struct wm_coeff_ctl *ctl;
        int ret;
        int val;
 
@@ -1023,7 +1425,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
                if (ret != 0)
                        goto err;
 
-               ret = wm_adsp_setup_algs(dsp);
+               ret = wm_adsp_setup_algs(dsp, codec);
                if (ret != 0)
                        goto err;
 
@@ -1031,6 +1433,16 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
                if (ret != 0)
                        goto err;
 
+               /* Initialize caches for enabled and unset controls */
+               ret = wm_coeff_init_control_caches(dsp->wm_coeff);
+               if (ret != 0)
+                       goto err;
+
+               /* Sync set controls */
+               ret = wm_coeff_sync_controls(dsp->wm_coeff);
+               if (ret != 0)
+                       goto err;
+
                /* Start the core running */
                regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
                                   ADSP1_CORE_ENA | ADSP1_START,
@@ -1047,6 +1459,11 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
 
                regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
                                   ADSP1_SYS_ENA, 0);
+
+               list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
+                                   list) {
+                       ctl->enabled = 0;
+               }
                break;
 
        default:
@@ -1099,6 +1516,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
        struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
        struct wm_adsp *dsp = &dsps[w->shift];
        struct wm_adsp_alg_region *alg_region;
+       struct wm_coeff_ctl *ctl;
        unsigned int val;
        int ret;
 
@@ -1164,7 +1582,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
                if (ret != 0)
                        goto err;
 
-               ret = wm_adsp_setup_algs(dsp);
+               ret = wm_adsp_setup_algs(dsp, codec);
                if (ret != 0)
                        goto err;
 
@@ -1172,6 +1590,16 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
                if (ret != 0)
                        goto err;
 
+               /* Initialize caches for enabled and unset controls */
+               ret = wm_coeff_init_control_caches(dsp->wm_coeff);
+               if (ret != 0)
+                       goto err;
+
+               /* Sync set controls */
+               ret = wm_coeff_sync_controls(dsp->wm_coeff);
+               if (ret != 0)
+                       goto err;
+
                ret = regmap_update_bits(dsp->regmap,
                                         dsp->base + ADSP2_CONTROL,
                                         ADSP2_CORE_ENA | ADSP2_START,
@@ -1209,6 +1637,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
                                        ret);
                }
 
+               list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
+                                   list) {
+                       ctl->enabled = 0;
+               }
+
                while (!list_empty(&dsp->alg_regions)) {
                        alg_region = list_first_entry(&dsp->alg_regions,
                                                      struct wm_adsp_alg_region,
@@ -1247,36 +1680,48 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
 
        INIT_LIST_HEAD(&adsp->alg_regions);
 
+       adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff),
+                                GFP_KERNEL);
+       if (!adsp->wm_coeff)
+               return -ENOMEM;
+       adsp->wm_coeff->regmap = adsp->regmap;
+       adsp->wm_coeff->dev = adsp->dev;
+       INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list);
+
        if (dvfs) {
                adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
                if (IS_ERR(adsp->dvfs)) {
                        ret = PTR_ERR(adsp->dvfs);
                        dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
-                       return ret;
+                       goto out_coeff;
                }
 
                ret = regulator_enable(adsp->dvfs);
                if (ret != 0) {
                        dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
                                ret);
-                       return ret;
+                       goto out_coeff;
                }
 
                ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
                if (ret != 0) {
                        dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
                                ret);
-                       return ret;
+                       goto out_coeff;
                }
 
                ret = regulator_disable(adsp->dvfs);
                if (ret != 0) {
                        dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
                                ret);
-                       return ret;
+                       goto out_coeff;
                }
        }
 
        return 0;
+
+out_coeff:
+       kfree(adsp->wm_coeff);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_init);
index fea5146..6e890b9 100644 (file)
@@ -30,6 +30,7 @@ struct wm_adsp_alg_region {
        unsigned int alg;
        int type;
        unsigned int base;
+       size_t len;
 };
 
 struct wm_adsp {
@@ -55,6 +56,8 @@ struct wm_adsp {
        bool running;
 
        struct regulator *dvfs;
+
+       struct wm_coeff *wm_coeff;
 };
 
 #define WM_ADSP1(wname, num) \
index 9e11a14..c82f89c 100644 (file)
@@ -54,16 +54,6 @@ config  SND_DM6467_SOC_EVM
        help
          Say Y if you want to add support for SoC audio on TI
 
-config SND_DAVINCI_SOC_SFFSDR
-       tristate "SoC Audio support for SFFSDR"
-       depends on SND_DAVINCI_SOC && MACH_SFFSDR
-       select SND_DAVINCI_SOC_I2S
-       select SND_SOC_PCM3008
-       select SFFSDR_FPGA
-       help
-         Say Y if you want to add support for SoC audio on
-         Lyrtech SFFSDR board.
-
 config  SND_DA830_SOC_EVM
        tristate "SoC Audio support for DA830/OMAP-L137 EVM"
        depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM
index a93679d..a396ab6 100644 (file)
@@ -11,10 +11,8 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
 
 # DAVINCI Machine Support
 snd-soc-evm-objs := davinci-evm.o
-snd-soc-sffsdr-objs := davinci-sffsdr.o
 
 obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
 obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o
 obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o
 obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
-obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
index 56ecfc7..32ddb7f 100644 (file)
@@ -631,7 +631,8 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
                                       int word_length)
 {
        u32 fmt;
-       u32 rotate = (word_length / 4) & 0x7;
+       u32 tx_rotate = (word_length / 4) & 0x7;
+       u32 rx_rotate = (32 - word_length) / 4;
        u32 mask = (1ULL << word_length) - 1;
 
        /*
@@ -655,9 +656,9 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
                mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
                                TXSSZ(fmt), TXSSZ(0x0F));
                mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
-                               TXROT(rotate), TXROT(7));
+                               TXROT(tx_rotate), TXROT(7));
                mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
-                               RXROT(rotate), RXROT(7));
+                               RXROT(rx_rotate), RXROT(7));
                mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG,
                                mask);
        }
@@ -1023,7 +1024,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
        struct device_node *np = pdev->dev.of_node;
        struct snd_platform_data *pdata = NULL;
        const struct of_device_id *match =
-                       of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev);
+                       of_match_device(mcasp_dt_ids, &pdev->dev);
 
        const u32 *of_serial_dir32;
        u8 *of_serial_dir;
@@ -1256,7 +1257,7 @@ static struct platform_driver davinci_mcasp_driver = {
        .driver         = {
                .name   = "davinci-mcasp",
                .owner  = THIS_MODULE,
-               .of_match_table = of_match_ptr(mcasp_dt_ids),
+               .of_match_table = mcasp_dt_ids,
        },
 };
 
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
deleted file mode 100644 (file)
index 5be65aa..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * ASoC driver for Lyrtech SFFSDR board.
- *
- * Author:     Hugo Villeneuve
- * Copyright (C) 2008 Lyrtech inc
- *
- * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
- * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/dma.h>
-#include <asm/mach-types.h>
-#ifdef CONFIG_SFFSDR_FPGA
-#include <asm/plat-sffsdr/sffsdr-fpga.h>
-#endif
-
-#include <mach/edma.h>
-
-#include "../codecs/pcm3008.h"
-#include "davinci-pcm.h"
-#include "davinci-i2s.h"
-
-/*
- * CLKX and CLKR are the inputs for the Sample Rate Generator.
- * FSX and FSR are outputs, driven by the sample Rate Generator.
- */
-#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B |   \
-                     SND_SOC_DAIFMT_CBM_CFS |  \
-                     SND_SOC_DAIFMT_IB_NF)
-
-static int sffsdr_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;
-       int fs;
-       int ret = 0;
-
-       /* Fsref can be 32000, 44100 or 48000. */
-       fs = params_rate(params);
-
-#ifndef CONFIG_SFFSDR_FPGA
-       /* Without the FPGA module, the Fs is fixed at 44100 Hz */
-       if (fs != 44100) {
-               pr_debug("warning: only 44.1 kHz is supported without SFFSDR FPGA module\n");
-               return -EINVAL;
-       }
-#endif
-
-       /* set cpu DAI configuration */
-       ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
-       if (ret < 0)
-               return ret;
-
-       pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
-
-#ifndef CONFIG_SFFSDR_FPGA
-       return 0;
-#else
-       return sffsdr_fpga_set_codec_fs(fs);
-#endif
-}
-
-static struct snd_soc_ops sffsdr_ops = {
-       .hw_params = sffsdr_hw_params,
-};
-
-/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sffsdr_dai = {
-       .name = "PCM3008", /* Codec name */
-       .stream_name = "PCM3008 HiFi",
-       .cpu_dai_name = "davinci-mcbsp",
-       .codec_dai_name = "pcm3008-hifi",
-       .codec_name = "pcm3008-codec",
-       .platform_name = "davinci-mcbsp",
-       .ops = &sffsdr_ops,
-};
-
-/* davinci-sffsdr audio machine driver */
-static struct snd_soc_card snd_soc_sffsdr = {
-       .name = "DaVinci SFFSDR",
-       .owner = THIS_MODULE,
-       .dai_link = &sffsdr_dai,
-       .num_links = 1,
-};
-
-/* sffsdr audio private data */
-static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
-       .dem0_pin = GPIO(45),
-       .dem1_pin = GPIO(46),
-       .pdad_pin = GPIO(47),
-       .pdda_pin = GPIO(38),
-};
-
-struct platform_device pcm3008_codec = {
-               .name = "pcm3008-codec",
-               .id = 0,
-               .dev = {
-                               .platform_data = &sffsdr_pcm3008_setup,
-               },
-};
-
-static struct resource sffsdr_snd_resources[] = {
-       {
-               .start = DAVINCI_MCBSP_BASE,
-               .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-};
-
-static struct evm_snd_platform_data sffsdr_snd_data = {
-       .tx_dma_ch      = DAVINCI_DMA_MCBSP_TX,
-       .rx_dma_ch      = DAVINCI_DMA_MCBSP_RX,
-};
-
-static struct platform_device *sffsdr_snd_device;
-
-static int __init sffsdr_init(void)
-{
-       int ret;
-
-       if (!machine_is_sffsdr())
-               return -EINVAL;
-
-       platform_device_register(&pcm3008_codec);
-
-       sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
-       if (!sffsdr_snd_device) {
-               printk(KERN_ERR "platform device allocation failed\n");
-               return -ENOMEM;
-       }
-
-       platform_set_drvdata(sffsdr_snd_device, &snd_soc_sffsdr);
-       platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data,
-                                sizeof(sffsdr_snd_data));
-
-       ret = platform_device_add_resources(sffsdr_snd_device,
-                                           sffsdr_snd_resources,
-                                           ARRAY_SIZE(sffsdr_snd_resources));
-       if (ret) {
-               printk(KERN_ERR "platform device add resources failed\n");
-               goto error;
-       }
-
-       ret = platform_device_add(sffsdr_snd_device);
-       if (ret)
-               goto error;
-
-       return ret;
-
-error:
-       platform_device_put(sffsdr_snd_device);
-       return ret;
-}
-
-static void __exit sffsdr_exit(void)
-{
-       platform_device_unregister(sffsdr_snd_device);
-       platform_device_unregister(&pcm3008_codec);
-}
-
-module_init(sffsdr_init);
-module_exit(sffsdr_exit);
-
-MODULE_AUTHOR("Hugo Villeneuve");
-MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
-MODULE_LICENSE("GPL");
index 593a3ea..70eb37a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ALSA SoC Synopsys I2S Audio Layer
  *
- * sound/soc/spear/designware_i2s.c
+ * sound/soc/dwc/designware_i2s.c
  *
  * Copyright (C) 2010 ST Microelectronics
  * Rajeev Kumar <rajeev-dlh.kumar@st.com>
@@ -396,7 +396,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
        }
 
        if (cap & DWC_I2S_PLAY) {
-               dev_dbg(&pdev->dev, " SPEAr: play supported\n");
+               dev_dbg(&pdev->dev, " designware: play supported\n");
                dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
                dw_i2s_dai->playback.channels_max = pdata->channel;
                dw_i2s_dai->playback.formats = pdata->snd_fmts;
@@ -404,7 +404,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
        }
 
        if (cap & DWC_I2S_RECORD) {
-               dev_dbg(&pdev->dev, "SPEAr: record supported\n");
+               dev_dbg(&pdev->dev, "designware: record supported\n");
                dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
                dw_i2s_dai->capture.channels_max = pdata->channel;
                dw_i2s_dai->capture.formats = pdata->snd_fmts;
index 3843a18..aa43854 100644 (file)
@@ -108,18 +108,13 @@ if SND_IMX_SOC
 config SND_SOC_IMX_SSI
        tristate
 
-config SND_SOC_IMX_PCM
-       tristate
-
 config SND_SOC_IMX_PCM_FIQ
        bool
        select FIQ
-       select SND_SOC_IMX_PCM
 
 config SND_SOC_IMX_PCM_DMA
        bool
        select SND_SOC_GENERIC_DMAENGINE_PCM
-       select SND_SOC_IMX_PCM
 
 config SND_SOC_IMX_AUDMUX
        tristate
@@ -173,6 +168,18 @@ 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
+       select SND_SOC_WM8962
+       select SND_SOC_IMX_PCM_DMA
+       select SND_SOC_IMX_AUDMUX
+       select SND_SOC_FSL_SSI
+       select SND_SOC_FSL_UTILS
+       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_SGTL5000
        tristate "SoC Audio support for i.MX boards with sgtl5000"
        depends on OF && I2C
index afd3479..d4b4aa8 100644 (file)
@@ -30,18 +30,11 @@ obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
 # i.MX Platform Support
 snd-soc-imx-ssi-objs := imx-ssi.o
 snd-soc-imx-audmux-objs := imx-audmux.o
-snd-soc-imx-pcm-objs := imx-pcm.o
-ifneq ($(CONFIG_SND_SOC_IMX_PCM_FIQ),)
-       snd-soc-imx-pcm-objs += imx-pcm-fiq.o
-endif
-ifneq ($(CONFIG_SND_SOC_IMX_PCM_DMA),)
-       snd-soc-imx-pcm-objs += imx-pcm-dma.o
-endif
-
 obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
 obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
 
-obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
+obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
+obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
 
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
@@ -49,6 +42,7 @@ snd-soc-phycore-ac97-objs := phycore-ac97.o
 snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
+snd-soc-imx-wm8962-objs := imx-wm8962.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
@@ -56,4 +50,5 @@ obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
 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_SGTL5000) += snd-soc-imx-sgtl5000.o
+obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
index 75ffdf0..9a4a0ca 100644 (file)
@@ -80,7 +80,7 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = {
        .name           = "tlv320aic23",
        .stream_name    = "TLV320AIC23",
        .codec_dai_name = "tlv320aic23-hifi",
-       .platform_name  = "imx-fiq-pcm-audio.0",
+       .platform_name  = "imx-ssi.0",
        .codec_name     = "tlv320aic23-codec.0-001a",
        .cpu_dai_name   = "imx-ssi.0",
        .ops            = &eukrea_tlv320_snd_ops,
index 0f0bed6..2f2d837 100644 (file)
@@ -122,7 +122,6 @@ struct fsl_ssi_private {
        bool new_binding;
        bool ssi_on_imx;
        struct clk *clk;
-       struct platform_device *imx_pcm_pdev;
        struct snd_dmaengine_dai_dma_data dma_params_tx;
        struct snd_dmaengine_dai_dma_data dma_params_rx;
        struct imx_dma_data filter_data_tx;
@@ -809,13 +808,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
        }
 
        if (ssi_private->ssi_on_imx) {
-               ssi_private->imx_pcm_pdev =
-                       platform_device_register_simple("imx-pcm-audio",
-                                                       -1, NULL, 0);
-               if (IS_ERR(ssi_private->imx_pcm_pdev)) {
-                       ret = PTR_ERR(ssi_private->imx_pcm_pdev);
+               ret = imx_pcm_dma_init(pdev);
+               if (ret)
                        goto error_dev;
-               }
        }
 
        /*
@@ -854,7 +849,7 @@ done:
 
 error_dai:
        if (ssi_private->ssi_on_imx)
-               platform_device_unregister(ssi_private->imx_pcm_pdev);
+               imx_pcm_dma_exit(pdev);
        snd_soc_unregister_component(&pdev->dev);
 
 error_dev:
@@ -889,7 +884,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
        if (!ssi_private->new_binding)
                platform_device_unregister(ssi_private->pdev);
        if (ssi_private->ssi_on_imx) {
-               platform_device_unregister(ssi_private->imx_pcm_pdev);
+               imx_pcm_dma_exit(pdev);
                clk_disable_unprepare(ssi_private->clk);
                clk_put(ssi_private->clk);
        }
index 47f046a..e260f1f 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/pinctrl/consumer.h>
 
 #include "imx-audmux.h"
 
@@ -247,7 +246,6 @@ EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
 static int imx_audmux_probe(struct platform_device *pdev)
 {
        struct resource *res;
-       struct pinctrl *pinctrl;
        const struct of_device_id *of_id =
                        of_match_device(imx_audmux_dt_ids, &pdev->dev);
 
@@ -256,12 +254,6 @@ static int imx_audmux_probe(struct platform_device *pdev)
        if (IS_ERR(audmux_base))
                return PTR_ERR(audmux_base);
 
-       pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-       if (IS_ERR(pinctrl)) {
-               dev_err(&pdev->dev, "setup pinctrl failed!");
-               return PTR_ERR(pinctrl);
-       }
-
        audmux_clk = devm_clk_get(&pdev->dev, "audmux");
        if (IS_ERR(audmux_clk)) {
                dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
index 4ae30f2..9df173c 100644 (file)
@@ -64,7 +64,7 @@ static struct snd_soc_dai_link imx_mc13783_dai_mc13783[] = {
                .codec_dai_name  = "mc13783-hifi",
                .codec_name      = "mc13783-codec",
                .cpu_dai_name    = "imx-ssi.0",
-               .platform_name   = "imx-pcm-audio.0",
+               .platform_name   = "imx-ssi.0",
                .ops             = &imx_mc13783_hifi_ops,
                .symmetric_rates = 1,
                .dai_fmt         = FMT_SSI,
index c246fb5..fde4d2e 100644 (file)
@@ -67,8 +67,10 @@ int imx_pcm_dma_init(struct platform_device *pdev)
                SND_DMAENGINE_PCM_FLAG_NO_DT |
                SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
+EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
 
 void imx_pcm_dma_exit(struct platform_device *pdev)
 {
        snd_dmaengine_pcm_unregister(&pdev->dev);
 }
+EXPORT_SYMBOL_GPL(imx_pcm_dma_exit);
index 670b96b..310d902 100644 (file)
@@ -225,6 +225,22 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
        return 0;
 }
 
+static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
+               struct vm_area_struct *vma)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       int ret;
+
+       ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
+               runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
+
+       pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
+                       runtime->dma_area,
+                       runtime->dma_addr,
+                       runtime->dma_bytes);
+       return ret;
+}
+
 static struct snd_pcm_ops imx_pcm_ops = {
        .open           = snd_imx_open,
        .close          = snd_imx_close,
@@ -236,6 +252,54 @@ static struct snd_pcm_ops imx_pcm_ops = {
        .mmap           = snd_imx_pcm_mmap,
 };
 
+static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+{
+       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+       struct snd_dma_buffer *buf = &substream->dma_buffer;
+       size_t size = IMX_SSI_DMABUF_SIZE;
+
+       buf->dev.type = SNDRV_DMA_TYPE_DEV;
+       buf->dev.dev = pcm->card->dev;
+       buf->private_data = NULL;
+       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+                                          &buf->addr, GFP_KERNEL);
+       if (!buf->area)
+               return -ENOMEM;
+       buf->bytes = size;
+
+       return 0;
+}
+
+static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
+
+static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_card *card = rtd->card->snd_card;
+       struct snd_pcm *pcm = rtd->pcm;
+       int ret = 0;
+
+       if (!card->dev->dma_mask)
+               card->dev->dma_mask = &imx_pcm_dmamask;
+       if (!card->dev->coherent_dma_mask)
+               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+               ret = imx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_PLAYBACK);
+               if (ret)
+                       goto out;
+       }
+
+       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+               ret = imx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_CAPTURE);
+               if (ret)
+                       goto out;
+       }
+
+out:
+       return ret;
+}
+
 static int ssi_irq = 0;
 
 static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
@@ -268,6 +332,27 @@ static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
        return 0;
 }
 
+static void imx_pcm_free(struct snd_pcm *pcm)
+{
+       struct snd_pcm_substream *substream;
+       struct snd_dma_buffer *buf;
+       int stream;
+
+       for (stream = 0; stream < 2; stream++) {
+               substream = pcm->streams[stream].substream;
+               if (!substream)
+                       continue;
+
+               buf = &substream->dma_buffer;
+               if (!buf->area)
+                       continue;
+
+               dma_free_writecombine(pcm->card->dev, buf->bytes,
+                                     buf->area, buf->addr);
+               buf->area = NULL;
+       }
+}
+
 static void imx_pcm_fiq_free(struct snd_pcm *pcm)
 {
        mxc_set_irq_fiq(ssi_irq, 0);
@@ -314,3 +399,10 @@ failed_register:
 
        return ret;
 }
+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-pcm.c b/sound/soc/fsl/imx-pcm.c
deleted file mode 100644 (file)
index c498964..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
- *
- * This code is based on code copyrighted by Freescale,
- * Liam Girdwood, Javier Martin and probably others.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the 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/dma-mapping.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include "imx-pcm.h"
-
-int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
-               struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       int ret;
-
-       ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
-               runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
-
-       pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
-                       runtime->dma_area,
-                       runtime->dma_addr,
-                       runtime->dma_bytes);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
-
-static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-       size_t size = IMX_SSI_DMABUF_SIZE;
-
-       buf->dev.type = SNDRV_DMA_TYPE_DEV;
-       buf->dev.dev = pcm->card->dev;
-       buf->private_data = NULL;
-       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
-                                          &buf->addr, GFP_KERNEL);
-       if (!buf->area)
-               return -ENOMEM;
-       buf->bytes = size;
-
-       return 0;
-}
-
-static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
-
-int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       struct snd_pcm *pcm = rtd->pcm;
-       int ret = 0;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &imx_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-       if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
-               ret = imx_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_PLAYBACK);
-               if (ret)
-                       goto out;
-       }
-
-       if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-               ret = imx_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_CAPTURE);
-               if (ret)
-                       goto out;
-       }
-
-out:
-       return ret;
-}
-EXPORT_SYMBOL_GPL(imx_pcm_new);
-
-void imx_pcm_free(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-
-       for (stream = 0; stream < 2; stream++) {
-               substream = pcm->streams[stream].substream;
-               if (!substream)
-                       continue;
-
-               buf = &substream->dma_buffer;
-               if (!buf->area)
-                       continue;
-
-               dma_free_writecombine(pcm->card->dev, buf->bytes,
-                                     buf->area, buf->addr);
-               buf->area = NULL;
-       }
-}
-EXPORT_SYMBOL_GPL(imx_pcm_free);
-
-static int imx_pcm_probe(struct platform_device *pdev)
-{
-       if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0)
-               return imx_pcm_fiq_init(pdev);
-
-       return imx_pcm_dma_init(pdev);
-}
-
-static int imx_pcm_remove(struct platform_device *pdev)
-{
-       if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0)
-               snd_soc_unregister_platform(&pdev->dev);
-       else
-               imx_pcm_dma_exit(pdev);
-
-       return 0;
-}
-
-static struct platform_device_id imx_pcm_devtype[] = {
-       { .name = "imx-pcm-audio", },
-       { .name = "imx-fiq-pcm-audio", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(platform, imx_pcm_devtype);
-
-static struct platform_driver imx_pcm_driver = {
-       .driver = {
-                       .name = "imx-pcm",
-                       .owner = THIS_MODULE,
-       },
-       .id_table = imx_pcm_devtype,
-       .probe = imx_pcm_probe,
-       .remove = imx_pcm_remove,
-};
-module_platform_driver(imx_pcm_driver);
-
-MODULE_DESCRIPTION("Freescale i.MX PCM driver");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_LICENSE("GPL");
index b7fa0d7..67f656c 100644 (file)
@@ -32,11 +32,6 @@ imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
                dma_data->peripheral_type = IMX_DMATYPE_SSI;
 }
 
-int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
-                    struct vm_area_struct *vma);
-int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
-void imx_pcm_free(struct snd_pcm *pcm);
-
 #ifdef CONFIG_SND_SOC_IMX_PCM_DMA
 int imx_pcm_dma_init(struct platform_device *pdev);
 void imx_pcm_dma_exit(struct platform_device *pdev);
@@ -53,11 +48,16 @@ static inline void imx_pcm_dma_exit(struct platform_device *pdev)
 
 #ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
 int imx_pcm_fiq_init(struct platform_device *pdev);
+void imx_pcm_fiq_exit(struct platform_device *pdev);
 #else
 static inline int imx_pcm_fiq_init(struct platform_device *pdev)
 {
        return -ENODEV;
 }
+
+static inline void imx_pcm_fiq_exit(struct platform_device *pdev)
+{
+}
 #endif
 
 #endif /* _IMX_PCM_H */
index 9584e78..7a8bc12 100644 (file)
@@ -128,28 +128,18 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
                goto fail;
        }
 
-       data->codec_clk = clk_get(&codec_dev->dev, NULL);
-       if (IS_ERR(data->codec_clk)) {
-               /* assuming clock enabled by default */
-               data->codec_clk = NULL;
-               ret = of_property_read_u32(codec_np, "clock-frequency",
-                                       &data->clk_frequency);
-               if (ret) {
-                       dev_err(&codec_dev->dev,
-                               "clock-frequency missing or invalid\n");
-                       goto fail;
-               }
-       } else {
-               data->clk_frequency = clk_get_rate(data->codec_clk);
-               clk_prepare_enable(data->codec_clk);
-       }
+       data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
+       if (IS_ERR(data->codec_clk))
+               goto fail;
+
+       data->clk_frequency = clk_get_rate(data->codec_clk);
 
        data->dai.name = "HiFi";
        data->dai.stream_name = "HiFi";
        data->dai.codec_dai_name = "sgtl5000";
        data->dai.codec_of_node = codec_np;
        data->dai.cpu_of_node = ssi_np;
-       data->dai.platform_name = "imx-pcm-audio";
+       data->dai.platform_of_node = ssi_np;
        data->dai.init = &imx_sgtl5000_dai_init;
        data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
                            SND_SOC_DAIFMT_CBM_CFM;
@@ -157,10 +147,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
        data->card.dev = &pdev->dev;
        ret = snd_soc_of_parse_card_name(&data->card, "model");
        if (ret)
-               goto clk_fail;
+               goto fail;
        ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
        if (ret)
-               goto clk_fail;
+               goto fail;
        data->card.num_links = 1;
        data->card.owner = THIS_MODULE;
        data->card.dai_link = &data->dai;
@@ -170,12 +160,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
        ret = snd_soc_register_card(&data->card);
        if (ret) {
                dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
-               goto clk_fail;
+               goto fail;
        }
 
        platform_set_drvdata(pdev, data);
-clk_fail:
-       clk_put(data->codec_clk);
+       of_node_put(ssi_np);
+       of_node_put(codec_np);
+
+       return 0;
+
 fail:
        if (ssi_np)
                of_node_put(ssi_np);
@@ -189,10 +182,6 @@ static int imx_sgtl5000_remove(struct platform_device *pdev)
 {
        struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
 
-       if (data->codec_clk) {
-               clk_disable_unprepare(data->codec_clk);
-               clk_put(data->codec_clk);
-       }
        snd_soc_unregister_card(&data->card);
 
        return 0;
index c6fa03e..a8362be 100644 (file)
@@ -590,41 +590,19 @@ static int imx_ssi_probe(struct platform_device *pdev)
                goto failed_register;
        }
 
-       ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev_fiq) {
-               ret = -ENOMEM;
-               goto failed_pdev_fiq_alloc;
-       }
-
-       platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
-       ret = platform_device_add(ssi->soc_platform_pdev_fiq);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform device\n");
-               goto failed_pdev_fiq_add;
-       }
+       ret = imx_pcm_fiq_init(pdev);
+       if (ret)
+               goto failed_pcm_fiq;
 
-       ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
-       if (!ssi->soc_platform_pdev) {
-               ret = -ENOMEM;
-               goto failed_pdev_alloc;
-       }
-
-       platform_set_drvdata(ssi->soc_platform_pdev, ssi);
-       ret = platform_device_add(ssi->soc_platform_pdev);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to add platform device\n");
-               goto failed_pdev_add;
-       }
+       ret = imx_pcm_dma_init(pdev);
+       if (ret)
+               goto failed_pcm_dma;
 
        return 0;
 
-failed_pdev_add:
-       platform_device_put(ssi->soc_platform_pdev);
-failed_pdev_alloc:
-       platform_device_del(ssi->soc_platform_pdev_fiq);
-failed_pdev_fiq_add:
-       platform_device_put(ssi->soc_platform_pdev_fiq);
-failed_pdev_fiq_alloc:
+failed_pcm_dma:
+       imx_pcm_fiq_exit(pdev);
+failed_pcm_fiq:
        snd_soc_unregister_component(&pdev->dev);
 failed_register:
        release_mem_region(res->start, resource_size(res));
@@ -639,8 +617,8 @@ static int imx_ssi_remove(struct platform_device *pdev)
        struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        struct imx_ssi *ssi = platform_get_drvdata(pdev);
 
-       platform_device_unregister(ssi->soc_platform_pdev);
-       platform_device_unregister(ssi->soc_platform_pdev_fiq);
+       imx_pcm_dma_exit(pdev);
+       imx_pcm_fiq_exit(pdev);
 
        snd_soc_unregister_component(&pdev->dev);
 
index bb6b3db..d5003ce 100644 (file)
@@ -211,9 +211,6 @@ struct imx_ssi {
        struct imx_dma_data filter_data_rx;
 
        int enabled;
-
-       struct platform_device *soc_platform_pdev;
-       struct platform_device *soc_platform_pdev_fiq;
 };
 
 #endif /* _IMX_SSI_H */
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
new file mode 100644 (file)
index 0000000..52a36a9
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * 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/of_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];
+       struct clk *codec_clk;
+       unsigned int clk_frequency;
+};
+
+struct imx_priv {
+       struct platform_device *pdev;
+};
+static struct imx_priv card_priv;
+
+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 sample_rate = 44100;
+static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
+               struct snd_pcm_hw_params *params)
+{
+       sample_rate = params_rate(params);
+       sample_format = params_format(params);
+
+       return 0;
+}
+
+static 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_dai *codec_dai = card->rtd[0].codec_dai;
+       struct imx_priv *priv = &card_priv;
+       struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
+       struct device *dev = &priv->pdev->dev;
+       unsigned int pll_out;
+       int ret;
+
+       if (dapm->dev != codec_dai->dev)
+               return 0;
+
+       switch (level) {
+       case SND_SOC_BIAS_PREPARE:
+               if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
+                       if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
+                               pll_out = sample_rate * 384;
+                       else
+                               pll_out = 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;
+       }
+
+       dapm->bias_level = level;
+
+       return 0;
+}
+
+static int imx_wm8962_late_probe(struct snd_soc_card *card)
+{
+       struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+       struct imx_priv *priv = &card_priv;
+       struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
+       struct device *dev = &priv->pdev->dev;
+       int ret;
+
+       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 imx_priv *priv = &card_priv;
+       struct i2c_client *codec_dev;
+       struct imx_wm8962_data *data;
+       int int_port, ext_port;
+       int ret;
+
+       priv->pdev = pdev;
+
+       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;
+       }
+       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->driver) {
+               dev_err(&pdev->dev, "failed to find codec platform device\n");
+               return -EINVAL;
+       }
+
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       if (!data) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
+       if (IS_ERR(data->codec_clk)) {
+               ret = PTR_ERR(data->codec_clk);
+               dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
+               goto fail;
+       }
+
+       data->clk_frequency = clk_get_rate(data->codec_clk);
+       ret = clk_prepare_enable(data->codec_clk);
+       if (ret) {
+               dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
+               goto fail;
+       }
+
+       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 clk_fail;
+       ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
+       if (ret)
+               goto clk_fail;
+       data->card.num_links = 1;
+       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;
+
+       ret = snd_soc_register_card(&data->card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+               goto clk_fail;
+       }
+
+       platform_set_drvdata(pdev, data);
+       of_node_put(ssi_np);
+       of_node_put(codec_np);
+
+       return 0;
+
+clk_fail:
+       if (!IS_ERR(data->codec_clk))
+               clk_disable_unprepare(data->codec_clk);
+fail:
+       if (ssi_np)
+               of_node_put(ssi_np);
+       if (codec_np)
+               of_node_put(codec_np);
+
+       return ret;
+}
+
+static int imx_wm8962_remove(struct platform_device *pdev)
+{
+       struct imx_wm8962_data *data = platform_get_drvdata(pdev);
+
+       if (!IS_ERR(data->codec_clk))
+               clk_disable_unprepare(data->codec_clk);
+       snd_soc_unregister_card(&data->card);
+
+       return 0;
+}
+
+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",
+               .owner = THIS_MODULE,
+               .of_match_table = imx_wm8962_dt_ids,
+       },
+       .probe = imx_wm8962_probe,
+       .remove = imx_wm8962_remove,
+};
+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 3d10741..f4c3bda 100644 (file)
@@ -161,7 +161,7 @@ static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
        .name           = "tlv320aic32x4",
        .stream_name    = "TLV320AIC32X4",
        .codec_dai_name = "tlv320aic32x4-hifi",
-       .platform_name  = "imx-pcm-audio.0",
+       .platform_name  = "imx-ssi.0",
        .codec_name     = "tlv320aic32x4.0-0018",
        .cpu_dai_name   = "imx-ssi.0",
        .ops            = &mx27vis_aic32x4_snd_ops,
index f8da6dd..ae403c2 100644 (file)
@@ -33,7 +33,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
                .codec_dai_name         = "wm9712-hifi",
                .codec_name     = "wm9712-codec",
                .cpu_dai_name   = "imx-ssi.0",
-               .platform_name  = "imx-fiq-pcm-audio.0",
+               .platform_name  = "imx-ssi.0",
                .ops            = &imx_phycore_hifi_ops,
        },
 };
index fe54a69..fce6325 100644 (file)
@@ -245,7 +245,7 @@ static struct snd_soc_dai_link wm1133_ev1_dai = {
        .stream_name = "Audio",
        .cpu_dai_name = "imx-ssi.0",
        .codec_dai_name = "wm8350-hifi",
-       .platform_name = "imx-fiq-pcm-audio.0",
+       .platform_name = "imx-ssi.0",
        .codec_name = "wm8350-codec.0-0x1a",
        .init = wm1133_ev1_init,
        .ops = &wm1133_ev1_ops,
index 9a12644..4c849a4 100644 (file)
@@ -118,7 +118,7 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
        ctrl |= JZ_AIC_CTRL_FLUSH;
        jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
 
-       clk_enable(i2s->clk_i2s);
+       clk_prepare_enable(i2s->clk_i2s);
 
        conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
        conf |= JZ_AIC_CONF_ENABLE;
@@ -140,7 +140,7 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
        conf &= ~JZ_AIC_CONF_ENABLE;
        jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
 
-       clk_disable(i2s->clk_i2s);
+       clk_disable_unprepare(i2s->clk_i2s);
 }
 
 static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -314,10 +314,10 @@ static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
                conf &= ~JZ_AIC_CONF_ENABLE;
                jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
 
-               clk_disable(i2s->clk_i2s);
+               clk_disable_unprepare(i2s->clk_i2s);
        }
 
-       clk_disable(i2s->clk_aic);
+       clk_disable_unprepare(i2s->clk_aic);
 
        return 0;
 }
@@ -327,10 +327,10 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai)
        struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
        uint32_t conf;
 
-       clk_enable(i2s->clk_aic);
+       clk_prepare_enable(i2s->clk_aic);
 
        if (dai->active) {
-               clk_enable(i2s->clk_i2s);
+               clk_prepare_enable(i2s->clk_i2s);
 
                conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
                conf |= JZ_AIC_CONF_ENABLE;
@@ -368,7 +368,7 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
        struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
        uint32_t conf;
 
-       clk_enable(i2s->clk_aic);
+       clk_prepare_enable(i2s->clk_aic);
 
        jz4740_i2c_init_pcm_config(i2s);
 
@@ -388,7 +388,7 @@ static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai)
 {
        struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 
-       clk_disable(i2s->clk_aic);
+       clk_disable_unprepare(i2s->clk_aic);
        return 0;
 }
 
@@ -509,7 +509,6 @@ static int jz4740_i2s_dev_remove(struct platform_device *pdev)
        iounmap(i2s->base);
        release_mem_region(i2s->mem->start, resource_size(i2s->mem));
 
-       platform_set_drvdata(pdev, NULL);
        kfree(i2s);
 
        return 0;
index d3d4bdc..a9f1453 100644 (file)
@@ -289,7 +289,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
        return count;
 }
 
-struct snd_pcm_ops kirkwood_dma_ops = {
+static struct snd_pcm_ops kirkwood_dma_ops = {
        .open =         kirkwood_dma_open,
        .close =        kirkwood_dma_close,
        .ioctl =        snd_pcm_lib_ioctl,
index b41fffc..b16abbb 100644 (file)
@@ -49,24 +49,8 @@ static const struct snd_pcm_hardware snd_mxs_hardware = {
        .fifo_size              = 32,
 };
 
-static bool filter(struct dma_chan *chan, void *param)
-{
-       struct mxs_pcm_dma_params *dma_params = param;
-
-       if (!mxs_dma_is_apbx(chan))
-               return false;
-
-       if (chan->chan_id != dma_params->chan_num)
-               return false;
-
-       chan->private = &dma_params->dma_data;
-
-       return true;
-}
-
 static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = {
        .pcm_hardware = &snd_mxs_hardware,
-       .compat_filter_fn = filter,
        .prealloc_buffer_size = 64 * 1024,
 };
 
@@ -74,8 +58,6 @@ int mxs_pcm_platform_register(struct device *dev)
 {
        return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config,
                SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
-               SND_DMAENGINE_PCM_FLAG_NO_DT |
-               SND_DMAENGINE_PCM_FLAG_COMPAT |
                SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX);
 }
 EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);
index 3aa918f..bc685b6 100644 (file)
 #ifndef _MXS_PCM_H
 #define _MXS_PCM_H
 
-#include <linux/fsl/mxs-dma.h>
-
-struct mxs_pcm_dma_params {
-       struct mxs_dma_data dma_data;
-       int chan_num;
-};
-
 int mxs_pcm_platform_register(struct device *dev);
 void mxs_pcm_platform_unregister(struct device *dev);
 
index d31dc52..49d8700 100644 (file)
@@ -26,8 +26,6 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/time.h>
-#include <linux/fsl/mxs-dma.h>
-#include <linux/pinctrl/consumer.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -605,8 +603,6 @@ static int mxs_saif_dai_probe(struct snd_soc_dai *dai)
        struct mxs_saif *saif = dev_get_drvdata(dai->dev);
 
        snd_soc_dai_set_drvdata(dai, saif);
-       dai->playback_dma_data = &saif->dma_param;
-       dai->capture_dma_data = &saif->dma_param;
 
        return 0;
 }
@@ -665,9 +661,8 @@ static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
 static int mxs_saif_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
-       struct resource *iores, *dmares;
+       struct resource *iores;
        struct mxs_saif *saif;
-       struct pinctrl *pinctrl;
        int ret = 0;
        struct device_node *master;
 
@@ -707,12 +702,6 @@ static int mxs_saif_probe(struct platform_device *pdev)
 
        mxs_saif[saif->id] = saif;
 
-       pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-       if (IS_ERR(pinctrl)) {
-               ret = PTR_ERR(pinctrl);
-               return ret;
-       }
-
        saif->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(saif->clk)) {
                ret = PTR_ERR(saif->clk);
@@ -727,22 +716,6 @@ static int mxs_saif_probe(struct platform_device *pdev)
        if (IS_ERR(saif->base))
                return PTR_ERR(saif->base);
 
-       dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!dmares) {
-               /*
-                * TODO: This is a temporary solution and should be changed
-                * to use generic DMA binding later when the helplers get in.
-                */
-               ret = of_property_read_u32(np, "fsl,saif-dma-channel",
-                                          &saif->dma_param.chan_num);
-               if (ret) {
-                       dev_err(&pdev->dev, "failed to get dma channel\n");
-                       return ret;
-               }
-       } else {
-               saif->dma_param.chan_num = dmares->start;
-       }
-
        saif->irq = platform_get_irq(pdev, 0);
        if (saif->irq < 0) {
                ret = saif->irq;
@@ -759,14 +732,6 @@ static int mxs_saif_probe(struct platform_device *pdev)
                return ret;
        }
 
-       saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1);
-       if (saif->dma_param.dma_data.chan_irq < 0) {
-               ret = saif->dma_param.dma_data.chan_irq;
-               dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
-                       ret);
-               return ret;
-       }
-
        platform_set_drvdata(pdev, saif);
 
        ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component,
index 3cb342e..53eaa4b 100644 (file)
@@ -117,7 +117,6 @@ struct mxs_saif {
        unsigned int mclk_in_use;
        void __iomem *base;
        int irq;
-       struct mxs_pcm_dma_params dma_param;
        unsigned int id;
        unsigned int master_id;
        unsigned int cur_rate;
index b1d9b5e..1b134d7 100644 (file)
@@ -90,17 +90,11 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
                .name           = "HiFi Tx",
                .stream_name    = "HiFi Playback",
                .codec_dai_name = "sgtl5000",
-               .codec_name     = "sgtl5000.0-000a",
-               .cpu_dai_name   = "mxs-saif.0",
-               .platform_name  = "mxs-saif.0",
                .ops            = &mxs_sgtl5000_hifi_ops,
        }, {
                .name           = "HiFi Rx",
                .stream_name    = "HiFi Capture",
                .codec_dai_name = "sgtl5000",
-               .codec_name     = "sgtl5000.0-000a",
-               .cpu_dai_name   = "mxs-saif.1",
-               .platform_name  = "mxs-saif.1",
                .ops            = &mxs_sgtl5000_hifi_ops,
        },
 };
@@ -116,7 +110,7 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct device_node *saif_np[2], *codec_np;
-       int i, ret = 0;
+       int i;
 
        if (!np)
                return 1; /* no device tree */
@@ -142,7 +136,7 @@ static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
        of_node_put(saif_np[0]);
        of_node_put(saif_np[1]);
 
-       return ret;
+       return 0;
 }
 
 static int mxs_sgtl5000_probe(struct platform_device *pdev)
index 2b22594..a725905 100644 (file)
@@ -26,7 +26,6 @@ obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
 obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
 obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
 obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
 obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
index d4eaa92..7e66e9c 100644 (file)
@@ -35,7 +35,7 @@ static struct snd_soc_dai_link omap_hdmi_dai = {
        .cpu_dai_name = "omap-hdmi-audio-dai",
        .platform_name = "omap-pcm-audio",
        .codec_name = "hdmi-audio-codec",
-       .codec_dai_name = "omap-hdmi-hifi",
+       .codec_dai_name = "hdmi-hifi",
 };
 
 static struct snd_soc_card snd_soc_omap_hdmi = {
index eadbfb6..7483efb 100644 (file)
@@ -814,8 +814,6 @@ static int asoc_mcbsp_remove(struct platform_device *pdev)
 
        clk_put(mcbsp->fclk);
 
-       platform_set_drvdata(pdev, NULL);
-
        return 0;
 }
 
index 4d2e46f..b358094 100644 (file)
@@ -130,26 +130,6 @@ config SND_PXA2XX_SOC_PALM27X
          Say Y if you want to add support for SoC audio on
          Palm T|X, T5, E2 or LifeDrive handheld computer.
 
-config SND_SOC_SAARB
-       tristate "SoC Audio support for Marvell Saarb"
-       depends on SND_PXA2XX_SOC && MACH_SAARB
-       select MFD_88PM860X
-       select SND_PXA_SOC_SSP
-       select SND_SOC_88PM860X
-       help
-         Say Y if you want to add support for SoC audio on the
-         Marvell Saarb reference platform.
-
-config SND_SOC_TAVOREVB3
-       tristate "SoC Audio support for Marvell Tavor EVB3"
-       depends on SND_PXA2XX_SOC && MACH_TAVOREVB3
-       select MFD_88PM860X
-       select SND_PXA_SOC_SSP
-       select SND_SOC_88PM860X
-       help
-         Say Y if you want to add support for SoC audio on the
-         Marvell Saarb reference platform.
-
 config SND_PXA910_SOC
        tristate "SoC Audio for Marvell PXA910 chip"
        depends on ARCH_MMP && SND
index d8a265d..2cff67b 100644 (file)
@@ -23,8 +23,6 @@ snd-soc-e800-objs := e800_wm9712.o
 snd-soc-spitz-objs := spitz.o
 snd-soc-em-x270-objs := em-x270.o
 snd-soc-palm27x-objs := palm27x.o
-snd-soc-saarb-objs := saarb.o
-snd-soc-tavorevb3-objs := tavorevb3.o
 snd-soc-zylonite-objs := zylonite.o
 snd-soc-hx4700-objs := hx4700.o
 snd-soc-magician-objs := magician.o
@@ -48,8 +46,6 @@ obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
 obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
 obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
 obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
-obj-$(CONFIG_SND_SOC_SAARB) += snd-soc-saarb.o
-obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o
 obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
 obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
 obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
index 3499300..5d57e07 100644 (file)
@@ -147,7 +147,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
                vma->vm_end - vma->vm_start, vma->vm_page_prot);
 }
 
-struct snd_pcm_ops mmp_pcm_ops = {
+static struct snd_pcm_ops mmp_pcm_ops = {
        .open           = mmp_pcm_open,
        .close          = snd_dmaengine_pcm_close_release_chan,
        .ioctl          = snd_pcm_lib_ioctl,
@@ -208,7 +208,7 @@ static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
        return 0;
 }
 
-int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd)
+static int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_pcm_substream *substream;
        struct snd_pcm *pcm = rtd->pcm;
@@ -229,7 +229,7 @@ err:
        return ret;
 }
 
-struct snd_soc_platform_driver mmp_soc_platform = {
+static struct snd_soc_platform_driver mmp_soc_platform = {
        .ops            = &mmp_pcm_ops,
        .pcm_new        = mmp_pcm_new,
        .pcm_free       = mmp_pcm_free_dma_buffers,
index a647799..62142ce 100644 (file)
@@ -388,7 +388,7 @@ static struct snd_soc_dai_ops mmp_sspa_dai_ops = {
        .set_fmt        = mmp_sspa_set_dai_fmt,
 };
 
-struct snd_soc_dai_driver mmp_sspa_dai = {
+static struct snd_soc_dai_driver mmp_sspa_dai = {
        .probe = mmp_sspa_probe,
        .playback = {
                .channels_min = 1,
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
deleted file mode 100644 (file)
index c34146b..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * saarb.c -- SoC audio for saarb
- *
- * Copyright (C) 2010 Marvell International Ltd.
- *     Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/88pm860x-codec.h"
-#include "pxa-ssp.h"
-
-static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd);
-
-static struct platform_device *saarb_snd_device;
-
-static struct snd_soc_jack hs_jack, mic_jack;
-
-static struct snd_soc_jack_pin hs_jack_pins[] = {
-       { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
-};
-
-static struct snd_soc_jack_pin mic_jack_pins[] = {
-       { .pin = "Headset Mic 2",       .mask = SND_JACK_MICROPHONE, },
-};
-
-/* saarb machine dapm widgets */
-static const struct snd_soc_dapm_widget saarb_dapm_widgets[] = {
-       SND_SOC_DAPM_HP("Headphone Stereophone", NULL),
-       SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
-       SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
-       SND_SOC_DAPM_SPK("Ext Speaker", NULL),
-       SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
-       SND_SOC_DAPM_MIC("Headset Mic", NULL),
-       SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
-};
-
-/* saarb machine audio map */
-static const struct snd_soc_dapm_route saarb_audio_map[] = {
-       {"Headset Stereophone", NULL, "HS1"},
-       {"Headset Stereophone", NULL, "HS2"},
-
-       {"Ext Speaker", NULL, "LSP"},
-       {"Ext Speaker", NULL, "LSN"},
-
-       {"Lineout Out 1", NULL, "LINEOUT1"},
-       {"Lineout Out 2", NULL, "LINEOUT2"},
-
-       {"MIC1P", NULL, "Mic1 Bias"},
-       {"MIC1N", NULL, "Mic1 Bias"},
-       {"Mic1 Bias", NULL, "Ext Mic 1"},
-
-       {"MIC2P", NULL, "Mic1 Bias"},
-       {"MIC2N", NULL, "Mic1 Bias"},
-       {"Mic1 Bias", NULL, "Headset Mic 2"},
-
-       {"MIC3P", NULL, "Mic3 Bias"},
-       {"MIC3N", NULL, "Mic3 Bias"},
-       {"Mic3 Bias", NULL, "Ext Mic 3"},
-};
-
-static int saarb_i2s_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       int width = snd_pcm_format_physical_width(params_format(params));
-       int ret;
-
-       ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
-                                    PM860X_CLK_DIR_OUT);
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
-
-       return ret;
-}
-
-static struct snd_soc_ops saarb_i2s_ops = {
-       .hw_params      = saarb_i2s_hw_params,
-};
-
-static struct snd_soc_dai_link saarb_dai[] = {
-       {
-               .name           = "88PM860x I2S",
-               .stream_name    = "I2S Audio",
-               .cpu_dai_name   = "pxa-ssp-dai.1",
-               .codec_dai_name = "88pm860x-i2s",
-               .platform_name  = "pxa-pcm-audio",
-               .codec_name     = "88pm860x-codec",
-               .init           = saarb_pm860x_init,
-               .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-                                 SND_SOC_DAIFMT_CBM_CFM,
-               .ops            = &saarb_i2s_ops,
-       },
-};
-
-static struct snd_soc_card snd_soc_card_saarb = {
-       .name = "Saarb",
-       .owner = THIS_MODULE,
-       .dai_link = saarb_dai,
-       .num_links = ARRAY_SIZE(saarb_dai),
-
-       .dapm_widgets = saarb_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(saarb_dapm_widgets),
-       .dapm_routes = saarb_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(saarb_audio_map),
-};
-
-static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       /* connected pins */
-       snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
-       snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
-       snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
-       snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
-       snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
-
-       /* Headset jack detection */
-       snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
-                       | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
-                       &hs_jack);
-       snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
-                             hs_jack_pins);
-       snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
-                        &mic_jack);
-       snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
-                             mic_jack_pins);
-
-       /* headphone, microphone detection & headset short detection */
-       pm860x_hs_jack_detect(codec, &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);
-       return 0;
-}
-
-static int __init saarb_init(void)
-{
-       int ret;
-
-       if (!machine_is_saarb())
-               return -ENODEV;
-       saarb_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!saarb_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(saarb_snd_device, &snd_soc_card_saarb);
-
-       ret = platform_device_add(saarb_snd_device);
-       if (ret)
-               platform_device_put(saarb_snd_device);
-
-       return ret;
-}
-
-static void __exit saarb_exit(void)
-{
-       platform_device_unregister(saarb_snd_device);
-}
-
-module_init(saarb_init);
-module_exit(saarb_exit);
-
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_DESCRIPTION("ALSA SoC 88PM860x Saarb");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
deleted file mode 100644 (file)
index 8b5ab8f..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * tavorevb3.c -- SoC audio for Tavor EVB3
- *
- * Copyright (C) 2010 Marvell International Ltd.
- *     Haojian Zhuang <haojian.zhuang@marvell.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-
-#include "../codecs/88pm860x-codec.h"
-#include "pxa-ssp.h"
-
-static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd);
-
-static struct platform_device *evb3_snd_device;
-
-static struct snd_soc_jack hs_jack, mic_jack;
-
-static struct snd_soc_jack_pin hs_jack_pins[] = {
-       { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
-};
-
-static struct snd_soc_jack_pin mic_jack_pins[] = {
-       { .pin = "Headset Mic 2",       .mask = SND_JACK_MICROPHONE, },
-};
-
-/* tavorevb3 machine dapm widgets */
-static const struct snd_soc_dapm_widget evb3_dapm_widgets[] = {
-       SND_SOC_DAPM_HP("Headset Stereophone", NULL),
-       SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
-       SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
-       SND_SOC_DAPM_SPK("Ext Speaker", NULL),
-       SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
-       SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
-       SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
-};
-
-/* tavorevb3 machine audio map */
-static const struct snd_soc_dapm_route evb3_audio_map[] = {
-       {"Headset Stereophone", NULL, "HS1"},
-       {"Headset Stereophone", NULL, "HS2"},
-
-       {"Ext Speaker", NULL, "LSP"},
-       {"Ext Speaker", NULL, "LSN"},
-
-       {"Lineout Out 1", NULL, "LINEOUT1"},
-       {"Lineout Out 2", NULL, "LINEOUT2"},
-
-       {"MIC1P", NULL, "Mic1 Bias"},
-       {"MIC1N", NULL, "Mic1 Bias"},
-       {"Mic1 Bias", NULL, "Ext Mic 1"},
-
-       {"MIC2P", NULL, "Mic1 Bias"},
-       {"MIC2N", NULL, "Mic1 Bias"},
-       {"Mic1 Bias", NULL, "Headset Mic 2"},
-
-       {"MIC3P", NULL, "Mic3 Bias"},
-       {"MIC3N", NULL, "Mic3 Bias"},
-       {"Mic3 Bias", NULL, "Ext Mic 3"},
-};
-
-static int evb3_i2s_hw_params(struct snd_pcm_substream *substream,
-                             struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       int width = snd_pcm_format_physical_width(params_format(params));
-       int ret;
-
-       ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
-                                    PM860X_CLK_DIR_OUT);
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
-       if (ret < 0)
-               return ret;
-
-       ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
-       return ret;
-}
-
-static struct snd_soc_ops evb3_i2s_ops = {
-       .hw_params      = evb3_i2s_hw_params,
-};
-
-static struct snd_soc_dai_link evb3_dai[] = {
-       {
-               .name           = "88PM860x I2S",
-               .stream_name    = "I2S Audio",
-               .cpu_dai_name   = "pxa-ssp-dai.1",
-               .codec_dai_name = "88pm860x-i2s",
-               .platform_name  = "pxa-pcm-audio",
-               .codec_name     = "88pm860x-codec",
-               .init           = evb3_pm860x_init,
-               .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-                                 SND_SOC_DAIFMT_CBM_CFM,
-               .ops            = &evb3_i2s_ops,
-       },
-};
-
-static struct snd_soc_card snd_soc_card_evb3 = {
-       .name = "Tavor EVB3",
-       .owner = THIS_MODULE,
-       .dai_link = evb3_dai,
-       .num_links = ARRAY_SIZE(evb3_dai),
-
-       .dapm_widgets = evb3_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(evb3_dapm_widgets),
-       .dapm_routes = evb3_audio_map,
-       .num_dapm_routes = ARRAY_SIZE(evb3_audio_map),
-};
-
-static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       /* connected pins */
-       snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
-       snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
-       snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
-       snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
-       snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
-
-       /* Headset jack detection */
-       snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
-                       | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
-                       &hs_jack);
-       snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
-                             hs_jack_pins);
-       snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
-                        &mic_jack);
-       snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
-                             mic_jack_pins);
-
-       /* headphone, microphone detection & headset short detection */
-       pm860x_hs_jack_detect(codec, &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);
-       return 0;
-}
-
-static int __init tavorevb3_init(void)
-{
-       int ret;
-
-       if (!machine_is_tavorevb3())
-               return -ENODEV;
-       evb3_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!evb3_snd_device)
-               return -ENOMEM;
-
-       platform_set_drvdata(evb3_snd_device, &snd_soc_card_evb3);
-
-       ret = platform_device_add(evb3_snd_device);
-       if (ret)
-               platform_device_put(evb3_snd_device);
-
-       return ret;
-}
-
-static void __exit tavorevb3_exit(void)
-{
-       platform_device_unregister(evb3_snd_device);
-}
-
-module_init(tavorevb3_init);
-module_exit(tavorevb3_exit);
-
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_DESCRIPTION("ALSA SoC 88PM860x Tavor EVB3");
-MODULE_LICENSE("GPL");
index ceb6566..db8aadf 100644 (file)
@@ -256,7 +256,6 @@ static struct snd_soc_card zylonite = {
        .resume_pre = &zylonite_resume_pre,
        .dai_link = zylonite_dai,
        .num_links = ARRAY_SIZE(zylonite_dai),
-       .owner = THIS_MODULE,
 };
 
 static struct platform_device *zylonite_snd_ac97_device;
index 475fb0d..ae0ea87 100644 (file)
@@ -39,7 +39,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753
        depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
        select SND_S3C24XX_I2S
        select SND_SOC_WM8753
-       select SND_SOC_DFBMCS320
+       select SND_SOC_SCO
        help
          Say Y here to enable audio support for the Openmoko Neo1973
          Smartphones.
index ceed466..29e2468 100644 (file)
@@ -350,8 +350,16 @@ static struct snd_soc_codec_conf bells_codec_conf[] = {
        },
 };
 
+static struct snd_soc_dapm_widget bells_widgets[] = {
+       SND_SOC_DAPM_MIC("DMIC", NULL),
+};
+
 static struct snd_soc_dapm_route bells_routes[] = {
        { "Sub CLK_SYS", NULL, "OPCLK" },
+
+       { "DMIC", NULL, "MICBIAS2" },
+       { "IN2L", NULL, "DMIC" },
+       { "IN2R", NULL, "DMIC" },
 };
 
 static struct snd_soc_card bells_cards[] = {
@@ -365,6 +373,8 @@ static struct snd_soc_card bells_cards[] = {
 
                .late_probe = bells_late_probe,
 
+               .dapm_widgets = bells_widgets,
+               .num_dapm_widgets = ARRAY_SIZE(bells_widgets),
                .dapm_routes = bells_routes,
                .num_dapm_routes = ARRAY_SIZE(bells_routes),
 
@@ -383,6 +393,8 @@ static struct snd_soc_card bells_cards[] = {
 
                .late_probe = bells_late_probe,
 
+               .dapm_widgets = bells_widgets,
+               .num_dapm_widgets = ARRAY_SIZE(bells_widgets),
                .dapm_routes = bells_routes,
                .num_dapm_routes = ARRAY_SIZE(bells_routes),
 
@@ -401,6 +413,8 @@ static struct snd_soc_card bells_cards[] = {
 
                .late_probe = bells_late_probe,
 
+               .dapm_widgets = bells_widgets,
+               .num_dapm_widgets = ARRAY_SIZE(bells_widgets),
                .dapm_routes = bells_routes,
                .num_dapm_routes = ARRAY_SIZE(bells_routes),
 
index e591c38..807db41 100644 (file)
@@ -373,7 +373,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
 { /* Voice via BT */
        .name = "Bluetooth",
        .stream_name = "Voice",
-       .cpu_dai_name = "dfbmcs320-pcm",
+       .cpu_dai_name = "bt-sco-pcm",
        .codec_dai_name = "wm8753-voice",
        .codec_name = "wm8753.0-001a",
        .ops = &neo1973_voice_ops,
index e43bd42..23a9204 100644 (file)
@@ -176,7 +176,6 @@ static int snd_smdk_probe(struct platform_device *pdev)
 static int snd_smdk_remove(struct platform_device *pdev)
 {
        snd_soc_unregister_card(&smdk_pcm);
-       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
index 3688a32..0c84ca0 100644 (file)
@@ -146,7 +146,6 @@ static int snd_smdk_probe(struct platform_device *pdev)
 static int snd_smdk_remove(struct platform_device *pdev)
 {
        snd_soc_unregister_card(&smdk_pcm);
-       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
index f830c41..3039026 100644 (file)
@@ -276,7 +276,7 @@ struct fsi_stream_handler {
        int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev);
        int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
        int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
-       void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
+       int (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
                           int enable);
 };
 #define fsi_stream_handler_call(io, func, args...)     \
@@ -1188,7 +1188,7 @@ static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
                                  samples);
 }
 
-static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
+static int fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
                               int enable)
 {
        struct fsi_master *master = fsi_get_master(fsi);
@@ -1201,6 +1201,8 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
 
        if (fsi_is_clk_master(fsi))
                fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+
+       return 0;
 }
 
 static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io)
@@ -1409,7 +1411,7 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
        return 0;
 }
 
-static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
+static int fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
                                 int start)
 {
        struct fsi_master *master = fsi_get_master(fsi);
@@ -1422,6 +1424,8 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
 
        if (fsi_is_clk_master(fsi))
                fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+
+       return 0;
 }
 
 static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
index 3853f7e..06a8000 100644 (file)
@@ -220,8 +220,12 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
                        goto err;
        }
 
-       snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
-                               SND_SOC_DAPM_STREAM_START);
+       if (cstream->direction == SND_COMPRESS_PLAYBACK)
+               snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
+                                       SND_SOC_DAPM_STREAM_START);
+       else
+               snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
+                                       SND_SOC_DAPM_STREAM_START);
 
        /* cancel any delayed stream shutdown that is pending */
        rtd->pop_wait = 0;
index d56bbea..4489c5b 100644 (file)
@@ -272,8 +272,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
        codec->debugfs_codec_root = debugfs_create_dir(codec->name,
                                                       debugfs_card_root);
        if (!codec->debugfs_codec_root) {
-               dev_warn(codec->dev, "ASoC: Failed to create codec debugfs"
-                       " directory\n");
+               dev_warn(codec->dev,
+                       "ASoC: Failed to create codec debugfs directory\n");
                return;
        }
 
@@ -286,8 +286,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
                                                 codec->debugfs_codec_root,
                                                 codec, &codec_reg_fops);
        if (!codec->debugfs_reg)
-               dev_warn(codec->dev, "ASoC: Failed to create codec register"
-                       " debugfs file\n");
+               dev_warn(codec->dev,
+                       "ASoC: Failed to create codec register debugfs file\n");
 
        snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
 }
@@ -631,8 +631,7 @@ int snd_soc_suspend(struct device *dev)
                                 */
                                if (codec->dapm.idle_bias_off) {
                                        dev_dbg(codec->dev,
-                                               "ASoC: idle_bias_off CODEC on"
-                                               " over suspend\n");
+                                               "ASoC: idle_bias_off CODEC on over suspend\n");
                                        break;
                                }
                        case SND_SOC_BIAS_OFF:
@@ -643,8 +642,8 @@ int snd_soc_suspend(struct device *dev)
                                        regcache_mark_dirty(codec->control_data);
                                break;
                        default:
-                               dev_dbg(codec->dev, "ASoC: CODEC is on"
-                                       " over suspend\n");
+                               dev_dbg(codec->dev,
+                                       "ASoC: CODEC is on over suspend\n");
                                break;
                        }
                }
@@ -713,8 +712,8 @@ static void soc_resume_deferred(struct work_struct *work)
                                codec->suspended = 0;
                                break;
                        default:
-                               dev_dbg(codec->dev, "ASoC: CODEC was on over"
-                                       " suspend\n");
+                               dev_dbg(codec->dev,
+                                       "ASoC: CODEC was on over suspend\n");
                                break;
                        }
                }
@@ -1110,8 +1109,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
                }
                WARN(codec->dapm.idle_bias_off &&
                        codec->dapm.bias_level != SND_SOC_BIAS_OFF,
-                       "codec %s can not start from non-off bias"
-                       " with idle_bias_off==1\n", codec->name);
+                       "codec %s can not start from non-off bias with idle_bias_off==1\n",
+                       codec->name);
        }
 
        /* If the driver didn't set I/O up try regmap */
@@ -1582,8 +1581,9 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
                codec->compress_type = compress_type;
        ret = snd_soc_cache_init(codec);
        if (ret < 0) {
-               dev_err(codec->dev, "ASoC: Failed to set cache compression"
-                       " type: %d\n", ret);
+               dev_err(codec->dev,
+                       "ASoC: Failed to set cache compression type: %d\n",
+                       ret);
                return ret;
        }
        codec->cache_init = 1;
@@ -1639,8 +1639,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
        ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
                        card->owner, 0, &card->snd_card);
        if (ret < 0) {
-               dev_err(card->dev, "ASoC: can't create sound card for"
-                       " card %s: %d\n", card->name, ret);
+               dev_err(card->dev,
+                       "ASoC: can't create sound card for card %s: %d\n",
+                       card->name, ret);
                goto base_error;
        }
        card->snd_card->dev = card->dev;
@@ -1815,8 +1816,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
        for (i = 0; i < card->num_rtd; i++) {
                ret = soc_register_ac97_dai_link(&card->rtd[i]);
                if (ret < 0) {
-                       dev_err(card->dev, "ASoC: failed to register AC97:"
-                               " %d\n", ret);
+                       dev_err(card->dev,
+                               "ASoC: failed to register AC97: %d\n", ret);
                        while (--i >= 0)
                                soc_unregister_ac97_dai_link(card->rtd[i].codec);
                        goto probe_aux_dev_err;
@@ -2219,29 +2220,6 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
 EXPORT_SYMBOL_GPL(snd_soc_test_bits);
 
 /**
- * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
- * @substream: the pcm substream
- * @hw: the hardware parameters
- *
- * Sets the substream runtime hardware parameters.
- */
-int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
-       const struct snd_pcm_hardware *hw)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       runtime->hw.info = hw->info;
-       runtime->hw.formats = hw->formats;
-       runtime->hw.period_bytes_min = hw->period_bytes_min;
-       runtime->hw.period_bytes_max = hw->period_bytes_max;
-       runtime->hw.periods_min = hw->periods_min;
-       runtime->hw.periods_max = hw->periods_max;
-       runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
-       runtime->hw.fifo_size = hw->fifo_size;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
-
-/**
  * snd_soc_cnew - create new control
  * @_template: control template
  * @data: control private data
@@ -2259,7 +2237,6 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
        struct snd_kcontrol_new template;
        struct snd_kcontrol *kcontrol;
        char *name = NULL;
-       int name_len;
 
        memcpy(&template, _template, sizeof(template));
        template.index = 0;
@@ -2268,13 +2245,10 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
                long_name = template.name;
 
        if (prefix) {
-               name_len = strlen(long_name) + strlen(prefix) + 2;
-               name = kmalloc(name_len, GFP_KERNEL);
+               name = kasprintf(GFP_KERNEL, "%s %s", prefix, long_name);
                if (!name)
                        return NULL;
 
-               snprintf(name, name_len, "%s %s", prefix, long_name);
-
                template.name = name;
        } else {
                template.name = long_name;
@@ -3586,14 +3560,16 @@ int snd_soc_register_card(struct snd_soc_card *card)
                 * not both or neither.
                 */
                if (!!link->codec_name == !!link->codec_of_node) {
-                       dev_err(card->dev, "ASoC: Neither/both codec"
-                               " name/of_node are set for %s\n", link->name);
+                       dev_err(card->dev,
+                               "ASoC: Neither/both codec name/of_node are set for %s\n",
+                               link->name);
                        return -EINVAL;
                }
                /* Codec DAI name must be specified */
                if (!link->codec_dai_name) {
-                       dev_err(card->dev, "ASoC: codec_dai_name not"
-                               " set for %s\n", link->name);
+                       dev_err(card->dev,
+                               "ASoC: codec_dai_name not set for %s\n",
+                               link->name);
                        return -EINVAL;
                }
 
@@ -3602,8 +3578,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
                 * can be left unspecified, and a dummy platform will be used.
                 */
                if (link->platform_name && link->platform_of_node) {
-                       dev_err(card->dev, "ASoC: Both platform name/of_node"
-                               " are set for %s\n", link->name);
+                       dev_err(card->dev,
+                               "ASoC: Both platform name/of_node are set for %s\n",
+                               link->name);
                        return -EINVAL;
                }
 
@@ -3613,8 +3590,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
                 * name alone..
                 */
                if (link->cpu_name && link->cpu_of_node) {
-                       dev_err(card->dev, "ASoC: Neither/both "
-                               "cpu name/of_node are set for %s\n",link->name);
+                       dev_err(card->dev,
+                               "ASoC: Neither/both cpu name/of_node are set for %s\n",
+                               link->name);
                        return -EINVAL;
                }
                /*
@@ -3623,8 +3601,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
                 */
                if (!link->cpu_dai_name &&
                    !(link->cpu_name || link->cpu_of_node)) {
-                       dev_err(card->dev, "ASoC: Neither cpu_dai_name nor "
-                               "cpu_name/of_node are set for %s\n", link->name);
+                       dev_err(card->dev,
+                               "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
+                               link->name);
                        return -EINVAL;
                }
        }
@@ -3728,8 +3707,9 @@ static inline char *fmt_multiple_name(struct device *dev,
                struct snd_soc_dai_driver *dai_drv)
 {
        if (dai_drv->name == NULL) {
-               dev_err(dev, "ASoC: error - multiple DAI %s registered with"
-                               " no name\n", dev_name(dev));
+               dev_err(dev,
+                       "ASoC: error - multiple DAI %s registered with no name\n",
+                       dev_name(dev));
                return NULL;
        }
 
@@ -3859,8 +3839,9 @@ static int snd_soc_register_dais(struct device *dev,
 
                list_for_each_entry(codec, &codec_list, list) {
                        if (codec->dev == dev) {
-                               dev_dbg(dev, "ASoC: Mapped DAI %s to "
-                                       "CODEC %s\n", dai->name, codec->name);
+                               dev_dbg(dev,
+                                       "ASoC: Mapped DAI %s to CODEC %s\n",
+                                       dai->name, codec->name);
                                dai->codec = codec;
                                break;
                        }
@@ -4296,8 +4277,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
 
        num_routes = of_property_count_strings(np, propname);
        if (num_routes < 0 || num_routes & 1) {
-               dev_err(card->dev, "ASoC: Property '%s' does not exist or its"
-                       " length is not even\n", propname);
+               dev_err(card->dev,
+                       "ASoC: Property '%s' does not exist or its length is not even\n",
+                       propname);
                return -EINVAL;
        }
        num_routes /= 2;
index a80c883..b941908 100644 (file)
@@ -55,7 +55,8 @@ static int dapm_up_seq[] = {
        [snd_soc_dapm_clock_supply] = 1,
        [snd_soc_dapm_micbias] = 2,
        [snd_soc_dapm_dai_link] = 2,
-       [snd_soc_dapm_dai] = 3,
+       [snd_soc_dapm_dai_in] = 3,
+       [snd_soc_dapm_dai_out] = 3,
        [snd_soc_dapm_aif_in] = 3,
        [snd_soc_dapm_aif_out] = 3,
        [snd_soc_dapm_mic] = 4,
@@ -63,6 +64,7 @@ static int dapm_up_seq[] = {
        [snd_soc_dapm_virt_mux] = 5,
        [snd_soc_dapm_value_mux] = 5,
        [snd_soc_dapm_dac] = 6,
+       [snd_soc_dapm_switch] = 7,
        [snd_soc_dapm_mixer] = 7,
        [snd_soc_dapm_mixer_named_ctl] = 7,
        [snd_soc_dapm_pga] = 8,
@@ -82,6 +84,7 @@ static int dapm_down_seq[] = {
        [snd_soc_dapm_line] = 2,
        [snd_soc_dapm_out_drv] = 2,
        [snd_soc_dapm_pga] = 4,
+       [snd_soc_dapm_switch] = 5,
        [snd_soc_dapm_mixer_named_ctl] = 5,
        [snd_soc_dapm_mixer] = 5,
        [snd_soc_dapm_dac] = 6,
@@ -92,7 +95,8 @@ static int dapm_down_seq[] = {
        [snd_soc_dapm_value_mux] = 9,
        [snd_soc_dapm_aif_in] = 10,
        [snd_soc_dapm_aif_out] = 10,
-       [snd_soc_dapm_dai] = 10,
+       [snd_soc_dapm_dai_in] = 10,
+       [snd_soc_dapm_dai_out] = 10,
        [snd_soc_dapm_dai_link] = 11,
        [snd_soc_dapm_clock_supply] = 12,
        [snd_soc_dapm_regulator_supply] = 12,
@@ -363,11 +367,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
                val = soc_widget_read(w, e->reg);
                item = (val >> e->shift_l) & e->mask;
 
-               p->connect = 0;
-               for (i = 0; i < e->max; i++) {
-                       if (!(strcmp(p->name, e->texts[i])) && item == i)
-                               p->connect = 1;
-               }
+               if (item < e->max && !strcmp(p->name, e->texts[item]))
+                       p->connect = 1;
+               else
+                       p->connect = 0;
        }
        break;
        case snd_soc_dapm_virt_mux: {
@@ -397,11 +400,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
                                break;
                }
 
-               p->connect = 0;
-               for (i = 0; i < e->max; i++) {
-                       if (!(strcmp(p->name, e->texts[i])) && item == i)
-                               p->connect = 1;
-               }
+               if (item < e->max && !strcmp(p->name, e->texts[item]))
+                       p->connect = 1;
+               else
+                       p->connect = 0;
        }
        break;
        /* does not affect routing - always connected */
@@ -419,7 +421,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
        case snd_soc_dapm_clock_supply:
        case snd_soc_dapm_aif_in:
        case snd_soc_dapm_aif_out:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_in:
+       case snd_soc_dapm_dai_out:
        case snd_soc_dapm_hp:
        case snd_soc_dapm_mic:
        case snd_soc_dapm_spk:
@@ -504,6 +507,11 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
        return 0;
 }
 
+static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
+{
+       kfree(kctl->private_data);
+}
+
 /*
  * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
  * create it. Either way, add the widget into the control's widget list
@@ -521,7 +529,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
        int wlistentries;
        size_t wlistsize;
        bool wname_in_long_name, kcname_in_long_name;
-       size_t name_len;
        char *long_name;
        const char *name;
        int ret;
@@ -586,25 +593,19 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
                }
 
                if (wname_in_long_name && kcname_in_long_name) {
-                       name_len = strlen(w->name) - prefix_len + 1 +
-                                  strlen(w->kcontrol_news[kci].name) + 1;
-
-                       long_name = kmalloc(name_len, GFP_KERNEL);
-                       if (long_name == NULL) {
-                               kfree(wlist);
-                               return -ENOMEM;
-                       }
-
                        /*
                         * The control will get a prefix from the control
                         * creation process but we're also using the same
                         * prefix for widgets so cut the prefix off the
                         * front of the widget name.
                         */
-                       snprintf(long_name, name_len, "%s %s",
+                       long_name = kasprintf(GFP_KERNEL, "%s %s",
                                 w->name + prefix_len,
                                 w->kcontrol_news[kci].name);
-                       long_name[name_len - 1] = '\0';
+                       if (long_name == NULL) {
+                               kfree(wlist);
+                               return -ENOMEM;
+                       }
 
                        name = long_name;
                } else if (wname_in_long_name) {
@@ -617,17 +618,16 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
 
                kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name,
                                        prefix);
+               kcontrol->private_free = dapm_kcontrol_free;
+               kfree(long_name);
                ret = snd_ctl_add(card, kcontrol);
                if (ret < 0) {
                        dev_err(dapm->dev,
                                "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
                                w->name, name, ret);
                        kfree(wlist);
-                       kfree(long_name);
                        return ret;
                }
-
-               path->long_name = long_name;
        }
 
        kcontrol->private_data = wlist;
@@ -820,7 +820,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
        switch (widget->id) {
        case snd_soc_dapm_adc:
        case snd_soc_dapm_aif_out:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_out:
                if (widget->active) {
                        widget->outputs = snd_soc_dapm_suspend_check(widget);
                        return widget->outputs;
@@ -916,7 +916,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
        switch (widget->id) {
        case snd_soc_dapm_dac:
        case snd_soc_dapm_aif_in:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_in:
                if (widget->active) {
                        widget->inputs = snd_soc_dapm_suspend_check(widget);
                        return widget->inputs;
@@ -1135,16 +1135,6 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
        return out != 0 && in != 0;
 }
 
-static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
-{
-       DAPM_UPDATE_STAT(w, power_checks);
-
-       if (w->active)
-               return w->active;
-
-       return dapm_generic_check_power(w);
-}
-
 /* Check to see if an ADC has power */
 static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
 {
@@ -1277,6 +1267,14 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
                ev_name = "POST_PMD";
                power = 0;
                break;
+       case SND_SOC_DAPM_WILL_PMU:
+               ev_name = "WILL_PMU";
+               power = 1;
+               break;
+       case SND_SOC_DAPM_WILL_PMD:
+               ev_name = "WILL_PMD";
+               power = 0;
+               break;
        default:
                BUG();
                return;
@@ -1737,6 +1735,14 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
                                        &async_domain);
        async_synchronize_full_domain(&async_domain);
 
+       list_for_each_entry(w, &down_list, power_list) {
+               dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMD);
+       }
+
+       list_for_each_entry(w, &up_list, power_list) {
+               dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMU);
+       }
+
        /* Power down widgets first; try to avoid amplifying pops. */
        dapm_seq_run(dapm, &down_list, event, false);
 
@@ -2101,6 +2107,14 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
        device_remove_file(dev, &dev_attr_dapm_widget);
 }
 
+static void dapm_free_path(struct snd_soc_dapm_path *path)
+{
+       list_del(&path->list_sink);
+       list_del(&path->list_source);
+       list_del(&path->list);
+       kfree(path);
+}
+
 /* free all dapm widgets and resources */
 static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
 {
@@ -2116,20 +2130,12 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
                 * While removing the path, remove reference to it from both
                 * source and sink widgets so that path is removed only once.
                 */
-               list_for_each_entry_safe(p, next_p, &w->sources, list_sink) {
-                       list_del(&p->list_sink);
-                       list_del(&p->list_source);
-                       list_del(&p->list);
-                       kfree(p->long_name);
-                       kfree(p);
-               }
-               list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
-                       list_del(&p->list_sink);
-                       list_del(&p->list_source);
-                       list_del(&p->list);
-                       kfree(p->long_name);
-                       kfree(p);
-               }
+               list_for_each_entry_safe(p, next_p, &w->sources, list_sink)
+                       dapm_free_path(p);
+
+               list_for_each_entry_safe(p, next_p, &w->sinks, list_source)
+                       dapm_free_path(p);
+
                kfree(w->kcontrols);
                kfree(w->name);
                kfree(w);
@@ -2318,7 +2324,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
        case snd_soc_dapm_clock_supply:
        case snd_soc_dapm_aif_in:
        case snd_soc_dapm_aif_out:
-       case snd_soc_dapm_dai:
+       case snd_soc_dapm_dai_in:
+       case snd_soc_dapm_dai_out:
        case snd_soc_dapm_dai_link:
                list_add(&path->list, &dapm->card->paths);
                list_add(&path->list_sink, &wsink->sources);
@@ -2404,10 +2411,7 @@ static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
                dapm_mark_dirty(path->source, "Route removed");
                dapm_mark_dirty(path->sink, "Route removed");
 
-               list_del(&path->list);
-               list_del(&path->list_sink);
-               list_del(&path->list_source);
-               kfree(path);
+               dapm_free_path(path);
        } else {
                dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n",
                         source, sink);
@@ -3061,7 +3065,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
                         const struct snd_soc_dapm_widget *widget)
 {
        struct snd_soc_dapm_widget *w;
-       size_t name_len;
        int ret;
 
        if ((w = dapm_cnew_widget(widget)) == NULL)
@@ -3102,19 +3105,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
                break;
        }
 
-       name_len = strlen(widget->name) + 1;
        if (dapm->codec && dapm->codec->name_prefix)
-               name_len += 1 + strlen(dapm->codec->name_prefix);
-       w->name = kmalloc(name_len, GFP_KERNEL);
+               w->name = kasprintf(GFP_KERNEL, "%s %s",
+                       dapm->codec->name_prefix, widget->name);
+       else
+               w->name = kasprintf(GFP_KERNEL, "%s", widget->name);
+
        if (w->name == NULL) {
                kfree(w);
                return NULL;
        }
-       if (dapm->codec && dapm->codec->name_prefix)
-               snprintf((char *)w->name, name_len, "%s %s",
-                       dapm->codec->name_prefix, widget->name);
-       else
-               snprintf((char *)w->name, name_len, "%s", widget->name);
 
        switch (w->id) {
        case snd_soc_dapm_switch:
@@ -3129,10 +3129,12 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
                break;
        case snd_soc_dapm_adc:
        case snd_soc_dapm_aif_out:
+       case snd_soc_dapm_dai_out:
                w->power_check = dapm_adc_check_power;
                break;
        case snd_soc_dapm_dac:
        case snd_soc_dapm_aif_in:
+       case snd_soc_dapm_dai_in:
                w->power_check = dapm_dac_check_power;
                break;
        case snd_soc_dapm_pga:
@@ -3152,9 +3154,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
        case snd_soc_dapm_clock_supply:
                w->power_check = dapm_supply_check_power;
                break;
-       case snd_soc_dapm_dai:
-               w->power_check = dapm_dai_check_power;
-               break;
        default:
                w->power_check = dapm_always_on_check_power;
                break;
@@ -3375,7 +3374,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
        template.reg = SND_SOC_NOPM;
 
        if (dai->driver->playback.stream_name) {
-               template.id = snd_soc_dapm_dai;
+               template.id = snd_soc_dapm_dai_in;
                template.name = dai->driver->playback.stream_name;
                template.sname = dai->driver->playback.stream_name;
 
@@ -3393,7 +3392,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
        }
 
        if (dai->driver->capture.stream_name) {
-               template.id = snd_soc_dapm_dai;
+               template.id = snd_soc_dapm_dai_out;
                template.name = dai->driver->capture.stream_name;
                template.sname = dai->driver->capture.stream_name;
 
@@ -3423,8 +3422,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
 
        /* For each DAI widget... */
        list_for_each_entry(dai_w, &card->widgets, list) {
-               if (dai_w->id != snd_soc_dapm_dai)
+               switch (dai_w->id) {
+               case snd_soc_dapm_dai_in:
+               case snd_soc_dapm_dai_out:
+                       break;
+               default:
                        continue;
+               }
 
                dai = dai_w->priv;
 
@@ -3433,8 +3437,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
                        if (w->dapm != dai_w->dapm)
                                continue;
 
-                       if (w->id == snd_soc_dapm_dai)
+                       switch (w->id) {
+                       case snd_soc_dapm_dai_in:
+                       case snd_soc_dapm_dai_out:
                                continue;
+                       default:
+                               break;
+                       }
 
                        if (!w->sname)
                                continue;
index 73bb8ee..b6c6403 100644 (file)
 
 #define DPCM_MAX_BE_USERS      8
 
+/**
+ * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
+ * @substream: the pcm substream
+ * @hw: the hardware parameters
+ *
+ * Sets the substream runtime hardware parameters.
+ */
+int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
+       const struct snd_pcm_hardware *hw)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       runtime->hw.info = hw->info;
+       runtime->hw.formats = hw->formats;
+       runtime->hw.period_bytes_min = hw->period_bytes_min;
+       runtime->hw.period_bytes_max = hw->period_bytes_max;
+       runtime->hw.periods_min = hw->periods_min;
+       runtime->hw.periods_max = hw->periods_max;
+       runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
+       runtime->hw.fifo_size = hw->fifo_size;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
+
 /* DPCM stream event, send event to FE and all active BEs. */
 static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
        int event)
@@ -124,6 +147,26 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
        }
 }
 
+static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
+       struct snd_soc_pcm_stream *codec_stream,
+       struct snd_soc_pcm_stream *cpu_stream)
+{
+       hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min);
+       hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
+       hw->channels_min = max(codec_stream->channels_min,
+               cpu_stream->channels_min);
+       hw->channels_max = min(codec_stream->channels_max,
+               cpu_stream->channels_max);
+       hw->formats = codec_stream->formats & cpu_stream->formats;
+       hw->rates = codec_stream->rates & cpu_stream->rates;
+       if (codec_stream->rates
+               & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
+               hw->rates |= cpu_stream->rates;
+       if (cpu_stream->rates
+               & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
+               hw->rates |= codec_stream->rates;
+}
+
 /*
  * Called by ALSA when a PCM substream is opened, the runtime->hw record is
  * then initialized and any private data can be allocated. This also calls
@@ -189,51 +232,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 
        /* Check that the codec and cpu DAIs are compatible */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               runtime->hw.rate_min =
-                       max(codec_dai_drv->playback.rate_min,
-                           cpu_dai_drv->playback.rate_min);
-               runtime->hw.rate_max =
-                       min(codec_dai_drv->playback.rate_max,
-                           cpu_dai_drv->playback.rate_max);
-               runtime->hw.channels_min =
-                       max(codec_dai_drv->playback.channels_min,
-                               cpu_dai_drv->playback.channels_min);
-               runtime->hw.channels_max =
-                       min(codec_dai_drv->playback.channels_max,
-                               cpu_dai_drv->playback.channels_max);
-               runtime->hw.formats =
-                       codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
-               runtime->hw.rates =
-                       codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
-               if (codec_dai_drv->playback.rates
-                          & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
-                       runtime->hw.rates |= cpu_dai_drv->playback.rates;
-               if (cpu_dai_drv->playback.rates
-                          & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
-                       runtime->hw.rates |= codec_dai_drv->playback.rates;
+               soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback,
+                       &cpu_dai_drv->playback);
        } else {
-               runtime->hw.rate_min =
-                       max(codec_dai_drv->capture.rate_min,
-                           cpu_dai_drv->capture.rate_min);
-               runtime->hw.rate_max =
-                       min(codec_dai_drv->capture.rate_max,
-                           cpu_dai_drv->capture.rate_max);
-               runtime->hw.channels_min =
-                       max(codec_dai_drv->capture.channels_min,
-                               cpu_dai_drv->capture.channels_min);
-               runtime->hw.channels_max =
-                       min(codec_dai_drv->capture.channels_max,
-                               cpu_dai_drv->capture.channels_max);
-               runtime->hw.formats =
-                       codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
-               runtime->hw.rates =
-                       codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
-               if (codec_dai_drv->capture.rates
-                          & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
-                       runtime->hw.rates |= cpu_dai_drv->capture.rates;
-               if (cpu_dai_drv->capture.rates
-                          & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
-                       runtime->hw.rates |= codec_dai_drv->capture.rates;
+               soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture,
+                       &cpu_dai_drv->capture);
        }
 
        ret = -EINVAL;
@@ -928,8 +931,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
        /* Create any new FE <--> BE connections */
        for (i = 0; i < list->num_widgets; i++) {
 
-               if (list->widgets[i]->id != snd_soc_dapm_dai)
+               switch (list->widgets[i]->id) {
+               case snd_soc_dapm_dai_in:
+               case snd_soc_dapm_dai_out:
+                       break;
+               default:
                        continue;
+               }
 
                /* is there a valid BE rtd for this widget */
                be = dpcm_get_be(card, list->widgets[i], stream);
@@ -2011,9 +2019,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
                if (cpu_dai->driver->capture.channels_min)
                        capture = 1;
        } else {
-               if (codec_dai->driver->playback.channels_min)
+               if (codec_dai->driver->playback.channels_min &&
+                   cpu_dai->driver->playback.channels_min)
                        playback = 1;
-               if (codec_dai->driver->capture.channels_min)
+               if (codec_dai->driver->capture.channels_min &&
+                   cpu_dai->driver->capture.channels_min)
                        capture = 1;
        }
 
index 4b3be6c..29b211e 100644 (file)
@@ -159,15 +159,10 @@ int __init snd_soc_util_init(void)
 {
        int ret;
 
-       soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1);
-       if (!soc_dummy_dev)
-               return -ENOMEM;
-
-       ret = platform_device_add(soc_dummy_dev);
-       if (ret != 0) {
-               platform_device_put(soc_dummy_dev);
-               return ret;
-       }
+       soc_dummy_dev =
+               platform_device_register_simple("snd-soc-dummy", -1, NULL, 0);
+       if (IS_ERR(soc_dummy_dev))
+               return PTR_ERR(soc_dummy_dev);
 
        ret = platform_driver_register(&soc_dummy_driver);
        if (ret != 0)
diff --git a/sound/soc/spear/Kconfig b/sound/soc/spear/Kconfig
new file mode 100644 (file)
index 0000000..3567d73
--- /dev/null
@@ -0,0 +1,9 @@
+config SND_SPEAR_SOC
+       tristate
+       select SND_SOC_DMAENGINE_PCM
+
+config SND_SPEAR_SPDIF_OUT
+       tristate
+
+config SND_SPEAR_SPDIF_IN
+       tristate
diff --git a/sound/soc/spear/Makefile b/sound/soc/spear/Makefile
new file mode 100644 (file)
index 0000000..c4ea716
--- /dev/null
@@ -0,0 +1,8 @@
+# SPEAR Platform Support
+snd-soc-spear-pcm-objs := spear_pcm.o
+snd-soc-spear-spdif-in-objs := spdif_in.o
+snd-soc-spear-spdif-out-objs := spdif_out.o
+
+obj-$(CONFIG_SND_SPEAR_SOC) += snd-soc-spear-pcm.o
+obj-$(CONFIG_SND_SPEAR_SPDIF_IN) += snd-soc-spear-spdif-in.o
+obj-$(CONFIG_SND_SPEAR_SPDIF_OUT) += snd-soc-spear-spdif-out.o
index 14d57e8..63acfeb 100644 (file)
@@ -49,15 +49,12 @@ static void spdif_in_configure(struct spdif_in_dev *host)
        writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK);
 }
 
-static int spdif_in_startup(struct snd_pcm_substream *substream,
-               struct snd_soc_dai *cpu_dai)
+static int spdif_in_dai_probe(struct snd_soc_dai *dai)
 {
-       struct spdif_in_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
+       struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
 
-       if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
-               return -EINVAL;
+       dai->capture_dma_data = &host->dma_params;
 
-       snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
        return 0;
 }
 
@@ -70,7 +67,6 @@ static void spdif_in_shutdown(struct snd_pcm_substream *substream,
                return;
 
        writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
-       snd_soc_dai_set_dma_data(dai, substream, NULL);
 }
 
 static void spdif_in_format(struct spdif_in_dev *host, u32 format)
@@ -151,13 +147,13 @@ static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
 }
 
 static struct snd_soc_dai_ops spdif_in_dai_ops = {
-       .startup        = spdif_in_startup,
        .shutdown       = spdif_in_shutdown,
        .trigger        = spdif_in_trigger,
        .hw_params      = spdif_in_hw_params,
 };
 
-struct snd_soc_dai_driver spdif_in_dai = {
+static struct snd_soc_dai_driver spdif_in_dai = {
+       .probe = spdif_in_dai_probe,
        .capture = {
                .channels_min = 2,
                .channels_max = 2,
@@ -235,7 +231,7 @@ static int spdif_in_probe(struct platform_device *pdev)
        if (host->irq < 0)
                return -EINVAL;
 
-       host->clk = clk_get(&pdev->dev, NULL);
+       host->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(host->clk))
                return PTR_ERR(host->clk);
 
@@ -257,34 +253,21 @@ static int spdif_in_probe(struct platform_device *pdev)
        ret = devm_request_irq(&pdev->dev, host->irq, spdif_in_irq, 0,
                        "spdif-in", host);
        if (ret) {
-               clk_put(host->clk);
                dev_warn(&pdev->dev, "request_irq failed\n");
                return ret;
        }
 
-       ret = snd_soc_register_component(&pdev->dev, &spdif_in_component,
+       return snd_soc_register_component(&pdev->dev, &spdif_in_component,
                                         &spdif_in_dai, 1);
-       if (ret != 0) {
-               clk_put(host->clk);
-               return ret;
-       }
-
-       return 0;
 }
 
 static int spdif_in_remove(struct platform_device *pdev)
 {
-       struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev);
-
        snd_soc_unregister_component(&pdev->dev);
-       dev_set_drvdata(&pdev->dev, NULL);
-
-       clk_put(host->clk);
 
        return 0;
 }
 
-
 static struct platform_driver spdif_in_driver = {
        .probe          = spdif_in_probe,
        .remove         = spdif_in_remove,
index 1e3c3dd..2fdf68c 100644 (file)
@@ -62,8 +62,6 @@ static int spdif_out_startup(struct snd_pcm_substream *substream,
        if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
                return -EINVAL;
 
-       snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
-
        ret = clk_enable(host->clk);
        if (ret)
                return ret;
@@ -84,7 +82,6 @@ static void spdif_out_shutdown(struct snd_pcm_substream *substream,
 
        clk_disable(host->clk);
        host->running = false;
-       snd_soc_dai_set_dma_data(dai, substream, NULL);
 }
 
 static void spdif_out_clock(struct spdif_out_dev *host, u32 core_freq,
@@ -243,8 +240,12 @@ static const struct snd_kcontrol_new spdif_out_controls[] = {
                        spdif_mute_get, spdif_mute_put),
 };
 
-int spdif_soc_dai_probe(struct snd_soc_dai *dai)
+static int spdif_soc_dai_probe(struct snd_soc_dai *dai)
 {
+       struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
+
+       dai->playback_dma_data = &host->dma_params;
+
        return snd_soc_add_dai_controls(dai, spdif_out_controls,
                                ARRAY_SIZE(spdif_out_controls));
 }
@@ -281,30 +282,18 @@ static int spdif_out_probe(struct platform_device *pdev)
        struct resource *res;
        int ret;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -EINVAL;
-
-       if (!devm_request_mem_region(&pdev->dev, res->start,
-                               resource_size(res), pdev->name)) {
-               dev_warn(&pdev->dev, "Failed to get memory resourse\n");
-               return -ENOENT;
-       }
-
        host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
        if (!host) {
                dev_warn(&pdev->dev, "kzalloc fail\n");
                return -ENOMEM;
        }
 
-       host->io_base = devm_ioremap(&pdev->dev, res->start,
-                               resource_size(res));
-       if (!host->io_base) {
-               dev_warn(&pdev->dev, "ioremap failed\n");
-               return -ENOMEM;
-       }
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       host->io_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(host->io_base))
+               return PTR_ERR(host->io_base);
 
-       host->clk = clk_get(&pdev->dev, NULL);
+       host->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(host->clk))
                return PTR_ERR(host->clk);
 
@@ -320,22 +309,12 @@ static int spdif_out_probe(struct platform_device *pdev)
 
        ret = snd_soc_register_component(&pdev->dev, &spdif_out_component,
                                         &spdif_out_dai, 1);
-       if (ret != 0) {
-               clk_put(host->clk);
-               return ret;
-       }
-
-       return 0;
+       return ret;
 }
 
 static int spdif_out_remove(struct platform_device *pdev)
 {
-       struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
-
        snd_soc_unregister_component(&pdev->dev);
-       dev_set_drvdata(&pdev->dev, NULL);
-
-       clk_put(host->clk);
 
        return 0;
 }
index 2fbd489..4707f2b 100644 (file)
 
 #include <linux/module.h>
 #include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-#include <sound/core.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm.h>
-#include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/spear_dma.h>
 
-static struct snd_pcm_hardware spear_pcm_hardware = {
+static const struct snd_pcm_hardware spear_pcm_hardware = {
        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
                 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
                 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
@@ -37,149 +31,33 @@ static struct snd_pcm_hardware spear_pcm_hardware = {
        .fifo_size = 0, /* fifo size in bytes */
 };
 
-static int spear_pcm_hw_params(struct snd_pcm_substream *substream,
-               struct snd_pcm_hw_params *params)
+static struct dma_chan *spear_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
+       struct snd_pcm_substream *substream)
 {
-       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+       struct spear_dma_data *dma_data;
 
-       return 0;
-}
-
-static int spear_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-       snd_pcm_set_runtime_buffer(substream, NULL);
-
-       return 0;
-}
-
-static int spear_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
-       struct spear_dma_data *dma_data = (struct spear_dma_data *)
-               snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-       int ret;
-
-       ret = snd_soc_set_runtime_hwparams(substream, &spear_pcm_hardware);
-       if (ret)
-               return ret;
+       dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
-       return snd_dmaengine_pcm_open_request_chan(substream, dma_data->filter,
-                               dma_data);
+       return snd_dmaengine_pcm_request_channel(dma_data->filter, dma_data);
 }
 
-static int spear_pcm_mmap(struct snd_pcm_substream *substream,
-               struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-
-       return dma_mmap_writecombine(substream->pcm->card->dev, vma,
-                       runtime->dma_area, runtime->dma_addr,
-                       runtime->dma_bytes);
-}
-
-static struct snd_pcm_ops spear_pcm_ops = {
-       .open           = spear_pcm_open,
-       .close          = snd_dmaengine_pcm_close_release_chan,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = spear_pcm_hw_params,
-       .hw_free        = spear_pcm_hw_free,
-       .trigger        = snd_dmaengine_pcm_trigger,
-       .pointer        = snd_dmaengine_pcm_pointer,
-       .mmap           = spear_pcm_mmap,
-};
-
-static int
-spear_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
-               size_t size)
-{
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-
-       buf->dev.type = SNDRV_DMA_TYPE_DEV;
-       buf->dev.dev = pcm->card->dev;
-       buf->private_data = NULL;
-
-       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
-                       &buf->addr, GFP_KERNEL);
-       if (!buf->area)
-               return -ENOMEM;
-
-       dev_info(buf->dev.dev,
-                       " preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
-                       (void *)buf->area, (void *)buf->addr, size);
-
-       buf->bytes = size;
-       return 0;
-}
-
-static void spear_pcm_free(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-
-       for (stream = 0; stream < 2; stream++) {
-               substream = pcm->streams[stream].substream;
-               if (!substream)
-                       continue;
-
-               buf = &substream->dma_buffer;
-               if (!buf || !buf->area)
-                       continue;
-
-               dma_free_writecombine(pcm->card->dev, buf->bytes,
-                               buf->area, buf->addr);
-               buf->area = NULL;
-       }
-}
-
-static u64 spear_pcm_dmamask = DMA_BIT_MASK(32);
-
-static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_card *card = rtd->card->snd_card;
-       int ret;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &spear_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
-       if (rtd->cpu_dai->driver->playback.channels_min) {
-               ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
-                               SNDRV_PCM_STREAM_PLAYBACK,
-                               spear_pcm_hardware.buffer_bytes_max);
-               if (ret)
-                       return ret;
-       }
-
-       if (rtd->cpu_dai->driver->capture.channels_min) {
-               ret = spear_pcm_preallocate_dma_buffer(rtd->pcm,
-                               SNDRV_PCM_STREAM_CAPTURE,
-                               spear_pcm_hardware.buffer_bytes_max);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static struct snd_soc_platform_driver spear_soc_platform = {
-       .ops            =       &spear_pcm_ops,
-       .pcm_new        =       spear_pcm_new,
-       .pcm_free       =       spear_pcm_free,
+static const struct snd_dmaengine_pcm_config spear_dmaengine_pcm_config = {
+       .pcm_hardware = &spear_pcm_hardware,
+       .compat_request_channel = spear_pcm_request_chan,
+       .prealloc_buffer_size = 16 * 1024,
 };
 
 static int spear_soc_platform_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_platform(&pdev->dev, &spear_soc_platform);
+       return snd_dmaengine_pcm_register(&pdev->dev,
+               &spear_dmaengine_pcm_config,
+               SND_DMAENGINE_PCM_FLAG_NO_DT |
+               SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
 
 static int spear_soc_platform_remove(struct platform_device *pdev)
 {
-       snd_soc_unregister_platform(&pdev->dev);
-
+       snd_dmaengine_pcm_unregister(&pdev->dev);
        return 0;
 }
 
index b1c9d57..995b120 100644 (file)
@@ -59,6 +59,16 @@ config SND_SOC_TEGRA30_I2S
          Tegra30 I2S interface. You will also need to select the individual
          machine drivers to support below.
 
+config SND_SOC_TEGRA_RT5640
+       tristate "SoC Audio support for Tegra boards using an RT5640 codec"
+       depends on SND_SOC_TEGRA && I2C
+       select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
+       select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
+       select SND_SOC_RT5640
+       help
+         Say Y or M here if you want to add support for SoC audio on Tegra
+         boards using the RT5640 codec, such as Dalmore.
+
 config SND_SOC_TEGRA_WM8753
        tristate "SoC Audio support for Tegra boards using a WM8753 codec"
        depends on SND_SOC_TEGRA && I2C
index 416a14b..21d2550 100644 (file)
@@ -18,12 +18,14 @@ obj-$(CONFIG_SND_SOC_TEGRA30_AHUB) += snd-soc-tegra30-ahub.o
 obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o
 
 # Tegra machine Support
+snd-soc-tegra-rt5640-objs := tegra_rt5640.o
 snd-soc-tegra-wm8753-objs := tegra_wm8753.o
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
 snd-soc-tegra-wm9712-objs := tegra_wm9712.o
 snd-soc-tegra-trimslice-objs := trimslice.o
 snd-soc-tegra-alc5632-objs := tegra_alc5632.o
 
+obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o
 obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
 obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
 obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o
index 23e592f..d554d46 100644 (file)
@@ -627,9 +627,34 @@ static int tegra30_ahub_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int tegra30_ahub_suspend(struct device *dev)
+{
+       regcache_mark_dirty(ahub->regmap_ahub);
+       regcache_mark_dirty(ahub->regmap_apbif);
+
+       return 0;
+}
+
+static int tegra30_ahub_resume(struct device *dev)
+{
+       int ret;
+
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
+               return ret;
+       ret = regcache_sync(ahub->regmap_ahub);
+       ret |= regcache_sync(ahub->regmap_apbif);
+       pm_runtime_put(dev);
+
+       return ret;
+}
+#endif
+
 static const struct dev_pm_ops tegra30_ahub_pm_ops = {
        SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
                           tegra30_ahub_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(tegra30_ahub_suspend, tegra30_ahub_resume)
 };
 
 static struct platform_driver tegra30_ahub_driver = {
index 31d092d..d04146c 100644 (file)
@@ -514,6 +514,31 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int tegra30_i2s_suspend(struct device *dev)
+{
+       struct tegra30_i2s *i2s = dev_get_drvdata(dev);
+
+       regcache_mark_dirty(i2s->regmap);
+
+       return 0;
+}
+
+static int tegra30_i2s_resume(struct device *dev)
+{
+       struct tegra30_i2s *i2s = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
+               return ret;
+       ret = regcache_sync(i2s->regmap);
+       pm_runtime_put(dev);
+
+       return ret;
+}
+#endif
+
 static const struct of_device_id tegra30_i2s_of_match[] = {
        { .compatible = "nvidia,tegra30-i2s", },
        {},
@@ -522,6 +547,7 @@ static const struct of_device_id tegra30_i2s_of_match[] = {
 static const struct dev_pm_ops tegra30_i2s_pm_ops = {
        SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
                           tegra30_i2s_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(tegra30_i2s_suspend, tegra30_i2s_resume)
 };
 
 static struct platform_driver tegra30_i2s_driver = {
index 24fb001..d173880 100644 (file)
@@ -173,7 +173,6 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
                          struct device *dev)
 {
        int ret;
-       bool new_clocks = false;
 
        data->dev = dev;
 
@@ -181,40 +180,28 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
                data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
        else if (of_machine_is_compatible("nvidia,tegra30"))
                data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
-       else if (of_machine_is_compatible("nvidia,tegra114")) {
+       else if (of_machine_is_compatible("nvidia,tegra114"))
                data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114;
-               new_clocks = true;
-       } else {
+       else {
                dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n");
                return -EINVAL;
        }
 
-       if (new_clocks)
-               data->clk_pll_a = clk_get(dev, "pll_a");
-       else
-               data->clk_pll_a = clk_get_sys(NULL, "pll_a");
+       data->clk_pll_a = clk_get(dev, "pll_a");
        if (IS_ERR(data->clk_pll_a)) {
                dev_err(data->dev, "Can't retrieve clk pll_a\n");
                ret = PTR_ERR(data->clk_pll_a);
                goto err;
        }
 
-       if (new_clocks)
-               data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0");
-       else
-               data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
+       data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0");
        if (IS_ERR(data->clk_pll_a_out0)) {
                dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
                ret = PTR_ERR(data->clk_pll_a_out0);
                goto err_put_pll_a;
        }
 
-       if (new_clocks)
-               data->clk_cdev1 = clk_get(dev, "mclk");
-       else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
-               data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
-       else
-               data->clk_cdev1 = clk_get_sys("extern1", NULL);
+       data->clk_cdev1 = clk_get(dev, "mclk");
        if (IS_ERR(data->clk_cdev1)) {
                dev_err(data->dev, "Can't retrieve clk cdev1\n");
                ret = PTR_ERR(data->clk_cdev1);
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
new file mode 100644 (file)
index 0000000..08794f9
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+* tegra_rt5640.c - Tegra machine ASoC driver for boards using WM8903 codec.
+ *
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Based on code copyright/by:
+ *
+ * Copyright (C) 2010-2012 - NVIDIA, Inc.
+ * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+ * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
+ * Copyright 2007 Wolfson Microelectronics PLC.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "../codecs/rt5640.h"
+
+#include "tegra_asoc_utils.h"
+
+#define DRV_NAME "tegra-snd-rt5640"
+
+struct tegra_rt5640 {
+       struct tegra_asoc_utils_data util_data;
+       int gpio_hp_det;
+};
+
+static int tegra_rt5640_asoc_hw_params(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_card *card = codec->card;
+       struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
+       int srate, mclk;
+       int err;
+
+       srate = params_rate(params);
+       mclk = 256 * srate;
+
+       err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
+       if (err < 0) {
+               dev_err(card->dev, "Can't configure clocks\n");
+               return err;
+       }
+
+       err = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, mclk,
+                                       SND_SOC_CLOCK_IN);
+       if (err < 0) {
+               dev_err(card->dev, "codec_dai clock not set\n");
+               return err;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops tegra_rt5640_ops = {
+       .hw_params = tegra_rt5640_asoc_hw_params,
+};
+
+static struct snd_soc_jack tegra_rt5640_hp_jack;
+
+static struct snd_soc_jack_pin tegra_rt5640_hp_jack_pins[] = {
+       {
+               .pin = "Headphones",
+               .mask = SND_JACK_HEADPHONE,
+       },
+};
+
+static struct snd_soc_jack_gpio tegra_rt5640_hp_jack_gpio = {
+       .name = "Headphone detection",
+       .report = SND_JACK_HEADPHONE,
+       .debounce_time = 150,
+       .invert = 1,
+};
+
+static const struct snd_soc_dapm_widget tegra_rt5640_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphones", NULL),
+       SND_SOC_DAPM_SPK("Speakers", NULL),
+};
+
+static const struct snd_kcontrol_new tegra_rt5640_controls[] = {
+       SOC_DAPM_PIN_SWITCH("Speakers"),
+};
+
+static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(codec->card);
+
+       snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE,
+                        &tegra_rt5640_hp_jack);
+       snd_soc_jack_add_pins(&tegra_rt5640_hp_jack,
+                       ARRAY_SIZE(tegra_rt5640_hp_jack_pins),
+                       tegra_rt5640_hp_jack_pins);
+
+       if (gpio_is_valid(machine->gpio_hp_det)) {
+               tegra_rt5640_hp_jack_gpio.gpio = machine->gpio_hp_det;
+               snd_soc_jack_add_gpios(&tegra_rt5640_hp_jack,
+                                               1,
+                                               &tegra_rt5640_hp_jack_gpio);
+       }
+
+       return 0;
+}
+
+static struct snd_soc_dai_link tegra_rt5640_dai = {
+       .name = "RT5640",
+       .stream_name = "RT5640 PCM",
+       .codec_dai_name = "rt5640-aif1",
+       .init = tegra_rt5640_asoc_init,
+       .ops = &tegra_rt5640_ops,
+       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+                       SND_SOC_DAIFMT_CBS_CFS,
+};
+
+static struct snd_soc_card snd_soc_tegra_rt5640 = {
+       .name = "tegra-rt5640",
+       .owner = THIS_MODULE,
+       .dai_link = &tegra_rt5640_dai,
+       .num_links = 1,
+       .controls = tegra_rt5640_controls,
+       .num_controls = ARRAY_SIZE(tegra_rt5640_controls),
+       .dapm_widgets = tegra_rt5640_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(tegra_rt5640_dapm_widgets),
+       .fully_routed = true,
+};
+
+static int tegra_rt5640_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct snd_soc_card *card = &snd_soc_tegra_rt5640;
+       struct tegra_rt5640 *machine;
+       int ret;
+
+       machine = devm_kzalloc(&pdev->dev,
+                       sizeof(struct tegra_rt5640), GFP_KERNEL);
+       if (!machine) {
+               dev_err(&pdev->dev, "Can't allocate tegra_rt5640\n");
+               return -ENOMEM;
+       }
+
+       card->dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+       snd_soc_card_set_drvdata(card, machine);
+
+       machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
+       if (machine->gpio_hp_det == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+
+       ret = snd_soc_of_parse_card_name(card, "nvidia,model");
+       if (ret)
+               goto err;
+
+       ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
+       if (ret)
+               goto err;
+
+       tegra_rt5640_dai.codec_of_node = of_parse_phandle(np,
+                       "nvidia,audio-codec", 0);
+       if (!tegra_rt5640_dai.codec_of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'nvidia,audio-codec' missing or invalid\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       tegra_rt5640_dai.cpu_of_node = of_parse_phandle(np,
+                       "nvidia,i2s-controller", 0);
+       if (!tegra_rt5640_dai.cpu_of_node) {
+               dev_err(&pdev->dev,
+                       "Property 'nvidia,i2s-controller' missing or invalid\n");
+               ret = -EINVAL;
+               goto err;
+       }
+
+       tegra_rt5640_dai.platform_of_node = tegra_rt5640_dai.cpu_of_node;
+
+       ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
+       if (ret)
+               goto err;
+
+       ret = snd_soc_register_card(card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+                       ret);
+               goto err_fini_utils;
+       }
+
+       return 0;
+
+err_fini_utils:
+       tegra_asoc_utils_fini(&machine->util_data);
+err:
+       return ret;
+}
+
+static int tegra_rt5640_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
+
+       snd_soc_jack_free_gpios(&tegra_rt5640_hp_jack, 1,
+                               &tegra_rt5640_hp_jack_gpio);
+
+       snd_soc_unregister_card(card);
+
+       tegra_asoc_utils_fini(&machine->util_data);
+
+       return 0;
+}
+
+static const struct of_device_id tegra_rt5640_of_match[] = {
+       { .compatible = "nvidia,tegra-audio-rt5640", },
+       {},
+};
+
+static struct platform_driver tegra_rt5640_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .pm = &snd_soc_pm_ops,
+               .of_match_table = tegra_rt5640_of_match,
+       },
+       .probe = tegra_rt5640_probe,
+       .remove = tegra_rt5640_remove,
+};
+module_platform_driver(tegra_rt5640_driver);
+
+MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
+MODULE_DESCRIPTION("Tegra+RT5640 machine ASoC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_rt5640_of_match);
index 204b899..8f5cd00 100644 (file)
@@ -27,7 +27,7 @@
 #include "mop500_ab8500.h"
 
 /* Define the whole MOP500 soundcard, linking platform to the codec-drivers  */
-struct snd_soc_dai_link mop500_dai_links[] = {
+static struct snd_soc_dai_link mop500_dai_links[] = {
        {
                .name = "ab8500_0",
                .stream_name = "ab8500_0",
index 892ad9a..7e923ec 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/mutex.h>
 
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -24,6 +25,7 @@
 
 #include "ux500_pcm.h"
 #include "ux500_msp_dai.h"
+#include "mop500_ab8500.h"
 #include "../codecs/ab8500-codec.h"
 
 #define TX_SLOT_MONO   0x0008
 static unsigned int tx_slots = DEF_TX_SLOTS;
 static unsigned int rx_slots = DEF_RX_SLOTS;
 
+/* Configuration consistency parameters */
+static DEFINE_MUTEX(mop500_ab8500_params_lock);
+static unsigned long mop500_ab8500_usage;
+static int mop500_ab8500_rate;
+static int mop500_ab8500_channels;
+
 /* Clocks */
 static const char * const enum_mclk[] = {
        "SYSCLK",
@@ -125,9 +133,9 @@ static int mop500_ab8500_set_mclk(struct device *dev,
 static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
        struct mop500_ab8500_drvdata *drvdata =
-                               snd_soc_card_get_drvdata(codec->card);
+                               snd_soc_card_get_drvdata(card);
 
        ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
 
@@ -137,9 +145,9 @@ static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
 static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
        struct mop500_ab8500_drvdata *drvdata =
-                               snd_soc_card_get_drvdata(codec->card);
+                               snd_soc_card_get_drvdata(card);
        unsigned int val = ucontrol->value.enumerated.item[0];
 
        if (val > (unsigned int)MCLK_ULPCLK)
@@ -160,16 +168,6 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
        SOC_ENUM_EXT("Master Clock Select",
                soc_enum_mclk,
                mclk_input_control_get, mclk_input_control_put),
-       /* Digital interface - Clocks */
-       SOC_SINGLE("Digital Interface Master Generator Switch",
-               AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN,
-               1, 0),
-       SOC_SINGLE("Digital Interface 0 Bit-clock Switch",
-               AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0,
-               1, 0),
-       SOC_SINGLE("Digital Interface 1 Bit-clock Switch",
-               AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1,
-               1, 0),
        SOC_DAPM_PIN_SWITCH("Headset Left"),
        SOC_DAPM_PIN_SWITCH("Headset Right"),
        SOC_DAPM_PIN_SWITCH("Earpiece"),
@@ -193,7 +191,7 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
 
 /* ASoC */
 
-int mop500_ab8500_startup(struct snd_pcm_substream *substream)
+static int mop500_ab8500_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 
@@ -202,7 +200,7 @@ int mop500_ab8500_startup(struct snd_pcm_substream *substream)
                                snd_soc_card_get_drvdata(rtd->card));
 }
 
-void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
+static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct device *dev = rtd->card->dev;
@@ -216,7 +214,7 @@ void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
                rx_slots = DEF_RX_SLOTS;
 }
 
-int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
+static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
                        struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -240,6 +238,21 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
                substream->name,
                substream->number);
 
+       /* Ensure configuration consistency between DAIs */
+       mutex_lock(&mop500_ab8500_params_lock);
+       if (mop500_ab8500_usage) {
+               if (mop500_ab8500_rate != params_rate(params) ||
+                   mop500_ab8500_channels != params_channels(params)) {
+                       mutex_unlock(&mop500_ab8500_params_lock);
+                       return -EBUSY;
+               }
+       } else {
+               mop500_ab8500_rate = params_rate(params);
+               mop500_ab8500_channels = params_channels(params);
+       }
+       __set_bit(cpu_dai->id, &mop500_ab8500_usage);
+       mutex_unlock(&mop500_ab8500_params_lock);
+
        channels = params_channels(params);
 
        switch (params_format(params)) {
@@ -338,9 +351,22 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+       mutex_lock(&mop500_ab8500_params_lock);
+       __clear_bit(cpu_dai->id, &mop500_ab8500_usage);
+       mutex_unlock(&mop500_ab8500_params_lock);
+
+       return 0;
+}
+
 struct snd_soc_ops mop500_ab8500_ops[] = {
        {
                .hw_params = mop500_ab8500_hw_params,
+               .hw_free = mop500_ab8500_hw_free,
                .startup = mop500_ab8500_startup,
                .shutdown = mop500_ab8500_shutdown,
        }
@@ -385,7 +411,7 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
        drvdata->mclk_sel = MCLK_ULPCLK;
 
        /* Add controls */
-       ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls,
+       ret = snd_soc_add_card_controls(codec->card, mop500_ab8500_ctrls,
                        ARRAY_SIZE(mop500_ab8500_ctrls));
        if (ret < 0) {
                pr_err("%s: Failed to add machine-controls (%d)!\n",
index 7d5fc13..c6fb5cc 100644 (file)
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
 {
        struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
 
-       drvdata->playback_dma_data.dma_cfg = drvdata->msp->dma_cfg_tx;
-       drvdata->capture_dma_data.dma_cfg = drvdata->msp->dma_cfg_rx;
+       dai->playback_dma_data = &drvdata->msp->playback_dma_data;
+       dai->capture_dma_data = &drvdata->msp->capture_dma_data;
 
-       dai->playback_dma_data = &drvdata->playback_dma_data;
-       dai->capture_dma_data = &drvdata->capture_dma_data;
-
-       drvdata->playback_dma_data.data_size = drvdata->slot_width;
-       drvdata->capture_dma_data.data_size = drvdata->slot_width;
+       drvdata->msp->playback_dma_data.data_size = drvdata->slot_width;
+       drvdata->msp->capture_dma_data.data_size = drvdata->slot_width;
 
        return 0;
 }
index f531043..312ae53 100644 (file)
@@ -51,15 +51,11 @@ enum ux500_msp_clock_id {
 struct ux500_msp_i2s_drvdata {
        struct ux500_msp *msp;
        struct regulator *reg_vape;
-       struct ux500_msp_dma_params playback_dma_data;
-       struct ux500_msp_dma_params capture_dma_data;
        unsigned int fmt;
        unsigned int tx_mask;
        unsigned int rx_mask;
        int slots;
        int slot_width;
-       u8 configured;
-       int data_delay;
 
        /* Clocks */
        unsigned int master_clk;
index f2db6c9..1ca8b08 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/io.h>
@@ -26,9 +25,6 @@
 
 #include "ux500_msp_i2s.h"
 
-/* MSP1/3 Tx/Rx usage protection */
-static DEFINE_SPINLOCK(msp_rxtx_lock);
-
  /* Protocol desciptors */
 static const struct msp_protdesc prot_descs[] = {
        { /* I2S */
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp,
 
 static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
 {
-       int status = 0, retval = 0;
+       int status = 0;
        u32 reg_val_DMACR, reg_val_GCR;
-       unsigned long flags;
-
-       /* Check msp state whether in RUN or CONFIGURED Mode */
-       if (msp->msp_state == MSP_STATE_IDLE) {
-               spin_lock_irqsave(&msp_rxtx_lock, flags);
-               if (msp->pinctrl_rxtx_ref == 0 &&
-                       !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) {
-                       retval = pinctrl_select_state(msp->pinctrl_p,
-                                               msp->pinctrl_def);
-                       if (retval)
-                               pr_err("could not set MSP defstate\n");
-               }
-               if (!retval)
-                       msp->pinctrl_rxtx_ref++;
-               spin_unlock_irqrestore(&msp_rxtx_lock, flags);
-       }
 
        /* Configure msp with protocol dependent settings */
        configure_protocol(msp, config);
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
        }
 
        /* Make sure the correct DMA-directions are configured */
-       if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) {
+       if ((config->direction & MSP_DIR_RX) &&
+                       !msp->capture_dma_data.dma_cfg) {
                dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
                        __func__);
                return -EINVAL;
        }
-       if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) {
+       if ((config->direction == MSP_DIR_TX) &&
+                       !msp->playback_dma_data.dma_cfg) {
                dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
                        __func__);
                return -EINVAL;
@@ -630,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
 
 int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
 {
-       int status = 0, retval = 0;
-       unsigned long flags;
+       int status = 0;
 
        dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
 
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
                               (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
                              msp->registers + MSP_GCR);
 
-               spin_lock_irqsave(&msp_rxtx_lock, flags);
-               WARN_ON(!msp->pinctrl_rxtx_ref);
-               msp->pinctrl_rxtx_ref--;
-               if (msp->pinctrl_rxtx_ref == 0 &&
-                       !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) {
-                       retval = pinctrl_select_state(msp->pinctrl_p,
-                                               msp->pinctrl_sleep);
-                       if (retval)
-                               pr_err("could not set MSP sleepstate\n");
-               }
-               spin_unlock_irqrestore(&msp_rxtx_lock, flags);
-
                writel(0, msp->registers + MSP_GCR);
                writel(0, msp->registers + MSP_TCF);
                writel(0, msp->registers + MSP_RCF);
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
                        struct msp_i2s_platform_data *platform_data)
 {
        struct resource *res = NULL;
-       struct i2s_controller *i2s_cont;
        struct device_node *np = pdev->dev.of_node;
        struct ux500_msp *msp;
 
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
 
        msp->id = platform_data->id;
        msp->dev = &pdev->dev;
-       msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
-       msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
+       msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx;
+       msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
                return -ENOMEM;
        }
 
+       msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR;
+       msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR;
+
        msp->registers = devm_ioremap(&pdev->dev, res->start,
                                      resource_size(res));
        if (msp->registers == NULL) {
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
        msp->msp_state = MSP_STATE_IDLE;
        msp->loopback_enable = 0;
 
-       /* I2S-controller is allocated and added in I2S controller class. */
-       i2s_cont = devm_kzalloc(&pdev->dev, sizeof(*i2s_cont), GFP_KERNEL);
-       if (!i2s_cont) {
-               dev_err(&pdev->dev,
-                       "%s: ERROR: Failed to allocate I2S-controller!\n",
-                       __func__);
-               return -ENOMEM;
-       }
-       i2s_cont->dev.parent = &pdev->dev;
-       i2s_cont->data = (void *)msp;
-       i2s_cont->id = (s16)msp->id;
-       snprintf(i2s_cont->name, sizeof(i2s_cont->name), "ux500-msp-i2s.%04x",
-               msp->id);
-       dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
-       msp->i2s_cont = i2s_cont;
-
-       msp->pinctrl_p = pinctrl_get(msp->dev);
-       if (IS_ERR(msp->pinctrl_p))
-               dev_err(&pdev->dev, "could not get MSP pinctrl\n");
-       else {
-               msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
-                                               PINCTRL_STATE_DEFAULT);
-               if (IS_ERR(msp->pinctrl_def)) {
-                       dev_err(&pdev->dev,
-                               "could not get MSP defstate (%li)\n",
-                               PTR_ERR(msp->pinctrl_def));
-               }
-               msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
-                                               PINCTRL_STATE_SLEEP);
-               if (IS_ERR(msp->pinctrl_sleep))
-                       dev_err(&pdev->dev,
-                               "could not get MSP idlestate (%li)\n",
-                               PTR_ERR(msp->pinctrl_def));
-       }
-
        return 0;
 }
 
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
                        struct ux500_msp *msp)
 {
        dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
-
-       device_unregister(&msp->i2s_cont->dev);
 }
 
 MODULE_LICENSE("GPL v2");
index e5cd105..258d0bc 100644 (file)
@@ -16,6 +16,7 @@
 #define UX500_MSP_I2S_H
 
 #include <linux/platform_device.h>
+#include <linux/platform_data/asoc-ux500-msp.h>
 
 #define MSP_INPUT_FREQ_APB 48000000
 
@@ -341,11 +342,6 @@ enum msp_compress_mode {
        MSP_COMPRESS_MODE_A_LAW = 3
 };
 
-enum msp_spi_burst_mode {
-       MSP_SPI_BURST_MODE_DISABLE = 0,
-       MSP_SPI_BURST_MODE_ENABLE = 1
-};
-
 enum msp_expand_mode {
        MSP_EXPAND_MODE_LINEAR = 0,
        MSP_EXPAND_MODE_LINEAR_SIGNED = 1,
@@ -370,13 +366,6 @@ enum msp_protocol {
  */
 #define MAX_MSP_BACKUP_REGS 36
 
-enum enum_i2s_controller {
-       MSP_0_I2S_CONTROLLER = 0,
-       MSP_1_I2S_CONTROLLER,
-       MSP_2_I2S_CONTROLLER,
-       MSP_3_I2S_CONTROLLER,
-};
-
 enum i2s_direction_t {
        MSP_DIR_TX = 0x01,
        MSP_DIR_RX = 0x02,
@@ -454,32 +443,6 @@ struct msp_protdesc {
        u32 clocks_per_frame;
 };
 
-struct i2s_message {
-       enum i2s_direction_t i2s_direction;
-       void *txdata;
-       void *rxdata;
-       size_t txbytes;
-       size_t rxbytes;
-       int dma_flag;
-       int tx_offset;
-       int rx_offset;
-       bool cyclic_dma;
-       dma_addr_t buf_addr;
-       size_t buf_len;
-       size_t period_len;
-};
-
-struct i2s_controller {
-       struct module *owner;
-       unsigned int id;
-       unsigned int class;
-       const struct i2s_algorithm *algo; /* the algorithm to access the bus */
-       void *data;
-       struct mutex bus_lock;
-       struct device dev; /* the controller device */
-       char name[48];
-};
-
 struct ux500_msp_config {
        unsigned int f_inputclk;
        unsigned int rx_clk_sel;
@@ -491,8 +454,6 @@ struct ux500_msp_config {
        unsigned int tx_fsync_sel;
        unsigned int rx_fifo_config;
        unsigned int tx_fifo_config;
-       unsigned int spi_clk_mode;
-       unsigned int spi_burst_mode;
        unsigned int loopback_enable;
        unsigned int tx_data_enable;
        unsigned int default_protdesc;
@@ -502,43 +463,28 @@ struct ux500_msp_config {
        unsigned int direction;
        unsigned int protocol;
        unsigned int frame_freq;
-       unsigned int frame_size;
        enum msp_data_size data_size;
        unsigned int def_elem_len;
        unsigned int iodelay;
-       void (*handler) (void *data);
-       void *tx_callback_data;
-       void *rx_callback_data;
+};
+
+struct ux500_msp_dma_params {
+       unsigned int data_size;
+       dma_addr_t tx_rx_addr;
+       struct stedma40_chan_cfg *dma_cfg;
 };
 
 struct ux500_msp {
-       enum enum_i2s_controller id;
+       enum msp_i2s_id id;
        void __iomem *registers;
        struct device *dev;
-       struct i2s_controller *i2s_cont;
-       struct stedma40_chan_cfg *dma_cfg_rx;
-       struct stedma40_chan_cfg *dma_cfg_tx;
-       struct dma_chan *tx_pipeid;
-       struct dma_chan *rx_pipeid;
+       struct ux500_msp_dma_params playback_dma_data;
+       struct ux500_msp_dma_params capture_dma_data;
        enum msp_state msp_state;
-       int (*transfer) (struct ux500_msp *msp, struct i2s_message *message);
-       struct timer_list notify_timer;
        int def_elem_len;
        unsigned int dir_busy;
        int loopback_enable;
-       u32 backup_regs[MAX_MSP_BACKUP_REGS];
        unsigned int f_bitclk;
-       /* Pin modes */
-       struct pinctrl *pinctrl_p;
-       struct pinctrl_state *pinctrl_def;
-       struct pinctrl_state *pinctrl_sleep;
-       /* Reference Count */
-       int pinctrl_rxtx_ref;
-};
-
-struct ux500_msp_dma_params {
-       unsigned int data_size;
-       struct stedma40_chan_cfg *dma_cfg;
 };
 
 struct msp_i2s_platform_data;
index b6e5ae2..5f01c19 100644 (file)
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd,
        return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg);
 }
 
+static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
+               struct snd_pcm_hw_params *params,
+               struct dma_slave_config *slave_config)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct ux500_msp_dma_params *dma_params;
+       struct stedma40_chan_cfg *dma_cfg;
+       int ret;
+
+       dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+       dma_cfg = dma_params->dma_cfg;
+
+       ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
+       if (ret)
+               return ret;
+
+       slave_config->dst_maxburst = 4;
+       slave_config->dst_addr_width = dma_cfg->dst_info.data_width;
+       slave_config->src_maxburst = 4;
+       slave_config->src_addr_width = dma_cfg->src_info.data_width;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               slave_config->dst_addr = dma_params->tx_rx_addr;
+       else
+               slave_config->src_addr = dma_params->tx_rx_addr;
+
+       return 0;
+}
+
 static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = {
        .pcm_hardware = &ux500_pcm_hw,
        .compat_request_channel = ux500_pcm_request_chan,
        .prealloc_buffer_size = 128 * 1024,
+       .prepare_slave_config = ux500_pcm_prepare_slave_config,
 };
 
 int ux500_pcm_register_platform(struct platform_device *pdev)
index a1d9b07..b9defcd 100644 (file)
@@ -42,8 +42,8 @@ static const u8 ep_w_max_packet_size[] = {
        0x94, 0x01, 0x5c, 0x02  /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
 };
 
-static const u8 known_fw_versions[][4] = {
-       { 0x03, 0x01, 0x0b, 0x00 }
+static const u8 known_fw_versions[][2] = {
+       { 0x03, 0x01 }
 };
 
 struct ihex_record {
@@ -343,7 +343,7 @@ static int usb6fire_fw_check(u8 *version)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
-               if (!memcmp(version, known_fw_versions + i, 4))
+               if (!memcmp(version, known_fw_versions + i, 2))
                        return 0;
 
        snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. "
index ca4739c..e5c7f9f 100644 (file)
@@ -886,6 +886,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
        case USB_ID(0x046d, 0x0808):
        case USB_ID(0x046d, 0x0809):
        case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
+       case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
        case USB_ID(0x046d, 0x0991):
        /* Most audio usb devices lie about volume resolution.
         * Most Logitech webcams have res = 384.
index 7f1722f..8b75bcf 100644 (file)
        .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
 },
 {
-       USB_DEVICE(0x046d, 0x0990),
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                      USB_DEVICE_ID_MATCH_INT_CLASS |
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+       .idVendor = 0x046d,
+       .idProduct = 0x0990,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+       .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
        .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
                .vendor_name = "Logitech, Inc.",
                .product_name = "QuickCam Pro 9000",
@@ -1792,7 +1798,11 @@ YAMAHA_DEVICE(0x7010, "UB99"),
        USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
        .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
                .ifnum = 0,
-               .type = QUIRK_MIDI_STANDARD_INTERFACE
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const struct snd_usb_midi_endpoint_info) {
+                       .out_cables = 0x0007,
+                       .in_cables  = 0x0007
+               }
        }
 },
 {
index 9e9d348..fe70207 100644 (file)
@@ -2191,7 +2191,7 @@ int initialize_counters(int cpu_id)
 
 void allocate_output_buffer()
 {
-       output_buffer = calloc(1, (1 + topo.num_cpus) * 128);
+       output_buffer = calloc(1, (1 + topo.num_cpus) * 256);
        outp = output_buffer;
        if (outp == NULL) {
                perror("calloc");