Merge remote-tracking branches 'asoc/topic/intel', 'asoc/topic/io' and 'asoc/topic...
authorMark Brown <broonie@linaro.org>
Sun, 23 Mar 2014 14:00:52 +0000 (14:00 +0000)
committerMark Brown <broonie@linaro.org>
Sun, 23 Mar 2014 14:00:52 +0000 (14:00 +0000)
276 files changed:
Documentation/devicetree/bindings/sound/armada-370db-audio.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/cs42xx8.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/mvebu-audio.txt
Documentation/devicetree/bindings/sound/tlv320aic31xx.txt [new file with mode: 0644]
Documentation/networking/packet_mmap.txt
Documentation/networking/timestamping.txt
MAINTAINERS
Makefile
arch/arm/mach-shmobile/board-armadillo800eva.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/mach-shmobile/board-mackerel.c
arch/cris/include/asm/bitops.h
arch/ia64/kernel/uncached.c
arch/powerpc/platforms/cell/ras.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-se/7724/setup.c
arch/x86/Kconfig.cpu
arch/x86/include/asm/barrier.h
arch/x86/include/asm/io.h
arch/x86/include/asm/spinlock.h
arch/x86/kernel/cpu/centaur.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/kernel/i387.c
arch/x86/kernel/quirks.c
arch/x86/kvm/svm.c
arch/x86/net/bpf_jit.S
arch/x86/um/asm/barrier.h
drivers/acpi/sleep.c
drivers/ata/libata-core.c
drivers/cpufreq/cpufreq.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/cik_sdma.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_bo_vm.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/i2c/busses/Kconfig
drivers/md/dm-cache-target.c
drivers/misc/sgi-xp/xpc_uv.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_options.c
drivers/net/ethernet/broadcom/bnx2.c
drivers/net/ethernet/broadcom/bnx2.h
drivers/net/ethernet/brocade/bna/bfa_ioc.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/ibm/ibmveth.h
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/realtek/r8169.c
drivers/net/ethernet/stmicro/stmmac/chain_mode.c
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/ring_mode.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/hyperv/rndis_filter.c
drivers/net/ieee802154/at86rf230.c
drivers/net/phy/phy.c
drivers/net/usb/Makefile
drivers/net/usb/cdc_ether.c
drivers/net/usb/r8152.c
drivers/net/usb/r815x.c [deleted file]
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/mwifiex/11ac.c
drivers/net/wireless/mwifiex/11n.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/ti/wl1251/rx.c
drivers/net/xen-netback/interface.c
drivers/net/xen-netback/netback.c
drivers/pci/bus.c
drivers/pci/pci.c
drivers/pnp/pnpacpi/rsparser.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/isci/host.h
drivers/scsi/isci/port_config.c
drivers/scsi/isci/task.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/storvsc_drv.c
fs/cifs/cifsglob.h
fs/cifs/file.c
fs/cifs/transport.c
fs/file.c
fs/file_table.c
fs/hfsplus/catalog.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/hfsplus_raw.h
fs/hfsplus/inode.c
fs/namei.c
fs/ocfs2/file.c
fs/open.c
fs/proc/base.c
fs/read_write.c
include/dt-bindings/sound/tlv320aic31xx-micbias.h [new file with mode: 0644]
include/kvm/arm_vgic.h
include/linux/audit.h
include/linux/file.h
include/linux/fs.h
include/linux/gfp.h
include/linux/mmzone.h
include/linux/slab.h
include/net/sock.h
include/sound/soc.h
init/main.c
ipc/msg.c
kernel/audit.c
kernel/audit.h
kernel/auditfilter.c
kernel/profile.c
kernel/sched/clock.c
kernel/sched/core.c
kernel/stop_machine.c
mm/Kconfig
mm/compaction.c
mm/migrate.c
net/8021q/vlan_dev.c
net/bridge/br_multicast.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/inet_fragment.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/exthdrs_offload.c
net/ipv6/route.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_netlink.c
net/l2tp/l2tp_ppp.c
net/mac80211/chan.c
net/mac80211/mesh_ps.c
net/mac80211/sta_info.c
net/sched/sch_api.c
net/sched/sch_fq.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/socket.c
net/tipc/config.c
net/tipc/handler.c
net/tipc/name_table.c
net/tipc/server.c
net/tipc/socket.c
net/tipc/subscr.c
net/unix/af_unix.c
net/wireless/core.c
scripts/kallsyms.c
sound/pci/hda/patch_realtek.c
sound/soc/cirrus/snappercl15.c
sound/soc/codecs/88pm860x-codec.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ad193x.c
sound/soc/codecs/adau1373.c
sound/soc/codecs/adav80x.c
sound/soc/codecs/ak4535.c
sound/soc/codecs/ak4641.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/ak4671.c
sound/soc/codecs/alc5623.c
sound/soc/codecs/alc5632.c
sound/soc/codecs/cq93vc.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l73.c
sound/soc/codecs/cs42xx8-i2c.c [new file with mode: 0644]
sound/soc/codecs/cs42xx8.c [new file with mode: 0644]
sound/soc/codecs/cs42xx8.h [new file with mode: 0644]
sound/soc/codecs/da7210.c
sound/soc/codecs/da7213.c
sound/soc/codecs/da732x.c
sound/soc/codecs/da9055.c
sound/soc/codecs/isabelle.c
sound/soc/codecs/lm4857.c
sound/soc/codecs/lm49453.c
sound/soc/codecs/max9768.c
sound/soc/codecs/max98088.c
sound/soc/codecs/max98090.c
sound/soc/codecs/max98095.c
sound/soc/codecs/max9850.c
sound/soc/codecs/mc13783.c
sound/soc/codecs/ml26124.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/rt5640.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/si476x.c
sound/soc/codecs/sn95031.c
sound/soc/codecs/ssm2518.c
sound/soc/codecs/ssm2602.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/sta529.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic31xx.c [new file with mode: 0644]
sound/soc/codecs/tlv320aic31xx.h [new file with mode: 0644]
sound/soc/codecs/tlv320aic32x4.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/uda134x.c
sound/soc/codecs/uda1380.c
sound/soc/codecs/wm2000.c
sound/soc/codecs/wm2200.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8400.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8737.c
sound/soc/codecs/wm8741.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8770.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8804.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8940.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8961.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8971.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm8978.c
sound/soc/codecs/wm8983.c
sound/soc/codecs/wm8985.c
sound/soc/codecs/wm8988.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm8991.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8995.c
sound/soc/codecs/wm8996.c
sound/soc/codecs/wm8997.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm9090.c
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/edma-pcm.c [new file with mode: 0644]
sound/soc/davinci/edma-pcm.h [new file with mode: 0644]
sound/soc/kirkwood/Kconfig
sound/soc/kirkwood/Makefile
sound/soc/kirkwood/armada-370-db.c [new file with mode: 0644]
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/omap/ams-delta.c
sound/soc/pxa/magician.c
sound/soc/pxa/tosa.c
sound/soc/s6000/s6105-ipcam.c
sound/soc/sh/fsi.c
sound/soc/sh/rcar/core.c
sound/soc/soc-core.c
sound/soc/soc-io.c
sound/soc/soc-jack.c
sound/soc/soc-pcm.c
sound/soc/tegra/tegra20_ac97.c
sound/soc/tegra/tegra20_das.c
sound/soc/tegra/tegra20_i2s.c
sound/soc/tegra/tegra20_spdif.c
sound/soc/tegra/tegra30_ahub.c
sound/soc/tegra/tegra30_i2s.c
tools/net/Makefile
tools/perf/builtin-trace.c
tools/perf/util/machine.c
tools/perf/util/symbol-elf.c
tools/testing/selftests/ipc/msgque.c

diff --git a/Documentation/devicetree/bindings/sound/armada-370db-audio.txt b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt
new file mode 100644 (file)
index 0000000..bf984d2
--- /dev/null
@@ -0,0 +1,27 @@
+Device Tree bindings for the Armada 370 DB audio
+================================================
+
+These Device Tree bindings are used to describe the audio complex
+found on the Armada 370 DB platform.
+
+Mandatory properties:
+
+ * compatible: must be "marvell,a370db-audio"
+
+ * marvell,audio-controller: a phandle that points to the audio
+   controller of the Armada 370 SoC.
+
+ * marvell,audio-codec: a set of three phandles that points to:
+
+    1/ the analog audio codec connected to the Armada 370 SoC
+    2/ the S/PDIF transceiver
+    3/ the S/PDIF receiver
+
+Example:
+
+       sound {
+             compatible = "marvell,a370db-audio";
+             marvell,audio-controller = <&audio_controller>;
+             marvell,audio-codec = <&audio_codec &spdif_out &spdif_in>;
+             status = "okay";
+       };
diff --git a/Documentation/devicetree/bindings/sound/cs42xx8.txt b/Documentation/devicetree/bindings/sound/cs42xx8.txt
new file mode 100644 (file)
index 0000000..f631fbc
--- /dev/null
@@ -0,0 +1,28 @@
+CS42448/CS42888 audio CODEC
+
+Required properties:
+
+  - compatible : must contain one of "cirrus,cs42448" and "cirrus,cs42888"
+
+  - reg : the I2C address of the device for I2C
+
+  - clocks : a list of phandles + clock-specifiers, one for each entry in
+    clock-names
+
+  - clock-names : must contain "mclk"
+
+  - VA-supply, VD-supply, VLS-supply, VLC-supply: power supplies for the device,
+    as covered in Documentation/devicetree/bindings/regulator/regulator.txt
+
+Example:
+
+codec: cs42888@48 {
+       compatible = "cirrus,cs42888";
+       reg = <0x48>;
+       clocks = <&codec_mclk 0>;
+       clock-names = "mclk";
+       VA-supply = <&reg_audio>;
+       VD-supply = <&reg_audio>;
+       VLS-supply = <&reg_audio>;
+       VLC-supply = <&reg_audio>;
+};
index f0062c5871b4d1d525af5dac77fa85a2398a83ec..cb8c07c81ce4498e77a94003ae16bfb9ec9b2e5c 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
 - compatible:
   "marvell,kirkwood-audio" for Kirkwood platforms
   "marvell,dove-audio" for Dove platforms
+  "marvell,armada370-audio" for Armada 370 platforms
 
 - reg: physical base address of the controller and length of memory mapped
   region.
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
new file mode 100644 (file)
index 0000000..74c66de
--- /dev/null
@@ -0,0 +1,61 @@
+Texas Instruments - tlv320aic31xx Codec module
+
+The tlv320aic31xx serial control bus communicates through I2C protocols
+
+Required properties:
+
+- compatible - "string" - One of:
+    "ti,tlv320aic310x" - Generic TLV320AIC31xx with mono speaker amp
+    "ti,tlv320aic311x" - Generic TLV320AIC31xx with stereo speaker amp
+    "ti,tlv320aic3100" - TLV320AIC3100 (mono speaker amp, no MiniDSP)
+    "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP)
+    "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP)
+    "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP)
+
+- reg - <int> -  I2C slave address
+
+
+Optional properties:
+
+- gpio-reset - gpio pin number used for codec reset
+- ai31xx-micbias-vg - MicBias Voltage setting
+        1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V
+        2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V
+        3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD
+       If this node is not mentioned or if the value is unknown, then
+       micbias is set to 2.0V.
+- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
+  DVDD-supply : power supplies for the device as covered in
+  Documentation/devicetree/bindings/regulator/regulator.txt
+
+CODEC output pins:
+  * HPL
+  * HPR
+  * SPL, devices with stereo speaker amp
+  * SPR, devices with stereo speaker amp
+  * SPK, devices with mono speaker amp
+  * MICBIAS
+
+CODEC input pins:
+  * MIC1LP
+  * MIC1RP
+  * MIC1LM
+
+The pins can be used in referring sound node's audio-routing property.
+
+Example:
+#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+
+tlv320aic31xx: tlv320aic31xx@18 {
+       compatible = "ti,tlv320aic311x";
+       reg = <0x18>;
+
+       ai31xx-micbias-vg = <MICBIAS_OFF>;
+
+       HPVDD-supply = <&regulator>;
+       SPRVDD-supply = <&regulator>;
+       SPLVDD-supply = <&regulator>;
+       AVDD-supply = <&regulator>;
+       IOVDD-supply = <&regulator>;
+       DVDD-supply = <&regulator>;
+};
index 1404674c0a0282af7d077cf55a5da076875bd2ed..6fea79efb4cbfd31cc1d0155aef320b94b89da9e 100644 (file)
@@ -453,7 +453,7 @@ TP_STATUS_COPY        : This flag indicates that the frame (and associated
                         enabled previously with setsockopt() and 
                         the PACKET_COPY_THRESH option. 
 
-                        The number of frames than can be buffered to 
+                        The number of frames that can be buffered to
                         be read with recvfrom is limited like a normal socket.
                         See the SO_RCVBUF option in the socket (7) man page.
 
index 661d3c316a17721d787a8a601f3e9c8356e957be..048c92b487f6a50b552cf12d47abe4212ba66f36 100644 (file)
@@ -21,26 +21,38 @@ has such a feature).
 
 SO_TIMESTAMPING:
 
-Instructs the socket layer which kind of information is wanted. The
-parameter is an integer with some of the following bits set. Setting
-other bits is an error and doesn't change the current state.
-
-SOF_TIMESTAMPING_TX_HARDWARE:  try to obtain send time stamp in hardware
-SOF_TIMESTAMPING_TX_SOFTWARE:  if SOF_TIMESTAMPING_TX_HARDWARE is off or
-                               fails, then do it in software
-SOF_TIMESTAMPING_RX_HARDWARE:  return the original, unmodified time stamp
-                               as generated by the hardware
-SOF_TIMESTAMPING_RX_SOFTWARE:  if SOF_TIMESTAMPING_RX_HARDWARE is off or
-                               fails, then do it in software
-SOF_TIMESTAMPING_RAW_HARDWARE: return original raw hardware time stamp
-SOF_TIMESTAMPING_SYS_HARDWARE: return hardware time stamp transformed to
-                               the system time base
-SOF_TIMESTAMPING_SOFTWARE:     return system time stamp generated in
-                               software
-
-SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
-SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
-following control message:
+Instructs the socket layer which kind of information should be collected
+and/or reported.  The parameter is an integer with some of the following
+bits set. Setting other bits is an error and doesn't change the current
+state.
+
+Four of the bits are requests to the stack to try to generate
+timestamps.  Any combination of them is valid.
+
+SOF_TIMESTAMPING_TX_HARDWARE:  try to obtain send time stamps in hardware
+SOF_TIMESTAMPING_TX_SOFTWARE:  try to obtain send time stamps in software
+SOF_TIMESTAMPING_RX_HARDWARE:  try to obtain receive time stamps in hardware
+SOF_TIMESTAMPING_RX_SOFTWARE:  try to obtain receive time stamps in software
+
+The other three bits control which timestamps will be reported in a
+generated control message.  If none of these bits are set or if none of
+the set bits correspond to data that is available, then the control
+message will not be generated:
+
+SOF_TIMESTAMPING_SOFTWARE:     report systime if available
+SOF_TIMESTAMPING_SYS_HARDWARE: report hwtimetrans if available
+SOF_TIMESTAMPING_RAW_HARDWARE: report hwtimeraw if available
+
+It is worth noting that timestamps may be collected for reasons other
+than being requested by a particular socket with
+SOF_TIMESTAMPING_[TR]X_(HARD|SOFT)WARE.  For example, most drivers that
+can generate hardware receive timestamps ignore
+SOF_TIMESTAMPING_RX_HARDWARE.  It is still a good idea to set that flag
+in case future drivers pay attention.
+
+If timestamps are reported, they will appear in a control message with
+cmsg_level==SOL_SOCKET, cmsg_type==SO_TIMESTAMPING, and a payload like
+this:
 
 struct scm_timestamping {
        struct timespec systime;
index b7befe758429293e12f6523a5b35fa546f19ac4b..7c42d59effabd556c92968e60ce72155af882a13 100644 (file)
@@ -1738,6 +1738,7 @@ F:        include/uapi/linux/bfs_fs.h
 BLACKFIN ARCHITECTURE
 M:     Steven Miao <realmz6@gmail.com>
 L:     adi-buildroot-devel@lists.sourceforge.net
+T:     git git://git.code.sf.net/p/adi-linux/code
 W:     http://blackfin.uclinux.org
 S:     Supported
 F:     arch/blackfin/
@@ -2202,6 +2203,13 @@ L:       alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Odd Fixes
 F:     sound/soc/codecs/cs4270*
 
+CIRRUS LOGIC AUDIO CODEC DRIVERS
+M:     Brian Austin <brian.austin@cirrus.com>
+M:     Paul Handrigan <Paul.Handrigan@cirrus.com>
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Maintained
+F:     sound/soc/codecs/cs*
+
 CLEANCACHE API
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 L:     linux-kernel@vger.kernel.org
@@ -6002,6 +6010,8 @@ F:        include/linux/netdevice.h
 F:     include/uapi/linux/in.h
 F:     include/uapi/linux/net.h
 F:     include/uapi/linux/netdevice.h
+F:     tools/net/
+F:     tools/testing/selftests/net/
 
 NETWORKING [IPv4/IPv6]
 M:     "David S. Miller" <davem@davemloft.net>
index 1a2628ee5d917376f0f9262eb8c0ba4722a89775..ef779ec26f62c21c3777ee6f9a0fa437bd5825aa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 14
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Shuffling Zombie Juror
 
 # *DOCUMENTATION*
index 93533e2710a83927d1935799ce56410bb26d098f..9323854242ca10f8bf0f8f1956ae79828d4505a2 100644 (file)
@@ -988,14 +988,12 @@ static struct asoc_simple_card_info fsi_wm8978_info = {
        .card           = "FSI2A-WM8978",
        .codec          = "wm8978.0-001a",
        .platform       = "sh_fsi2",
-       .daifmt         = SND_SOC_DAIFMT_I2S,
+       .daifmt         = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM,
        .cpu_dai = {
                .name   = "fsia-dai",
-               .fmt    = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_IB_NF,
        },
        .codec_dai = {
                .name   = "wm8978-hifi",
-               .fmt    = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF,
                .sysclk = 12288000,
        },
 };
index bc40b853ffd3cff2204bdfdc283863a9577f51bc..03dc3ac84502edd8f83aa51820ef1a05f24f9648 100644 (file)
@@ -589,14 +589,12 @@ static struct asoc_simple_card_info fsi2_ak4648_info = {
        .card           = "FSI2A-AK4648",
        .codec          = "ak4642-codec.0-0012",
        .platform       = "sh_fsi2",
-       .daifmt         = SND_SOC_DAIFMT_LEFT_J,
+       .daifmt         = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
        .cpu_dai = {
                .name   = "fsia-dai",
-               .fmt    = SND_SOC_DAIFMT_CBS_CFS,
        },
        .codec_dai = {
                .name   = "ak4642-hifi",
-               .fmt    = SND_SOC_DAIFMT_CBM_CFM,
                .sysclk = 11289600,
        },
 };
index 3aba0372f6305b7458e87dcffa9b27c8c515425e..0ff4d8e45cf7d9a2a7dc5974756b43d14256b1c8 100644 (file)
@@ -509,9 +509,9 @@ static struct asoc_simple_card_info fsi2_hdmi_info = {
        .card           = "FSI2B-HDMI",
        .codec          = "sh-mobile-hdmi",
        .platform       = "sh_fsi2",
+       .daifmt         = SND_SOC_DAIFMT_CBS_CFS,
        .cpu_dai = {
                .name   = "fsib-dai",
-               .fmt    = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF,
        },
        .codec_dai = {
                .name   = "sh_mobile_hdmi-hifi",
@@ -905,14 +905,12 @@ static struct asoc_simple_card_info fsi2_ak4643_info = {
        .card           = "FSI2A-AK4643",
        .codec          = "ak4642-codec.0-0013",
        .platform       = "sh_fsi2",
-       .daifmt         = SND_SOC_DAIFMT_LEFT_J,
+       .daifmt         = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
        .cpu_dai = {
                .name   = "fsia-dai",
-               .fmt    = SND_SOC_DAIFMT_CBS_CFS,
        },
        .codec_dai = {
                .name   = "ak4642-hifi",
-               .fmt    = SND_SOC_DAIFMT_CBM_CFM,
                .sysclk = 11289600,
        },
 };
index 184066ceb1f6146c9254a778c8e9c7f6b9656668..053c17b3655926ed97427a927a83081ec289d224 100644 (file)
@@ -144,7 +144,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
  * definition, which doesn't have the same semantics.  We don't want to
  * use -fno-builtin, so just hide the name ffs.
  */
-#define ffs kernel_ffs
+#define ffs(x) kernel_ffs(x)
 
 #include <asm-generic/bitops/fls.h>
 #include <asm-generic/bitops/__fls.h>
index a96bcf83a735dae2f812f81e0fc54635bb3de072..20e8a9b21d7519ebf7d506e4825d83c05629ba37 100644 (file)
@@ -98,7 +98,7 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid)
        /* attempt to allocate a granule's worth of cached memory pages */
 
        page = alloc_pages_exact_node(nid,
-                               GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+                               GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
                                IA64_GRANULE_SHIFT-PAGE_SHIFT);
        if (!page) {
                mutex_unlock(&uc_pool->add_chunk_mutex);
index 5ec1e47a0d771eba56e8b8c42111a19aed7df25a..e865d748179b2ac1b0b7550c1d3bebbcae71e049 100644 (file)
@@ -123,7 +123,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order)
 
        area->nid = nid;
        area->order = order;
-       area->pages = alloc_pages_exact_node(area->nid, GFP_KERNEL|GFP_THISNODE,
+       area->pages = alloc_pages_exact_node(area->nid,
+                                               GFP_KERNEL|__GFP_THISNODE,
                                                area->order);
 
        if (!area->pages) {
index 5bc3a15465c71a53906ed0f99a848298c30b2831..85d5255d259f690247494072635d35f29f9c5c8d 100644 (file)
@@ -861,14 +861,12 @@ static struct asoc_simple_card_info fsi_da7210_info = {
        .card           = "FSIB-DA7210",
        .codec          = "da7210.0-001a",
        .platform       = "sh_fsi.0",
-       .daifmt         = SND_SOC_DAIFMT_I2S,
+       .daifmt         = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM,
        .cpu_dai = {
                .name   = "fsib-dai",
-               .fmt    = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_IB_NF,
        },
        .codec_dai = {
                .name   = "da7210-hifi",
-               .fmt    = SND_SOC_DAIFMT_CBM_CFM,
        },
 };
 
index 21e4230659a57d978ac7631016ca42adf1ddc795..1162bc6945a38ebd19ac3f13def4cef2459b907a 100644 (file)
@@ -304,14 +304,12 @@ static struct asoc_simple_card_info fsi_ak4642_info = {
        .card           = "FSIA-AK4642",
        .codec          = "ak4642-codec.0-0012",
        .platform       = "sh_fsi.0",
-       .daifmt         = SND_SOC_DAIFMT_LEFT_J,
+       .daifmt         = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
        .cpu_dai = {
                .name   = "fsia-dai",
-               .fmt    = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_IB_NF,
        },
        .codec_dai = {
                .name   = "ak4642-hifi",
-               .fmt    = SND_SOC_DAIFMT_CBM_CFM,
                .sysclk = 11289600,
        },
 };
index c026cca5602c6fe5c84619f0b43b2fe7c3bb2382..f3aaf231b4e590fad07b58b51583eb6693a924cd 100644 (file)
@@ -341,10 +341,6 @@ config X86_USE_3DNOW
        def_bool y
        depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
 
-config X86_OOSTORE
-       def_bool y
-       depends on (MWINCHIP3D || MWINCHIPC6) && MTRR
-
 #
 # P6_NOPs are a relatively minor optimization that require a family >=
 # 6 processor, except that it is broken on certain VIA chips.
index 04a48903b2eb31973080d60d36cfd93b3fc68a5f..69bbb484502089b6a01d93d58e4c16a3f90e14f9 100644 (file)
 #else
 # define smp_rmb()     barrier()
 #endif
-#ifdef CONFIG_X86_OOSTORE
-# define smp_wmb()     wmb()
-#else
-# define smp_wmb()     barrier()
-#endif
+#define smp_wmb()      barrier()
 #define smp_read_barrier_depends()     read_barrier_depends()
 #define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
 #else /* !SMP */
 #define set_mb(var, value) do { var = value; barrier(); } while (0)
 #endif /* SMP */
 
-#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
+#if defined(CONFIG_X86_PPRO_FENCE)
 
 /*
  * For either of these options x86 doesn't have a strong TSO memory
index 34f69cb9350ae3ecf36e4b8cd8d410a6a7b67a0b..91d9c69a629e2731f25aa152de91dd17663ec619 100644 (file)
@@ -237,7 +237,7 @@ memcpy_toio(volatile void __iomem *dst, const void *src, size_t count)
 
 static inline void flush_write_buffers(void)
 {
-#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
+#if defined(CONFIG_X86_PPRO_FENCE)
        asm volatile("lock; addl $0,0(%%esp)": : :"memory");
 #endif
 }
index bf156ded74b56006a76cc02b8917984117af8afd..0f62f5482d91ec8fca86e884b6822fc467239dbc 100644 (file)
 # define LOCK_PTR_REG "D"
 #endif
 
-#if defined(CONFIG_X86_32) && \
-       (defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE))
+#if defined(CONFIG_X86_32) && (defined(CONFIG_X86_PPRO_FENCE))
 /*
- * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock
+ * On PPro SMP, we use a locked operation to unlock
  * (PPro errata 66, 92)
  */
 # define UNLOCK_LOCK_PREFIX LOCK_PREFIX
index 8779edab684efdcd04fd93d22d79d4633c6fd4f9..d8fba5c15fbd8882f317daa2779c39ff4429b0d4 100644 (file)
@@ -8,236 +8,6 @@
 
 #include "cpu.h"
 
-#ifdef CONFIG_X86_OOSTORE
-
-static u32 power2(u32 x)
-{
-       u32 s = 1;
-
-       while (s <= x)
-               s <<= 1;
-
-       return s >>= 1;
-}
-
-
-/*
- * Set up an actual MCR
- */
-static void centaur_mcr_insert(int reg, u32 base, u32 size, int key)
-{
-       u32 lo, hi;
-
-       hi = base & ~0xFFF;
-       lo = ~(size-1);         /* Size is a power of 2 so this makes a mask */
-       lo &= ~0xFFF;           /* Remove the ctrl value bits */
-       lo |= key;              /* Attribute we wish to set */
-       wrmsr(reg+MSR_IDT_MCR0, lo, hi);
-       mtrr_centaur_report_mcr(reg, lo, hi);   /* Tell the mtrr driver */
-}
-
-/*
- * Figure what we can cover with MCR's
- *
- * Shortcut: We know you can't put 4Gig of RAM on a winchip
- */
-static u32 ramtop(void)
-{
-       u32 clip = 0xFFFFFFFFUL;
-       u32 top = 0;
-       int i;
-
-       for (i = 0; i < e820.nr_map; i++) {
-               unsigned long start, end;
-
-               if (e820.map[i].addr > 0xFFFFFFFFUL)
-                       continue;
-               /*
-                * Don't MCR over reserved space. Ignore the ISA hole
-                * we frob around that catastrophe already
-                */
-               if (e820.map[i].type == E820_RESERVED) {
-                       if (e820.map[i].addr >= 0x100000UL &&
-                           e820.map[i].addr < clip)
-                               clip = e820.map[i].addr;
-                       continue;
-               }
-               start = e820.map[i].addr;
-               end = e820.map[i].addr + e820.map[i].size;
-               if (start >= end)
-                       continue;
-               if (end > top)
-                       top = end;
-       }
-       /*
-        * Everything below 'top' should be RAM except for the ISA hole.
-        * Because of the limited MCR's we want to map NV/ACPI into our
-        * MCR range for gunk in RAM
-        *
-        * Clip might cause us to MCR insufficient RAM but that is an
-        * acceptable failure mode and should only bite obscure boxes with
-        * a VESA hole at 15Mb
-        *
-        * The second case Clip sometimes kicks in is when the EBDA is marked
-        * as reserved. Again we fail safe with reasonable results
-        */
-       if (top > clip)
-               top = clip;
-
-       return top;
-}
-
-/*
- * Compute a set of MCR's to give maximum coverage
- */
-static int centaur_mcr_compute(int nr, int key)
-{
-       u32 mem = ramtop();
-       u32 root = power2(mem);
-       u32 base = root;
-       u32 top = root;
-       u32 floor = 0;
-       int ct = 0;
-
-       while (ct < nr) {
-               u32 fspace = 0;
-               u32 high;
-               u32 low;
-
-               /*
-                * Find the largest block we will fill going upwards
-                */
-               high = power2(mem-top);
-
-               /*
-                * Find the largest block we will fill going downwards
-                */
-               low = base/2;
-
-               /*
-                * Don't fill below 1Mb going downwards as there
-                * is an ISA hole in the way.
-                */
-               if (base <= 1024*1024)
-                       low = 0;
-
-               /*
-                * See how much space we could cover by filling below
-                * the ISA hole
-                */
-
-               if (floor == 0)
-                       fspace = 512*1024;
-               else if (floor == 512*1024)
-                       fspace = 128*1024;
-
-               /* And forget ROM space */
-
-               /*
-                * Now install the largest coverage we get
-                */
-               if (fspace > high && fspace > low) {
-                       centaur_mcr_insert(ct, floor, fspace, key);
-                       floor += fspace;
-               } else if (high > low) {
-                       centaur_mcr_insert(ct, top, high, key);
-                       top += high;
-               } else if (low > 0) {
-                       base -= low;
-                       centaur_mcr_insert(ct, base, low, key);
-               } else
-                       break;
-               ct++;
-       }
-       /*
-        * We loaded ct values. We now need to set the mask. The caller
-        * must do this bit.
-        */
-       return ct;
-}
-
-static void centaur_create_optimal_mcr(void)
-{
-       int used;
-       int i;
-
-       /*
-        * Allocate up to 6 mcrs to mark as much of ram as possible
-        * as write combining and weak write ordered.
-        *
-        * To experiment with: Linux never uses stack operations for
-        * mmio spaces so we could globally enable stack operation wc
-        *
-        * Load the registers with type 31 - full write combining, all
-        * writes weakly ordered.
-        */
-       used = centaur_mcr_compute(6, 31);
-
-       /*
-        * Wipe unused MCRs
-        */
-       for (i = used; i < 8; i++)
-               wrmsr(MSR_IDT_MCR0+i, 0, 0);
-}
-
-static void winchip2_create_optimal_mcr(void)
-{
-       u32 lo, hi;
-       int used;
-       int i;
-
-       /*
-        * Allocate up to 6 mcrs to mark as much of ram as possible
-        * as write combining, weak store ordered.
-        *
-        * Load the registers with type 25
-        *      8       -       weak write ordering
-        *      16      -       weak read ordering
-        *      1       -       write combining
-        */
-       used = centaur_mcr_compute(6, 25);
-
-       /*
-        * Mark the registers we are using.
-        */
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       for (i = 0; i < used; i++)
-               lo |= 1<<(9+i);
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-
-       /*
-        * Wipe unused MCRs
-        */
-
-       for (i = used; i < 8; i++)
-               wrmsr(MSR_IDT_MCR0+i, 0, 0);
-}
-
-/*
- * Handle the MCR key on the Winchip 2.
- */
-static void winchip2_unprotect_mcr(void)
-{
-       u32 lo, hi;
-       u32 key;
-
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       lo &= ~0x1C0;   /* blank bits 8-6 */
-       key = (lo>>17) & 7;
-       lo |= key<<6;   /* replace with unlock key */
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-}
-
-static void winchip2_protect_mcr(void)
-{
-       u32 lo, hi;
-
-       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-       lo &= ~0x1C0;   /* blank bits 8-6 */
-       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-}
-#endif /* CONFIG_X86_OOSTORE */
-
 #define ACE_PRESENT    (1 << 6)
 #define ACE_ENABLED    (1 << 7)
 #define ACE_FCR                (1 << 28)       /* MSR_VIA_FCR */
@@ -362,20 +132,6 @@ static void init_centaur(struct cpuinfo_x86 *c)
                        fcr_clr = DPDC;
                        printk(KERN_NOTICE "Disabling bugged TSC.\n");
                        clear_cpu_cap(c, X86_FEATURE_TSC);
-#ifdef CONFIG_X86_OOSTORE
-                       centaur_create_optimal_mcr();
-                       /*
-                        * Enable:
-                        *      write combining on non-stack, non-string
-                        *      write combining on string, all types
-                        *      weak write ordering
-                        *
-                        * The C6 original lacks weak read order
-                        *
-                        * Note 0x120 is write only on Winchip 1
-                        */
-                       wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);
-#endif
                        break;
                case 8:
                        switch (c->x86_mask) {
@@ -392,40 +148,12 @@ static void init_centaur(struct cpuinfo_x86 *c)
                        fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|
                                  E2MMX|EAMD3D;
                        fcr_clr = DPDC;
-#ifdef CONFIG_X86_OOSTORE
-                       winchip2_unprotect_mcr();
-                       winchip2_create_optimal_mcr();
-                       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                       /*
-                        * Enable:
-                        *      write combining on non-stack, non-string
-                        *      write combining on string, all types
-                        *      weak write ordering
-                        */
-                       lo |= 31;
-                       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                       winchip2_protect_mcr();
-#endif
                        break;
                case 9:
                        name = "3";
                        fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|
                                  E2MMX|EAMD3D;
                        fcr_clr = DPDC;
-#ifdef CONFIG_X86_OOSTORE
-                       winchip2_unprotect_mcr();
-                       winchip2_create_optimal_mcr();
-                       rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                       /*
-                        * Enable:
-                        *      write combining on non-stack, non-string
-                        *      write combining on string, all types
-                        *      weak write ordering
-                        */
-                       lo |= 31;
-                       wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-                       winchip2_protect_mcr();
-#endif
                        break;
                default:
                        name = "??";
index c88f7f4b03ee063ba090ec1e53c864fa4279fdec..047f540cf3f71cfe03f69d796a1957b8a58caebc 100644 (file)
@@ -3334,6 +3334,8 @@ static int __init uncore_type_init(struct intel_uncore_type *type)
        if (!pmus)
                return -ENOMEM;
 
+       type->pmus = pmus;
+
        type->unconstrainted = (struct event_constraint)
                __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
                                0, type->num_counters, 0, 0);
@@ -3369,7 +3371,6 @@ static int __init uncore_type_init(struct intel_uncore_type *type)
        }
 
        type->pmu_group = &uncore_pmu_attr_group;
-       type->pmus = pmus;
        return 0;
 fail:
        uncore_type_exit(type);
index e8368c6dd2a2988c2d9d68cacc7030554424ad70..d5dd808144190ffd1d443229b4dbbd56740fface 100644 (file)
@@ -86,10 +86,19 @@ EXPORT_SYMBOL(__kernel_fpu_begin);
 
 void __kernel_fpu_end(void)
 {
-       if (use_eager_fpu())
-               math_state_restore();
-       else
+       if (use_eager_fpu()) {
+               /*
+                * For eager fpu, most the time, tsk_used_math() is true.
+                * Restore the user math as we are done with the kernel usage.
+                * At few instances during thread exit, signal handling etc,
+                * tsk_used_math() is false. Those few places will take proper
+                * actions, so we don't need to restore the math here.
+                */
+               if (likely(tsk_used_math(current)))
+                       math_state_restore();
+       } else {
                stts();
+       }
 }
 EXPORT_SYMBOL(__kernel_fpu_end);
 
index 7c6acd4b8995e532f5422a03a7fb65c716cbf35d..ff898bbf579d7f34ce7b8c98a5482f72e4d338bf 100644 (file)
@@ -529,7 +529,7 @@ static void quirk_amd_nb_node(struct pci_dev *dev)
                return;
 
        pci_read_config_dword(nb_ht, 0x60, &val);
-       node = val & 7;
+       node = pcibus_to_node(dev->bus) | (val & 7);
        /*
         * Some hardware may return an invalid node ID,
         * so check it first:
index e81df8fce0275781a654f356fe77e38129d5210a..2de1bc09a8d40a0508e7e364bc1de301215cc7c5 100644 (file)
@@ -3002,10 +3002,8 @@ static int cr8_write_interception(struct vcpu_svm *svm)
        u8 cr8_prev = kvm_get_cr8(&svm->vcpu);
        /* instruction emulation calls kvm_set_cr8() */
        r = cr_interception(svm);
-       if (irqchip_in_kernel(svm->vcpu.kvm)) {
-               clr_cr_intercept(svm, INTERCEPT_CR8_WRITE);
+       if (irqchip_in_kernel(svm->vcpu.kvm))
                return r;
-       }
        if (cr8_prev <= kvm_get_cr8(&svm->vcpu))
                return r;
        kvm_run->exit_reason = KVM_EXIT_SET_TPR;
@@ -3567,6 +3565,8 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
        if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK))
                return;
 
+       clr_cr_intercept(svm, INTERCEPT_CR8_WRITE);
+
        if (irr == -1)
                return;
 
index 877b9a1b21523183d06973b60a9beb2459fff895..01495755701bd3d068db95df291ef71096d9cf33 100644 (file)
@@ -140,7 +140,7 @@ bpf_slow_path_byte_msh:
        push    %r9;                                            \
        push    SKBDATA;                                        \
 /* rsi already has offset */                                   \
-       mov     $SIZE,%ecx;     /* size */                      \
+       mov     $SIZE,%edx;     /* size */                      \
        call    bpf_internal_load_pointer_neg_helper;           \
        test    %rax,%rax;                                      \
        pop     SKBDATA;                                        \
index 7d01b8c56c0029a59aa9b5b9e33036728ea7c77e..cc04e67bfd0589966e1c4b4b2fa29079c439ae24 100644 (file)
 #define smp_rmb()      barrier()
 #endif /* CONFIG_X86_PPRO_FENCE */
 
-#ifdef CONFIG_X86_OOSTORE
-#define smp_wmb()      wmb()
-#else /* CONFIG_X86_OOSTORE */
 #define smp_wmb()      barrier()
-#endif /* CONFIG_X86_OOSTORE */
 
 #define smp_read_barrier_depends()     read_barrier_depends()
 #define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
index b718806657cdac29d9ccb3a1cad3fe6528865176..c40fb2e81bbc5d4ce9266174c0c2d7614755c644 100644 (file)
@@ -71,6 +71,17 @@ static int acpi_sleep_prepare(u32 acpi_state)
        return 0;
 }
 
+static bool acpi_sleep_state_supported(u8 sleep_state)
+{
+       acpi_status status;
+       u8 type_a, type_b;
+
+       status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);
+       return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware
+               || (acpi_gbl_FADT.sleep_control.address
+                       && acpi_gbl_FADT.sleep_status.address));
+}
+
 #ifdef CONFIG_ACPI_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
 
@@ -604,15 +615,9 @@ static void acpi_sleep_suspend_setup(void)
 {
        int i;
 
-       for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
-               acpi_status status;
-               u8 type_a, type_b;
-
-               status = acpi_get_sleep_type_data(i, &type_a, &type_b);
-               if (ACPI_SUCCESS(status)) {
+       for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
+               if (acpi_sleep_state_supported(i))
                        sleep_states[i] = 1;
-               }
-       }
 
        suspend_set_ops(old_suspend_ordering ?
                &acpi_suspend_ops_old : &acpi_suspend_ops);
@@ -740,11 +745,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
 
 static void acpi_sleep_hibernate_setup(void)
 {
-       acpi_status status;
-       u8 type_a, type_b;
-
-       status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b);
-       if (ACPI_FAILURE(status))
+       if (!acpi_sleep_state_supported(ACPI_STATE_S4))
                return;
 
        hibernation_set_ops(old_suspend_ordering ?
@@ -793,8 +794,6 @@ static void acpi_power_off(void)
 
 int __init acpi_sleep_init(void)
 {
-       acpi_status status;
-       u8 type_a, type_b;
        char supported[ACPI_S_STATE_COUNT * 3 + 1];
        char *pos = supported;
        int i;
@@ -806,8 +805,7 @@ int __init acpi_sleep_init(void)
        acpi_sleep_suspend_setup();
        acpi_sleep_hibernate_setup();
 
-       status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
-       if (ACPI_SUCCESS(status)) {
+       if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
                sleep_states[ACPI_STATE_S5] = 1;
                pm_power_off_prepare = acpi_power_off_prepare;
                pm_power_off = acpi_power_off;
index 65d3f1b5966ce9d567dfdd3ed0806d4624d203b1..8cb2522d592ac87f7b144f1f41d244cd5df777dc 100644 (file)
@@ -4225,8 +4225,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 
        /* devices that don't properly handle queued TRIM commands */
        { "Micron_M500*",               NULL,   ATA_HORKAGE_NO_NCQ_TRIM, },
-       { "Crucial_CT???M500SSD1",      NULL,   ATA_HORKAGE_NO_NCQ_TRIM, },
-       { "Crucial_CT???M500SSD3",      NULL,   ATA_HORKAGE_NO_NCQ_TRIM, },
+       { "Crucial_CT???M500SSD*",      NULL,   ATA_HORKAGE_NO_NCQ_TRIM, },
 
        /*
         * Some WD SATA-I drives spin up and down erratically when the link
index cf485d9289035fe58ed9c84223ccd9f412a4b6cd..199b52b7c3e1ad6e9d00102905a215137901b71d 100644 (file)
@@ -1129,7 +1129,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
                per_cpu(cpufreq_cpu_data, j) = policy;
        write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       if (cpufreq_driver->get) {
+       if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
                policy->cur = cpufreq_driver->get(policy->cpu);
                if (!policy->cur) {
                        pr_err("%s: ->get() failed\n", __func__);
@@ -2143,7 +2143,7 @@ int cpufreq_update_policy(unsigned int cpu)
         * BIOS might change freq behind our back
         * -> ask driver for current freq and notify governors about a change
         */
-       if (cpufreq_driver->get) {
+       if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
                new_policy.cur = cpufreq_driver->get(cpu);
                if (!policy->cur) {
                        pr_debug("Driver did not initialize current freq");
index e22be8458d92783f426a699d2e3feef271b7a3f0..bbb17841a9e57ad2fdc44425a26d658848892f4c 100644 (file)
@@ -4134,8 +4134,11 @@ static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable)
 {
        if (enable)
                WREG32(CP_MEC_CNTL, 0);
-       else
+       else {
                WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT));
+               rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
+               rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
+       }
        udelay(50);
 }
 
index 1ecb3f1070e35c6ed3516e5f325eeeb61bc795b2..94626ea90fa57abc5efca249ab4d0d08cfc9566d 100644 (file)
@@ -264,6 +264,8 @@ static void cik_sdma_gfx_stop(struct radeon_device *rdev)
                WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl);
                WREG32(SDMA0_GFX_IB_CNTL + reg_offset, 0);
        }
+       rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
+       rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false;
 }
 
 /**
@@ -291,6 +293,11 @@ void cik_sdma_enable(struct radeon_device *rdev, bool enable)
        u32 me_cntl, reg_offset;
        int i;
 
+       if (enable == false) {
+               cik_sdma_gfx_stop(rdev);
+               cik_sdma_rlc_stop(rdev);
+       }
+
        for (i = 0; i < 2; i++) {
                if (i == 0)
                        reg_offset = SDMA0_REGISTER_OFFSET;
@@ -420,10 +427,6 @@ static int cik_sdma_load_microcode(struct radeon_device *rdev)
        if (!rdev->sdma_fw)
                return -EINVAL;
 
-       /* stop the gfx rings and rlc compute queues */
-       cik_sdma_gfx_stop(rdev);
-       cik_sdma_rlc_stop(rdev);
-
        /* halt the MEs */
        cik_sdma_enable(rdev, false);
 
@@ -492,9 +495,6 @@ int cik_sdma_resume(struct radeon_device *rdev)
  */
 void cik_sdma_fini(struct radeon_device *rdev)
 {
-       /* stop the gfx rings and rlc compute queues */
-       cik_sdma_gfx_stop(rdev);
-       cik_sdma_rlc_stop(rdev);
        /* halt the MEs */
        cik_sdma_enable(rdev, false);
        radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
index 2aecd6dc26109653741bc3671ea4b82136106954..66ed3ea7144010e7c95bc0d07c01ad5499242947 100644 (file)
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
+
+#if defined(CONFIG_VGA_SWITCHEROO)
+bool radeon_is_px(void);
+#else
+static inline bool radeon_is_px(void) { return false; }
+#endif
+
 /**
  * radeon_driver_unload_kms - Main unload function for KMS.
  *
@@ -130,7 +137,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
                                "Error during ACPI methods call\n");
        }
 
-       if (radeon_runtime_pm != 0) {
+       if ((radeon_runtime_pm == 1) ||
+           ((radeon_runtime_pm == -1) && radeon_is_px())) {
                pm_runtime_use_autosuspend(dev->dev);
                pm_runtime_set_autosuspend_delay(dev->dev, 5000);
                pm_runtime_set_active(dev->dev);
index a066513093880a218d185624589ec07efce66b0b..214b7992a3aa74296eeb2a083b28398c08c3cb4d 100644 (file)
@@ -351,9 +351,11 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
 
 moved:
        if (bo->evicted) {
-               ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement);
-               if (ret)
-                       pr_err("Can not flush read caches\n");
+               if (bdev->driver->invalidate_caches) {
+                       ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement);
+                       if (ret)
+                               pr_err("Can not flush read caches\n");
+               }
                bo->evicted = false;
        }
 
index 801231c9ae483980afe0e93a0af73a7f07123864..0ce48e5a9cb4a70b56461f0ceb529e2c48ed58aa 100644 (file)
@@ -339,11 +339,13 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
        vma->vm_private_data = bo;
 
        /*
-        * PFNMAP is faster than MIXEDMAP due to reduced page
-        * administration. So use MIXEDMAP only if private VMA, where
-        * we need to support COW.
+        * We'd like to use VM_PFNMAP on shared mappings, where
+        * (vma->vm_flags & VM_SHARED) != 0, for performance reasons,
+        * but for some reason VM_PFNMAP + x86 PAT + write-combine is very
+        * bad for performance. Until that has been sorted out, use
+        * VM_MIXEDMAP on all mappings. See freedesktop.org bug #75719
         */
-       vma->vm_flags |= (vma->vm_flags & VM_SHARED) ? VM_PFNMAP : VM_MIXEDMAP;
+       vma->vm_flags |= VM_MIXEDMAP;
        vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
        return 0;
 out_unref:
@@ -359,7 +361,7 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
 
        vma->vm_ops = &ttm_bo_vm_ops;
        vma->vm_private_data = ttm_bo_reference(bo);
-       vma->vm_flags |= (vma->vm_flags & VM_SHARED) ? VM_PFNMAP : VM_MIXEDMAP;
+       vma->vm_flags |= VM_MIXEDMAP;
        vma->vm_flags |= VM_IO | VM_DONTEXPAND;
        return 0;
 }
index 82468d9029156c6588a4480a9c0ed8c0aed82736..e7af580ab977f5932629b8d45e5d5e68a52942a5 100644 (file)
@@ -830,6 +830,24 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
        if (unlikely(ret != 0))
                goto out_unlock;
 
+       /*
+        * A gb-aware client referencing a shared surface will
+        * expect a backup buffer to be present.
+        */
+       if (dev_priv->has_mob && req->shareable) {
+               uint32_t backup_handle;
+
+               ret = vmw_user_dmabuf_alloc(dev_priv, tfile,
+                                           res->backup_size,
+                                           true,
+                                           &backup_handle,
+                                           &res->backup);
+               if (unlikely(ret != 0)) {
+                       vmw_resource_unreference(&res);
+                       goto out_unlock;
+               }
+       }
+
        tmp = vmw_resource_reference(&srf->res);
        ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
                                    req->shareable, VMW_RES_SURFACE,
index f5ed03164d86c314942453d244f103d6e9276070..de17c5593d97c1d702563217f0932aa0a0aee6bd 100644 (file)
@@ -387,7 +387,7 @@ config I2C_CBUS_GPIO
 
 config I2C_CPM
        tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
-       depends on (CPM1 || CPM2) && OF_I2C
+       depends on CPM1 || CPM2
        help
          This supports the use of the I2C interface on Freescale
          processors with CPM1 or CPM2.
index 1af70145fab9bcee990dd54c08224f9e16924851..074b9c8e4cf0840dd0d64014776dc297c2d82da6 100644 (file)
@@ -979,12 +979,13 @@ static void issue_copy_real(struct dm_cache_migration *mg)
        int r;
        struct dm_io_region o_region, c_region;
        struct cache *cache = mg->cache;
+       sector_t cblock = from_cblock(mg->cblock);
 
        o_region.bdev = cache->origin_dev->bdev;
        o_region.count = cache->sectors_per_block;
 
        c_region.bdev = cache->cache_dev->bdev;
-       c_region.sector = from_cblock(mg->cblock) * cache->sectors_per_block;
+       c_region.sector = cblock * cache->sectors_per_block;
        c_region.count = cache->sectors_per_block;
 
        if (mg->writeback || mg->demote) {
@@ -2464,20 +2465,18 @@ static int cache_map(struct dm_target *ti, struct bio *bio)
        bool discarded_block;
        struct dm_bio_prison_cell *cell;
        struct policy_result lookup_result;
-       struct per_bio_data *pb;
+       struct per_bio_data *pb = init_per_bio_data(bio, pb_data_size);
 
-       if (from_oblock(block) > from_oblock(cache->origin_blocks)) {
+       if (unlikely(from_oblock(block) >= from_oblock(cache->origin_blocks))) {
                /*
                 * This can only occur if the io goes to a partial block at
                 * the end of the origin device.  We don't cache these.
                 * Just remap to the origin and carry on.
                 */
-               remap_to_origin_clear_discard(cache, bio, block);
+               remap_to_origin(cache, bio);
                return DM_MAPIO_REMAPPED;
        }
 
-       pb = init_per_bio_data(bio, pb_data_size);
-
        if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) {
                defer_bio(cache, bio);
                return DM_MAPIO_SUBMITTED;
index b9e2000969f025894be4bcae2c6950d699ded3a9..95c894482fddf443d4516ffad39c54adda5be754 100644 (file)
@@ -240,7 +240,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
 
        nid = cpu_to_node(cpu);
        page = alloc_pages_exact_node(nid,
-                                     GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+                                     GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
                                      pg_order);
        if (page == NULL) {
                dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
index a2c47476804dc388406e05b4c425c4be59089add..e8f133e926aae720d09d76117bd0c84dcc90d775 100644 (file)
@@ -730,7 +730,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
                        client_info->ntt = 0;
                }
 
-               if (!vlan_get_tag(skb, &client_info->vlan_id))
+               if (vlan_get_tag(skb, &client_info->vlan_id))
                        client_info->vlan_id = 0;
 
                if (!client_info->assigned) {
index c378784327172a327bfc55a8cc4ee8737db93b43..298c26509095cdd6a6306aa954fe79b1ba46622b 100644 (file)
@@ -121,6 +121,7 @@ static struct bond_opt_value bond_resend_igmp_tbl[] = {
 static struct bond_opt_value bond_lp_interval_tbl[] = {
        { "minval",  1,       BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT},
        { "maxval",  INT_MAX, BOND_VALFLAG_MAX},
+       { NULL,      -1,      0},
 };
 
 static struct bond_option bond_opts[] = {
index cda25ac45b475ad7c173a78191f232ea7a252882..6c9e1c9bdeb8cbe06ae1788bd7ecb628e2ea4564 100644 (file)
@@ -2507,6 +2507,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
 
        bp->fw_wr_seq++;
        msg_data |= bp->fw_wr_seq;
+       bp->fw_last_msg = msg_data;
 
        bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
 
@@ -4000,8 +4001,23 @@ bnx2_setup_wol(struct bnx2 *bp)
                        wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
        }
 
-       if (!(bp->flags & BNX2_FLAG_NO_WOL))
-               bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 1, 0);
+       if (!(bp->flags & BNX2_FLAG_NO_WOL)) {
+               u32 val;
+
+               wol_msg |= BNX2_DRV_MSG_DATA_WAIT3;
+               if (bp->fw_last_msg || BNX2_CHIP(bp) != BNX2_CHIP_5709) {
+                       bnx2_fw_sync(bp, wol_msg, 1, 0);
+                       return;
+               }
+               /* Tell firmware not to power down the PHY yet, otherwise
+                * the chip will take a long time to respond to MMIO reads.
+                */
+               val = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE);
+               bnx2_shmem_wr(bp, BNX2_PORT_FEATURE,
+                             val | BNX2_PORT_FEATURE_ASF_ENABLED);
+               bnx2_fw_sync(bp, wol_msg, 1, 0);
+               bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, val);
+       }
 
 }
 
@@ -4033,9 +4049,22 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
 
                        if (bp->wol)
                                pci_set_power_state(bp->pdev, PCI_D3hot);
-               } else {
-                       pci_set_power_state(bp->pdev, PCI_D3hot);
+                       break;
+
+               }
+               if (!bp->fw_last_msg && BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+                       u32 val;
+
+                       /* Tell firmware not to power down the PHY yet,
+                        * otherwise the other port may not respond to
+                        * MMIO reads.
+                        */
+                       val = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
+                       val &= ~BNX2_CONDITION_PM_STATE_MASK;
+                       val |= BNX2_CONDITION_PM_STATE_UNPREP;
+                       bnx2_shmem_wr(bp, BNX2_BC_STATE_CONDITION, val);
                }
+               pci_set_power_state(bp->pdev, PCI_D3hot);
 
                /* No more memory access after this point until
                 * device is brought back to D0.
index f1cf2c44e7ed549519fe2eaf860d0d01302b032d..e341bc366fa5f1d003a9355516a8ebdd81811ac8 100644 (file)
@@ -6900,6 +6900,7 @@ struct bnx2 {
 
        u16                     fw_wr_seq;
        u16                     fw_drv_pulse_wr_seq;
+       u32                     fw_last_msg;
 
        int                     rx_max_ring;
        int                     rx_ring_size;
@@ -7406,6 +7407,10 @@ struct bnx2_rv2p_fw_file {
 #define BNX2_CONDITION_MFW_RUN_NCSI             0x00006000
 #define BNX2_CONDITION_MFW_RUN_NONE             0x0000e000
 #define BNX2_CONDITION_MFW_RUN_MASK             0x0000e000
+#define BNX2_CONDITION_PM_STATE_MASK            0x00030000
+#define BNX2_CONDITION_PM_STATE_FULL            0x00030000
+#define BNX2_CONDITION_PM_STATE_PREP            0x00020000
+#define BNX2_CONDITION_PM_STATE_UNPREP          0x00010000
 
 #define BNX2_BC_STATE_DEBUG_CMD                        0x1dc
 #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE      0x42440000
index 1803c39590442d497d1cc7f543ef8148ac7e56ec..354ae9792badb329e89b0ab37f59ff78c73efd11 100644 (file)
@@ -1704,7 +1704,7 @@ bfa_flash_sem_get(void __iomem *bar)
        while (!bfa_raw_sem_get(bar)) {
                if (--n <= 0)
                        return BFA_STATUS_BADFLASH;
-               udelay(10000);
+               mdelay(10);
        }
        return BFA_STATUS_OK;
 }
index 3190d38e16fbd5d59a8cbc0cca7378a500572402..d0c38e01e99fdc70e802b33dc977e081d1a72f5c 100644 (file)
@@ -632,11 +632,16 @@ static void gem_rx_refill(struct macb *bp)
                                           "Unable to allocate sk_buff\n");
                                break;
                        }
-                       bp->rx_skbuff[entry] = skb;
 
                        /* now fill corresponding descriptor entry */
                        paddr = dma_map_single(&bp->pdev->dev, skb->data,
                                               bp->rx_buffer_size, DMA_FROM_DEVICE);
+                       if (dma_mapping_error(&bp->pdev->dev, paddr)) {
+                               dev_kfree_skb(skb);
+                               break;
+                       }
+
+                       bp->rx_skbuff[entry] = skb;
 
                        if (entry == RX_RING_SIZE - 1)
                                paddr |= MACB_BIT(RX_WRAP);
@@ -725,7 +730,7 @@ static int gem_rx(struct macb *bp, int budget)
                skb_put(skb, len);
                addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, addr));
                dma_unmap_single(&bp->pdev->dev, addr,
-                                len, DMA_FROM_DEVICE);
+                                bp->rx_buffer_size, DMA_FROM_DEVICE);
 
                skb->protocol = eth_type_trans(skb, bp->dev);
                skb_checksum_none_assert(skb);
@@ -1036,11 +1041,15 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        entry = macb_tx_ring_wrap(bp->tx_head);
-       bp->tx_head++;
        netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry);
        mapping = dma_map_single(&bp->pdev->dev, skb->data,
                                 len, DMA_TO_DEVICE);
+       if (dma_mapping_error(&bp->pdev->dev, mapping)) {
+               kfree_skb(skb);
+               goto unlock;
+       }
 
+       bp->tx_head++;
        tx_skb = &bp->tx_skb[entry];
        tx_skb->skb = skb;
        tx_skb->mapping = mapping;
@@ -1066,6 +1075,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1)
                netif_stop_queue(dev);
 
+unlock:
        spin_unlock_irqrestore(&bp->lock, flags);
 
        return NETDEV_TX_OK;
index 479a7cba45c0632e68df427778eab534e73d7580..03a351300013c82999474fb411731f1487755550 100644 (file)
@@ -528,13 +528,6 @@ fec_restart(struct net_device *ndev, int duplex)
        /* Clear any outstanding interrupt. */
        writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
-       /* Setup multicast filter. */
-       set_multicast_list(ndev);
-#ifndef CONFIG_M5272
-       writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
-       writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
-#endif
-
        /* Set maximum receive buffer size. */
        writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
 
@@ -655,6 +648,13 @@ fec_restart(struct net_device *ndev, int duplex)
 
        writel(rcntl, fep->hwp + FEC_R_CNTRL);
 
+       /* Setup multicast filter. */
+       set_multicast_list(ndev);
+#ifndef CONFIG_M5272
+       writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
+#endif
+
        if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
                /* enable ENET endian swap */
                ecntl |= (1 << 8);
index 4be9715904616b3f9c1ff2a3bc38d55b58135e58..1fc8334fc181ad6d949ecffa2a289eb899c2a160 100644 (file)
@@ -522,10 +522,21 @@ retry:
        return rc;
 }
 
+static u64 ibmveth_encode_mac_addr(u8 *mac)
+{
+       int i;
+       u64 encoded = 0;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               encoded = (encoded << 8) | mac[i];
+
+       return encoded;
+}
+
 static int ibmveth_open(struct net_device *netdev)
 {
        struct ibmveth_adapter *adapter = netdev_priv(netdev);
-       u64 mac_address = 0;
+       u64 mac_address;
        int rxq_entries = 1;
        unsigned long lpar_rc;
        int rc;
@@ -579,8 +590,7 @@ static int ibmveth_open(struct net_device *netdev)
        adapter->rx_queue.num_slots = rxq_entries;
        adapter->rx_queue.toggle = 1;
 
-       memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
-       mac_address = mac_address >> 16;
+       mac_address = ibmveth_encode_mac_addr(netdev->dev_addr);
 
        rxq_desc.fields.flags_len = IBMVETH_BUF_VALID |
                                        adapter->rx_queue.queue_len;
@@ -1183,8 +1193,8 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
                /* add the addresses to the filter table */
                netdev_for_each_mc_addr(ha, netdev) {
                        /* add the multicast address to the filter table */
-                       unsigned long mcast_addr = 0;
-                       memcpy(((char *)&mcast_addr)+2, ha->addr, ETH_ALEN);
+                       u64 mcast_addr;
+                       mcast_addr = ibmveth_encode_mac_addr(ha->addr);
                        lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address,
                                                   IbmVethMcastAddFilter,
                                                   mcast_addr);
@@ -1372,9 +1382,6 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 
        netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
 
-       adapter->mac_addr = 0;
-       memcpy(&adapter->mac_addr, mac_addr_p, ETH_ALEN);
-
        netdev->irq = dev->irq;
        netdev->netdev_ops = &ibmveth_netdev_ops;
        netdev->ethtool_ops = &netdev_ethtool_ops;
@@ -1383,7 +1390,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        netdev->features |= netdev->hw_features;
 
-       memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
+       memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN);
 
        for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
                struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
index 451ba7949e152a66ee87e661e90722496792dfb8..1f37499d43981d260c61cdc1c089d7328a7942c9 100644 (file)
@@ -138,7 +138,6 @@ struct ibmveth_adapter {
     struct napi_struct napi;
     struct net_device_stats stats;
     unsigned int mcastFilterSize;
-    unsigned long mac_addr;
     void * buffer_list_addr;
     void * filter_list_addr;
     dma_addr_t buffer_list_dma;
index fad45316200aa0fbcb115e3f6b4ec56a24ca29cd..84a96f70dfb51ea7cecf3c5f0e03daa90f52a880 100644 (file)
@@ -742,6 +742,14 @@ static int mlx4_en_replace_mac(struct mlx4_en_priv *priv, int qpn,
                                err = mlx4_en_uc_steer_add(priv, new_mac,
                                                           &qpn,
                                                           &entry->reg_id);
+                               if (err)
+                                       return err;
+                               if (priv->tunnel_reg_id) {
+                                       mlx4_flow_detach(priv->mdev->dev, priv->tunnel_reg_id);
+                                       priv->tunnel_reg_id = 0;
+                               }
+                               err = mlx4_en_tunnel_steer_add(priv, new_mac, qpn,
+                                                              &priv->tunnel_reg_id);
                                return err;
                        }
                }
@@ -1792,6 +1800,8 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
                mc_list[5] = priv->port;
                mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp,
                                      mc_list, MLX4_PROT_ETH, mclist->reg_id);
+               if (mclist->tunnel_reg_id)
+                       mlx4_flow_detach(mdev->dev, mclist->tunnel_reg_id);
        }
        mlx4_en_clear_list(dev);
        list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) {
index 91b69ff4b4a20f8f2bd2f6c9405cf6ab60af7f6a..7e2995ecea6f4b3e6d4a2fbadbdfb6876a73e5c8 100644 (file)
@@ -129,13 +129,14 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
                [0] = "RSS support",
                [1] = "RSS Toeplitz Hash Function support",
                [2] = "RSS XOR Hash Function support",
-               [3] = "Device manage flow steering support",
+               [3] = "Device managed flow steering support",
                [4] = "Automatic MAC reassignment support",
                [5] = "Time stamping support",
                [6] = "VST (control vlan insertion/stripping) support",
                [7] = "FSM (MAC anti-spoofing) support",
                [8] = "Dynamic QP updates support",
-               [9] = "TCP/IP offloads/flow-steering for VXLAN support"
+               [9] = "Device managed flow steering IPoIB support",
+               [10] = "TCP/IP offloads/flow-steering for VXLAN support"
        };
        int i;
 
@@ -859,7 +860,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET);
 
        /* For guests, disable vxlan tunneling */
-       MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN);
+       MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VXLAN);
        field &= 0xf7;
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN);
 
@@ -869,7 +870,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET);
 
        /* For guests, disable mw type 2 */
-       MLX4_GET(bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
+       MLX4_GET(bmme_flags, outbox->buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
        bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
        MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
 
@@ -883,7 +884,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        }
 
        /* turn off ipoib managed steering for guests */
-       MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
+       MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
        field &= ~0x80;
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
 
index d711158b0d4b1ab59bb3d1cf8973e8d4936ce853..936c15364739171993bfcb52598bd03f5be8afb6 100644 (file)
@@ -150,6 +150,8 @@ struct mlx4_port_config {
        struct pci_dev *pdev;
 };
 
+static atomic_t pf_loading = ATOMIC_INIT(0);
+
 int mlx4_check_port_params(struct mlx4_dev *dev,
                           enum mlx4_port_type *port_type)
 {
@@ -749,7 +751,7 @@ static void mlx4_request_modules(struct mlx4_dev *dev)
                        has_eth_port = true;
        }
 
-       if (has_ib_port)
+       if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
                request_module_nowait(IB_DRV_NAME);
        if (has_eth_port)
                request_module_nowait(EN_DRV_NAME);
@@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev)
        u32 slave_read;
        u32 cmd_channel_ver;
 
+       if (atomic_read(&pf_loading)) {
+               mlx4_warn(dev, "PF is not ready. Deferring probe\n");
+               return -EPROBE_DEFER;
+       }
+
        mutex_lock(&priv->cmd.slave_cmd_mutex);
        priv->cmd.max_cmds = 1;
        mlx4_warn(dev, "Sending reset\n");
@@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
 
                if (num_vfs) {
                        mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs);
+
+                       atomic_inc(&pf_loading);
                        err = pci_enable_sriov(pdev, num_vfs);
+                       atomic_dec(&pf_loading);
+
                        if (err) {
                                mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
                                         err);
@@ -2684,6 +2695,7 @@ static struct pci_driver mlx4_driver = {
        .name           = DRV_NAME,
        .id_table       = mlx4_pci_table,
        .probe          = mlx4_init_one,
+       .shutdown       = mlx4_remove_one,
        .remove         = mlx4_remove_one,
        .err_handler    = &mlx4_err_handler,
 };
index e9779653cd4ce6cee899f92694b071ed5e7cd7a8..3ff7bc3e7a23ba419c9957917a9471a939db54f2 100644 (file)
@@ -209,7 +209,7 @@ static const struct {
        [RTL_GIGA_MAC_VER_16] =
                _R("RTL8101e",          RTL_TD_0, NULL, JUMBO_1K, true),
        [RTL_GIGA_MAC_VER_17] =
-               _R("RTL8168b/8111b",    RTL_TD_1, NULL, JUMBO_4K, false),
+               _R("RTL8168b/8111b",    RTL_TD_0, NULL, JUMBO_4K, false),
        [RTL_GIGA_MAC_VER_18] =
                _R("RTL8168cp/8111cp",  RTL_TD_1, NULL, JUMBO_6K, false),
        [RTL_GIGA_MAC_VER_19] =
index 72d282bf33a51e8e2cb0036cac6fd03fe19acdf0..c553f6b5a9131f0af16230f59ccd0557fe1116a5 100644 (file)
@@ -151,7 +151,7 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
                                          sizeof(struct dma_desc)));
 }
 
-const struct stmmac_chain_mode_ops chain_mode_ops = {
+const struct stmmac_mode_ops chain_mode_ops = {
        .init = stmmac_init_dma_chain,
        .is_jumbo_frm = stmmac_is_jumbo_frm,
        .jumbo_frm = stmmac_jumbo_frm,
index 7834a39939464a844fd4fd8bf8ecbc2f9f8847c0..74610f3aca9e5bc8670c49f4a25901c4b4575136 100644 (file)
@@ -419,20 +419,13 @@ struct mii_regs {
        unsigned int data;      /* MII Data */
 };
 
-struct stmmac_ring_mode_ops {
-       unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
-       unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
-       void (*refill_desc3) (void *priv, struct dma_desc *p);
-       void (*init_desc3) (struct dma_desc *p);
-       void (*clean_desc3) (void *priv, struct dma_desc *p);
-       int (*set_16kib_bfsize) (int mtu);
-};
-
-struct stmmac_chain_mode_ops {
+struct stmmac_mode_ops {
        void (*init) (void *des, dma_addr_t phy_addr, unsigned int size,
                      unsigned int extend_desc);
        unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
        unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
+       int (*set_16kib_bfsize)(int mtu);
+       void (*init_desc3)(struct dma_desc *p);
        void (*refill_desc3) (void *priv, struct dma_desc *p);
        void (*clean_desc3) (void *priv, struct dma_desc *p);
 };
@@ -441,8 +434,7 @@ struct mac_device_info {
        const struct stmmac_ops *mac;
        const struct stmmac_desc_ops *desc;
        const struct stmmac_dma_ops *dma;
-       const struct stmmac_ring_mode_ops *ring;
-       const struct stmmac_chain_mode_ops *chain;
+       const struct stmmac_mode_ops *mode;
        const struct stmmac_hwtimestamp *ptp;
        struct mii_regs mii;    /* MII register Addresses */
        struct mac_link link;
@@ -460,7 +452,7 @@ void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
 void stmmac_set_mac(void __iomem *ioaddr, bool enable);
 
 void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
-extern const struct stmmac_ring_mode_ops ring_mode_ops;
-extern const struct stmmac_chain_mode_ops chain_mode_ops;
+extern const struct stmmac_mode_ops ring_mode_ops;
+extern const struct stmmac_mode_ops chain_mode_ops;
 
 #endif /* __COMMON_H__ */
index a96c7c2f5f3f220b32df9c0ebad2b197e7ecd45a..650a4be6bce5243e046fcd226719e669f66444e8 100644 (file)
@@ -100,10 +100,9 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
 {
        struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
 
-       if (unlikely(priv->plat->has_gmac))
-               /* Fill DES3 in case of RING mode */
-               if (priv->dma_buf_sz >= BUF_SIZE_8KiB)
-                       p->des3 = p->des2 + BUF_SIZE_8KiB;
+       /* Fill DES3 in case of RING mode */
+       if (priv->dma_buf_sz >= BUF_SIZE_8KiB)
+               p->des3 = p->des2 + BUF_SIZE_8KiB;
 }
 
 /* In ring mode we need to fill the desc3 because it is used as buffer */
@@ -126,7 +125,7 @@ static int stmmac_set_16kib_bfsize(int mtu)
        return ret;
 }
 
-const struct stmmac_ring_mode_ops ring_mode_ops = {
+const struct stmmac_mode_ops ring_mode_ops = {
        .is_jumbo_frm = stmmac_is_jumbo_frm,
        .jumbo_frm = stmmac_jumbo_frm,
        .refill_desc3 = stmmac_refill_desc3,
index 078ad0ec859307270e432bd0c20658440eebc0fd..8543e1cfd55edb4a60f5cb543a1e5ea9fc18a097 100644 (file)
@@ -92,8 +92,8 @@ static int tc = TC_DEFAULT;
 module_param(tc, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(tc, "DMA threshold control value");
 
-#define DMA_BUFFER_SIZE        BUF_SIZE_4KiB
-static int buf_sz = DMA_BUFFER_SIZE;
+#define        DEFAULT_BUFSIZE 1536
+static int buf_sz = DEFAULT_BUFSIZE;
 module_param(buf_sz, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(buf_sz, "DMA buffer size");
 
@@ -136,8 +136,8 @@ static void stmmac_verify_args(void)
                dma_rxsize = DMA_RX_SIZE;
        if (unlikely(dma_txsize < 0))
                dma_txsize = DMA_TX_SIZE;
-       if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
-               buf_sz = DMA_BUFFER_SIZE;
+       if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB)))
+               buf_sz = DEFAULT_BUFSIZE;
        if (unlikely(flow_ctrl > 1))
                flow_ctrl = FLOW_AUTO;
        else if (likely(flow_ctrl < 0))
@@ -286,10 +286,25 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
 
        /* MAC core supports the EEE feature. */
        if (priv->dma_cap.eee) {
+               int tx_lpi_timer = priv->tx_lpi_timer;
+
                /* Check if the PHY supports EEE */
-               if (phy_init_eee(priv->phydev, 1))
+               if (phy_init_eee(priv->phydev, 1)) {
+                       /* To manage at run-time if the EEE cannot be supported
+                        * anymore (for example because the lp caps have been
+                        * changed).
+                        * In that case the driver disable own timers.
+                        */
+                       if (priv->eee_active) {
+                               pr_debug("stmmac: disable EEE\n");
+                               del_timer_sync(&priv->eee_ctrl_timer);
+                               priv->hw->mac->set_eee_timer(priv->ioaddr, 0,
+                                                            tx_lpi_timer);
+                       }
+                       priv->eee_active = 0;
                        goto out;
-
+               }
+               /* Activate the EEE and start timers */
                if (!priv->eee_active) {
                        priv->eee_active = 1;
                        init_timer(&priv->eee_ctrl_timer);
@@ -300,13 +315,13 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
 
                        priv->hw->mac->set_eee_timer(priv->ioaddr,
                                                     STMMAC_DEFAULT_LIT_LS,
-                                                    priv->tx_lpi_timer);
+                                                    tx_lpi_timer);
                } else
                        /* Set HW EEE according to the speed */
                        priv->hw->mac->set_eee_pls(priv->ioaddr,
                                                   priv->phydev->link);
 
-               pr_info("stmmac: Energy-Efficient Ethernet initialized\n");
+               pr_debug("stmmac: Energy-Efficient Ethernet initialized\n");
 
                ret = true;
        }
@@ -886,10 +901,10 @@ static int stmmac_set_bfsize(int mtu, int bufsize)
                ret = BUF_SIZE_8KiB;
        else if (mtu >= BUF_SIZE_2KiB)
                ret = BUF_SIZE_4KiB;
-       else if (mtu >= DMA_BUFFER_SIZE)
+       else if (mtu > DEFAULT_BUFSIZE)
                ret = BUF_SIZE_2KiB;
        else
-               ret = DMA_BUFFER_SIZE;
+               ret = DEFAULT_BUFSIZE;
 
        return ret;
 }
@@ -951,9 +966,9 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
 
        p->des2 = priv->rx_skbuff_dma[i];
 
-       if ((priv->mode == STMMAC_RING_MODE) &&
+       if ((priv->hw->mode->init_desc3) &&
            (priv->dma_buf_sz == BUF_SIZE_16KiB))
-               priv->hw->ring->init_desc3(p);
+               priv->hw->mode->init_desc3(p);
 
        return 0;
 }
@@ -984,11 +999,8 @@ static int init_dma_desc_rings(struct net_device *dev)
        unsigned int bfsize = 0;
        int ret = -ENOMEM;
 
-       /* Set the max buffer size according to the DESC mode
-        * and the MTU. Note that RING mode allows 16KiB bsize.
-        */
-       if (priv->mode == STMMAC_RING_MODE)
-               bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu);
+       if (priv->hw->mode->set_16kib_bfsize)
+               bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu);
 
        if (bfsize < BUF_SIZE_16KiB)
                bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
@@ -1029,15 +1041,15 @@ static int init_dma_desc_rings(struct net_device *dev)
        /* Setup the chained descriptor addresses */
        if (priv->mode == STMMAC_CHAIN_MODE) {
                if (priv->extend_desc) {
-                       priv->hw->chain->init(priv->dma_erx, priv->dma_rx_phy,
-                                             rxsize, 1);
-                       priv->hw->chain->init(priv->dma_etx, priv->dma_tx_phy,
-                                             txsize, 1);
+                       priv->hw->mode->init(priv->dma_erx, priv->dma_rx_phy,
+                                            rxsize, 1);
+                       priv->hw->mode->init(priv->dma_etx, priv->dma_tx_phy,
+                                            txsize, 1);
                } else {
-                       priv->hw->chain->init(priv->dma_rx, priv->dma_rx_phy,
-                                             rxsize, 0);
-                       priv->hw->chain->init(priv->dma_tx, priv->dma_tx_phy,
-                                             txsize, 0);
+                       priv->hw->mode->init(priv->dma_rx, priv->dma_rx_phy,
+                                            rxsize, 0);
+                       priv->hw->mode->init(priv->dma_tx, priv->dma_tx_phy,
+                                            txsize, 0);
                }
        }
 
@@ -1288,7 +1300,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
                                         DMA_TO_DEVICE);
                        priv->tx_skbuff_dma[entry] = 0;
                }
-               priv->hw->ring->clean_desc3(priv, p);
+               priv->hw->mode->clean_desc3(priv, p);
 
                if (likely(skb != NULL)) {
                        dev_kfree_skb(skb);
@@ -1844,6 +1856,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        int nfrags = skb_shinfo(skb)->nr_frags;
        struct dma_desc *desc, *first;
        unsigned int nopaged_len = skb_headlen(skb);
+       unsigned int enh_desc = priv->plat->enh_desc;
 
        if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
                if (!netif_queue_stopped(dev)) {
@@ -1871,27 +1884,19 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        first = desc;
 
        /* To program the descriptors according to the size of the frame */
-       if (priv->mode == STMMAC_RING_MODE) {
-               is_jumbo = priv->hw->ring->is_jumbo_frm(skb->len,
-                                                       priv->plat->enh_desc);
-               if (unlikely(is_jumbo))
-                       entry = priv->hw->ring->jumbo_frm(priv, skb,
-                                                         csum_insertion);
-       } else {
-               is_jumbo = priv->hw->chain->is_jumbo_frm(skb->len,
-                                                        priv->plat->enh_desc);
-               if (unlikely(is_jumbo))
-                       entry = priv->hw->chain->jumbo_frm(priv, skb,
-                                                          csum_insertion);
-       }
+       if (enh_desc)
+               is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc);
+
        if (likely(!is_jumbo)) {
                desc->des2 = dma_map_single(priv->device, skb->data,
                                            nopaged_len, DMA_TO_DEVICE);
                priv->tx_skbuff_dma[entry] = desc->des2;
                priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
                                                csum_insertion, priv->mode);
-       } else
+       } else {
                desc = first;
+               entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion);
+       }
 
        for (i = 0; i < nfrags; i++) {
                const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2029,7 +2034,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
 
                        p->des2 = priv->rx_skbuff_dma[entry];
 
-                       priv->hw->ring->refill_desc3(priv, p);
+                       priv->hw->mode->refill_desc3(priv, p);
 
                        if (netif_msg_rx_status(priv))
                                pr_debug("\trefill entry #%d\n", entry);
@@ -2633,11 +2638,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
 
        /* To use the chained or ring mode */
        if (chain_mode) {
-               priv->hw->chain = &chain_mode_ops;
+               priv->hw->mode = &chain_mode_ops;
                pr_info(" Chain mode enabled\n");
                priv->mode = STMMAC_CHAIN_MODE;
        } else {
-               priv->hw->ring = &ring_mode_ops;
+               priv->hw->mode = &ring_mode_ops;
                pr_info(" Ring mode enabled\n");
                priv->mode = STMMAC_RING_MODE;
        }
index c61bc72b8e9006a2f8cb654421a7aaed50730436..8fb32a80f1c1999a18234a2daec7323affd3917a 100644 (file)
@@ -36,7 +36,7 @@ static const struct of_device_id stmmac_dt_ids[] = {
 #ifdef CONFIG_DWMAC_STI
        { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data},
        { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data},
-       { .compatible = "st,stih127-dwmac", .data = &sti_gmac_data},
+       { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data},
 #endif
        /* SoC specific glue layers should come before generic bindings */
        { .compatible = "st,spear600-gmac"},
index 7141a1937360fabe59070e983c8737701307b48b..d6fce9750b9553b221759f18fd4ec48158af4e73 100644 (file)
@@ -442,6 +442,8 @@ static int netvsc_probe(struct hv_device *dev,
        if (!net)
                return -ENOMEM;
 
+       netif_carrier_off(net);
+
        net_device_ctx = netdev_priv(net);
        net_device_ctx->device_ctx = dev;
        hv_set_drvdata(dev, net);
@@ -473,6 +475,8 @@ static int netvsc_probe(struct hv_device *dev,
                pr_err("Unable to register netdev.\n");
                rndis_filter_device_remove(dev);
                free_netdev(net);
+       } else {
+               schedule_delayed_work(&net_device_ctx->dwork, 0);
        }
 
        return ret;
index 1084e5de3ceb4c805d2ef9e98b90c6d68a9a9991..b54fd257652bb629b8228162712bb557e9023943 100644 (file)
@@ -243,6 +243,22 @@ static int rndis_filter_send_request(struct rndis_device *dev,
        return ret;
 }
 
+static void rndis_set_link_state(struct rndis_device *rdev,
+                                struct rndis_request *request)
+{
+       u32 link_status;
+       struct rndis_query_complete *query_complete;
+
+       query_complete = &request->response_msg.msg.query_complete;
+
+       if (query_complete->status == RNDIS_STATUS_SUCCESS &&
+           query_complete->info_buflen == sizeof(u32)) {
+               memcpy(&link_status, (void *)((unsigned long)query_complete +
+                      query_complete->info_buf_offset), sizeof(u32));
+               rdev->link_state = link_status != 0;
+       }
+}
+
 static void rndis_filter_receive_response(struct rndis_device *dev,
                                       struct rndis_message *resp)
 {
@@ -272,6 +288,10 @@ static void rndis_filter_receive_response(struct rndis_device *dev,
                    sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
                        memcpy(&request->response_msg, resp,
                               resp->msg_len);
+                       if (request->request_msg.ndis_msg_type ==
+                           RNDIS_MSG_QUERY && request->request_msg.msg.
+                           query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS)
+                               rndis_set_link_state(dev, request);
                } else {
                        netdev_err(ndev,
                                "rndis response buffer overflow "
@@ -620,7 +640,6 @@ static int rndis_filter_query_device_link_status(struct rndis_device *dev)
        ret = rndis_filter_query_device(dev,
                                      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
                                      &link_status, &size);
-       dev->link_state = (link_status != 0) ? true : false;
 
        return ret;
 }
index ab31544bc25487ac82b1703beef9df6c069e615e..a30258aad139e9ae3491c92211a191f9aea42cc6 100644 (file)
@@ -546,12 +546,12 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
        int rc;
        unsigned long flags;
 
-       spin_lock(&lp->lock);
+       spin_lock_irqsave(&lp->lock, flags);
        if  (lp->irq_busy) {
-               spin_unlock(&lp->lock);
+               spin_unlock_irqrestore(&lp->lock, flags);
                return -EBUSY;
        }
-       spin_unlock(&lp->lock);
+       spin_unlock_irqrestore(&lp->lock, flags);
 
        might_sleep();
 
@@ -725,10 +725,11 @@ static void at86rf230_irqwork_level(struct work_struct *work)
 static irqreturn_t at86rf230_isr(int irq, void *data)
 {
        struct at86rf230_local *lp = data;
+       unsigned long flags;
 
-       spin_lock(&lp->lock);
+       spin_lock_irqsave(&lp->lock, flags);
        lp->irq_busy = 1;
-       spin_unlock(&lp->lock);
+       spin_unlock_irqrestore(&lp->lock, flags);
 
        schedule_work(&lp->irqwork);
 
index 19c9eca0ef2638165dc9dc087d87aee934d28348..76d96b9ebcdb94d2e57c3f52d5b49a41e7397ab4 100644 (file)
@@ -164,9 +164,9 @@ static const struct phy_setting settings[] = {
  *   of that setting.  Returns the index of the last setting if
  *   none of the others match.
  */
-static inline int phy_find_setting(int speed, int duplex)
+static inline unsigned int phy_find_setting(int speed, int duplex)
 {
-       int idx = 0;
+       unsigned int idx = 0;
 
        while (idx < ARRAY_SIZE(settings) &&
               (settings[idx].speed != speed || settings[idx].duplex != duplex))
@@ -185,7 +185,7 @@ static inline int phy_find_setting(int speed, int duplex)
  *   the mask in features.  Returns the index of the last setting
  *   if nothing else matches.
  */
-static inline int phy_find_valid(int idx, u32 features)
+static inline unsigned int phy_find_valid(unsigned int idx, u32 features)
 {
        while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features))
                idx++;
@@ -204,7 +204,7 @@ static inline int phy_find_valid(int idx, u32 features)
 static void phy_sanitize_settings(struct phy_device *phydev)
 {
        u32 features = phydev->supported;
-       int idx;
+       unsigned int idx;
 
        /* Sanitize settings based on PHY capabilities */
        if ((features & SUPPORTED_Autoneg) == 0)
@@ -954,7 +954,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
            (phydev->interface == PHY_INTERFACE_MODE_RGMII))) {
                int eee_lp, eee_cap, eee_adv;
                u32 lp, cap, adv;
-               int idx, status;
+               int status;
+               unsigned int idx;
 
                /* Read phy status to properly get the right settings */
                status = phy_read_status(phydev);
index 433f0a00c68324e46e60aa04b8e16989fac36701..e2797f1e1b31ee51f82c11d50b23e6bd274d29ab 100644 (file)
@@ -11,7 +11,7 @@ obj-$(CONFIG_USB_HSO)         += hso.o
 obj-$(CONFIG_USB_NET_AX8817X)  += asix.o
 asix-y := asix_devices.o asix_common.o ax88172a.o
 obj-$(CONFIG_USB_NET_AX88179_178A)      += ax88179_178a.o
-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o
+obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
index 42e176912c8ea151606883c0b8563e45fa95a447..bd363b27e8540e3bfe2acc6173adcc8a1952f4b7 100644 (file)
@@ -652,6 +652,13 @@ static const struct usb_device_id  products[] = {
        .driver_info = 0,
 },
 
+/* Samsung USB Ethernet Adapters */
+{
+       USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+       .driver_info = 0,
+},
+
 /* WHITELIST!!!
  *
  * CDC Ether uses two interfaces, not necessarily consecutive.
index d89dbe395ad2929441bec4a3d6cdf96b1ffe8686..adb12f349a61fc58582d2092c49db5a9ceb7b7cf 100644 (file)
@@ -449,9 +449,6 @@ enum rtl8152_flags {
 #define MCU_TYPE_PLA                   0x0100
 #define MCU_TYPE_USB                   0x0000
 
-#define REALTEK_USB_DEVICE(vend, prod) \
-       USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC)
-
 struct rx_desc {
        __le32 opts1;
 #define RX_LEN_MASK                    0x7fff
@@ -2739,6 +2736,12 @@ static int rtl8152_probe(struct usb_interface *intf,
        struct net_device *netdev;
        int ret;
 
+       if (udev->actconfig->desc.bConfigurationValue != 1) {
+               usb_driver_set_configuration(udev, 1);
+               return -ENODEV;
+       }
+
+       usb_reset_device(udev);
        netdev = alloc_etherdev(sizeof(struct r8152));
        if (!netdev) {
                dev_err(&intf->dev, "Out of memory\n");
@@ -2819,9 +2822,9 @@ static void rtl8152_disconnect(struct usb_interface *intf)
 
 /* table of devices that work with this driver */
 static struct usb_device_id rtl8152_table[] = {
-       {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)},
-       {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)},
-       {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)},
+       {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)},
+       {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)},
+       {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)},
        {}
 };
 
diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c
deleted file mode 100644 (file)
index f0a8791..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/mii.h>
-#include <linux/usb.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/usbnet.h>
-
-#define RTL815x_REQT_READ      0xc0
-#define RTL815x_REQT_WRITE     0x40
-#define RTL815x_REQ_GET_REGS   0x05
-#define RTL815x_REQ_SET_REGS   0x05
-
-#define MCU_TYPE_PLA           0x0100
-#define OCP_BASE               0xe86c
-#define BASE_MII               0xa400
-
-#define BYTE_EN_DWORD          0xff
-#define BYTE_EN_WORD           0x33
-#define BYTE_EN_BYTE           0x11
-
-#define R815x_PHY_ID           32
-#define REALTEK_VENDOR_ID      0x0bda
-
-
-static int pla_read_word(struct usb_device *udev, u16 index)
-{
-       int ret;
-       u8 shift = index & 2;
-       __le32 *tmp;
-
-       tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-
-       index &= ~3;
-
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                             RTL815x_REQ_GET_REGS, RTL815x_REQT_READ,
-                             index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500);
-       if (ret < 0)
-               goto out2;
-
-       ret = __le32_to_cpu(*tmp);
-       ret >>= (shift * 8);
-       ret &= 0xffff;
-
-out2:
-       kfree(tmp);
-       return ret;
-}
-
-static int pla_write_word(struct usb_device *udev, u16 index, u32 data)
-{
-       __le32 *tmp;
-       u32 mask = 0xffff;
-       u16 byen = BYTE_EN_WORD;
-       u8 shift = index & 2;
-       int ret;
-
-       tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-
-       data &= mask;
-
-       if (shift) {
-               byen <<= shift;
-               mask <<= (shift * 8);
-               data <<= (shift * 8);
-               index &= ~3;
-       }
-
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
-                             RTL815x_REQ_GET_REGS, RTL815x_REQT_READ,
-                             index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500);
-       if (ret < 0)
-               goto out3;
-
-       data |= __le32_to_cpu(*tmp) & ~mask;
-       *tmp = __cpu_to_le32(data);
-
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                             RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE,
-                             index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp),
-                             500);
-
-out3:
-       kfree(tmp);
-       return ret;
-}
-
-static int ocp_reg_read(struct usbnet *dev, u16 addr)
-{
-       u16 ocp_base, ocp_index;
-       int ret;
-
-       ocp_base = addr & 0xf000;
-       ret = pla_write_word(dev->udev, OCP_BASE, ocp_base);
-       if (ret < 0)
-               goto out;
-
-       ocp_index = (addr & 0x0fff) | 0xb000;
-       ret = pla_read_word(dev->udev, ocp_index);
-
-out:
-       return ret;
-}
-
-static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data)
-{
-       u16 ocp_base, ocp_index;
-       int ret;
-
-       ocp_base = addr & 0xf000;
-       ret = pla_write_word(dev->udev, OCP_BASE, ocp_base);
-       if (ret < 0)
-               goto out1;
-
-       ocp_index = (addr & 0x0fff) | 0xb000;
-       ret = pla_write_word(dev->udev, ocp_index, data);
-
-out1:
-       return ret;
-}
-
-static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg)
-{
-       struct usbnet *dev = netdev_priv(netdev);
-       int ret;
-
-       if (phy_id != R815x_PHY_ID)
-               return -EINVAL;
-
-       if (usb_autopm_get_interface(dev->intf) < 0)
-               return -ENODEV;
-
-       ret = ocp_reg_read(dev, BASE_MII + reg * 2);
-
-       usb_autopm_put_interface(dev->intf);
-       return ret;
-}
-
-static
-void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val)
-{
-       struct usbnet *dev = netdev_priv(netdev);
-
-       if (phy_id != R815x_PHY_ID)
-               return;
-
-       if (usb_autopm_get_interface(dev->intf) < 0)
-               return;
-
-       ocp_reg_write(dev, BASE_MII + reg * 2, val);
-
-       usb_autopm_put_interface(dev->intf);
-}
-
-static int r8153_bind(struct usbnet *dev, struct usb_interface *intf)
-{
-       int status;
-
-       status = usbnet_cdc_bind(dev, intf);
-       if (status < 0)
-               return status;
-
-       dev->mii.dev = dev->net;
-       dev->mii.mdio_read = r815x_mdio_read;
-       dev->mii.mdio_write = r815x_mdio_write;
-       dev->mii.phy_id_mask = 0x3f;
-       dev->mii.reg_num_mask = 0x1f;
-       dev->mii.phy_id = R815x_PHY_ID;
-       dev->mii.supports_gmii = 1;
-
-       return status;
-}
-
-static int r8152_bind(struct usbnet *dev, struct usb_interface *intf)
-{
-       int status;
-
-       status = usbnet_cdc_bind(dev, intf);
-       if (status < 0)
-               return status;
-
-       dev->mii.dev = dev->net;
-       dev->mii.mdio_read = r815x_mdio_read;
-       dev->mii.mdio_write = r815x_mdio_write;
-       dev->mii.phy_id_mask = 0x3f;
-       dev->mii.reg_num_mask = 0x1f;
-       dev->mii.phy_id = R815x_PHY_ID;
-       dev->mii.supports_gmii = 0;
-
-       return status;
-}
-
-static const struct driver_info r8152_info = {
-       .description =  "RTL8152 ECM Device",
-       .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
-       .bind =         r8152_bind,
-       .unbind =       usbnet_cdc_unbind,
-       .status =       usbnet_cdc_status,
-       .manage_power = usbnet_manage_power,
-};
-
-static const struct driver_info r8153_info = {
-       .description =  "RTL8153 ECM Device",
-       .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
-       .bind =         r8153_bind,
-       .unbind =       usbnet_cdc_unbind,
-       .status =       usbnet_cdc_status,
-       .manage_power = usbnet_manage_power,
-};
-
-static const struct usb_device_id products[] = {
-{
-       USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
-                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-       .driver_info = (unsigned long) &r8152_info,
-},
-
-{
-       USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM,
-                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
-       .driver_info = (unsigned long) &r8153_info,
-},
-
-       { },            /* END */
-};
-MODULE_DEVICE_TABLE(usb, products);
-
-static struct usb_driver r815x_driver = {
-       .name =         "r815x",
-       .id_table =     products,
-       .probe =        usbnet_probe,
-       .disconnect =   usbnet_disconnect,
-       .suspend =      usbnet_suspend,
-       .resume =       usbnet_resume,
-       .reset_resume = usbnet_resume,
-       .supports_autosuspend = 1,
-       .disable_hub_initiated_lpm = 1,
-};
-
-module_usb_driver(r815x_driver);
-
-MODULE_AUTHOR("Hayes Wang");
-MODULE_DESCRIPTION("Realtek USB ECM device");
-MODULE_LICENSE("GPL");
index 3be786faaaec222f0226b8285dde01e88b147e59..0fa3b44f7342dc0cf979cf69b6b1d6c3444411f3 100644 (file)
@@ -1762,11 +1762,20 @@ vmxnet3_netpoll(struct net_device *netdev)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 
-       if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
-               vmxnet3_disable_all_intrs(adapter);
-
-       vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size);
-       vmxnet3_enable_all_intrs(adapter);
+       switch (adapter->intr.type) {
+#ifdef CONFIG_PCI_MSI
+       case VMXNET3_IT_MSIX: {
+               int i;
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       vmxnet3_msix_rx(0, &adapter->rx_queue[i]);
+               break;
+       }
+#endif
+       case VMXNET3_IT_MSI:
+       default:
+               vmxnet3_intr(0, adapter->netdev);
+               break;
+       }
 
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
index 76cde6ce6551dc0a9996a91edc36cad5b40e5588..18a895a949d4520a02af0f34232f6a739a4c4552 100644 (file)
@@ -872,8 +872,11 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        lockdep_assert_held(&mvm->mutex);
 
-       /* Rssi update while not associated ?! */
-       if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT))
+       /*
+        * Rssi update while not associated - can happen since the statistics
+        * are handled asynchronously
+        */
+       if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
                return;
 
        /* No BT - reports should be disabled */
index f47bcbe2945aabf35702cd0319ba322bf073aef7..3872ead75488d6ac485a5cb147a4037988f7ee89 100644 (file)
@@ -359,13 +359,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 /* 7265 Series */
        {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
-       {IWL_PCI_DEVICE(0x095A, 0x5112, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)},
-       {IWL_PCI_DEVICE(0x095A, 0x510A, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
-       {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)},
        {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
index 5e0eec4d71c7a5d61e4d65b73ca503aaaf54a085..5d9a8084665d5176fc3b54afd62c1b821c7278df 100644 (file)
@@ -189,8 +189,7 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
                vht_cap->header.len  =
                                cpu_to_le16(sizeof(struct ieee80211_vht_cap));
                memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header),
-                      (u8 *)bss_desc->bcn_vht_cap +
-                      sizeof(struct ieee_types_header),
+                      (u8 *)bss_desc->bcn_vht_cap,
                       le16_to_cpu(vht_cap->header.len));
 
                mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band);
index 6261f8c53d44bd7a6ba4f30651bfc8c67da6f4e5..7db1a89fdd9559fda27bf19a17c114e2b4643d56 100644 (file)
@@ -308,8 +308,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
                ht_cap->header.len =
                                cpu_to_le16(sizeof(struct ieee80211_ht_cap));
                memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header),
-                      (u8 *) bss_desc->bcn_ht_cap +
-                      sizeof(struct ieee_types_header),
+                      (u8 *)bss_desc->bcn_ht_cap,
                       le16_to_cpu(ht_cap->header.len));
 
                mwifiex_fill_cap_info(priv, radio_type, ht_cap);
index 0a8a26e10f01a421361a5872065954a8ae79c614..668547c2de8464ed93fedc37066ef0fc3c50f320 100644 (file)
@@ -2101,12 +2101,12 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
                         curr_bss->ht_info_offset);
 
        if (curr_bss->bcn_vht_cap)
-               curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf +
-                                               curr_bss->vht_cap_offset);
+               curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf +
+                                                curr_bss->vht_cap_offset);
 
        if (curr_bss->bcn_vht_oper)
-               curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf +
-                                                curr_bss->vht_info_offset);
+               curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf +
+                                                 curr_bss->vht_info_offset);
 
        if (curr_bss->bcn_bss_co_2040)
                curr_bss->bcn_bss_co_2040 =
index 123c4bb50e0a0c2eff220c4509c2ece5aab7b365..cde0eaf99714b4054176bd7a3cad9e850d97abea 100644 (file)
@@ -180,7 +180,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
        wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
 
        /* The actual length doesn't include the target's alignment */
-       skb->len = desc->length  - PLCP_HEADER_LENGTH;
+       skb_trim(skb, desc->length - PLCP_HEADER_LENGTH);
 
        fc = (u16 *)skb->data;
 
index 7669d49a67e2271bebe14e80aaaa9c59312edea2..301cc037fda886f2bc2de48a347a8693eadee178 100644 (file)
@@ -132,8 +132,7 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* If the skb is GSO then we'll also need an extra slot for the
         * metadata.
         */
-       if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 ||
-           skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+       if (skb_is_gso(skb))
                min_slots_needed++;
 
        /* If the skb can't possibly fit in the remaining slots
index e5284bca2d90e6e80ec0d682475404e9dc236e33..438d0c09b7e6019b513f8e996f5549bb327463d2 100644 (file)
@@ -240,7 +240,7 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
        struct gnttab_copy *copy_gop;
        struct xenvif_rx_meta *meta;
        unsigned long bytes;
-       int gso_type;
+       int gso_type = XEN_NETIF_GSO_TYPE_NONE;
 
        /* Data must not cross a page boundary. */
        BUG_ON(size + offset > PAGE_SIZE<<compound_order(page));
@@ -299,12 +299,12 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
                }
 
                /* Leave a gap for the GSO descriptor. */
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
-                       gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
-               else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-                       gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
-               else
-                       gso_type = XEN_NETIF_GSO_TYPE_NONE;
+               if (skb_is_gso(skb)) {
+                       if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+                               gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
+                       else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+                               gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
+               }
 
                if (*head && ((1 << gso_type) & vif->gso_mask))
                        vif->rx.req_cons++;
@@ -338,19 +338,15 @@ static int xenvif_gop_skb(struct sk_buff *skb,
        int head = 1;
        int old_meta_prod;
        int gso_type;
-       int gso_size;
 
        old_meta_prod = npo->meta_prod;
 
-       if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
-               gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
-               gso_size = skb_shinfo(skb)->gso_size;
-       } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
-               gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
-               gso_size = skb_shinfo(skb)->gso_size;
-       } else {
-               gso_type = XEN_NETIF_GSO_TYPE_NONE;
-               gso_size = 0;
+       gso_type = XEN_NETIF_GSO_TYPE_NONE;
+       if (skb_is_gso(skb)) {
+               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+                       gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
+               else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+                       gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
        }
 
        /* Set up a GSO prefix descriptor, if necessary */
@@ -358,7 +354,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
                req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
                meta = npo->meta + npo->meta_prod++;
                meta->gso_type = gso_type;
-               meta->gso_size = gso_size;
+               meta->gso_size = skb_shinfo(skb)->gso_size;
                meta->size = 0;
                meta->id = req->id;
        }
@@ -368,7 +364,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
 
        if ((1 << gso_type) & vif->gso_mask) {
                meta->gso_type = gso_type;
-               meta->gso_size = gso_size;
+               meta->gso_size = skb_shinfo(skb)->gso_size;
        } else {
                meta->gso_type = XEN_NETIF_GSO_TYPE_NONE;
                meta->gso_size = 0;
@@ -500,8 +496,9 @@ static void xenvif_rx_action(struct xenvif *vif)
                        size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
                        max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE);
                }
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 ||
-                   skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+               if (skb_is_gso(skb) &&
+                  (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 ||
+                   skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6))
                        max_slots_needed++;
 
                /* If the skb may not fit then bail out now */
index 00660cc502c5e0df1da9946281ba2b6fa6d08afc..38901665c77086a20a6bd1cd087f24971c0d172b 100644 (file)
@@ -162,8 +162,6 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
 
                avail = *r;
                pci_clip_resource_to_region(bus, &avail, region);
-               if (!resource_size(&avail))
-                       continue;
 
                /*
                 * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to
index 6b05f6134b68700dc1450b249b1f9bfe7b43bdca..fdbc294821e6468d55ca7d5fd68162b407607e97 100644 (file)
@@ -1192,6 +1192,9 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
                return err;
        pci_fixup_device(pci_fixup_enable, dev);
 
+       if (dev->msi_enabled || dev->msix_enabled)
+               return 0;
+
        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
        if (pin) {
                pci_read_config_word(dev, PCI_COMMAND, &cmd);
index 167f3d00c916d2e30a63dcc31d260a45d1e5cada..66977ebf13b30cba09b6bb1b7c06eeb07e2e5bd0 100644 (file)
@@ -183,9 +183,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        struct resource r = {0};
        int i, flags;
 
-       if (acpi_dev_resource_memory(res, &r)
-           || acpi_dev_resource_io(res, &r)
-           || acpi_dev_resource_address_space(res, &r)
+       if (acpi_dev_resource_address_space(res, &r)
            || acpi_dev_resource_ext_address_space(res, &r)) {
                pnp_add_resource(dev, &r);
                return AE_OK;
@@ -217,6 +215,17 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        }
 
        switch (res->type) {
+       case ACPI_RESOURCE_TYPE_MEMORY24:
+       case ACPI_RESOURCE_TYPE_MEMORY32:
+       case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+               if (acpi_dev_resource_memory(res, &r))
+                       pnp_add_resource(dev, &r);
+               break;
+       case ACPI_RESOURCE_TYPE_IO:
+       case ACPI_RESOURCE_TYPE_FIXED_IO:
+               if (acpi_dev_resource_io(res, &r))
+                       pnp_add_resource(dev, &r);
+               break;
        case ACPI_RESOURCE_TYPE_DMA:
                dma = &res->data.dma;
                if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
index 1f375051483a428d24c63c206fb24a40cda06211..5642a9b250c2fe11201510460563ec576c70461c 100644 (file)
@@ -325,7 +325,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
                if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
                        continue;
 
-               if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
+               if (sc->device->lun != abrt_task->sc->device->lun)
                        continue;
 
                /* Invalidate WRB Posted for this Task */
index 4911310a38f5e42fd9d292b89de93b57369c7419..22a9bb1abae1473062b06031494bb38b2cc11576 100644 (file)
@@ -311,9 +311,8 @@ static inline struct Scsi_Host *to_shost(struct isci_host *ihost)
 }
 
 #define for_each_isci_host(id, ihost, pdev) \
-       for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \
-            id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \
-            ihost = to_pci_info(pdev)->hosts[++id])
+       for (id = 0; id < SCI_MAX_CONTROLLERS && \
+            (ihost = to_pci_info(pdev)->hosts[id]); id++)
 
 static inline void wait_for_start(struct isci_host *ihost)
 {
index 85c77f6b802bdcba5795ced971a39e29f39ae8b9..ac879745ef8007ab2a4973aff26e3c950e8f1dba 100644 (file)
@@ -615,13 +615,6 @@ static void sci_apc_agent_link_up(struct isci_host *ihost,
                                          SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
        } else {
                /* the phy is already the part of the port */
-               u32 port_state = iport->sm.current_state_id;
-
-               /* if the PORT'S state is resetting then the link up is from
-                * port hard reset in this case, we need to tell the port
-                * that link up is recieved
-                */
-               BUG_ON(port_state != SCI_PORT_RESETTING);
                port_agent->phy_ready_mask |= 1 << phy_index;
                sci_port_link_up(iport, iphy);
        }
index 0d30ca849e8f71502c9ecddfa9aa539e4e59af0f..5d6fda72d659770d080e2c4201c4d3e6c7af1adc 100644 (file)
@@ -801,7 +801,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev)
                /* XXX: need to cleanup any ireqs targeting this
                 * domain_device
                 */
-               ret = TMF_RESP_FUNC_COMPLETE;
+               ret = -ENODEV;
                goto out;
        }
 
index e1fe95ef23e11353aed91a8da9dd1d1f8ef2a9c3..266724b6b8996d451c4bf81c2ff5f0dbee5c1de5 100644 (file)
@@ -2996,8 +2996,7 @@ struct qla_hw_data {
                                IS_QLA82XX(ha) || IS_QLA83XX(ha) || \
                                IS_QLA8044(ha))
 #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha))
-#define IS_NOPOLLING_TYPE(ha)  ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
-                       IS_QLA83XX(ha)) && (ha)->flags.msix_enabled)
+#define IS_NOPOLLING_TYPE(ha)  (IS_QLA81XX(ha) && (ha)->flags.msix_enabled)
 #define IS_FAC_REQUIRED(ha)    (IS_QLA81XX(ha) || IS_QLA83XX(ha))
 #define IS_NOCACHE_VPD_TYPE(ha)        (IS_QLA81XX(ha) || IS_QLA83XX(ha))
 #define IS_ALOGIO_CAPABLE(ha)  (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
index 9bc86b9e86b172145443d161e0715658df6acdc7..0a1dcb43d18bdb6b4c734e0ad38ac956ddeb5fe7 100644 (file)
@@ -2880,6 +2880,7 @@ static int
 qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
 {
 #define MIN_MSIX_COUNT 2
+#define ATIO_VECTOR    2
        int i, ret;
        struct msix_entry *entries;
        struct qla_msix_entry *qentry;
@@ -2936,34 +2937,47 @@ msix_failed:
        }
 
        /* Enable MSI-X vectors for the base queue */
-       for (i = 0; i < ha->msix_count; i++) {
+       for (i = 0; i < 2; i++) {
                qentry = &ha->msix_entries[i];
-               if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) {
-                       ret = request_irq(qentry->vector,
-                               qla83xx_msix_entries[i].handler,
-                               0, qla83xx_msix_entries[i].name, rsp);
-               } else if (IS_P3P_TYPE(ha)) {
+               if (IS_P3P_TYPE(ha))
                        ret = request_irq(qentry->vector,
                                qla82xx_msix_entries[i].handler,
                                0, qla82xx_msix_entries[i].name, rsp);
-               } else {
+               else
                        ret = request_irq(qentry->vector,
                                msix_entries[i].handler,
                                0, msix_entries[i].name, rsp);
-               }
-               if (ret) {
-                       ql_log(ql_log_fatal, vha, 0x00cb,
-                           "MSI-X: unable to register handler -- %x/%d.\n",
-                           qentry->vector, ret);
-                       qla24xx_disable_msix(ha);
-                       ha->mqenable = 0;
-                       goto msix_out;
-               }
+               if (ret)
+                       goto msix_register_fail;
                qentry->have_irq = 1;
                qentry->rsp = rsp;
                rsp->msix = qentry;
        }
 
+       /*
+        * If target mode is enable, also request the vector for the ATIO
+        * queue.
+        */
+       if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) {
+               qentry = &ha->msix_entries[ATIO_VECTOR];
+               ret = request_irq(qentry->vector,
+                       qla83xx_msix_entries[ATIO_VECTOR].handler,
+                       0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp);
+               qentry->have_irq = 1;
+               qentry->rsp = rsp;
+               rsp->msix = qentry;
+       }
+
+msix_register_fail:
+       if (ret) {
+               ql_log(ql_log_fatal, vha, 0x00cb,
+                   "MSI-X: unable to register handler -- %x/%d.\n",
+                   qentry->vector, ret);
+               qla24xx_disable_msix(ha);
+               ha->mqenable = 0;
+               goto msix_out;
+       }
+
        /* Enable MSI-X vector for response queue update for queue 0 */
        if (IS_QLA83XX(ha)) {
                if (ha->msixbase && ha->mqiobase &&
index 17d7404272400dd1a76989a3965e0c4b85343036..9969fa1ef7c4ef09ac4fc72c942c5ef72703ae49 100644 (file)
@@ -1419,6 +1419,9 @@ static void storvsc_device_destroy(struct scsi_device *sdevice)
 {
        struct stor_mem_pools *memp = sdevice->hostdata;
 
+       if (!memp)
+               return;
+
        mempool_destroy(memp->request_mempool);
        kmem_cache_destroy(memp->request_pool);
        kfree(memp);
index cf32f03933694cb56fd518a5e25388f35d834162..c0f3718b77a83e7e0e010b089e436356e83a1eb7 100644 (file)
@@ -513,7 +513,7 @@ struct cifs_mnt_data {
 static inline unsigned int
 get_rfc1002_length(void *buf)
 {
-       return be32_to_cpu(*((__be32 *)buf));
+       return be32_to_cpu(*((__be32 *)buf)) & 0xffffff;
 }
 
 static inline void
index 53c15074bb3622b9a251bef0eafeed866a24ce0b..834fce759d8075313261dfa0a01c76ba9c2cb5b3 100644 (file)
@@ -2579,31 +2579,19 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
        struct cifsInodeInfo *cinode = CIFS_I(inode);
        struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
        ssize_t rc = -EACCES;
+       loff_t lock_pos = pos;
 
-       BUG_ON(iocb->ki_pos != pos);
-
+       if (file->f_flags & O_APPEND)
+               lock_pos = i_size_read(inode);
        /*
         * We need to hold the sem to be sure nobody modifies lock list
         * with a brlock that prevents writing.
         */
        down_read(&cinode->lock_sem);
-       if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs),
+       if (!cifs_find_lock_conflict(cfile, lock_pos, iov_length(iov, nr_segs),
                                     server->vals->exclusive_lock_type, NULL,
-                                    CIFS_WRITE_OP)) {
-               mutex_lock(&inode->i_mutex);
-               rc = __generic_file_aio_write(iocb, iov, nr_segs,
-                                              &iocb->ki_pos);
-               mutex_unlock(&inode->i_mutex);
-       }
-
-       if (rc > 0) {
-               ssize_t err;
-
-               err = generic_write_sync(file, iocb->ki_pos - rc, rc);
-               if (err < 0)
-                       rc = err;
-       }
-
+                                    CIFS_WRITE_OP))
+               rc = generic_file_aio_write(iocb, iov, nr_segs, pos);
        up_read(&cinode->lock_sem);
        return rc;
 }
index b375709528467b5a1a74e078fae2aeb7813e1a1e..18cd5650a5fc6106394691f6ee5baf37f5d8d49b 100644 (file)
@@ -270,6 +270,26 @@ cifs_rqst_page_to_kvec(struct smb_rqst *rqst, unsigned int idx,
                iov->iov_len = rqst->rq_pagesz;
 }
 
+static unsigned long
+rqst_len(struct smb_rqst *rqst)
+{
+       unsigned int i;
+       struct kvec *iov = rqst->rq_iov;
+       unsigned long buflen = 0;
+
+       /* total up iov array first */
+       for (i = 0; i < rqst->rq_nvec; i++)
+               buflen += iov[i].iov_len;
+
+       /* add in the page array if there is one */
+       if (rqst->rq_npages) {
+               buflen += rqst->rq_pagesz * (rqst->rq_npages - 1);
+               buflen += rqst->rq_tailsz;
+       }
+
+       return buflen;
+}
+
 static int
 smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 {
@@ -277,6 +297,7 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
        struct kvec *iov = rqst->rq_iov;
        int n_vec = rqst->rq_nvec;
        unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
+       unsigned long send_length;
        unsigned int i;
        size_t total_len = 0, sent;
        struct socket *ssocket = server->ssocket;
@@ -285,6 +306,14 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
        if (ssocket == NULL)
                return -ENOTSOCK;
 
+       /* sanity check send length */
+       send_length = rqst_len(rqst);
+       if (send_length != smb_buf_length + 4) {
+               WARN(1, "Send length mismatch(send_length=%lu smb_buf_length=%u)\n",
+                       send_length, smb_buf_length);
+               return -EIO;
+       }
+
        cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
        dump_smb(iov[0].iov_base, iov[0].iov_len);
 
index db25c2bdfe464035be537cee3fc09acad77e8cdb..60a45e9f53231379c87b9ee75cb64eb8d6d71979 100644 (file)
--- a/fs/file.c
+++ b/fs/file.c
@@ -683,35 +683,65 @@ EXPORT_SYMBOL(fget_raw);
  * The fput_needed flag returned by fget_light should be passed to the
  * corresponding fput_light.
  */
-struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed)
+static unsigned long __fget_light(unsigned int fd, fmode_t mask)
 {
        struct files_struct *files = current->files;
        struct file *file;
 
-       *fput_needed = 0;
        if (atomic_read(&files->count) == 1) {
                file = __fcheck_files(files, fd);
-               if (file && (file->f_mode & mask))
-                       file = NULL;
+               if (!file || unlikely(file->f_mode & mask))
+                       return 0;
+               return (unsigned long)file;
        } else {
                file = __fget(fd, mask);
-               if (file)
-                       *fput_needed = 1;
+               if (!file)
+                       return 0;
+               return FDPUT_FPUT | (unsigned long)file;
        }
-
-       return file;
 }
-struct file *fget_light(unsigned int fd, int *fput_needed)
+unsigned long __fdget(unsigned int fd)
 {
-       return __fget_light(fd, FMODE_PATH, fput_needed);
+       return __fget_light(fd, FMODE_PATH);
 }
-EXPORT_SYMBOL(fget_light);
+EXPORT_SYMBOL(__fdget);
 
-struct file *fget_raw_light(unsigned int fd, int *fput_needed)
+unsigned long __fdget_raw(unsigned int fd)
 {
-       return __fget_light(fd, 0, fput_needed);
+       return __fget_light(fd, 0);
+}
+
+unsigned long __fdget_pos(unsigned int fd)
+{
+       struct files_struct *files = current->files;
+       struct file *file;
+       unsigned long v;
+
+       if (atomic_read(&files->count) == 1) {
+               file = __fcheck_files(files, fd);
+               v = 0;
+       } else {
+               file = __fget(fd, 0);
+               v = FDPUT_FPUT;
+       }
+       if (!file)
+               return 0;
+
+       if (file->f_mode & FMODE_ATOMIC_POS) {
+               if (file_count(file) > 1) {
+                       v |= FDPUT_POS_UNLOCK;
+                       mutex_lock(&file->f_pos_lock);
+               }
+       }
+       return v | (unsigned long)file;
 }
 
+/*
+ * We only lock f_pos if we have threads or if the file might be
+ * shared with another process. In both cases we'll have an elevated
+ * file count (done either by fdget() or by fork()).
+ */
+
 void set_close_on_exec(unsigned int fd, int flag)
 {
        struct files_struct *files = current->files;
index 5fff9030be34df26aff0c0ed56081aee1306bf02..5b24008ea4f678b668ff2a52fa41f1812b579645 100644 (file)
@@ -135,6 +135,7 @@ struct file *get_empty_filp(void)
        atomic_long_set(&f->f_count, 1);
        rwlock_init(&f->f_owner.lock);
        spin_lock_init(&f->f_lock);
+       mutex_init(&f->f_pos_lock);
        eventpoll_init_file(f);
        /* f->f_version: 0 */
        return f;
index 968ce411db53e807b6f3b0fd216cd6730f226b5d..32602c667b4aaf697c97b7f7e709d808328a5468 100644 (file)
@@ -103,6 +103,8 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry,
                folder = &entry->folder;
                memset(folder, 0, sizeof(*folder));
                folder->type = cpu_to_be16(HFSPLUS_FOLDER);
+               if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags))
+                       folder->flags |= cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT);
                folder->id = cpu_to_be32(inode->i_ino);
                HFSPLUS_I(inode)->create_date =
                        folder->create_date =
@@ -203,6 +205,36 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
        return hfs_brec_find(fd, hfs_find_rec_by_key);
 }
 
+static void hfsplus_subfolders_inc(struct inode *dir)
+{
+       struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb);
+
+       if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) {
+               /*
+                * Increment subfolder count. Note, the value is only meaningful
+                * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set.
+                */
+               HFSPLUS_I(dir)->subfolders++;
+       }
+}
+
+static void hfsplus_subfolders_dec(struct inode *dir)
+{
+       struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb);
+
+       if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) {
+               /*
+                * Decrement subfolder count. Note, the value is only meaningful
+                * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set.
+                *
+                * Check for zero. Some subfolders may have been created
+                * by an implementation ignorant of this counter.
+                */
+               if (HFSPLUS_I(dir)->subfolders)
+                       HFSPLUS_I(dir)->subfolders--;
+       }
+}
+
 int hfsplus_create_cat(u32 cnid, struct inode *dir,
                struct qstr *str, struct inode *inode)
 {
@@ -247,6 +279,8 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir,
                goto err1;
 
        dir->i_size++;
+       if (S_ISDIR(inode->i_mode))
+               hfsplus_subfolders_inc(dir);
        dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
        hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY);
 
@@ -336,6 +370,8 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str)
                goto out;
 
        dir->i_size--;
+       if (type == HFSPLUS_FOLDER)
+               hfsplus_subfolders_dec(dir);
        dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
        hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY);
 
@@ -380,6 +416,7 @@ int hfsplus_rename_cat(u32 cnid,
 
        hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset,
                                src_fd.entrylength);
+       type = be16_to_cpu(entry.type);
 
        /* create new dir entry with the data from the old entry */
        hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name);
@@ -394,6 +431,8 @@ int hfsplus_rename_cat(u32 cnid,
        if (err)
                goto out;
        dst_dir->i_size++;
+       if (type == HFSPLUS_FOLDER)
+               hfsplus_subfolders_inc(dst_dir);
        dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
 
        /* finally remove the old entry */
@@ -405,6 +444,8 @@ int hfsplus_rename_cat(u32 cnid,
        if (err)
                goto out;
        src_dir->i_size--;
+       if (type == HFSPLUS_FOLDER)
+               hfsplus_subfolders_dec(src_dir);
        src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
 
        /* remove old thread entry */
index 08846425b67ffa112b7978650e1521b74955a1dc..62d571eb69bae9c7d04b5c27238b9fa2a1d4a633 100644 (file)
@@ -242,6 +242,7 @@ struct hfsplus_inode_info {
         */
        sector_t fs_blocks;
        u8 userflags;           /* BSD user file flags */
+       u32 subfolders;         /* Subfolder count (HFSX only) */
        struct list_head open_dir_list;
        loff_t phys_size;
 
index 8ffb3a8ffe75b9d6374cb9198d83d5dce5553457..5a126828d85eb011714b067976f0a14981103c7c 100644 (file)
@@ -261,7 +261,7 @@ struct hfsplus_cat_folder {
        struct DInfo user_info;
        struct DXInfo finder_info;
        __be32 text_encoding;
-       u32 reserved;
+       __be32 subfolders;      /* Subfolder count in HFSX. Reserved in HFS+. */
 } __packed;
 
 /* HFS file info (stolen from hfs.h) */
@@ -301,11 +301,13 @@ struct hfsplus_cat_file {
        struct hfsplus_fork_raw rsrc_fork;
 } __packed;
 
-/* File attribute bits */
+/* File and folder flag bits */
 #define HFSPLUS_FILE_LOCKED            0x0001
 #define HFSPLUS_FILE_THREAD_EXISTS     0x0002
 #define HFSPLUS_XATTR_EXISTS           0x0004
 #define HFSPLUS_ACL_EXISTS             0x0008
+#define HFSPLUS_HAS_FOLDER_COUNT       0x0010  /* Folder has subfolder count
+                                                * (HFSX only) */
 
 /* HFS+ catalog thread (part of a cat_entry) */
 struct hfsplus_cat_thread {
index fa929f325f87502074d66e208c1a57feba089c82..a4f45bd88a631ad5a153a8f45fdd1044a3637c1c 100644 (file)
@@ -375,6 +375,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode)
        hip->extent_state = 0;
        hip->flags = 0;
        hip->userflags = 0;
+       hip->subfolders = 0;
        memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec));
        memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
        hip->alloc_blocks = 0;
@@ -494,6 +495,10 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
                inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date);
                HFSPLUS_I(inode)->create_date = folder->create_date;
                HFSPLUS_I(inode)->fs_blocks = 0;
+               if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) {
+                       HFSPLUS_I(inode)->subfolders =
+                               be32_to_cpu(folder->subfolders);
+               }
                inode->i_op = &hfsplus_dir_inode_operations;
                inode->i_fop = &hfsplus_dir_operations;
        } else if (type == HFSPLUS_FILE) {
@@ -566,6 +571,10 @@ int hfsplus_cat_write_inode(struct inode *inode)
                folder->content_mod_date = hfsp_ut2mt(inode->i_mtime);
                folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
                folder->valence = cpu_to_be32(inode->i_size - 2);
+               if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) {
+                       folder->subfolders =
+                               cpu_to_be32(HFSPLUS_I(inode)->subfolders);
+               }
                hfs_bnode_write(fd.bnode, &entry, fd.entryoffset,
                                         sizeof(struct hfsplus_cat_folder));
        } else if (HFSPLUS_IS_RSRC(inode)) {
index 385f7817bfccbd12fbc352c39827586d4cf953d7..2f730ef9b4b3da78afd6a830c13c7ba13c706ffe 100644 (file)
@@ -1884,7 +1884,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
 
                nd->path = f.file->f_path;
                if (flags & LOOKUP_RCU) {
-                       if (f.need_put)
+                       if (f.flags & FDPUT_FPUT)
                                *fp = f.file;
                        nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
                        rcu_read_lock();
index 8450262bcf2a782777bafd01fdd3b9b58f0bd318..51632c40e896fd0b7c4e4c87b2afc5dc4f418aca 100644 (file)
@@ -2393,8 +2393,8 @@ out_dio:
 
        if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) ||
            ((file->f_flags & O_DIRECT) && !direct_io)) {
-               ret = filemap_fdatawrite_range(file->f_mapping, pos,
-                                              pos + count - 1);
+               ret = filemap_fdatawrite_range(file->f_mapping, *ppos,
+                                              *ppos + count - 1);
                if (ret < 0)
                        written = ret;
 
@@ -2407,8 +2407,8 @@ out_dio:
                }
 
                if (!ret)
-                       ret = filemap_fdatawait_range(file->f_mapping, pos,
-                                                     pos + count - 1);
+                       ret = filemap_fdatawait_range(file->f_mapping, *ppos,
+                                                     *ppos + count - 1);
        }
 
        /*
index 4b3e1edf2fe4d917e69e56b3e268e32f2ae7301a..b9ed8b25c108c69d68889b5b6eadac9878eb7bd9 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -705,6 +705,10 @@ static int do_dentry_open(struct file *f,
                return 0;
        }
 
+       /* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */
+       if (S_ISREG(inode->i_mode))
+               f->f_mode |= FMODE_ATOMIC_POS;
+
        f->f_op = fops_get(inode->i_fop);
        if (unlikely(WARN_ON(!f->f_op))) {
                error = -ENODEV;
index 51507065263b29e3b915a6aa2238630fe3f7ac67..b9760628e1fde7b9a5c681798a65185144abeb92 100644 (file)
@@ -1824,6 +1824,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
        if (rc)
                goto out_mmput;
 
+       rc = -ENOENT;
        down_read(&mm->mmap_sem);
        vma = find_exact_vma(mm, vm_start, vm_end);
        if (vma && vma->vm_file) {
index edc5746a902a090ce4dbda6b8b1205e729dff5b3..54e19b9392dc74381fec154fe3f0ceab32ce9bd8 100644 (file)
@@ -264,10 +264,22 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
 }
 EXPORT_SYMBOL(vfs_llseek);
 
+static inline struct fd fdget_pos(int fd)
+{
+       return __to_fd(__fdget_pos(fd));
+}
+
+static inline void fdput_pos(struct fd f)
+{
+       if (f.flags & FDPUT_POS_UNLOCK)
+               mutex_unlock(&f.file->f_pos_lock);
+       fdput(f);
+}
+
 SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
 {
        off_t retval;
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        if (!f.file)
                return -EBADF;
 
@@ -278,7 +290,7 @@ SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
                if (res != (loff_t)retval)
                        retval = -EOVERFLOW;    /* LFS: should only happen on 32 bit platforms */
        }
-       fdput(f);
+       fdput_pos(f);
        return retval;
 }
 
@@ -498,7 +510,7 @@ static inline void file_pos_write(struct file *file, loff_t pos)
 
 SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
 {
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        ssize_t ret = -EBADF;
 
        if (f.file) {
@@ -506,7 +518,7 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
                ret = vfs_read(f.file, buf, count, &pos);
                if (ret >= 0)
                        file_pos_write(f.file, pos);
-               fdput(f);
+               fdput_pos(f);
        }
        return ret;
 }
@@ -514,7 +526,7 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
 SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
                size_t, count)
 {
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        ssize_t ret = -EBADF;
 
        if (f.file) {
@@ -522,7 +534,7 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
                ret = vfs_write(f.file, buf, count, &pos);
                if (ret >= 0)
                        file_pos_write(f.file, pos);
-               fdput(f);
+               fdput_pos(f);
        }
 
        return ret;
@@ -797,7 +809,7 @@ EXPORT_SYMBOL(vfs_writev);
 SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
                unsigned long, vlen)
 {
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        ssize_t ret = -EBADF;
 
        if (f.file) {
@@ -805,7 +817,7 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
                ret = vfs_readv(f.file, vec, vlen, &pos);
                if (ret >= 0)
                        file_pos_write(f.file, pos);
-               fdput(f);
+               fdput_pos(f);
        }
 
        if (ret > 0)
@@ -817,7 +829,7 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
 SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
                unsigned long, vlen)
 {
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        ssize_t ret = -EBADF;
 
        if (f.file) {
@@ -825,7 +837,7 @@ SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
                ret = vfs_writev(f.file, vec, vlen, &pos);
                if (ret >= 0)
                        file_pos_write(f.file, pos);
-               fdput(f);
+               fdput_pos(f);
        }
 
        if (ret > 0)
@@ -968,7 +980,7 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
                const struct compat_iovec __user *,vec,
                compat_ulong_t, vlen)
 {
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        ssize_t ret;
        loff_t pos;
 
@@ -978,7 +990,7 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
        ret = compat_readv(f.file, vec, vlen, &pos);
        if (ret >= 0)
                f.file->f_pos = pos;
-       fdput(f);
+       fdput_pos(f);
        return ret;
 }
 
@@ -1035,7 +1047,7 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
                const struct compat_iovec __user *, vec,
                compat_ulong_t, vlen)
 {
-       struct fd f = fdget(fd);
+       struct fd f = fdget_pos(fd);
        ssize_t ret;
        loff_t pos;
 
@@ -1045,7 +1057,7 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
        ret = compat_writev(f.file, vec, vlen, &pos);
        if (ret >= 0)
                f.file->f_pos = pos;
-       fdput(f);
+       fdput_pos(f);
        return ret;
 }
 
diff --git a/include/dt-bindings/sound/tlv320aic31xx-micbias.h b/include/dt-bindings/sound/tlv320aic31xx-micbias.h
new file mode 100644 (file)
index 0000000..f5cb772
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __DT_TLV320AIC31XX_MICBIAS_H
+#define __DT_TLV320AIC31XX_MICBIAS_H
+
+#define MICBIAS_2_0V           1
+#define MICBIAS_2_5V           2
+#define MICBIAS_AVDDV          3
+
+#endif /* __DT_TLV320AIC31XX_MICBIAS_H */
index be85127bfed3a2da2a58a3284a48b7e72094ca91..f27000f55a83d6a27921372f9890520e492a747b 100644 (file)
@@ -171,6 +171,11 @@ static inline int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 add
        return 0;
 }
 
+static inline int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
+{
+       return -ENXIO;
+}
+
 static inline int kvm_vgic_init(struct kvm *kvm)
 {
        return 0;
index aa865a9a4c4f862b4aa693ed9918399b338e7696..ec1464df4c60930a7fde38f1bc6f35a35b7f79d3 100644 (file)
@@ -43,6 +43,7 @@ struct mq_attr;
 struct mqstat;
 struct audit_watch;
 struct audit_tree;
+struct sk_buff;
 
 struct audit_krule {
        int                     vers_ops;
@@ -463,7 +464,7 @@ extern int audit_filter_user(int type);
 extern int audit_filter_type(int type);
 extern int audit_rule_change(int type, __u32 portid, int seq,
                                void *data, size_t datasz);
-extern int audit_list_rules_send(__u32 portid, int seq);
+extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
 
 extern u32 audit_enabled;
 #else /* CONFIG_AUDIT */
index cbacf4faf447a9dd2b3fd50d3dc2e4f86a120e67..4d69123377a2b4e0a7869ba38cc91ceb4fd1c7b7 100644 (file)
@@ -28,33 +28,36 @@ static inline void fput_light(struct file *file, int fput_needed)
 
 struct fd {
        struct file *file;
-       int need_put;
+       unsigned int flags;
 };
+#define FDPUT_FPUT       1
+#define FDPUT_POS_UNLOCK 2
 
 static inline void fdput(struct fd fd)
 {
-       if (fd.need_put)
+       if (fd.flags & FDPUT_FPUT)
                fput(fd.file);
 }
 
 extern struct file *fget(unsigned int fd);
-extern struct file *fget_light(unsigned int fd, int *fput_needed);
+extern struct file *fget_raw(unsigned int fd);
+extern unsigned long __fdget(unsigned int fd);
+extern unsigned long __fdget_raw(unsigned int fd);
+extern unsigned long __fdget_pos(unsigned int fd);
 
-static inline struct fd fdget(unsigned int fd)
+static inline struct fd __to_fd(unsigned long v)
 {
-       int b;
-       struct file *f = fget_light(fd, &b);
-       return (struct fd){f,b};
+       return (struct fd){(struct file *)(v & ~3),v & 3};
 }
 
-extern struct file *fget_raw(unsigned int fd);
-extern struct file *fget_raw_light(unsigned int fd, int *fput_needed);
+static inline struct fd fdget(unsigned int fd)
+{
+       return __to_fd(__fdget(fd));
+}
 
 static inline struct fd fdget_raw(unsigned int fd)
 {
-       int b;
-       struct file *f = fget_raw_light(fd, &b);
-       return (struct fd){f,b};
+       return __to_fd(__fdget_raw(fd));
 }
 
 extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
index 60829565e5522a2c68f489665909d39f65230a25..23b2a35d712efbec3e31df0cae70b69a17b81616 100644 (file)
@@ -123,6 +123,9 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 /* File is opened with O_PATH; almost nothing can be done with it */
 #define FMODE_PATH             ((__force fmode_t)0x4000)
 
+/* File needs atomic accesses to f_pos */
+#define FMODE_ATOMIC_POS       ((__force fmode_t)0x8000)
+
 /* File was opened by fanotify and shouldn't generate fanotify events */
 #define FMODE_NONOTIFY         ((__force fmode_t)0x1000000)
 
@@ -780,13 +783,14 @@ struct file {
        const struct file_operations    *f_op;
 
        /*
-        * Protects f_ep_links, f_flags, f_pos vs i_size in lseek SEEK_CUR.
+        * Protects f_ep_links, f_flags.
         * Must not be taken from IRQ context.
         */
        spinlock_t              f_lock;
        atomic_long_t           f_count;
        unsigned int            f_flags;
        fmode_t                 f_mode;
+       struct mutex            f_pos_lock;
        loff_t                  f_pos;
        struct fown_struct      f_owner;
        const struct cred       *f_cred;
@@ -808,7 +812,7 @@ struct file {
 #ifdef CONFIG_DEBUG_WRITECOUNT
        unsigned long f_mnt_write_state;
 #endif
-};
+} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
 
 struct file_handle {
        __u32 handle_bytes;
index 0437439bc047bd4a99d7465132b1d9417667934e..39b81dc7d01acdb28e6e888fea3399f7866057f8 100644 (file)
@@ -123,6 +123,10 @@ struct vm_area_struct;
                         __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
                         __GFP_NO_KSWAPD)
 
+/*
+ * GFP_THISNODE does not perform any reclaim, you most likely want to
+ * use __GFP_THISNODE to allocate from a given node without fallback!
+ */
 #ifdef CONFIG_NUMA
 #define GFP_THISNODE   (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
 #else
index 5f2052c831547a33b66606d78ac5713086d285e3..9b61b9bf81ac86a90c1ce70d12400b745b7582eb 100644 (file)
@@ -590,10 +590,10 @@ static inline bool zone_is_empty(struct zone *zone)
 
 /*
  * The NUMA zonelists are doubled because we need zonelists that restrict the
- * allocations to a single node for GFP_THISNODE.
+ * allocations to a single node for __GFP_THISNODE.
  *
  * [0] : Zonelist with fallback
- * [1] : No fallback (GFP_THISNODE)
+ * [1] : No fallback (__GFP_THISNODE)
  */
 #define MAX_ZONELISTS 2
 
index 9260abdd67df801e002f18faf3f17bd00d494867..b5b2df60299e25c5c33b3be39ff90090c974689f 100644 (file)
@@ -410,7 +410,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
  *
  * %GFP_NOWAIT - Allocation will not sleep.
  *
- * %GFP_THISNODE - Allocate node-local memory only.
+ * %__GFP_THISNODE - Allocate node-local memory only.
  *
  * %GFP_DMA - Allocation suitable for DMA.
  *   Should only be used for kmalloc() caches. Otherwise, use a
index 5c3f7c3624aa00214572c47cd3b6dbb3777d93ee..b9586a137cadd38e8a36abcd34018cfe9b680047 100644 (file)
@@ -1488,6 +1488,11 @@ static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
  */
 #define sock_owned_by_user(sk) ((sk)->sk_lock.owned)
 
+static inline void sock_release_ownership(struct sock *sk)
+{
+       sk->sk_lock.owned = 0;
+}
+
 /*
  * Macro so as to not evaluate some arguments when
  * lockdep is not enabled.
@@ -2186,7 +2191,6 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
 {
 #define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)                      | \
                           (1UL << SOCK_RCVTSTAMP)                      | \
-                          (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)       | \
                           (1UL << SOCK_TIMESTAMPING_SOFTWARE)          | \
                           (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE)      | \
                           (1UL << SOCK_TIMESTAMPING_SYS_HARDWARE))
index 959f389499672a2137ffb017468e5e4de417f874..0b83168d8ff45a2ff394057ef0d172ab783f84d8 100644 (file)
@@ -354,12 +354,6 @@ typedef int (*hw_write_t)(void *,const char* ,int);
 
 extern struct snd_ac97_bus_ops *soc_ac97_ops;
 
-enum snd_soc_control_type {
-       SND_SOC_I2C = 1,
-       SND_SOC_SPI,
-       SND_SOC_REGMAP,
-};
-
 enum snd_soc_pcm_subclass {
        SND_SOC_PCM_CLASS_PCM   = 0,
        SND_SOC_PCM_CLASS_BE    = 1,
@@ -406,8 +400,7 @@ int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
 int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
                                    unsigned int reg);
 int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
-                              int addr_bits, int data_bits,
-                              enum snd_soc_control_type control);
+                              struct regmap *regmap);
 int snd_soc_cache_sync(struct snd_soc_codec *codec);
 int snd_soc_cache_init(struct snd_soc_codec *codec);
 int snd_soc_cache_exit(struct snd_soc_codec *codec);
@@ -614,7 +607,8 @@ struct snd_soc_jack_gpio {
        struct snd_soc_jack *jack;
        struct delayed_work work;
 
-       int (*jack_status_check)(void);
+       void *data;
+       int (*jack_status_check)(void *data);
 };
 
 struct snd_soc_jack {
@@ -717,7 +711,6 @@ struct snd_soc_codec {
        /* codec IO */
        void *control_data; /* codec control (i2c/3wire) data */
        hw_write_t hw_write;
-       unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
        unsigned int (*read)(struct snd_soc_codec *, unsigned int);
        int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
        void *reg_cache;
@@ -1114,6 +1107,19 @@ struct soc_enum {
        const unsigned int *values;
 };
 
+/**
+ * snd_soc_component_to_codec() - Casts a component to the CODEC it is embedded in
+ * @component: The component to cast to a CODEC
+ *
+ * This function must only be used on components that are known to be CODECs.
+ * Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_codec *snd_soc_component_to_codec(
+       struct snd_soc_component *component)
+{
+       return container_of(component, struct snd_soc_codec, component);
+}
+
 /* codec IO */
 unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
 unsigned int snd_soc_write(struct snd_soc_codec *codec,
index eb03090cdced5aac82787cf3154c2430b7410924..9c7fd4c9249f2c72395fcaf2ac953f782a3e2b59 100644 (file)
@@ -561,7 +561,6 @@ asmlinkage void __init start_kernel(void)
        init_timers();
        hrtimers_init();
        softirq_init();
-       acpi_early_init();
        timekeeping_init();
        time_init();
        sched_clock_postinit();
@@ -613,6 +612,7 @@ asmlinkage void __init start_kernel(void)
        calibrate_delay();
        pidmap_init();
        anon_vma_init();
+       acpi_early_init();
 #ifdef CONFIG_X86
        if (efi_enabled(EFI_RUNTIME_SERVICES))
                efi_enter_virtual_mode();
index 245db1140ad66a2be47744f02ef0d80deea5006f..649853105a5d773d30fac9929327030cad118a67 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -901,6 +901,8 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
                return -EINVAL;
 
        if (msgflg & MSG_COPY) {
+               if ((msgflg & MSG_EXCEPT) || !(msgflg & IPC_NOWAIT))
+                       return -EINVAL;
                copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax));
                if (IS_ERR(copy))
                        return PTR_ERR(copy);
index 34c5a2310fbf9545eeff2e3fa803c8a361031bb3..3392d3e0254ac5d93199c0b00e271cbb0b2bfc9c 100644 (file)
@@ -182,7 +182,7 @@ struct audit_buffer {
 
 struct audit_reply {
        __u32 portid;
-       pid_t pid;
+       struct net *net;        
        struct sk_buff *skb;
 };
 
@@ -500,7 +500,7 @@ int audit_send_list(void *_dest)
 {
        struct audit_netlink_list *dest = _dest;
        struct sk_buff *skb;
-       struct net *net = get_net_ns_by_pid(dest->pid);
+       struct net *net = dest->net;
        struct audit_net *aunet = net_generic(net, audit_net_id);
 
        /* wait for parent to finish and send an ACK */
@@ -510,6 +510,7 @@ int audit_send_list(void *_dest)
        while ((skb = __skb_dequeue(&dest->q)) != NULL)
                netlink_unicast(aunet->nlsk, skb, dest->portid, 0);
 
+       put_net(net);
        kfree(dest);
 
        return 0;
@@ -543,7 +544,7 @@ out_kfree_skb:
 static int audit_send_reply_thread(void *arg)
 {
        struct audit_reply *reply = (struct audit_reply *)arg;
-       struct net *net = get_net_ns_by_pid(reply->pid);
+       struct net *net = reply->net;
        struct audit_net *aunet = net_generic(net, audit_net_id);
 
        mutex_lock(&audit_cmd_mutex);
@@ -552,12 +553,13 @@ static int audit_send_reply_thread(void *arg)
        /* Ignore failure. It'll only happen if the sender goes away,
           because our timeout is set to infinite. */
        netlink_unicast(aunet->nlsk , reply->skb, reply->portid, 0);
+       put_net(net);
        kfree(reply);
        return 0;
 }
 /**
  * audit_send_reply - send an audit reply message via netlink
- * @portid: netlink port to which to send reply
+ * @request_skb: skb of request we are replying to (used to target the reply)
  * @seq: sequence number
  * @type: audit message type
  * @done: done (last) flag
@@ -568,9 +570,11 @@ static int audit_send_reply_thread(void *arg)
  * Allocates an skb, builds the netlink message, and sends it to the port id.
  * No failure notifications.
  */
-static void audit_send_reply(__u32 portid, int seq, int type, int done,
+static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
                             int multi, const void *payload, int size)
 {
+       u32 portid = NETLINK_CB(request_skb).portid;
+       struct net *net = sock_net(NETLINK_CB(request_skb).sk);
        struct sk_buff *skb;
        struct task_struct *tsk;
        struct audit_reply *reply = kmalloc(sizeof(struct audit_reply),
@@ -583,8 +587,8 @@ static void audit_send_reply(__u32 portid, int seq, int type, int done,
        if (!skb)
                goto out;
 
+       reply->net = get_net(net);
        reply->portid = portid;
-       reply->pid = task_pid_vnr(current);
        reply->skb = skb;
 
        tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
@@ -673,8 +677,7 @@ static int audit_get_feature(struct sk_buff *skb)
 
        seq = nlmsg_hdr(skb)->nlmsg_seq;
 
-       audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0,
-                        &af, sizeof(af));
+       audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &af, sizeof(af));
 
        return 0;
 }
@@ -794,8 +797,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                s.backlog               = skb_queue_len(&audit_skb_queue);
                s.version               = AUDIT_VERSION_LATEST;
                s.backlog_wait_time     = audit_backlog_wait_time;
-               audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0,
-                                &s, sizeof(s));
+               audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
                break;
        }
        case AUDIT_SET: {
@@ -905,7 +907,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                           seq, data, nlmsg_len(nlh));
                break;
        case AUDIT_LIST_RULES:
-               err = audit_list_rules_send(NETLINK_CB(skb).portid, seq);
+               err = audit_list_rules_send(skb, seq);
                break;
        case AUDIT_TRIM:
                audit_trim_trees();
@@ -970,8 +972,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        memcpy(sig_data->ctx, ctx, len);
                        security_release_secctx(ctx, len);
                }
-               audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_SIGNAL_INFO,
-                               0, 0, sig_data, sizeof(*sig_data) + len);
+               audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
+                                sig_data, sizeof(*sig_data) + len);
                kfree(sig_data);
                break;
        case AUDIT_TTY_GET: {
@@ -983,8 +985,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                s.log_passwd = tsk->signal->audit_tty_log_passwd;
                spin_unlock(&tsk->sighand->siglock);
 
-               audit_send_reply(NETLINK_CB(skb).portid, seq,
-                                AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
+               audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
                break;
        }
        case AUDIT_TTY_SET: {
index 57cc64d67718903eebeab175030348df648b4f17..8df132214606f2b06e08e916196779b1aee64ad6 100644 (file)
@@ -247,7 +247,7 @@ extern void             audit_panic(const char *message);
 
 struct audit_netlink_list {
        __u32 portid;
-       pid_t pid;
+       struct net *net;
        struct sk_buff_head q;
 };
 
index 14a78cca384edb9cf8f36dc3f7fb5340c267c623..92062fd6cc8cec4deff933c04848782bfdcded11 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/security.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
 #include "audit.h"
 
 /*
@@ -1065,11 +1067,13 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,
 
 /**
  * audit_list_rules_send - list the audit rules
- * @portid: target portid for netlink audit messages
+ * @request_skb: skb of request we are replying to (used to target the reply)
  * @seq: netlink audit message sequence (serial) number
  */
-int audit_list_rules_send(__u32 portid, int seq)
+int audit_list_rules_send(struct sk_buff *request_skb, int seq)
 {
+       u32 portid = NETLINK_CB(request_skb).portid;
+       struct net *net = sock_net(NETLINK_CB(request_skb).sk);
        struct task_struct *tsk;
        struct audit_netlink_list *dest;
        int err = 0;
@@ -1083,8 +1087,8 @@ int audit_list_rules_send(__u32 portid, int seq)
        dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
        if (!dest)
                return -ENOMEM;
+       dest->net = get_net(net);
        dest->portid = portid;
-       dest->pid = task_pid_vnr(current);
        skb_queue_head_init(&dest->q);
 
        mutex_lock(&audit_filter_mutex);
index 6631e1ef55ab0970f095b42ec350982abd8d9678..ebdd9c1a86b4dfd7840df57c64f13f72a1401156 100644 (file)
@@ -549,14 +549,14 @@ static int create_hash_tables(void)
                struct page *page;
 
                page = alloc_pages_exact_node(node,
-                               GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+                               GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
                                0);
                if (!page)
                        goto out_cleanup;
                per_cpu(cpu_profile_hits, cpu)[1]
                                = (struct profile_hit *)page_address(page);
                page = alloc_pages_exact_node(node,
-                               GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+                               GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,
                                0);
                if (!page)
                        goto out_cleanup;
index 43c2bcc35761e40c9342522b4fa87b92cdefd8f4..b30a2924ef1429a60152a40101ec4828c5e23268 100644 (file)
@@ -301,14 +301,14 @@ u64 sched_clock_cpu(int cpu)
        if (unlikely(!sched_clock_running))
                return 0ull;
 
-       preempt_disable();
+       preempt_disable_notrace();
        scd = cpu_sdc(cpu);
 
        if (cpu != smp_processor_id())
                clock = sched_clock_remote(scd);
        else
                clock = sched_clock_local(scd);
-       preempt_enable();
+       preempt_enable_notrace();
 
        return clock;
 }
index 6edbef296ece25a6ee68facac279445414692368..f5c6635b806c56550bcee17aa0c2490c96b16ff7 100644 (file)
@@ -3338,6 +3338,15 @@ recheck:
                                return -EPERM;
                }
 
+                /*
+                 * Can't set/change SCHED_DEADLINE policy at all for now
+                 * (safest behavior); in the future we would like to allow
+                 * unprivileged DL tasks to increase their relative deadline
+                 * or reduce their runtime (both ways reducing utilization)
+                 */
+               if (dl_policy(policy))
+                       return -EPERM;
+
                /*
                 * Treat SCHED_IDLE as nice 20. Only allow a switch to
                 * SCHED_NORMAL if the RLIMIT_NICE would normally permit it.
index 84571e09c9079e8887f73a0f24beefe58e00ff77..01fbae5b97b765199feccfbb6f985c1309dc3475 100644 (file)
@@ -293,7 +293,7 @@ int stop_two_cpus(unsigned int cpu1, unsigned int cpu2, cpu_stop_fn_t fn, void *
         */
        smp_call_function_single(min(cpu1, cpu2),
                                 &irq_cpu_stop_queue_work,
-                                &call_args, 0);
+                                &call_args, 1);
        lg_local_unlock(&stop_cpus_lock);
        preempt_enable();
 
index 2d9f1504d75e26d45ddf58fe2db8c048ecbc8d83..2888024e0b0abea6b6f37f4531ad0f8dfec5c7b3 100644 (file)
@@ -575,5 +575,5 @@ config PGTABLE_MAPPING
          then you should select this. This causes zsmalloc to use page table
          mapping rather than copying for object mapping.
 
-         You can check speed with zsmalloc benchmark[1].
-         [1] https://github.com/spartacus06/zsmalloc
+         You can check speed with zsmalloc benchmark:
+         https://github.com/spartacus06/zsmapbench
index b48c5259ea33dfed9e4c08c956d8e30a36480c42..918577595ea8695298cd21ecab7acaca35b1eb92 100644 (file)
@@ -251,7 +251,6 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 {
        int nr_scanned = 0, total_isolated = 0;
        struct page *cursor, *valid_page = NULL;
-       unsigned long nr_strict_required = end_pfn - blockpfn;
        unsigned long flags;
        bool locked = false;
 
@@ -264,11 +263,12 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 
                nr_scanned++;
                if (!pfn_valid_within(blockpfn))
-                       continue;
+                       goto isolate_fail;
+
                if (!valid_page)
                        valid_page = page;
                if (!PageBuddy(page))
-                       continue;
+                       goto isolate_fail;
 
                /*
                 * The zone lock must be held to isolate freepages.
@@ -289,12 +289,10 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 
                /* Recheck this is a buddy page under lock */
                if (!PageBuddy(page))
-                       continue;
+                       goto isolate_fail;
 
                /* Found a free page, break it into order-0 pages */
                isolated = split_free_page(page);
-               if (!isolated && strict)
-                       break;
                total_isolated += isolated;
                for (i = 0; i < isolated; i++) {
                        list_add(&page->lru, freelist);
@@ -305,7 +303,15 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
                if (isolated) {
                        blockpfn += isolated - 1;
                        cursor += isolated - 1;
+                       continue;
                }
+
+isolate_fail:
+               if (strict)
+                       break;
+               else
+                       continue;
+
        }
 
        trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated);
@@ -315,7 +321,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
         * pages requested were isolated. If there were any failures, 0 is
         * returned and CMA will fail.
         */
-       if (strict && nr_strict_required > total_isolated)
+       if (strict && blockpfn < end_pfn)
                total_isolated = 0;
 
        if (locked)
index 482a33d89134fd83e15d5f6863dae57f5cb05aac..b494fdb9a6363e058f802069ba5de8e677005b45 100644 (file)
@@ -1158,7 +1158,7 @@ static struct page *new_page_node(struct page *p, unsigned long private,
                                        pm->node);
        else
                return alloc_pages_exact_node(pm->node,
-                               GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0);
+                               GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0);
 }
 
 /*
@@ -1544,9 +1544,9 @@ static struct page *alloc_misplaced_dst_page(struct page *page,
        struct page *newpage;
 
        newpage = alloc_pages_exact_node(nid,
-                                        (GFP_HIGHUSER_MOVABLE | GFP_THISNODE |
-                                         __GFP_NOMEMALLOC | __GFP_NORETRY |
-                                         __GFP_NOWARN) &
+                                        (GFP_HIGHUSER_MOVABLE |
+                                         __GFP_THISNODE | __GFP_NOMEMALLOC |
+                                         __GFP_NORETRY | __GFP_NOWARN) &
                                         ~GFP_IOFS, 0);
 
        return newpage;
@@ -1747,7 +1747,8 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
                goto out_dropref;
 
        new_page = alloc_pages_node(node,
-               (GFP_TRANSHUGE | GFP_THISNODE) & ~__GFP_WAIT, HPAGE_PMD_ORDER);
+               (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_WAIT,
+               HPAGE_PMD_ORDER);
        if (!new_page)
                goto out_fail;
 
index de51c48c439382db712761747188dc72061c82b0..4b65aa492fb6bc7908243e96768ae796a68776b2 100644 (file)
@@ -538,6 +538,9 @@ static int vlan_passthru_hard_header(struct sk_buff *skb, struct net_device *dev
        struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
        struct net_device *real_dev = vlan->real_dev;
 
+       if (saddr == NULL)
+               saddr = dev->dev_addr;
+
        return dev_hard_header(skb, real_dev, type, daddr, saddr, len);
 }
 
index ef66365b7354da9f2fe2c4d87d2056d9a781f3c8..93067ecdb9a212321c8780bd65153d60e8203907 100644 (file)
@@ -1127,9 +1127,10 @@ static void br_multicast_query_received(struct net_bridge *br,
                                        struct net_bridge_port *port,
                                        struct bridge_mcast_querier *querier,
                                        int saddr,
+                                       bool is_general_query,
                                        unsigned long max_delay)
 {
-       if (saddr)
+       if (saddr && is_general_query)
                br_multicast_update_querier_timer(br, querier, max_delay);
        else if (timer_pending(&querier->timer))
                return;
@@ -1181,8 +1182,16 @@ static int br_ip4_multicast_query(struct net_bridge *br,
                            IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
        }
 
+       /* RFC2236+RFC3376 (IGMPv2+IGMPv3) require the multicast link layer
+        * all-systems destination addresses (224.0.0.1) for general queries
+        */
+       if (!group && iph->daddr != htonl(INADDR_ALLHOSTS_GROUP)) {
+               err = -EINVAL;
+               goto out;
+       }
+
        br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr,
-                                   max_delay);
+                                   !group, max_delay);
 
        if (!group)
                goto out;
@@ -1228,6 +1237,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
        unsigned long max_delay;
        unsigned long now = jiffies;
        const struct in6_addr *group = NULL;
+       bool is_general_query;
        int err = 0;
 
        spin_lock(&br->multicast_lock);
@@ -1235,6 +1245,12 @@ static int br_ip6_multicast_query(struct net_bridge *br,
            (port && port->state == BR_STATE_DISABLED))
                goto out;
 
+       /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */
+       if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
+               err = -EINVAL;
+               goto out;
+       }
+
        if (skb->len == sizeof(*mld)) {
                if (!pskb_may_pull(skb, sizeof(*mld))) {
                        err = -EINVAL;
@@ -1256,8 +1272,19 @@ static int br_ip6_multicast_query(struct net_bridge *br,
                max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL);
        }
 
+       is_general_query = group && ipv6_addr_any(group);
+
+       /* RFC2710+RFC3810 (MLDv1+MLDv2) require the multicast link layer
+        * all-nodes destination address (ff02::1) for general queries
+        */
+       if (is_general_query && !ipv6_addr_is_ll_all_nodes(&ip6h->daddr)) {
+               err = -EINVAL;
+               goto out;
+       }
+
        br_multicast_query_received(br, port, &br->ip6_querier,
-                                   !ipv6_addr_any(&ip6h->saddr), max_delay);
+                                   !ipv6_addr_any(&ip6h->saddr),
+                                   is_general_query, max_delay);
 
        if (!group)
                goto out;
index 5d6236d9fdce41eeea2e41433e8f51803b2be68a..869c7afe3b070576464693e4d6ca00482c151f42 100644 (file)
@@ -2838,81 +2838,84 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum);
 
 /**
  *     skb_segment - Perform protocol segmentation on skb.
- *     @skb: buffer to segment
+ *     @head_skb: buffer to segment
  *     @features: features for the output path (see dev->features)
  *
  *     This function performs segmentation on the given skb.  It returns
  *     a pointer to the first in a list of new skbs for the segments.
  *     In case of error it returns ERR_PTR(err).
  */
-struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
+struct sk_buff *skb_segment(struct sk_buff *head_skb,
+                           netdev_features_t features)
 {
        struct sk_buff *segs = NULL;
        struct sk_buff *tail = NULL;
-       struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
-       skb_frag_t *skb_frag = skb_shinfo(skb)->frags;
-       unsigned int mss = skb_shinfo(skb)->gso_size;
-       unsigned int doffset = skb->data - skb_mac_header(skb);
+       struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list;
+       skb_frag_t *frag = skb_shinfo(head_skb)->frags;
+       unsigned int mss = skb_shinfo(head_skb)->gso_size;
+       unsigned int doffset = head_skb->data - skb_mac_header(head_skb);
+       struct sk_buff *frag_skb = head_skb;
        unsigned int offset = doffset;
-       unsigned int tnl_hlen = skb_tnl_header_len(skb);
+       unsigned int tnl_hlen = skb_tnl_header_len(head_skb);
        unsigned int headroom;
        unsigned int len;
        __be16 proto;
        bool csum;
        int sg = !!(features & NETIF_F_SG);
-       int nfrags = skb_shinfo(skb)->nr_frags;
+       int nfrags = skb_shinfo(head_skb)->nr_frags;
        int err = -ENOMEM;
        int i = 0;
        int pos;
 
-       proto = skb_network_protocol(skb);
+       proto = skb_network_protocol(head_skb);
        if (unlikely(!proto))
                return ERR_PTR(-EINVAL);
 
        csum = !!can_checksum_protocol(features, proto);
-       __skb_push(skb, doffset);
-       headroom = skb_headroom(skb);
-       pos = skb_headlen(skb);
+       __skb_push(head_skb, doffset);
+       headroom = skb_headroom(head_skb);
+       pos = skb_headlen(head_skb);
 
        do {
                struct sk_buff *nskb;
-               skb_frag_t *frag;
+               skb_frag_t *nskb_frag;
                int hsize;
                int size;
 
-               len = skb->len - offset;
+               len = head_skb->len - offset;
                if (len > mss)
                        len = mss;
 
-               hsize = skb_headlen(skb) - offset;
+               hsize = skb_headlen(head_skb) - offset;
                if (hsize < 0)
                        hsize = 0;
                if (hsize > len || !sg)
                        hsize = len;
 
-               if (!hsize && i >= nfrags && skb_headlen(fskb) &&
-                   (skb_headlen(fskb) == len || sg)) {
-                       BUG_ON(skb_headlen(fskb) > len);
+               if (!hsize && i >= nfrags && skb_headlen(list_skb) &&
+                   (skb_headlen(list_skb) == len || sg)) {
+                       BUG_ON(skb_headlen(list_skb) > len);
 
                        i = 0;
-                       nfrags = skb_shinfo(fskb)->nr_frags;
-                       skb_frag = skb_shinfo(fskb)->frags;
-                       pos += skb_headlen(fskb);
+                       nfrags = skb_shinfo(list_skb)->nr_frags;
+                       frag = skb_shinfo(list_skb)->frags;
+                       frag_skb = list_skb;
+                       pos += skb_headlen(list_skb);
 
                        while (pos < offset + len) {
                                BUG_ON(i >= nfrags);
 
-                               size = skb_frag_size(skb_frag);
+                               size = skb_frag_size(frag);
                                if (pos + size > offset + len)
                                        break;
 
                                i++;
                                pos += size;
-                               skb_frag++;
+                               frag++;
                        }
 
-                       nskb = skb_clone(fskb, GFP_ATOMIC);
-                       fskb = fskb->next;
+                       nskb = skb_clone(list_skb, GFP_ATOMIC);
+                       list_skb = list_skb->next;
 
                        if (unlikely(!nskb))
                                goto err;
@@ -2933,7 +2936,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
                        __skb_push(nskb, doffset);
                } else {
                        nskb = __alloc_skb(hsize + doffset + headroom,
-                                          GFP_ATOMIC, skb_alloc_rx_flag(skb),
+                                          GFP_ATOMIC, skb_alloc_rx_flag(head_skb),
                                           NUMA_NO_NODE);
 
                        if (unlikely(!nskb))
@@ -2949,12 +2952,12 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
                        segs = nskb;
                tail = nskb;
 
-               __copy_skb_header(nskb, skb);
-               nskb->mac_len = skb->mac_len;
+               __copy_skb_header(nskb, head_skb);
+               nskb->mac_len = head_skb->mac_len;
 
                skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom);
 
-               skb_copy_from_linear_data_offset(skb, -tnl_hlen,
+               skb_copy_from_linear_data_offset(head_skb, -tnl_hlen,
                                                 nskb->data - tnl_hlen,
                                                 doffset + tnl_hlen);
 
@@ -2963,30 +2966,32 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
 
                if (!sg) {
                        nskb->ip_summed = CHECKSUM_NONE;
-                       nskb->csum = skb_copy_and_csum_bits(skb, offset,
+                       nskb->csum = skb_copy_and_csum_bits(head_skb, offset,
                                                            skb_put(nskb, len),
                                                            len, 0);
                        continue;
                }
 
-               frag = skb_shinfo(nskb)->frags;
+               nskb_frag = skb_shinfo(nskb)->frags;
 
-               skb_copy_from_linear_data_offset(skb, offset,
+               skb_copy_from_linear_data_offset(head_skb, offset,
                                                 skb_put(nskb, hsize), hsize);
 
-               skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
+               skb_shinfo(nskb)->tx_flags = skb_shinfo(head_skb)->tx_flags &
+                       SKBTX_SHARED_FRAG;
 
                while (pos < offset + len) {
                        if (i >= nfrags) {
-                               BUG_ON(skb_headlen(fskb));
+                               BUG_ON(skb_headlen(list_skb));
 
                                i = 0;
-                               nfrags = skb_shinfo(fskb)->nr_frags;
-                               skb_frag = skb_shinfo(fskb)->frags;
+                               nfrags = skb_shinfo(list_skb)->nr_frags;
+                               frag = skb_shinfo(list_skb)->frags;
+                               frag_skb = list_skb;
 
                                BUG_ON(!nfrags);
 
-                               fskb = fskb->next;
+                               list_skb = list_skb->next;
                        }
 
                        if (unlikely(skb_shinfo(nskb)->nr_frags >=
@@ -2997,27 +3002,30 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
                                goto err;
                        }
 
-                       *frag = *skb_frag;
-                       __skb_frag_ref(frag);
-                       size = skb_frag_size(frag);
+                       if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC)))
+                               goto err;
+
+                       *nskb_frag = *frag;
+                       __skb_frag_ref(nskb_frag);
+                       size = skb_frag_size(nskb_frag);
 
                        if (pos < offset) {
-                               frag->page_offset += offset - pos;
-                               skb_frag_size_sub(frag, offset - pos);
+                               nskb_frag->page_offset += offset - pos;
+                               skb_frag_size_sub(nskb_frag, offset - pos);
                        }
 
                        skb_shinfo(nskb)->nr_frags++;
 
                        if (pos + size <= offset + len) {
                                i++;
-                               skb_frag++;
+                               frag++;
                                pos += size;
                        } else {
-                               skb_frag_size_sub(frag, pos + size - (offset + len));
+                               skb_frag_size_sub(nskb_frag, pos + size - (offset + len));
                                goto skip_fraglist;
                        }
 
-                       frag++;
+                       nskb_frag++;
                }
 
 skip_fraglist:
@@ -3031,7 +3039,7 @@ perform_csum_check:
                                                  nskb->len - doffset, 0);
                        nskb->ip_summed = CHECKSUM_NONE;
                }
-       } while ((offset += len) < skb->len);
+       } while ((offset += len) < head_skb->len);
 
        return segs;
 
index 5b6a9431b0176142cb1f93392a0294c468d84887..c0fc6bdad1e3629f123244d6d7c77805c9b5f0bd 100644 (file)
@@ -2357,10 +2357,13 @@ void release_sock(struct sock *sk)
        if (sk->sk_backlog.tail)
                __release_sock(sk);
 
+       /* Warning : release_cb() might need to release sk ownership,
+        * ie call sock_release_ownership(sk) before us.
+        */
        if (sk->sk_prot->release_cb)
                sk->sk_prot->release_cb(sk);
 
-       sk->sk_lock.owned = 0;
+       sock_release_ownership(sk);
        if (waitqueue_active(&sk->sk_lock.wq))
                wake_up(&sk->sk_lock.wq);
        spin_unlock_bh(&sk->sk_lock.slock);
index bb075fc9a14f25169c175c7fcdcb86d56c709627..3b01959bf4bb0bbc208d8d564c8595c67eedd179 100644 (file)
@@ -208,7 +208,7 @@ int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force)
        }
 
        work = frag_mem_limit(nf) - nf->low_thresh;
-       while (work > 0) {
+       while (work > 0 || force) {
                spin_lock(&nf->lru_lock);
 
                if (list_empty(&nf->lru_list)) {
@@ -278,9 +278,10 @@ static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
 
        atomic_inc(&qp->refcnt);
        hlist_add_head(&qp->list, &hb->chain);
+       inet_frag_lru_add(nf, qp);
        spin_unlock(&hb->chain_lock);
        read_unlock(&f->lock);
-       inet_frag_lru_add(nf, qp);
+
        return qp;
 }
 
index f0eb4e337ec88fc631a30adc0d168817e5812ced..17a11e65e57fea3fa3728ce905df6130c580c48a 100644 (file)
@@ -767,6 +767,17 @@ void tcp_release_cb(struct sock *sk)
        if (flags & (1UL << TCP_TSQ_DEFERRED))
                tcp_tsq_handler(sk);
 
+       /* Here begins the tricky part :
+        * We are called from release_sock() with :
+        * 1) BH disabled
+        * 2) sk_lock.slock spinlock held
+        * 3) socket owned by us (sk->sk_lock.owned == 1)
+        *
+        * But following code is meant to be called from BH handlers,
+        * so we should keep BH disabled, but early release socket ownership
+        */
+       sock_release_ownership(sk);
+
        if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) {
                tcp_write_timer_handler(sk);
                __sock_put(sk);
index fdbfeca36d6344c22db31886c3661796eb9e8f86..344e972426df847a6f6b87414c37ef29e2ddd127 100644 (file)
@@ -1103,8 +1103,11 @@ retry:
         * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
         * an implementation must not create a temporary address with a zero
         * Preferred Lifetime.
+        * Use age calculation as in addrconf_verify to avoid unnecessary
+        * temporary addresses being generated.
         */
-       if (tmp_prefered_lft <= regen_advance) {
+       age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
+       if (tmp_prefered_lft <= regen_advance + age) {
                in6_ifa_put(ifp);
                in6_dev_put(idev);
                ret = -1;
index cf77f3abfd061280f6a211deb4a24bcd247c944a..447a7fbd1bb6f28dc78203ef4f4254705dc68c99 100644 (file)
@@ -25,11 +25,11 @@ int __init ipv6_exthdrs_offload_init(void)
        int ret;
 
        ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING);
-       if (!ret)
+       if (ret)
                goto out;
 
        ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS);
-       if (!ret)
+       if (ret)
                goto out_rt;
 
 out:
index 11dac21e658690cdf01d7eb41c7e653d142ad9d4..fba54a407bb2b7c2aae62ac2d03df806bc1a794a 100644 (file)
@@ -1513,7 +1513,7 @@ int ip6_route_add(struct fib6_config *cfg)
        if (!table)
                goto out;
 
-       rt = ip6_dst_alloc(net, NULL, DST_NOCOUNT, table);
+       rt = ip6_dst_alloc(net, NULL, (cfg->fc_flags & RTF_ADDRCONF) ? 0 : DST_NOCOUNT, table);
 
        if (!rt) {
                err = -ENOMEM;
index 735d0f60c83a126683b599d1e967eb9ca18b0471..85d9d94c0a3c57706540ce9b5efc78309dd69ca0 100644 (file)
@@ -112,7 +112,6 @@ struct l2tp_net {
        spinlock_t l2tp_session_hlist_lock;
 };
 
-static void l2tp_session_set_header_len(struct l2tp_session *session, int version);
 static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
 
 static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
@@ -1863,7 +1862,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_delete);
 /* We come here whenever a session's send_seq, cookie_len or
  * l2specific_len parameters are set.
  */
-static void l2tp_session_set_header_len(struct l2tp_session *session, int version)
+void l2tp_session_set_header_len(struct l2tp_session *session, int version)
 {
        if (version == L2TP_HDR_VER_2) {
                session->hdr_len = 6;
@@ -1876,6 +1875,7 @@ static void l2tp_session_set_header_len(struct l2tp_session *session, int versio
        }
 
 }
+EXPORT_SYMBOL_GPL(l2tp_session_set_header_len);
 
 struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)
 {
index 1f01ba3435bcf0889a79e510567f19f248b7eef5..3f93ccd6ba9768fe171f4e35e79d613226c1dbc7 100644 (file)
@@ -263,6 +263,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                      int length, int (*payload_hook)(struct sk_buff *skb));
 int l2tp_session_queue_purge(struct l2tp_session *session);
 int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb);
+void l2tp_session_set_header_len(struct l2tp_session *session, int version);
 
 int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb,
                  int hdr_len);
index 4cfd722e91536c1de137ec64f1e33bbc7fc5e1ea..bd7387adea9eff25ce7ffd0683589dcdcc020ad0 100644 (file)
@@ -578,8 +578,10 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf
        if (info->attrs[L2TP_ATTR_RECV_SEQ])
                session->recv_seq = nla_get_u8(info->attrs[L2TP_ATTR_RECV_SEQ]);
 
-       if (info->attrs[L2TP_ATTR_SEND_SEQ])
+       if (info->attrs[L2TP_ATTR_SEND_SEQ]) {
                session->send_seq = nla_get_u8(info->attrs[L2TP_ATTR_SEND_SEQ]);
+               l2tp_session_set_header_len(session, session->tunnel->version);
+       }
 
        if (info->attrs[L2TP_ATTR_LNS_MODE])
                session->lns_mode = nla_get_u8(info->attrs[L2TP_ATTR_LNS_MODE]);
index be5fadf3473946a3b7ef886eeadcb2d219e867aa..5990919356a5d7c7573d8cbd0f6c899f28eb7f67 100644 (file)
@@ -254,12 +254,14 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int
                po = pppox_sk(sk);
                ppp_input(&po->chan, skb);
        } else {
-               l2tp_info(session, PPPOL2TP_MSG_DATA, "%s: socket not bound\n",
-                         session->name);
+               l2tp_dbg(session, PPPOL2TP_MSG_DATA,
+                        "%s: recv %d byte data frame, passing to L2TP socket\n",
+                        session->name, data_len);
 
-               /* Not bound. Nothing we can do, so discard. */
-               atomic_long_inc(&session->stats.rx_errors);
-               kfree_skb(skb);
+               if (sock_queue_rcv_skb(sk, skb) < 0) {
+                       atomic_long_inc(&session->stats.rx_errors);
+                       kfree_skb(skb);
+               }
        }
 
        return;
@@ -1312,6 +1314,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
                        po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ :
                                PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
                }
+               l2tp_session_set_header_len(session, session->tunnel->version);
                l2tp_info(session, PPPOL2TP_MSG_CONTROL,
                          "%s: set send_seq=%d\n",
                          session->name, session->send_seq);
index f43613a97dd664e2daf1856b001d7bdee5708d4f..0c1ecfdf9a128b05f76e545d3e0b95de50123176 100644 (file)
@@ -100,6 +100,12 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
                }
                max_bw = max(max_bw, width);
        }
+
+       /* use the configured bandwidth in case of monitor interface */
+       sdata = rcu_dereference(local->monitor_sdata);
+       if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf)
+               max_bw = max(max_bw, conf->def.width);
+
        rcu_read_unlock();
 
        return max_bw;
index 2802f9d9279de1527927a88bc731489cc22613c7..ad8b377b4b9f6cfa5d5e222a3c0aff169f4d72d1 100644 (file)
@@ -36,6 +36,7 @@ static struct sk_buff *mps_qos_null_get(struct sta_info *sta)
                                      sdata->vif.addr);
        nullfunc->frame_control = fc;
        nullfunc->duration_id = 0;
+       nullfunc->seq_ctrl = 0;
        /* no address resolution for this frame -> set addr 1 immediately */
        memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
        memset(skb_put(skb, 2), 0, 2); /* append QoS control field */
index a023b432143b6f4b9db102b7a86c8ca417e1b3d2..137a192e64bc3c2aa61cc9c5912a89bd3008cbe3 100644 (file)
@@ -1206,6 +1206,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
        memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
        memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
        memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
+       nullfunc->seq_ctrl = 0;
 
        skb->priority = tid;
        skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]);
index 1313145e3b8650853514552a0ddb371b4000b788..a07d55e75698cf52068ebd54fb651a45d264817a 100644 (file)
@@ -273,11 +273,12 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
 
 void qdisc_list_add(struct Qdisc *q)
 {
-       struct Qdisc *root = qdisc_dev(q)->qdisc;
+       if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
+               struct Qdisc *root = qdisc_dev(q)->qdisc;
 
-       WARN_ON_ONCE(root == &noop_qdisc);
-       if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS))
+               WARN_ON_ONCE(root == &noop_qdisc);
                list_add_tail(&q->list, &root->list);
+       }
 }
 EXPORT_SYMBOL(qdisc_list_add);
 
index 08ef7a42c0e411657e789cb140fad522aef97ed1..21e251766eb1a099c8f603c1f7bb5d33ec5b04a2 100644 (file)
@@ -601,6 +601,7 @@ static int fq_resize(struct Qdisc *sch, u32 log)
 {
        struct fq_sched_data *q = qdisc_priv(sch);
        struct rb_root *array;
+       void *old_fq_root;
        u32 idx;
 
        if (q->fq_root && log == q->fq_trees_log)
@@ -615,13 +616,19 @@ static int fq_resize(struct Qdisc *sch, u32 log)
        for (idx = 0; idx < (1U << log); idx++)
                array[idx] = RB_ROOT;
 
-       if (q->fq_root) {
-               fq_rehash(q, q->fq_root, q->fq_trees_log, array, log);
-               fq_free(q->fq_root);
-       }
+       sch_tree_lock(sch);
+
+       old_fq_root = q->fq_root;
+       if (old_fq_root)
+               fq_rehash(q, old_fq_root, q->fq_trees_log, array, log);
+
        q->fq_root = array;
        q->fq_trees_log = log;
 
+       sch_tree_unlock(sch);
+
+       fq_free(old_fq_root);
+
        return 0;
 }
 
@@ -697,9 +704,11 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
                q->flow_refill_delay = usecs_to_jiffies(usecs_delay);
        }
 
-       if (!err)
+       if (!err) {
+               sch_tree_unlock(sch);
                err = fq_resize(sch, fq_log);
-
+               sch_tree_lock(sch);
+       }
        while (sch->q.qlen > sch->limit) {
                struct sk_buff *skb = fq_dequeue(sch);
 
index 632090b961c331b78efa79664392c7626451926d..3a1767ef3201a6a1870f641ef29e3683ea6dcff7 100644 (file)
@@ -1421,8 +1421,8 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
        BUG_ON(!list_empty(&chunk->list));
        list_del_init(&chunk->transmitted_list);
 
-       /* Free the chunk skb data and the SCTP_chunk stub itself. */
-       dev_kfree_skb(chunk->skb);
+       consume_skb(chunk->skb);
+       consume_skb(chunk->auth_chunk);
 
        SCTP_DBG_OBJCNT_DEC(chunk);
        kmem_cache_free(sctp_chunk_cachep, chunk);
index ae65b6b5973a9bceca7825037317f9fc9f39e2db..01e002430c858c293cdda11bd2962c3340043fb9 100644 (file)
@@ -760,7 +760,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
 
                /* Make sure that we and the peer are AUTH capable */
                if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) {
-                       kfree_skb(chunk->auth_chunk);
                        sctp_association_free(new_asoc);
                        return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
                }
@@ -775,10 +774,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
                auth.transport = chunk->transport;
 
                ret = sctp_sf_authenticate(net, ep, new_asoc, type, &auth);
-
-               /* We can now safely free the auth_chunk clone */
-               kfree_skb(chunk->auth_chunk);
-
                if (ret != SCTP_IERROR_NO_ERROR) {
                        sctp_association_free(new_asoc);
                        return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
index 879933aaed4c07ecd9cdad1809939ff729a588a7..a19ae1968d379d70ad36e51039d79469cfe30d18 100644 (file)
@@ -450,16 +450,17 @@ EXPORT_SYMBOL(sockfd_lookup);
 
 static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
 {
-       struct file *file;
+       struct fd f = fdget(fd);
        struct socket *sock;
 
        *err = -EBADF;
-       file = fget_light(fd, fput_needed);
-       if (file) {
-               sock = sock_from_file(file, err);
-               if (sock)
+       if (f.file) {
+               sock = sock_from_file(f.file, err);
+               if (likely(sock)) {
+                       *fput_needed = f.flags;
                        return sock;
-               fput_light(file, *fput_needed);
+               }
+               fdput(f);
        }
        return NULL;
 }
@@ -1985,6 +1986,10 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
 {
        if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
                return -EFAULT;
+
+       if (kmsg->msg_namelen < 0)
+               return -EINVAL;
+
        if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
                kmsg->msg_namelen = sizeof(struct sockaddr_storage);
        return 0;
index e74eef2e749011188a3d420f0bd8201c3d58f5c6..e6d721692ae016bbc900ac909406ca0a645848b0 100644 (file)
@@ -376,7 +376,6 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
        struct tipc_cfg_msg_hdr *req_hdr;
        struct tipc_cfg_msg_hdr *rep_hdr;
        struct sk_buff *rep_buf;
-       int ret;
 
        /* Validate configuration message header (ignore invalid message) */
        req_hdr = (struct tipc_cfg_msg_hdr *)buf;
@@ -398,12 +397,8 @@ static void cfg_conn_msg_event(int conid, struct sockaddr_tipc *addr,
                memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
                rep_hdr->tcm_len = htonl(rep_buf->len);
                rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
-
-               ret = tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
-                                       rep_buf->len);
-               if (ret < 0)
-                       pr_err("Sending cfg reply message failed, no memory\n");
-
+               tipc_conn_sendmsg(&cfgsrv, conid, addr, rep_buf->data,
+                                 rep_buf->len);
                kfree_skb(rep_buf);
        }
 }
index e4bc8a2967447fbde1f39d0d19146f2c7848ac99..1fabf160501f4f7b8127ef8d8a7583076e9b2eb4 100644 (file)
@@ -58,7 +58,6 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument)
 
        spin_lock_bh(&qitem_lock);
        if (!handler_enabled) {
-               pr_err("Signal request ignored by handler\n");
                spin_unlock_bh(&qitem_lock);
                return -ENOPROTOOPT;
        }
index 48302be175ce328d5b6d61d52a16c55ab31952a6..042e8e3cabc09f84aa5dce626c57a30faf3ca32d 100644 (file)
@@ -941,17 +941,48 @@ int tipc_nametbl_init(void)
        return 0;
 }
 
+/**
+ * tipc_purge_publications - remove all publications for a given type
+ *
+ * tipc_nametbl_lock must be held when calling this function
+ */
+static void tipc_purge_publications(struct name_seq *seq)
+{
+       struct publication *publ, *safe;
+       struct sub_seq *sseq;
+       struct name_info *info;
+
+       if (!seq->sseqs) {
+               nameseq_delete_empty(seq);
+               return;
+       }
+       sseq = seq->sseqs;
+       info = sseq->info;
+       list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) {
+               tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node,
+                                        publ->ref, publ->key);
+       }
+}
+
 void tipc_nametbl_stop(void)
 {
        u32 i;
+       struct name_seq *seq;
+       struct hlist_head *seq_head;
+       struct hlist_node *safe;
 
-       /* Verify name table is empty, then release it */
+       /* Verify name table is empty and purge any lingering
+        * publications, then release the name table
+        */
        write_lock_bh(&tipc_nametbl_lock);
        for (i = 0; i < TIPC_NAMETBL_SIZE; i++) {
                if (hlist_empty(&table.types[i]))
                        continue;
-               pr_err("nametbl_stop(): orphaned hash chain detected\n");
-               break;
+               seq_head = &table.types[i];
+               hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) {
+                       tipc_purge_publications(seq);
+               }
+               continue;
        }
        kfree(table.types);
        table.types = NULL;
index 373979789a73538bdd55dac4bde74505dc4310a9..646a930eefbf8fa9a86cfe7011848143aafa49b8 100644 (file)
@@ -87,7 +87,6 @@ static void tipc_clean_outqueues(struct tipc_conn *con);
 static void tipc_conn_kref_release(struct kref *kref)
 {
        struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
-       struct tipc_server *s = con->server;
 
        if (con->sock) {
                tipc_sock_release_local(con->sock);
@@ -95,10 +94,6 @@ static void tipc_conn_kref_release(struct kref *kref)
        }
 
        tipc_clean_outqueues(con);
-
-       if (con->conid)
-               s->tipc_conn_shutdown(con->conid, con->usr_data);
-
        kfree(con);
 }
 
@@ -181,6 +176,9 @@ static void tipc_close_conn(struct tipc_conn *con)
        struct tipc_server *s = con->server;
 
        if (test_and_clear_bit(CF_CONNECTED, &con->flags)) {
+               if (con->conid)
+                       s->tipc_conn_shutdown(con->conid, con->usr_data);
+
                spin_lock_bh(&s->idr_lock);
                idr_remove(&s->conn_idr, con->conid);
                s->idr_in_use--;
@@ -429,10 +427,12 @@ int tipc_conn_sendmsg(struct tipc_server *s, int conid,
        list_add_tail(&e->list, &con->outqueue);
        spin_unlock_bh(&con->outqueue_lock);
 
-       if (test_bit(CF_CONNECTED, &con->flags))
+       if (test_bit(CF_CONNECTED, &con->flags)) {
                if (!queue_work(s->send_wq, &con->swork))
                        conn_put(con);
-
+       } else {
+               conn_put(con);
+       }
        return 0;
 }
 
index a4cf274455aa42922c3e27947e0788da8e3ac794..0ed0eaa62f29e7148052907892ff90ebd20d2fed 100644 (file)
@@ -997,7 +997,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long timeo)
 
        for (;;) {
                prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
-               if (skb_queue_empty(&sk->sk_receive_queue)) {
+               if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
                        if (sock->state == SS_DISCONNECTING) {
                                err = -ENOTCONN;
                                break;
@@ -1623,7 +1623,7 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo)
        for (;;) {
                prepare_to_wait_exclusive(sk_sleep(sk), &wait,
                                          TASK_INTERRUPTIBLE);
-               if (skb_queue_empty(&sk->sk_receive_queue)) {
+               if (timeo && skb_queue_empty(&sk->sk_receive_queue)) {
                        release_sock(sk);
                        timeo = schedule_timeout(timeo);
                        lock_sock(sk);
index 7cb0bd5b1176872dcd09ca830a8a01c5b1ec37c6..11c9ae00837d66808755f1b8bee0542f449db6a1 100644 (file)
@@ -96,20 +96,16 @@ static void subscr_send_event(struct tipc_subscription *sub, u32 found_lower,
 {
        struct tipc_subscriber *subscriber = sub->subscriber;
        struct kvec msg_sect;
-       int ret;
 
        msg_sect.iov_base = (void *)&sub->evt;
        msg_sect.iov_len = sizeof(struct tipc_event);
-
        sub->evt.event = htohl(event, sub->swap);
        sub->evt.found_lower = htohl(found_lower, sub->swap);
        sub->evt.found_upper = htohl(found_upper, sub->swap);
        sub->evt.port.ref = htohl(port_ref, sub->swap);
        sub->evt.port.node = htohl(node, sub->swap);
-       ret = tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL,
-                               msg_sect.iov_base, msg_sect.iov_len);
-       if (ret < 0)
-               pr_err("Sending subscription event failed, no memory\n");
+       tipc_conn_sendmsg(&topsrv, subscriber->conid, NULL, msg_sect.iov_base,
+                         msg_sect.iov_len);
 }
 
 /**
@@ -153,14 +149,6 @@ static void subscr_timeout(struct tipc_subscription *sub)
        /* The spin lock per subscriber is used to protect its members */
        spin_lock_bh(&subscriber->lock);
 
-       /* Validate if the connection related to the subscriber is
-        * closed (in case subscriber is terminating)
-        */
-       if (subscriber->conid == 0) {
-               spin_unlock_bh(&subscriber->lock);
-               return;
-       }
-
        /* Validate timeout (in case subscription is being cancelled) */
        if (sub->timeout == TIPC_WAIT_FOREVER) {
                spin_unlock_bh(&subscriber->lock);
@@ -215,9 +203,6 @@ static void subscr_release(struct tipc_subscriber *subscriber)
 
        spin_lock_bh(&subscriber->lock);
 
-       /* Invalidate subscriber reference */
-       subscriber->conid = 0;
-
        /* Destroy any existing subscriptions for subscriber */
        list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
                                 subscription_list) {
index 29fc8bee97022f456f8b64b8ff6ff54a977962dd..ce6ec6c2f4de9b1eaaf34973f874e39eff408a79 100644 (file)
@@ -163,9 +163,8 @@ static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
 
 static inline unsigned int unix_hash_fold(__wsum n)
 {
-       unsigned int hash = (__force unsigned int)n;
+       unsigned int hash = (__force unsigned int)csum_fold(n);
 
-       hash ^= hash>>16;
        hash ^= hash>>8;
        return hash&(UNIX_HASH_SIZE-1);
 }
index 010892b81a06642a3886c7df9b74f0af9ecb1d3c..a3bf18d116095f14f4238bc792d22e5f51f2dd26 100644 (file)
@@ -788,8 +788,6 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
        default:
                break;
        }
-
-       wdev->beacon_interval = 0;
 }
 
 static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
index 276e84b8a8e57cb99cc5f1c956f1d4422657a0e7..10085de886fef49b78a12746a2e0a593545d56e0 100644 (file)
@@ -330,7 +330,8 @@ static void write_src(void)
                                printf("\tPTR\t_text + %#llx\n",
                                        table[i].addr - _text);
                        else
-                               printf("\tPTR\t%#llx\n", table[i].addr);
+                               printf("\tPTR\t_text - %#llx\n",
+                                       _text - table[i].addr);
                } else {
                        printf("\tPTR\t%#llx\n", table[i].addr);
                }
index 850296a1e0ff10db1bc699389b9912068f5b2761..8d0a84436674bf893ec871173a53b00b89f92c68 100644 (file)
@@ -3616,6 +3616,19 @@ static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
        }
 }
 
+static void alc_no_shutup(struct hda_codec *codec)
+{
+}
+
+static void alc_fixup_no_shutup(struct hda_codec *codec,
+                               const struct hda_fixup *fix, int action)
+{
+       if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+               struct alc_spec *spec = codec->spec;
+               spec->shutup = alc_no_shutup;
+       }
+}
+
 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
                                const struct hda_fixup *fix, int action)
 {
@@ -3844,6 +3857,7 @@ enum {
        ALC269_FIXUP_HP_GPIO_LED,
        ALC269_FIXUP_INV_DMIC,
        ALC269_FIXUP_LENOVO_DOCK,
+       ALC269_FIXUP_NO_SHUTUP,
        ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
        ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
        ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
@@ -4020,6 +4034,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_inv_dmic_0x12,
        },
+       [ALC269_FIXUP_NO_SHUTUP] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_no_shutup,
+       },
        [ALC269_FIXUP_LENOVO_DOCK] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -4405,6 +4423,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
        SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
index 29238a7476dd87e002d7500d0fffb3f37eada3d0..5b68b106cfc2161c95f5c1b1845d8646b152945f 100644 (file)
@@ -65,18 +65,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"MICIN", NULL, "Mic Jack"},
 };
 
-static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
-                                 ARRAY_SIZE(tlv320aic23_dapm_widgets));
-
-       snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-       return 0;
-}
-
 static struct snd_soc_dai_link snappercl15_dai = {
        .name           = "tlv320aic23",
        .stream_name    = "AIC23",
@@ -84,7 +72,6 @@ static struct snd_soc_dai_link snappercl15_dai = {
        .codec_dai_name = "tlv320aic23-hifi",
        .codec_name     = "tlv320aic23-codec.0-001a",
        .platform_name  = "ep93xx-i2s",
-       .init           = snappercl15_tlv320aic23_init,
        .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
                          SND_SOC_DAIFMT_CBS_CFS,
        .ops            = &snappercl15_ops,
@@ -95,6 +82,11 @@ static struct snd_soc_card snd_soc_snappercl15 = {
        .owner          = THIS_MODULE,
        .dai_link       = &snappercl15_dai,
        .num_links      = 1,
+
+       .dapm_widgets           = tlv320aic23_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(tlv320aic23_dapm_widgets),
+       .dapm_routes            = audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(audio_map),
 };
 
 static int snappercl15_probe(struct platform_device *pdev)
index 8703244ee9fbee59ad58c05f566fbd050cf59017..b07e17160f94a0453cf080cc487da4874f930673 100644 (file)
@@ -1327,8 +1327,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
 
        pm860x->codec = codec;
 
-       codec->control_data = pm860x->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+       ret = snd_soc_codec_set_cache_io(codec, pm860x->regmap);
        if (ret)
                return ret;
 
index 32d7a6f04b7d6bf1dfabb12097d48c55a8299c09..f0e8401378873721f0e69e7fe338fe00afe29fb5 100644 (file)
@@ -44,6 +44,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_CS42L73 if I2C
        select SND_SOC_CS4270 if I2C
        select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
+       select SND_SOC_CS42XX8_I2C if I2C
        select SND_SOC_CX20442 if TTY
        select SND_SOC_DA7210 if I2C
        select SND_SOC_DA7213 if I2C
@@ -85,6 +86,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_TLV320AIC23_I2C if I2C
        select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
        select SND_SOC_TLV320AIC26 if SPI_MASTER
+       select SND_SOC_TLV320AIC31XX if I2C
        select SND_SOC_TLV320AIC32X4 if I2C
        select SND_SOC_TLV320AIC3X if I2C
        select SND_SOC_TPA6130A2 if I2C
@@ -303,6 +305,15 @@ config SND_SOC_CS4271
        tristate "Cirrus Logic CS4271 CODEC"
        depends on SND_SOC_I2C_AND_SPI
 
+config SND_SOC_CS42XX8
+       tristate
+
+config SND_SOC_CS42XX8_I2C
+       tristate "Cirrus Logic CS42448/CS42888 CODEC (I2C)"
+       depends on I2C
+       select SND_SOC_CS42XX8
+       select REGMAP_I2C
+
 config SND_SOC_CX20442
        tristate
        depends on TTY
@@ -449,6 +460,9 @@ config SND_SOC_TLV320AIC26
        tristate
        depends on SPI
 
+config SND_SOC_TLV320AIC31XX
+        tristate
+
 config SND_SOC_TLV320AIC32X4
        tristate
 
index cb46c4c78dc20496c96c59c2426856d052e5e778..3c4d275d064bf8cc921c754a2dc577bdf72f4fe8 100644 (file)
@@ -30,6 +30,8 @@ snd-soc-cs42l52-objs := cs42l52.o
 snd-soc-cs42l73-objs := cs42l73.o
 snd-soc-cs4270-objs := cs4270.o
 snd-soc-cs4271-objs := cs4271.o
+snd-soc-cs42xx8-objs := cs42xx8.o
+snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
 snd-soc-da7213-objs := da7213.o
@@ -79,6 +81,7 @@ snd-soc-tlv320aic23-objs := tlv320aic23.o
 snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
 snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
 snd-soc-tlv320aic26-objs := tlv320aic26.o
+snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o
 snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
 snd-soc-tlv320aic3x-objs := tlv320aic3x.o
 snd-soc-tlv320dac33-objs := tlv320dac33.o
@@ -178,6 +181,8 @@ obj-$(CONFIG_SND_SOC_CS42L52)       += snd-soc-cs42l52.o
 obj-$(CONFIG_SND_SOC_CS42L73)  += snd-soc-cs42l73.o
 obj-$(CONFIG_SND_SOC_CS4270)   += snd-soc-cs4270.o
 obj-$(CONFIG_SND_SOC_CS4271)   += snd-soc-cs4271.o
+obj-$(CONFIG_SND_SOC_CS42XX8)  += snd-soc-cs42xx8.o
+obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
 obj-$(CONFIG_SND_SOC_CX20442)  += snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)   += snd-soc-da7210.o
 obj-$(CONFIG_SND_SOC_DA7213)   += snd-soc-da7213.o
@@ -223,6 +228,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC23)   += snd-soc-tlv320aic23.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C)  += snd-soc-tlv320aic23-i2c.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI)  += snd-soc-tlv320aic23-spi.o
 obj-$(CONFIG_SND_SOC_TLV320AIC26)      += snd-soc-tlv320aic26.o
+obj-$(CONFIG_SND_SOC_TLV320AIC31XX)     += snd-soc-tlv320aic31xx.o
 obj-$(CONFIG_SND_SOC_TLV320AIC32X4)     += snd-soc-tlv320aic32x4.o
 obj-$(CONFIG_SND_SOC_TLV320AIC3X)      += snd-soc-tlv320aic3x.o
 obj-$(CONFIG_SND_SOC_TLV320DAC33)      += snd-soc-tlv320dac33.o
index 9381a767e75fac9963ecf58e7a55d58b5c011a61..6844d0b2af6889e65501a954eca9ac5061913fe7 100644 (file)
@@ -322,14 +322,6 @@ static struct snd_soc_dai_driver ad193x_dai = {
 static int ad193x_codec_probe(struct snd_soc_codec *codec)
 {
        struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
-       int ret;
-
-       codec->control_data = ad193x->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;
-       }
 
        /* default setting for ad193x */
 
@@ -347,7 +339,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
        regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
        regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
 
-       return ret;
+       return 0;
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
index 5223800775ad431de1b22e08f653d5e14c1086ee..877f5737bb6b23bf924ab6b4a48c88f4498a950e 100644 (file)
@@ -1376,15 +1376,8 @@ static int adau1373_probe(struct snd_soc_codec *codec)
        struct adau1373_platform_data *pdata = codec->dev->platform_data;
        bool lineout_differential = false;
        unsigned int val;
-       int ret;
        int i;
 
-       ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
-       if (ret) {
-               dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        if (pdata) {
                if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
                        return -EINVAL;
index 7470831ba7561a79cc59536a380faf086c7d396f..5062e34ee8dcbdec1849ce83c299409b4ee6d582 100644 (file)
@@ -801,15 +801,8 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
 
 static int adav80x_probe(struct snd_soc_codec *codec)
 {
-       int ret;
        struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 
-       ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
-       if (ret) {
-               dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Force PLLs on for SYSCLK output */
        snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
        snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
index 684fe910669fd884f04e3900c03fc3631773e821..30e297890fec43eca2b01f344efc703aba14cacd 100644 (file)
@@ -388,15 +388,6 @@ static int ak4535_resume(struct snd_soc_codec *codec)
 
 static int ak4535_probe(struct snd_soc_codec *codec)
 {
-       struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
-       int ret;
-
-       codec->control_data = ak4535->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
        /* power on device */
        ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
index 684b56f2856ac3352d4d35c1b6889df13c686f36..868c0e2da1ece12102dc7f6a1ecc2aa6d50a66ab 100644 (file)
@@ -519,14 +519,6 @@ static int ak4641_resume(struct snd_soc_codec *codec)
 
 static int ak4641_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* power on device */
        ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
index 1f646c6e90c6b3ff688e0fd2582fcb1268679bb1..92655cc189ae0ad5791ab3483286de18dbd559b5 100644 (file)
@@ -465,14 +465,6 @@ static int ak4642_resume(struct snd_soc_codec *codec)
 
 static int ak4642_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        return 0;
index deb2b44669de4084bdf2b4386040580142a292a0..998fa0c5a0b93e2d351ec2a2936164748b8c1b91 100644 (file)
@@ -613,17 +613,7 @@ static struct snd_soc_dai_driver ak4671_dai = {
 
 static int ak4671_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
-       ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-       return ret;
+       return ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 }
 
 static int ak4671_remove(struct snd_soc_codec *codec)
index ed506253a9143351d14c4744fc1a1897dbe7663f..09f7e773bafb8721619843c187be4c24b06af73e 100644 (file)
@@ -904,13 +904,6 @@ static int alc5623_probe(struct snd_soc_codec *codec)
        struct snd_soc_dapm_context *dapm = &codec->dapm;
        int ret;
 
-       codec->control_data = alc5623->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;
-       }
-
        alc5623_reset(codec);
 
        /* power on device */
index d885056ad8f2a73d6ffe09d222db1e5ce33c9d72..ec071a6306ef567fb37b8c97981b64d1b3390f9e 100644 (file)
@@ -1063,14 +1063,6 @@ static int alc5632_probe(struct snd_soc_codec *codec)
        struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = alc5632->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;
-       }
-
        /* power on device  */
        alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
index 43737a27d79caff3dda074565d0201493d4fb96e..1e25c7af853bcdb7c40b7c94d4cb2ca6e878b8be 100644 (file)
@@ -138,9 +138,8 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
        struct davinci_vc *davinci_vc = codec->dev->platform_data;
 
        davinci_vc->cq93vc.codec = codec;
-       codec->control_data = davinci_vc->regmap;
 
-       snd_soc_codec_set_cache_io(codec, 32, 32, SND_SOC_REGMAP);
+       snd_soc_codec_set_cache_io(codec, davinci_vc->regmap);
 
        /* Off, with power on */
        cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
index 83c835d9fd884b18a87cdbb5420838b8fd9229f0..3920e626494885947853fd856f9d5ed37bc443ed 100644 (file)
@@ -506,15 +506,6 @@ static int cs4270_probe(struct snd_soc_codec *codec)
        struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       /* Tell ASoC what kind of I/O to use to read the registers.  ASoC will
-        * then do the I2C transactions itself.
-        */
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
-               return ret;
-       }
-
        /* Disable auto-mute.  This feature appears to be buggy.  In some
         * situations, auto-mute will not deactivate when it should, so we want
         * this feature disabled by default.  An application (e.g. alsactl) can
index 5caf75bc6bca3cf61ffbe79932db34e05f144218..6c0da2baa154e2a79a1baaf4392efacf4a7694af 100644 (file)
@@ -106,9 +106,8 @@ static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
 
 static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
 static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
-/* This is a lie. after -102 db, it stays at -102 */
-/* maybe a range would be better */
-static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0);
+
+static const DECLARE_TLV_DB_SCALE(aout_tlv, -10200, 50, 0);
 
 static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
 static const char *chan_mix[] = {
@@ -122,7 +121,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(cs42l51_chan_mix, chan_mix);
 static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
        SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
                        CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
-                       6, 0x19, 0x7F, adc_pcm_tlv),
+                       0, 0x19, 0x7F, adc_pcm_tlv),
        SOC_DOUBLE_R("PCM Playback Switch",
                        CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
        SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
@@ -130,7 +129,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
                        0, 0x34, 0xE4, aout_tlv),
        SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
                        CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
-                       6, 0x19, 0x7F, adc_pcm_tlv),
+                       0, 0x19, 0x7F, adc_pcm_tlv),
        SOC_DOUBLE_R("ADC Mixer Switch",
                        CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
        SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
@@ -488,12 +487,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
 {
        int ret, reg;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /*
         * DAC configuration
         * - Use signal processor
index be455ea5f2fed27b2a22489e26c5ae013fd9f804..f0ca6bee677159e0bb9a6af0a660bb937b815b7d 100644 (file)
@@ -341,7 +341,7 @@ static const char * const right_swap_text[] = {
 static const unsigned int swap_values[] = { 0, 1, 3 };
 
 static const struct soc_enum adca_swap_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 1,
+       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 3,
                              ARRAY_SIZE(left_swap_text),
                              left_swap_text,
                              swap_values);
@@ -350,7 +350,7 @@ static const struct snd_kcontrol_new adca_mixer =
        SOC_DAPM_ENUM("Route", adca_swap_enum);
 
 static const struct soc_enum pcma_swap_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 1,
+       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 3,
                              ARRAY_SIZE(left_swap_text),
                              left_swap_text,
                              swap_values);
@@ -359,7 +359,7 @@ static const struct snd_kcontrol_new pcma_mixer =
        SOC_DAPM_ENUM("Route", pcma_swap_enum);
 
 static const struct soc_enum adcb_swap_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 1,
+       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 3,
                              ARRAY_SIZE(right_swap_text),
                              right_swap_text,
                              swap_values);
@@ -368,7 +368,7 @@ static const struct snd_kcontrol_new adcb_mixer =
        SOC_DAPM_ENUM("Route", adcb_swap_enum);
 
 static const struct soc_enum pcmb_swap_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 1,
+       SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 3,
                              ARRAY_SIZE(right_swap_text),
                              right_swap_text,
                              swap_values);
@@ -1109,14 +1109,7 @@ static void cs42l52_free_beep(struct snd_soc_codec *codec)
 static int cs42l52_probe(struct snd_soc_codec *codec)
 {
        struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
-       int ret;
 
-       codec->control_data = cs42l52->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
        regcache_cache_only(cs42l52->regmap, true);
 
        cs42l52_add_mic_controls(codec);
@@ -1128,7 +1121,7 @@ static int cs42l52_probe(struct snd_soc_codec *codec)
        cs42l52->sysclk = CS42L52_DEFAULT_CLK;
        cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
 
-       return ret;
+       return 0;
 }
 
 static int cs42l52_remove(struct snd_soc_codec *codec)
index 06f42918482104b5b6c1aa61bc82103a1c197d35..0ee60a19a26334dcae0484244fcf9d374965fc88 100644 (file)
@@ -319,7 +319,7 @@ static const char * const cs42l73_mono_mix_texts[] = {
 static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 };
 
 static const struct soc_enum spk_asp_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1,
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 3,
                              ARRAY_SIZE(cs42l73_mono_mix_texts),
                              cs42l73_mono_mix_texts,
                              cs42l73_mono_mix_values);
@@ -337,7 +337,7 @@ static const struct snd_kcontrol_new spk_xsp_mixer =
        SOC_DAPM_ENUM("Route", spk_xsp_enum);
 
 static const struct soc_enum esl_asp_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5,
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 3,
                              ARRAY_SIZE(cs42l73_mono_mix_texts),
                              cs42l73_mono_mix_texts,
                              cs42l73_mono_mix_values);
@@ -346,7 +346,7 @@ static const struct snd_kcontrol_new esl_asp_mixer =
        SOC_DAPM_ENUM("Route", esl_asp_enum);
 
 static const struct soc_enum esl_xsp_enum =
-       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7,
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 3,
                              ARRAY_SIZE(cs42l73_mono_mix_texts),
                              cs42l73_mono_mix_texts,
                              cs42l73_mono_mix_values);
@@ -1345,17 +1345,8 @@ static int cs42l73_resume(struct snd_soc_codec *codec)
 
 static int cs42l73_probe(struct snd_soc_codec *codec)
 {
-       int ret;
        struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
 
-       codec->control_data = cs42l73->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        /* Set Charge Pump Frequency */
@@ -1368,7 +1359,7 @@ static int cs42l73_probe(struct snd_soc_codec *codec)
        cs42l73->mclksel = CS42L73_CLKID_MCLK1;
        cs42l73->mclk = 0;
 
-       return ret;
+       return 0;
 }
 
 static int cs42l73_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/cs42xx8-i2c.c b/sound/soc/codecs/cs42xx8-i2c.c
new file mode 100644 (file)
index 0000000..657dce2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Cirrus Logic CS42448/CS42888 Audio CODEC DAI I2C driver
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+
+#include "cs42xx8.h"
+
+static int cs42xx8_i2c_probe(struct i2c_client *i2c,
+                            const struct i2c_device_id *id)
+{
+       u32 ret = cs42xx8_probe(&i2c->dev,
+                       devm_regmap_init_i2c(i2c, &cs42xx8_regmap_config));
+       if (ret)
+               return ret;
+
+       pm_runtime_enable(&i2c->dev);
+       pm_request_idle(&i2c->dev);
+
+       return 0;
+}
+
+static int cs42xx8_i2c_remove(struct i2c_client *i2c)
+{
+       snd_soc_unregister_codec(&i2c->dev);
+       pm_runtime_disable(&i2c->dev);
+
+       return 0;
+}
+
+static struct i2c_device_id cs42xx8_i2c_id[] = {
+       {"cs42448", (kernel_ulong_t)&cs42448_data},
+       {"cs42888", (kernel_ulong_t)&cs42888_data},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, cs42xx8_i2c_id);
+
+static struct i2c_driver cs42xx8_i2c_driver = {
+       .driver = {
+               .name = "cs42xx8",
+               .owner = THIS_MODULE,
+               .pm = &cs42xx8_pm,
+       },
+       .probe = cs42xx8_i2c_probe,
+       .remove = cs42xx8_i2c_remove,
+       .id_table = cs42xx8_i2c_id,
+};
+
+module_i2c_driver(cs42xx8_i2c_driver);
+
+MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec I2C Driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
new file mode 100644 (file)
index 0000000..082299a
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "cs42xx8.h"
+
+#define CS42XX8_NUM_SUPPLIES 4
+static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = {
+       "VA",
+       "VD",
+       "VLS",
+       "VLC",
+};
+
+#define CS42XX8_FORMATS        (SNDRV_PCM_FMTBIT_S16_LE | \
+                        SNDRV_PCM_FMTBIT_S20_3LE | \
+                        SNDRV_PCM_FMTBIT_S24_LE | \
+                        SNDRV_PCM_FMTBIT_S32_LE)
+
+/* codec private data */
+struct cs42xx8_priv {
+       struct regulator_bulk_data supplies[CS42XX8_NUM_SUPPLIES];
+       const struct cs42xx8_driver_data *drvdata;
+       struct regmap *regmap;
+       struct clk *clk;
+
+       bool slave_mode;
+       unsigned long sysclk;
+};
+
+/* -127.5dB to 0dB with step of 0.5dB */
+static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
+/* -64dB to 24dB with step of 0.5dB */
+static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 0);
+
+static const char *const cs42xx8_adc_single[] = { "Differential", "Single-Ended" };
+static const char *const cs42xx8_szc[] = { "Immediate Change", "Zero Cross",
+                                       "Soft Ramp", "Soft Ramp on Zero Cross" };
+
+static const struct soc_enum adc1_single_enum =
+       SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 4, 2, cs42xx8_adc_single);
+static const struct soc_enum adc2_single_enum =
+       SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 3, 2, cs42xx8_adc_single);
+static const struct soc_enum adc3_single_enum =
+       SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 2, 2, cs42xx8_adc_single);
+static const struct soc_enum dac_szc_enum =
+       SOC_ENUM_SINGLE(CS42XX8_TXCTL, 5, 4, cs42xx8_szc);
+static const struct soc_enum adc_szc_enum =
+       SOC_ENUM_SINGLE(CS42XX8_TXCTL, 0, 4, cs42xx8_szc);
+
+static const struct snd_kcontrol_new cs42xx8_snd_controls[] = {
+       SOC_DOUBLE_R_TLV("DAC1 Playback Volume", CS42XX8_VOLAOUT1,
+                        CS42XX8_VOLAOUT2, 0, 0xff, 1, dac_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Playback Volume", CS42XX8_VOLAOUT3,
+                        CS42XX8_VOLAOUT4, 0, 0xff, 1, dac_tlv),
+       SOC_DOUBLE_R_TLV("DAC3 Playback Volume", CS42XX8_VOLAOUT5,
+                        CS42XX8_VOLAOUT6, 0, 0xff, 1, dac_tlv),
+       SOC_DOUBLE_R_TLV("DAC4 Playback Volume", CS42XX8_VOLAOUT7,
+                        CS42XX8_VOLAOUT8, 0, 0xff, 1, dac_tlv),
+       SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", CS42XX8_VOLAIN1,
+                          CS42XX8_VOLAIN2, 0, -0x80, 0x30, 7, 0, adc_tlv),
+       SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", CS42XX8_VOLAIN3,
+                          CS42XX8_VOLAIN4, 0, -0x80, 0x30, 7, 0, adc_tlv),
+       SOC_DOUBLE("DAC1 Invert Switch", CS42XX8_DACINV, 0, 1, 1, 0),
+       SOC_DOUBLE("DAC2 Invert Switch", CS42XX8_DACINV, 2, 3, 1, 0),
+       SOC_DOUBLE("DAC3 Invert Switch", CS42XX8_DACINV, 4, 5, 1, 0),
+       SOC_DOUBLE("DAC4 Invert Switch", CS42XX8_DACINV, 6, 7, 1, 0),
+       SOC_DOUBLE("ADC1 Invert Switch", CS42XX8_ADCINV, 0, 1, 1, 0),
+       SOC_DOUBLE("ADC2 Invert Switch", CS42XX8_ADCINV, 2, 3, 1, 0),
+       SOC_SINGLE("ADC High-Pass Filter Switch", CS42XX8_ADCCTL, 7, 1, 1),
+       SOC_SINGLE("DAC De-emphasis Switch", CS42XX8_ADCCTL, 5, 1, 0),
+       SOC_ENUM("ADC1 Single Ended Mode Switch", adc1_single_enum),
+       SOC_ENUM("ADC2 Single Ended Mode Switch", adc2_single_enum),
+       SOC_SINGLE("DAC Single Volume Control Switch", CS42XX8_TXCTL, 7, 1, 0),
+       SOC_ENUM("DAC Soft Ramp & Zero Cross Control Switch", dac_szc_enum),
+       SOC_SINGLE("DAC Auto Mute Switch", CS42XX8_TXCTL, 4, 1, 0),
+       SOC_SINGLE("Mute ADC Serial Port Switch", CS42XX8_TXCTL, 3, 1, 0),
+       SOC_SINGLE("ADC Single Volume Control Switch", CS42XX8_TXCTL, 2, 1, 0),
+       SOC_ENUM("ADC Soft Ramp & Zero Cross Control Switch", adc_szc_enum),
+};
+
+static const struct snd_kcontrol_new cs42xx8_adc3_snd_controls[] = {
+       SOC_DOUBLE_R_S_TLV("ADC3 Capture Volume", CS42XX8_VOLAIN5,
+                          CS42XX8_VOLAIN6, 0, -0x80, 0x30, 7, 0, adc_tlv),
+       SOC_DOUBLE("ADC3 Invert Switch", CS42XX8_ADCINV, 4, 5, 1, 0),
+       SOC_ENUM("ADC3 Single Ended Mode Switch", adc3_single_enum),
+};
+
+static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = {
+       SND_SOC_DAPM_DAC("DAC1", "Playback", CS42XX8_PWRCTL, 1, 1),
+       SND_SOC_DAPM_DAC("DAC2", "Playback", CS42XX8_PWRCTL, 2, 1),
+       SND_SOC_DAPM_DAC("DAC3", "Playback", CS42XX8_PWRCTL, 3, 1),
+       SND_SOC_DAPM_DAC("DAC4", "Playback", CS42XX8_PWRCTL, 4, 1),
+
+       SND_SOC_DAPM_OUTPUT("AOUT1L"),
+       SND_SOC_DAPM_OUTPUT("AOUT1R"),
+       SND_SOC_DAPM_OUTPUT("AOUT2L"),
+       SND_SOC_DAPM_OUTPUT("AOUT2R"),
+       SND_SOC_DAPM_OUTPUT("AOUT3L"),
+       SND_SOC_DAPM_OUTPUT("AOUT3R"),
+       SND_SOC_DAPM_OUTPUT("AOUT4L"),
+       SND_SOC_DAPM_OUTPUT("AOUT4R"),
+
+       SND_SOC_DAPM_ADC("ADC1", "Capture", CS42XX8_PWRCTL, 5, 1),
+       SND_SOC_DAPM_ADC("ADC2", "Capture", CS42XX8_PWRCTL, 6, 1),
+
+       SND_SOC_DAPM_INPUT("AIN1L"),
+       SND_SOC_DAPM_INPUT("AIN1R"),
+       SND_SOC_DAPM_INPUT("AIN2L"),
+       SND_SOC_DAPM_INPUT("AIN2R"),
+
+       SND_SOC_DAPM_SUPPLY("PWR", CS42XX8_PWRCTL, 0, 1, NULL, 0),
+};
+
+static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = {
+       SND_SOC_DAPM_ADC("ADC3", "Capture", CS42XX8_PWRCTL, 7, 1),
+
+       SND_SOC_DAPM_INPUT("AIN3L"),
+       SND_SOC_DAPM_INPUT("AIN3R"),
+};
+
+static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = {
+       /* Playback */
+       { "AOUT1L", NULL, "DAC1" },
+       { "AOUT1R", NULL, "DAC1" },
+       { "DAC1", NULL, "PWR" },
+
+       { "AOUT2L", NULL, "DAC2" },
+       { "AOUT2R", NULL, "DAC2" },
+       { "DAC2", NULL, "PWR" },
+
+       { "AOUT3L", NULL, "DAC3" },
+       { "AOUT3R", NULL, "DAC3" },
+       { "DAC3", NULL, "PWR" },
+
+       { "AOUT4L", NULL, "DAC4" },
+       { "AOUT4R", NULL, "DAC4" },
+       { "DAC4", NULL, "PWR" },
+
+       /* Capture */
+       { "ADC1", NULL, "AIN1L" },
+       { "ADC1", NULL, "AIN1R" },
+       { "ADC1", NULL, "PWR" },
+
+       { "ADC2", NULL, "AIN2L" },
+       { "ADC2", NULL, "AIN2R" },
+       { "ADC2", NULL, "PWR" },
+};
+
+static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
+       /* Capture */
+       { "ADC3", NULL, "AIN3L" },
+       { "ADC3", NULL, "AIN3R" },
+       { "ADC3", NULL, "PWR" },
+};
+
+struct cs42xx8_ratios {
+       unsigned int ratio;
+       unsigned char speed;
+       unsigned char mclk;
+};
+
+static const struct cs42xx8_ratios cs42xx8_ratios[] = {
+       { 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) },
+       { 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) },
+       { 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) },
+       { 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) },
+       { 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) },
+       { 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) },
+       { 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) },
+       { 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) },
+       { 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) }
+};
+
+static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+                                 int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+
+       cs42xx8->sysclk = freq;
+
+       return 0;
+}
+
+static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                              unsigned int format)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       u32 val;
+
+       /* Set DAI format */
+       switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_LEFT_J:
+               val = CS42XX8_INTF_DAC_DIF_LEFTJ | CS42XX8_INTF_ADC_DIF_LEFTJ;
+               break;
+       case SND_SOC_DAIFMT_I2S:
+               val = CS42XX8_INTF_DAC_DIF_I2S | CS42XX8_INTF_ADC_DIF_I2S;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ;
+               break;
+       default:
+               dev_err(codec->dev, "unsupported dai format\n");
+               return -EINVAL;
+       }
+
+       regmap_update_bits(cs42xx8->regmap, CS42XX8_INTF,
+                          CS42XX8_INTF_DAC_DIF_MASK |
+                          CS42XX8_INTF_ADC_DIF_MASK, val);
+
+       /* Set master/slave audio interface */
+       switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               cs42xx8->slave_mode = true;
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               cs42xx8->slave_mode = false;
+               break;
+       default:
+               dev_err(codec->dev, "unsupported master/slave mode\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cs42xx8_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 cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+       u32 ratio = cs42xx8->sysclk / params_rate(params);
+       u32 i, fm, val, mask;
+
+       for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
+               if (cs42xx8_ratios[i].ratio == ratio)
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(cs42xx8_ratios)) {
+               dev_err(codec->dev, "unsupported sysclk ratio\n");
+               return -EINVAL;
+       }
+
+       mask = CS42XX8_FUNCMOD_MFREQ_MASK;
+       val = cs42xx8_ratios[i].mclk;
+
+       fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed;
+
+       regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
+                          CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
+                          CS42XX8_FUNCMOD_xC_FM(tx, fm) | val);
+
+       return 0;
+}
+
+static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+
+       regmap_update_bits(cs42xx8->regmap, CS42XX8_DACMUTE,
+                          CS42XX8_DACMUTE_ALL, mute ? CS42XX8_DACMUTE_ALL : 0);
+
+       return 0;
+}
+
+static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
+       .set_fmt        = cs42xx8_set_dai_fmt,
+       .set_sysclk     = cs42xx8_set_dai_sysclk,
+       .hw_params      = cs42xx8_hw_params,
+       .digital_mute   = cs42xx8_digital_mute,
+};
+
+static struct snd_soc_dai_driver cs42xx8_dai = {
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 1,
+               .channels_max = 8,
+               .rates = SNDRV_PCM_RATE_8000_192000,
+               .formats = CS42XX8_FORMATS,
+       },
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .rates = SNDRV_PCM_RATE_8000_192000,
+               .formats = CS42XX8_FORMATS,
+       },
+       .ops = &cs42xx8_dai_ops,
+};
+
+static const struct reg_default cs42xx8_reg[] = {
+       { 0x01, 0x01 },   /* Chip I.D. and Revision Register */
+       { 0x02, 0x00 },   /* Power Control */
+       { 0x03, 0xF0 },   /* Functional Mode */
+       { 0x04, 0x46 },   /* Interface Formats */
+       { 0x05, 0x00 },   /* ADC Control & DAC De-Emphasis */
+       { 0x06, 0x10 },   /* Transition Control */
+       { 0x07, 0x00 },   /* DAC Channel Mute */
+       { 0x08, 0x00 },   /* Volume Control AOUT1 */
+       { 0x09, 0x00 },   /* Volume Control AOUT2 */
+       { 0x0a, 0x00 },   /* Volume Control AOUT3 */
+       { 0x0b, 0x00 },   /* Volume Control AOUT4 */
+       { 0x0c, 0x00 },   /* Volume Control AOUT5 */
+       { 0x0d, 0x00 },   /* Volume Control AOUT6 */
+       { 0x0e, 0x00 },   /* Volume Control AOUT7 */
+       { 0x0f, 0x00 },   /* Volume Control AOUT8 */
+       { 0x10, 0x00 },   /* DAC Channel Invert */
+       { 0x11, 0x00 },   /* Volume Control AIN1 */
+       { 0x12, 0x00 },   /* Volume Control AIN2 */
+       { 0x13, 0x00 },   /* Volume Control AIN3 */
+       { 0x14, 0x00 },   /* Volume Control AIN4 */
+       { 0x15, 0x00 },   /* Volume Control AIN5 */
+       { 0x16, 0x00 },   /* Volume Control AIN6 */
+       { 0x17, 0x00 },   /* ADC Channel Invert */
+       { 0x18, 0x00 },   /* Status Control */
+       { 0x1a, 0x00 },   /* Status Mask */
+       { 0x1b, 0x00 },   /* MUTEC Pin Control */
+};
+
+static bool cs42xx8_volatile_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case CS42XX8_STATUS:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool cs42xx8_writeable_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case CS42XX8_CHIPID:
+       case CS42XX8_STATUS:
+               return false;
+       default:
+               return true;
+       }
+}
+
+const struct regmap_config cs42xx8_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = CS42XX8_LASTREG,
+       .reg_defaults = cs42xx8_reg,
+       .num_reg_defaults = ARRAY_SIZE(cs42xx8_reg),
+       .volatile_reg = cs42xx8_volatile_register,
+       .writeable_reg = cs42xx8_writeable_register,
+       .cache_type = REGCACHE_RBTREE,
+};
+EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
+
+static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
+{
+       struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+
+       switch (cs42xx8->drvdata->num_adcs) {
+       case 3:
+               snd_soc_add_codec_controls(codec, cs42xx8_adc3_snd_controls,
+                                       ARRAY_SIZE(cs42xx8_adc3_snd_controls));
+               snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets,
+                                       ARRAY_SIZE(cs42xx8_adc3_dapm_widgets));
+               snd_soc_dapm_add_routes(dapm, cs42xx8_adc3_dapm_routes,
+                                       ARRAY_SIZE(cs42xx8_adc3_dapm_routes));
+               break;
+       default:
+               break;
+       }
+
+       /* Mute all DAC channels */
+       regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL);
+
+       return 0;
+}
+
+static const struct snd_soc_codec_driver cs42xx8_driver = {
+       .probe = cs42xx8_codec_probe,
+       .idle_bias_off = true,
+
+       .controls = cs42xx8_snd_controls,
+       .num_controls = ARRAY_SIZE(cs42xx8_snd_controls),
+       .dapm_widgets = cs42xx8_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets),
+       .dapm_routes = cs42xx8_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes),
+};
+
+const struct cs42xx8_driver_data cs42448_data = {
+       .name = "cs42448",
+       .num_adcs = 3,
+};
+EXPORT_SYMBOL_GPL(cs42448_data);
+
+const struct cs42xx8_driver_data cs42888_data = {
+       .name = "cs42888",
+       .num_adcs = 2,
+};
+EXPORT_SYMBOL_GPL(cs42888_data);
+
+const struct of_device_id cs42xx8_of_match[] = {
+       { .compatible = "cirrus,cs42448", .data = &cs42448_data, },
+       { .compatible = "cirrus,cs42888", .data = &cs42888_data, },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cs42xx8_of_match);
+EXPORT_SYMBOL_GPL(cs42xx8_of_match);
+
+int cs42xx8_probe(struct device *dev, struct regmap *regmap)
+{
+       const struct of_device_id *of_id = of_match_device(cs42xx8_of_match, dev);
+       struct cs42xx8_priv *cs42xx8;
+       int ret, val, i;
+
+       cs42xx8 = devm_kzalloc(dev, sizeof(*cs42xx8), GFP_KERNEL);
+       if (cs42xx8 == NULL)
+               return -ENOMEM;
+
+       dev_set_drvdata(dev, cs42xx8);
+
+       if (of_id)
+               cs42xx8->drvdata = of_id->data;
+
+       if (!cs42xx8->drvdata) {
+               dev_err(dev, "failed to find driver data\n");
+               return -EINVAL;
+       }
+
+       cs42xx8->clk = devm_clk_get(dev, "mclk");
+       if (IS_ERR(cs42xx8->clk)) {
+               dev_err(dev, "failed to get the clock: %ld\n",
+                               PTR_ERR(cs42xx8->clk));
+               return -EINVAL;
+       }
+
+       cs42xx8->sysclk = clk_get_rate(cs42xx8->clk);
+
+       for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++)
+               cs42xx8->supplies[i].supply = cs42xx8_supply_names[i];
+
+       ret = devm_regulator_bulk_get(dev,
+                       ARRAY_SIZE(cs42xx8->supplies), cs42xx8->supplies);
+       if (ret) {
+               dev_err(dev, "failed to request supplies: %d\n", ret);
+               return ret;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
+                                   cs42xx8->supplies);
+       if (ret) {
+               dev_err(dev, "failed to enable supplies: %d\n", ret);
+               return ret;
+       }
+
+       /* Make sure hardware reset done */
+       msleep(5);
+
+       cs42xx8->regmap = regmap;
+       if (IS_ERR(cs42xx8->regmap)) {
+               ret = PTR_ERR(cs42xx8->regmap);
+               dev_err(dev, "failed to allocate regmap: %d\n", ret);
+               goto err_enable;
+       }
+
+       /*
+        * We haven't marked the chip revision as volatile due to
+        * sharing a register with the right input volume; explicitly
+        * bypass the cache to read it.
+        */
+       regcache_cache_bypass(cs42xx8->regmap, true);
+
+       /* Validate the chip ID */
+       regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val);
+       if (val < 0) {
+               dev_err(dev, "failed to get device ID: %x", val);
+               ret = -EINVAL;
+               goto err_enable;
+       }
+
+       /* The top four bits of the chip ID should be 0000 */
+       if ((val & CS42XX8_CHIPID_CHIP_ID_MASK) != 0x00) {
+               dev_err(dev, "unmatched chip ID: %d\n",
+                               val & CS42XX8_CHIPID_CHIP_ID_MASK);
+               ret = -EINVAL;
+               goto err_enable;
+       }
+
+       dev_info(dev, "found device, revision %X\n",
+                       val & CS42XX8_CHIPID_REV_ID_MASK);
+
+       regcache_cache_bypass(cs42xx8->regmap, false);
+
+       cs42xx8_dai.name = cs42xx8->drvdata->name;
+
+       /* Each adc supports stereo input */
+       cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2;
+
+       ret = snd_soc_register_codec(dev, &cs42xx8_driver, &cs42xx8_dai, 1);
+       if (ret) {
+               dev_err(dev, "failed to register codec:%d\n", ret);
+               goto err_enable;
+       }
+
+       regcache_cache_only(cs42xx8->regmap, true);
+
+err_enable:
+       regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
+                              cs42xx8->supplies);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(cs42xx8_probe);
+
+#ifdef CONFIG_PM_RUNTIME
+static int cs42xx8_runtime_resume(struct device *dev)
+{
+       struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
+       int ret;
+
+       ret = clk_prepare_enable(cs42xx8->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable mclk: %d\n", ret);
+               return ret;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
+                                   cs42xx8->supplies);
+       if (ret) {
+               dev_err(dev, "failed to enable supplies: %d\n", ret);
+               goto err_clk;
+       }
+
+       /* Make sure hardware reset done */
+       msleep(5);
+
+       regcache_cache_only(cs42xx8->regmap, false);
+
+       ret = regcache_sync(cs42xx8->regmap);
+       if (ret) {
+               dev_err(dev, "failed to sync regmap: %d\n", ret);
+               goto err_bulk;
+       }
+
+       return 0;
+
+err_bulk:
+       regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
+                              cs42xx8->supplies);
+err_clk:
+       clk_disable_unprepare(cs42xx8->clk);
+
+       return ret;
+}
+
+static int cs42xx8_runtime_suspend(struct device *dev)
+{
+       struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev);
+
+       regcache_cache_only(cs42xx8->regmap, true);
+
+       regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
+                              cs42xx8->supplies);
+
+       clk_disable_unprepare(cs42xx8->clk);
+
+       return 0;
+}
+#endif
+
+const struct dev_pm_ops cs42xx8_pm = {
+       SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
+};
+EXPORT_SYMBOL_GPL(cs42xx8_pm);
+
+MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42xx8.h b/sound/soc/codecs/cs42xx8.h
new file mode 100644 (file)
index 0000000..da0b94a
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * cs42xx8.h - Cirrus Logic CS42448/CS42888 Audio CODEC driver header file
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef _CS42XX8_H
+#define _CS42XX8_H
+
+struct cs42xx8_driver_data {
+       char name[32];
+       int num_adcs;
+};
+
+extern const struct dev_pm_ops cs42xx8_pm;
+extern const struct cs42xx8_driver_data cs42448_data;
+extern const struct cs42xx8_driver_data cs42888_data;
+extern const struct regmap_config cs42xx8_regmap_config;
+int cs42xx8_probe(struct device *dev, struct regmap *regmap);
+
+/* CS42888 register map */
+#define CS42XX8_CHIPID                         0x01    /* Chip ID */
+#define CS42XX8_PWRCTL                         0x02    /* Power Control */
+#define CS42XX8_FUNCMOD                                0x03    /* Functional Mode */
+#define CS42XX8_INTF                           0x04    /* Interface Formats */
+#define CS42XX8_ADCCTL                         0x05    /* ADC Control */
+#define CS42XX8_TXCTL                          0x06    /* Transition Control */
+#define CS42XX8_DACMUTE                                0x07    /* DAC Mute Control */
+#define CS42XX8_VOLAOUT1                       0x08    /* Volume Control AOUT1 */
+#define CS42XX8_VOLAOUT2                       0x09    /* Volume Control AOUT2 */
+#define CS42XX8_VOLAOUT3                       0x0A    /* Volume Control AOUT3 */
+#define CS42XX8_VOLAOUT4                       0x0B    /* Volume Control AOUT4 */
+#define CS42XX8_VOLAOUT5                       0x0C    /* Volume Control AOUT5 */
+#define CS42XX8_VOLAOUT6                       0x0D    /* Volume Control AOUT6 */
+#define CS42XX8_VOLAOUT7                       0x0E    /* Volume Control AOUT7 */
+#define CS42XX8_VOLAOUT8                       0x0F    /* Volume Control AOUT8 */
+#define CS42XX8_DACINV                         0x10    /* DAC Channel Invert */
+#define CS42XX8_VOLAIN1                                0x11    /* Volume Control AIN1 */
+#define CS42XX8_VOLAIN2                                0x12    /* Volume Control AIN2 */
+#define CS42XX8_VOLAIN3                                0x13    /* Volume Control AIN3 */
+#define CS42XX8_VOLAIN4                                0x14    /* Volume Control AIN4 */
+#define CS42XX8_VOLAIN5                                0x15    /* Volume Control AIN5 */
+#define CS42XX8_VOLAIN6                                0x16    /* Volume Control AIN6 */
+#define CS42XX8_ADCINV                         0x17    /* ADC Channel Invert */
+#define CS42XX8_STATUSCTL                      0x18    /* Status Control */
+#define CS42XX8_STATUS                         0x19    /* Status */
+#define CS42XX8_STATUSM                                0x1A    /* Status Mask */
+#define CS42XX8_MUTEC                          0x1B    /* MUTEC Pin Control */
+
+#define CS42XX8_FIRSTREG                       CS42XX8_CHIPID
+#define CS42XX8_LASTREG                                CS42XX8_MUTEC
+#define CS42XX8_NUMREGS                                (CS42XX8_LASTREG - CS42XX8_FIRSTREG + 1)
+#define CS42XX8_I2C_INCR                       0x80
+
+/* Chip I.D. and Revision Register (Address 01h) */
+#define CS42XX8_CHIPID_CHIP_ID_MASK            0xF0
+#define CS42XX8_CHIPID_REV_ID_MASK             0x0F
+
+/* Power Control (Address 02h) */
+#define CS42XX8_PWRCTL_PDN_ADC3_SHIFT          7
+#define CS42XX8_PWRCTL_PDN_ADC3_MASK           (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC3                        (1 << CS42XX8_PWRCTL_PDN_ADC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC2_SHIFT          6
+#define CS42XX8_PWRCTL_PDN_ADC2_MASK           (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC2                        (1 << CS42XX8_PWRCTL_PDN_ADC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC1_SHIFT          5
+#define CS42XX8_PWRCTL_PDN_ADC1_MASK           (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_ADC1                        (1 << CS42XX8_PWRCTL_PDN_ADC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC4_SHIFT          4
+#define CS42XX8_PWRCTL_PDN_DAC4_MASK           (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC4                        (1 << CS42XX8_PWRCTL_PDN_DAC4_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC3_SHIFT          3
+#define CS42XX8_PWRCTL_PDN_DAC3_MASK           (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC3                        (1 << CS42XX8_PWRCTL_PDN_DAC3_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC2_SHIFT          2
+#define CS42XX8_PWRCTL_PDN_DAC2_MASK           (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC2                        (1 << CS42XX8_PWRCTL_PDN_DAC2_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC1_SHIFT          1
+#define CS42XX8_PWRCTL_PDN_DAC1_MASK           (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_DAC1                        (1 << CS42XX8_PWRCTL_PDN_DAC1_SHIFT)
+#define CS42XX8_PWRCTL_PDN_SHIFT               0
+#define CS42XX8_PWRCTL_PDN_MASK                        (1 << CS42XX8_PWRCTL_PDN_SHIFT)
+#define CS42XX8_PWRCTL_PDN                     (1 << CS42XX8_PWRCTL_PDN_SHIFT)
+
+/* Functional Mode (Address 03h) */
+#define CS42XX8_FUNCMOD_DAC_FM_SHIFT           6
+#define CS42XX8_FUNCMOD_DAC_FM_WIDTH           2
+#define CS42XX8_FUNCMOD_DAC_FM_MASK            (((1 << CS42XX8_FUNCMOD_DAC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_DAC_FM(v)              ((v) << CS42XX8_FUNCMOD_DAC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_ADC_FM_SHIFT           4
+#define CS42XX8_FUNCMOD_ADC_FM_WIDTH           2
+#define CS42XX8_FUNCMOD_ADC_FM_MASK            (((1 << CS42XX8_FUNCMOD_ADC_FM_WIDTH) - 1) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_ADC_FM(v)              ((v) << CS42XX8_FUNCMOD_ADC_FM_SHIFT)
+#define CS42XX8_FUNCMOD_xC_FM_MASK(x)          ((x) ? CS42XX8_FUNCMOD_DAC_FM_MASK : CS42XX8_FUNCMOD_ADC_FM_MASK)
+#define CS42XX8_FUNCMOD_xC_FM(x, v)            ((x) ? CS42XX8_FUNCMOD_DAC_FM(v) : CS42XX8_FUNCMOD_ADC_FM(v))
+#define CS42XX8_FUNCMOD_MFREQ_SHIFT            1
+#define CS42XX8_FUNCMOD_MFREQ_WIDTH            3
+#define CS42XX8_FUNCMOD_MFREQ_MASK             (((1 << CS42XX8_FUNCMOD_MFREQ_WIDTH) - 1) << CS42XX8_FUNCMOD_MFREQ_SHIFT)
+#define CS42XX8_FUNCMOD_MFREQ_256(s)           ((0 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_384(s)           ((1 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_512(s)           ((2 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_768(s)           ((3 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+#define CS42XX8_FUNCMOD_MFREQ_1024(s)          ((4 << CS42XX8_FUNCMOD_MFREQ_SHIFT) >> (s >> 1))
+
+#define CS42XX8_FM_SINGLE                      0
+#define CS42XX8_FM_DOUBLE                      1
+#define CS42XX8_FM_QUAD                                2
+#define CS42XX8_FM_AUTO                                3
+
+/* Interface Formats (Address 04h) */
+#define CS42XX8_INTF_FREEZE_SHIFT              7
+#define CS42XX8_INTF_FREEZE_MASK               (1 << CS42XX8_INTF_FREEZE_SHIFT)
+#define CS42XX8_INTF_FREEZE                    (1 << CS42XX8_INTF_FREEZE_SHIFT)
+#define CS42XX8_INTF_AUX_DIF_SHIFT             6
+#define CS42XX8_INTF_AUX_DIF_MASK              (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
+#define CS42XX8_INTF_AUX_DIF                   (1 << CS42XX8_INTF_AUX_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_SHIFT             3
+#define CS42XX8_INTF_DAC_DIF_WIDTH             3
+#define CS42XX8_INTF_DAC_DIF_MASK              (((1 << CS42XX8_INTF_DAC_DIF_WIDTH) - 1) << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_LEFTJ             (0 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_I2S               (1 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_RIGHTJ            (2 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_RIGHTJ_16         (3 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_ONELINE_20                (4 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_ONELINE_24                (6 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_DAC_DIF_TDM               (7 << CS42XX8_INTF_DAC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_SHIFT             0
+#define CS42XX8_INTF_ADC_DIF_WIDTH             3
+#define CS42XX8_INTF_ADC_DIF_MASK              (((1 << CS42XX8_INTF_ADC_DIF_WIDTH) - 1) << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_LEFTJ             (0 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_I2S               (1 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_RIGHTJ            (2 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_RIGHTJ_16         (3 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_ONELINE_20                (4 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_ONELINE_24                (6 << CS42XX8_INTF_ADC_DIF_SHIFT)
+#define CS42XX8_INTF_ADC_DIF_TDM               (7 << CS42XX8_INTF_ADC_DIF_SHIFT)
+
+/* ADC Control & DAC De-Emphasis (Address 05h) */
+#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT    7
+#define CS42XX8_ADCCTL_ADC_HPF_FREEZE_MASK     (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
+#define CS42XX8_ADCCTL_ADC_HPF_FREEZE          (1 << CS42XX8_ADCCTL_ADC_HPF_FREEZE_SHIFT)
+#define CS42XX8_ADCCTL_DAC_DEM_SHIFT           5
+#define CS42XX8_ADCCTL_DAC_DEM_MASK            (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
+#define CS42XX8_ADCCTL_DAC_DEM                 (1 << CS42XX8_ADCCTL_DAC_DEM_SHIFT)
+#define CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT       4
+#define CS42XX8_ADCCTL_ADC1_SINGLE_MASK                (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC1_SINGLE             (1 << CS42XX8_ADCCTL_ADC1_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT       3
+#define CS42XX8_ADCCTL_ADC2_SINGLE_MASK                (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC2_SINGLE             (1 << CS42XX8_ADCCTL_ADC2_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT       2
+#define CS42XX8_ADCCTL_ADC3_SINGLE_MASK                (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_ADC3_SINGLE             (1 << CS42XX8_ADCCTL_ADC3_SINGLE_SHIFT)
+#define CS42XX8_ADCCTL_AIN5_MUX_SHIFT          1
+#define CS42XX8_ADCCTL_AIN5_MUX_MASK           (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
+#define CS42XX8_ADCCTL_AIN5_MUX                        (1 << CS42XX8_ADCCTL_AIN5_MUX_SHIFT)
+#define CS42XX8_ADCCTL_AIN6_MUX_SHIFT          0
+#define CS42XX8_ADCCTL_AIN6_MUX_MASK           (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
+#define CS42XX8_ADCCTL_AIN6_MUX                        (1 << CS42XX8_ADCCTL_AIN6_MUX_SHIFT)
+
+/* Transition Control (Address 06h) */
+#define CS42XX8_TXCTL_DAC_SNGVOL_SHIFT         7
+#define CS42XX8_TXCTL_DAC_SNGVOL_MASK          (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_DAC_SNGVOL               (1 << CS42XX8_TXCTL_DAC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_SHIFT            5
+#define CS42XX8_TXCTL_DAC_SZC_WIDTH            2
+#define CS42XX8_TXCTL_DAC_SZC_MASK             (((1 << CS42XX8_TXCTL_DAC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_IC               (0 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_ZC               (1 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_SR               (2 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_DAC_SZC_SRZC             (3 << CS42XX8_TXCTL_DAC_SZC_SHIFT)
+#define CS42XX8_TXCTL_AMUTE_SHIFT              4
+#define CS42XX8_TXCTL_AMUTE_MASK               (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
+#define CS42XX8_TXCTL_AMUTE                    (1 << CS42XX8_TXCTL_AMUTE_SHIFT)
+#define CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT                3
+#define CS42XX8_TXCTL_MUTE_ADC_SP_MASK         (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
+#define CS42XX8_TXCTL_MUTE_ADC_SP              (1 << CS42XX8_TXCTL_MUTE_ADC_SP_SHIFT)
+#define CS42XX8_TXCTL_ADC_SNGVOL_SHIFT         2
+#define CS42XX8_TXCTL_ADC_SNGVOL_MASK          (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_ADC_SNGVOL               (1 << CS42XX8_TXCTL_ADC_SNGVOL_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_SHIFT            0
+#define CS42XX8_TXCTL_ADC_SZC_MASK             (((1 << CS42XX8_TXCTL_ADC_SZC_WIDTH) - 1) << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_IC               (0 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_ZC               (1 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_SR               (2 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+#define CS42XX8_TXCTL_ADC_SZC_SRZC             (3 << CS42XX8_TXCTL_ADC_SZC_SHIFT)
+
+/* DAC Channel Mute (Address 07h) */
+#define CS42XX8_DACMUTE_AOUT(n)                        (0x1 << n)
+#define CS42XX8_DACMUTE_ALL                    0xff
+
+/* Status Control (Address 18h)*/
+#define CS42XX8_STATUSCTL_INI_SHIFT            2
+#define CS42XX8_STATUSCTL_INI_WIDTH            2
+#define CS42XX8_STATUSCTL_INI_MASK             (((1 << CS42XX8_STATUSCTL_INI_WIDTH) - 1) << CS42XX8_STATUSCTL_INI_SHIFT)
+#define CS42XX8_STATUSCTL_INT_ACTIVE_HIGH      (0 << CS42XX8_STATUSCTL_INI_SHIFT)
+#define CS42XX8_STATUSCTL_INT_ACTIVE_LOW       (1 << CS42XX8_STATUSCTL_INI_SHIFT)
+#define CS42XX8_STATUSCTL_INT_OPEN_DRAIN       (2 << CS42XX8_STATUSCTL_INI_SHIFT)
+
+/* Status (Address 19h)*/
+#define CS42XX8_STATUS_DAC_CLK_ERR_SHIFT       4
+#define CS42XX8_STATUS_DAC_CLK_ERR_MASK                (1 << CS42XX8_STATUS_DAC_CLK_ERR_SHIFT)
+#define CS42XX8_STATUS_ADC_CLK_ERR_SHIFT       3
+#define CS42XX8_STATUS_ADC_CLK_ERR_MASK                (1 << CS42XX8_STATUS_ADC_CLK_ERR_SHIFT)
+#define CS42XX8_STATUS_ADC3_OVFL_SHIFT         2
+#define CS42XX8_STATUS_ADC3_OVFL_MASK          (1 << CS42XX8_STATUS_ADC3_OVFL_SHIFT)
+#define CS42XX8_STATUS_ADC2_OVFL_SHIFT         1
+#define CS42XX8_STATUS_ADC2_OVFL_MASK          (1 << CS42XX8_STATUS_ADC2_OVFL_SHIFT)
+#define CS42XX8_STATUS_ADC1_OVFL_SHIFT         0
+#define CS42XX8_STATUS_ADC1_OVFL_MASK          (1 << CS42XX8_STATUS_ADC1_OVFL_SHIFT)
+
+/* Status Mask (Address 1Ah) */
+#define CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT     4
+#define CS42XX8_STATUS_DAC_CLK_ERR_M_MASK      (1 << CS42XX8_STATUS_DAC_CLK_ERR_M_SHIFT)
+#define CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT     3
+#define CS42XX8_STATUS_ADC_CLK_ERR_M_MASK      (1 << CS42XX8_STATUS_ADC_CLK_ERR_M_SHIFT)
+#define CS42XX8_STATUS_ADC3_OVFL_M_SHIFT       2
+#define CS42XX8_STATUS_ADC3_OVFL_M_MASK                (1 << CS42XX8_STATUS_ADC3_OVFL_M_SHIFT)
+#define CS42XX8_STATUS_ADC2_OVFL_M_SHIFT       1
+#define CS42XX8_STATUS_ADC2_OVFL_M_MASK                (1 << CS42XX8_STATUS_ADC2_OVFL_M_SHIFT)
+#define CS42XX8_STATUS_ADC1_OVFL_M_SHIFT       0
+#define CS42XX8_STATUS_ADC1_OVFL_M_MASK                (1 << CS42XX8_STATUS_ADC1_OVFL_M_SHIFT)
+
+/* MUTEC Pin Control (Address 1Bh) */
+#define CS42XX8_MUTEC_MCPOLARITY_SHIFT         1
+#define CS42XX8_MUTEC_MCPOLARITY_MASK          (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
+#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_LOW    (0 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
+#define CS42XX8_MUTEC_MCPOLARITY_ACTIVE_HIGH   (1 << CS42XX8_MUTEC_MCPOLARITY_SHIFT)
+#define CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT       0
+#define CS42XX8_MUTEC_MUTEC_ACTIVE_MASK                (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
+#define CS42XX8_MUTEC_MUTEC_ACTIVE             (1 << CS42XX8_MUTEC_MUTEC_ACTIVE_SHIFT)
+#endif /* _CS42XX8_H */
index 01e55fc72307073d6786bca5e971a36eba983024..137e8ebc092c5a9f2c1264723211ba7e8405871f 100644 (file)
@@ -1071,17 +1071,9 @@ static struct snd_soc_dai_driver da7210_dai = {
 static int da7210_probe(struct snd_soc_codec *codec)
 {
        struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
-       int ret;
 
        dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
 
-       codec->control_data = da7210->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        da7210->mclk_rate       = 0;    /* This will be set from set_sysclk() */
        da7210->master          = 0;    /* This will be set from set_fmt() */
 
index 439d10387f1072078699d6173262dd65c87b902a..738fa18a50d2a82c900c49fbc68f3c07c7dd2c07 100644 (file)
@@ -1393,17 +1393,9 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 
 static int da7213_probe(struct snd_soc_codec *codec)
 {
-       int ret;
        struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
        struct da7213_platform_data *pdata = da7213->pdata;
 
-       codec->control_data = da7213->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Default to using ALC auto offset calibration mode. */
        snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
                            DA7213_ALC_CALIB_MODE_MAN, 0);
index 4d1c302f5a76edc06e4c1efa4fff4d3ba96818e7..7d168ec71cd70409095ee82fb95ec8a929601f98 100644 (file)
@@ -1297,9 +1297,9 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
        msleep(DA732X_WAIT_FOR_STABILIZATION);
 
        /* Check DAC offset sign */
-       sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+       sign[DA732X_HPL_DAC] = (snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
                                DA732X_HP_DAC_OFF_CNTL_COMPO);
-       sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+       sign[DA732X_HPR_DAC] = (snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
                                DA732X_HP_DAC_OFF_CNTL_COMPO);
 
        /* Binary search DAC offset values (both channels at once) */
@@ -1316,10 +1316,10 @@ static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
 
                msleep(DA732X_WAIT_FOR_STABILIZATION);
 
-               if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
+               if ((snd_soc_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
                     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
                        offset[DA732X_HPL_DAC] &= ~step;
-               if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
+               if ((snd_soc_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
                     DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
                        offset[DA732X_HPR_DAC] &= ~step;
 
@@ -1360,9 +1360,9 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
        msleep(DA732X_WAIT_FOR_STABILIZATION);
 
        /* Check output offset sign */
-       sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) &
+       sign[DA732X_HPL_AMP] = snd_soc_read(codec, DA732X_REG_HPL) &
                               DA732X_HP_OUT_COMPO;
-       sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) &
+       sign[DA732X_HPR_AMP] = snd_soc_read(codec, DA732X_REG_HPR) &
                               DA732X_HP_OUT_COMPO;
 
        snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
@@ -1383,10 +1383,10 @@ static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
 
                msleep(DA732X_WAIT_FOR_STABILIZATION);
 
-               if ((codec->hw_read(codec, DA732X_REG_HPL) &
+               if ((snd_soc_read(codec, DA732X_REG_HPL) &
                     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
                        offset[DA732X_HPL_AMP] &= ~step;
-               if ((codec->hw_read(codec, DA732X_REG_HPR) &
+               if ((snd_soc_read(codec, DA732X_REG_HPR) &
                     DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
                        offset[DA732X_HPR_AMP] &= ~step;
 
@@ -1512,23 +1512,14 @@ static int da732x_probe(struct snd_soc_codec *codec)
 {
        struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
        struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int ret = 0;
 
        da732x->codec = codec;
 
        dapm->idle_bias_off = false;
 
-       codec->control_data = da732x->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to register codec.\n");
-               goto err;
-       }
-
        da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-err:
-       return ret;
+
+       return 0;
 }
 
 static int da732x_remove(struct snd_soc_codec *codec)
index f118daa912346efbde7734a1251f5608e6313349..4ff06b50fbba78342b596058bfac5a9ce973d097 100644 (file)
@@ -1383,16 +1383,8 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
 
 static int da9055_probe(struct snd_soc_codec *codec)
 {
-       int ret;
        struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
 
-       codec->control_data = da9055->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Enable all Gain Ramps */
        snd_soc_update_bits(codec, DA9055_AUX_L_CTRL,
                            DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
index cb736ddc446dc0bc5a387dc3ebc28e4bb0fee9aa..3a89ce66d51d7e1c56b7c655fc0ed984e520e75b 100644 (file)
@@ -918,8 +918,7 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream,
                              struct snd_pcm_hw_params *params,
                              struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_codec *codec = dai->codec;
        u16 aif = 0;
        unsigned int fs_val = 0;
 
@@ -1090,23 +1089,7 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
        },
 };
 
-static int isabelle_probe(struct snd_soc_codec *codec)
-{
-       int ret = 0;
-
-       codec->control_data = dev_get_regmap(codec->dev, NULL);
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
 static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
-       .probe = isabelle_probe,
        .set_bias_level = isabelle_set_bias_level,
        .controls = isabelle_snd_controls,
        .num_controls = ARRAY_SIZE(isabelle_snd_controls),
index 0e5743ea79dfdf6c4a4191694955883fbede59ca..4f048db9f55f1aa0953f4c971c0425a3178a159c 100644 (file)
@@ -101,8 +101,7 @@ static const char *lm4857_mode[] = {
        "Headphone",
 };
 
-static const struct soc_enum lm4857_mode_enum =
-       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
+static SOC_ENUM_SINGLE_EXT_DECL(lm4857_mode_enum, lm4857_mode);
 
 static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
        SND_SOC_DAPM_INPUT("IN"),
index 6b7fe5e548810517ea78b26d36d2532c2177e53f..275b3f72f3f42db71bd94b7ca2b35f146b134d8a 100644 (file)
@@ -213,15 +213,13 @@ static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" };
 
 static const char *lm49453_adcr_mux_text[] = { "MIC2", "Aux_R" };
 
-static const struct soc_enum lm49453_adcl_enum =
-       SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 0,
-                       ARRAY_SIZE(lm49453_adcl_mux_text),
-                       lm49453_adcl_mux_text);
+static SOC_ENUM_SINGLE_DECL(lm49453_adcl_enum,
+                           LM49453_P0_ANALOG_MIXER_ADC_REG, 0,
+                           lm49453_adcl_mux_text);
 
-static const struct soc_enum lm49453_adcr_enum =
-       SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 1,
-                       ARRAY_SIZE(lm49453_adcr_mux_text),
-                       lm49453_adcr_mux_text);
+static SOC_ENUM_SINGLE_DECL(lm49453_adcr_enum,
+                           LM49453_P0_ANALOG_MIXER_ADC_REG, 1,
+                           lm49453_adcr_mux_text);
 
 static const struct snd_kcontrol_new lm49453_adcl_mux_control =
        SOC_DAPM_ENUM("ADC Left Mux", lm49453_adcl_enum);
@@ -1409,22 +1407,6 @@ static int lm49453_resume(struct snd_soc_codec *codec)
        return 0;
 }
 
-static int lm49453_probe(struct snd_soc_codec *codec)
-{
-       struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
-       int ret = 0;
-
-       codec->control_data = lm49453->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
 /* power down chip */
 static int lm49453_remove(struct snd_soc_codec *codec)
 {
@@ -1433,7 +1415,6 @@ static int lm49453_remove(struct snd_soc_codec *codec)
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
-       .probe = lm49453_probe,
        .remove = lm49453_remove,
        .suspend = lm49453_suspend,
        .resume = lm49453_resume,
index 31f91560e9f6df0fb115ea862b712e9863cad9dd..ec481fc428c7c9fcb7a963fbabd1e9f34c1ace7b 100644 (file)
@@ -135,11 +135,6 @@ static int max9768_probe(struct snd_soc_codec *codec)
        struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = max9768->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
-       if (ret)
-               return ret;
-
        if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
                ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
                if (ret)
index bb1ecfc4459b06bf31e0699f794d34af7601b838..ef7cf89f562342307828eafbe0c7b9094b5546e1 100644 (file)
@@ -597,28 +597,27 @@ static const unsigned int max98088_exmode_values[] = {
        0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32
 };
 
-static const struct soc_enum max98088_exmode_enum =
-       SOC_VALUE_ENUM_SINGLE(M98088_REG_41_SPKDHP, 0, 127,
-                             ARRAY_SIZE(max98088_exmode_texts),
-                             max98088_exmode_texts,
-                             max98088_exmode_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(max98088_exmode_enum,
+                                 M98088_REG_41_SPKDHP, 0, 127,
+                                 max98088_exmode_texts,
+                                 max98088_exmode_values);
 
 static const char *max98088_ex_thresh[] = { /* volts PP */
        "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};
-static const struct soc_enum max98088_ex_thresh_enum[] = {
-       SOC_ENUM_SINGLE(M98088_REG_42_SPKDHP_THRESH, 0, 8,
-               max98088_ex_thresh),
-};
+static SOC_ENUM_SINGLE_DECL(max98088_ex_thresh_enum,
+                           M98088_REG_42_SPKDHP_THRESH, 0,
+                           max98088_ex_thresh);
 
 static const char *max98088_fltr_mode[] = {"Voice", "Music" };
-static const struct soc_enum max98088_filter_mode_enum[] = {
-       SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 7, 2, max98088_fltr_mode),
-};
+static SOC_ENUM_SINGLE_DECL(max98088_filter_mode_enum,
+                           M98088_REG_18_DAI1_FILTERS, 7,
+                           max98088_fltr_mode);
 
 static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" };
 
-static const struct soc_enum max98088_extmic_enum =
-       SOC_ENUM_SINGLE(M98088_REG_48_CFG_MIC, 0, 3, max98088_extmic_text);
+static SOC_ENUM_SINGLE_DECL(max98088_extmic_enum,
+                           M98088_REG_48_CFG_MIC, 0,
+                           max98088_extmic_text);
 
 static const struct snd_kcontrol_new max98088_extmic_mux =
        SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum);
@@ -626,12 +625,12 @@ static const struct snd_kcontrol_new max98088_extmic_mux =
 static const char *max98088_dai1_fltr[] = {
        "Off", "fc=258/fs=16k", "fc=500/fs=16k",
        "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"};
-static const struct soc_enum max98088_dai1_dac_filter_enum[] = {
-       SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 0, 6, max98088_dai1_fltr),
-};
-static const struct soc_enum max98088_dai1_adc_filter_enum[] = {
-       SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 4, 6, max98088_dai1_fltr),
-};
+static SOC_ENUM_SINGLE_DECL(max98088_dai1_dac_filter_enum,
+                           M98088_REG_18_DAI1_FILTERS, 0,
+                           max98088_dai1_fltr);
+static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum,
+                           M98088_REG_18_DAI1_FILTERS, 4,
+                           max98088_dai1_fltr);
 
 static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
@@ -1915,12 +1914,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
 
        regcache_mark_dirty(max98088->regmap);
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* initialize private data */
 
        max98088->sysclk = (unsigned)-1;
index f363de19be07c9b92e9550b197a064f772a0808c..96a47459b3d7cb881e90b5fd83372daff07507a3 100644 (file)
@@ -2218,14 +2218,6 @@ static int max98090_probe(struct snd_soc_codec *codec)
 
        max98090->codec = codec;
 
-       codec->control_data = max98090->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Reset the codec, the DSP core, and disable all interrupts */
        max98090_reset(max98090);
 
index 5bce9cde4a6dc57becc23d7c4d96408d187b0d6b..03f0536e6f6185cf72178fad877484a4eb1dc679 100644 (file)
@@ -560,25 +560,27 @@ static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
 }
 
 static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
-static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
-       SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
-};
-static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
-       SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
-};
+static SOC_ENUM_SINGLE_DECL(max98095_dai1_filter_mode_enum,
+                           M98095_02E_DAI1_FILTERS, 7,
+                           max98095_fltr_mode);
+static SOC_ENUM_SINGLE_DECL(max98095_dai2_filter_mode_enum,
+                           M98095_038_DAI2_FILTERS, 7,
+                           max98095_fltr_mode);
 
 static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
 
-static const struct soc_enum max98095_extmic_enum =
-       SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
+static SOC_ENUM_SINGLE_DECL(max98095_extmic_enum,
+                           M98095_087_CFG_MIC, 0,
+                           max98095_extmic_text);
 
 static const struct snd_kcontrol_new max98095_extmic_mux =
        SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
 
 static const char * const max98095_linein_text[] = { "INA", "INB" };
 
-static const struct soc_enum max98095_linein_enum =
-       SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
+static SOC_ENUM_SINGLE_DECL(max98095_linein_enum,
+                           M98095_086_CFG_LINE, 6,
+                           max98095_linein_text);
 
 static const struct snd_kcontrol_new max98095_linein_mux =
        SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
@@ -586,24 +588,26 @@ static const struct snd_kcontrol_new max98095_linein_mux =
 static const char * const max98095_line_mode_text[] = {
        "Stereo", "Differential"};
 
-static const struct soc_enum max98095_linein_mode_enum =
-       SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
+static SOC_ENUM_SINGLE_DECL(max98095_linein_mode_enum,
+                           M98095_086_CFG_LINE, 7,
+                           max98095_line_mode_text);
 
-static const struct soc_enum max98095_lineout_mode_enum =
-       SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
+static SOC_ENUM_SINGLE_DECL(max98095_lineout_mode_enum,
+                           M98095_086_CFG_LINE, 4,
+                           max98095_line_mode_text);
 
 static const char * const max98095_dai_fltr[] = {
        "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
        "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
-static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
-       SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
-};
-static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
-       SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
-};
-static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
-       SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
-};
+static SOC_ENUM_SINGLE_DECL(max98095_dai1_dac_filter_enum,
+                           M98095_02E_DAI1_FILTERS, 0,
+                           max98095_dai_fltr);
+static SOC_ENUM_SINGLE_DECL(max98095_dai2_dac_filter_enum,
+                           M98095_038_DAI2_FILTERS, 0,
+                           max98095_dai_fltr);
+static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum,
+                           M98095_042_DAI3_FILTERS, 0,
+                           max98095_dai_fltr);
 
 static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
                                struct snd_ctl_elem_value *ucontrol)
@@ -2234,12 +2238,6 @@ static int max98095_probe(struct snd_soc_codec *codec)
        struct i2c_client *client;
        int ret = 0;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* reset the codec, the DSP core, and disable all interrupts */
        max98095_reset(codec);
 
index 82757ebf0301df25ab7d2a15da0d6af5cc5623ce..4fdf5aaa236f65cbb643cd837bd792da0619970d 100644 (file)
@@ -312,14 +312,6 @@ static int max9850_resume(struct snd_soc_codec *codec)
 
 static int max9850_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* enable zero-detect */
        snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
        /* enable slew-rate control */
index ec89b8f90a64eed5400a289a4257e6414ebbc95f..2c59b1fb69dc98368035e2c4d05a4db9f1cc167b 100644 (file)
@@ -106,8 +106,7 @@ static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_codec *codec = dai->codec;
        unsigned int rate = params_rate(params);
        int i;
 
@@ -126,8 +125,7 @@ static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params,
                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_codec *codec = dai->codec;
        unsigned int rate = params_rate(params);
        unsigned int val;
 
@@ -612,8 +610,8 @@ static int mc13783_probe(struct snd_soc_codec *codec)
        struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
-       ret = snd_soc_codec_set_cache_io(codec, 8, 24, SND_SOC_REGMAP);
+       ret = snd_soc_codec_set_cache_io(codec,
+                       dev_get_regmap(codec->dev->parent, NULL));
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
index 577fb8776ce7f6a675ea9cc798ec191baa31be16..e661e8420e3dd25b95179c7413adfea8637cd9e2 100644 (file)
@@ -586,16 +586,6 @@ static int ml26124_resume(struct snd_soc_codec *codec)
 
 static int ml26124_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-       struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
-       codec->control_data = priv->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Software Reset */
        snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
        snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
index ce199d37520912d7bd95ebc0bbf6b6f7a2385080..d4c229f0233ff34c0e474a26b584606f414e6195 100644 (file)
@@ -1570,15 +1570,6 @@ static int rt5631_probe(struct snd_soc_codec *codec)
 {
        struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
        unsigned int val;
-       int ret;
-
-       codec->control_data = rt5631->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;
-       }
 
        val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
        if (val & 0x0002)
index 1a1e1150237d8f09916ce7d124da465806c80298..0061ae6b671673e43615bcd9ebfeef001df487b2 100644 (file)
@@ -1594,8 +1594,7 @@ static int get_clk_info(int sclk, int rate)
 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 snd_soc_codec *codec = dai->codec;
        struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
        unsigned int val_len = 0, val_clk, mask_clk;
        int dai_sel, pre_div, bclk_ms, frame_size;
@@ -1936,16 +1935,8 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
 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);
index ab4754a7a88cfe99fe58d9760333a700d49927cf..d3ed1be5a186c50fdaab98e0cf725dce53cb4f32 100644 (file)
@@ -1352,14 +1352,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
        int ret;
        struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
 
-       /* setup i2c data ops */
-       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;
-       }
-
        ret = sgtl5000_enable_regulators(codec);
        if (ret)
                return ret;
index fa2b8e07f420dd9c14ac0dc944babfe66dfbe2b2..244c097cd9053948d43b13c77fee6d6a8b6c7342 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+#include <linux/regmap.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
 
@@ -209,8 +210,9 @@ out:
 
 static int si476x_codec_probe(struct snd_soc_codec *codec)
 {
-       codec->control_data = dev_get_regmap(codec->dev->parent, NULL);
-       return snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
+       struct regmap *regmap = dev_get_regmap(codec->dev->parent, NULL);
+
+       return snd_soc_codec_set_cache_io(codec, regmap);
 }
 
 static struct snd_soc_dai_ops si476x_dai_ops = {
index bca7d02b362a056fe2c2aa06840690101424240d..42dff26b3a2af8cd0f0df9d1a744d9d890c21e0b 100644 (file)
@@ -825,8 +825,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
 {
        pr_debug("codec_probe called\n");
 
-       snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
-
        /* PCM interface config
         * This sets the pcm rx slot conguration to max 6 slots
         * for max 4 dais (2 stereo and 2 mono)
index 806f3d826ffbeb116a42d523640c988017ede846..56adb3e2def9ca00f16a50e59c141206b4ab68d7 100644 (file)
@@ -648,16 +648,6 @@ static struct snd_soc_dai_driver ssm2518_dai = {
 
 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);
 }
 
index 12947096897c8903688ddb07de17311a84ff9ef6..97b0454eb346b712d4e1847008b2340f99933f90 100644 (file)
@@ -562,13 +562,6 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec)
        struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = ssm2602->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;
-       }
-
        ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
index 2735361a4c3cfc5fbc652ee10d62ec2728626184..12577749b17b3b0c0b0298b66758934ae4e87bdd 100644 (file)
@@ -872,16 +872,6 @@ static int sta32x_probe(struct snd_soc_codec *codec)
                return ret;
        }
 
-       /* Tell ASoC what kind of I/O to use to read the registers.  ASoC will
-        * then do the I2C transactions itself.
-        */
-       codec->control_data = sta32x->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
-               goto err;
-       }
-
        /* Chip documentation explicitly requires that the reset values
         * of reserved register bits are left untouched.
         * Write the register default value to cache for reserved registers,
@@ -946,10 +936,6 @@ static int sta32x_probe(struct snd_soc_codec *codec)
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 
        return 0;
-
-err:
-       regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-       return ret;
 }
 
 static int sta32x_remove(struct snd_soc_codec *codec)
index f15b0e37274cb4574864202d3b531e920b0b81dc..a40c4b0196a3cfc42a0ebd464d067e0d379f9daa 100644 (file)
@@ -193,8 +193,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params,
                struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_codec *codec = dai->codec;
        int pdata, play_freq_val, record_freq_val;
        int bclk_to_fs_ratio;
 
@@ -322,16 +321,6 @@ static struct snd_soc_dai_driver sta529_dai = {
 
 static int sta529_probe(struct snd_soc_codec *codec)
 {
-       struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
-       int ret;
-
-       codec->control_data = sta529->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
        sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        return 0;
index dc9a52fcb39ae248c5ad1169aa38c82e183c1132..20864ee8793b5e24be689f6686a2217d9c5c13b9 100644 (file)
@@ -559,14 +559,6 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
 
 static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Reset codec */
        snd_soc_write(codec, TLV320AIC23_RESET, 0);
 
index ff5f23d482b7f95062574d2d7a695259bada45bb..43069de3d56ac595c2c9a047d7bea3c4a97079d4 100644 (file)
@@ -296,8 +296,6 @@ static int aic26_probe(struct snd_soc_codec *codec)
        struct aic26 *aic26 = dev_get_drvdata(codec->dev);
        int ret, reg;
 
-       snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
-
        aic26->codec = codec;
 
        /* Reset the codec to power on defaults */
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
new file mode 100644 (file)
index 0000000..fa158cf
--- /dev/null
@@ -0,0 +1,1280 @@
+/*
+ * ALSA SoC TLV320AIC31XX codec driver
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Jyri Sarha <jsarha@ti.com>
+ *
+ * Based on ground work by: Ajit Kulkarni <x0175765@ti.com>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * The TLV320AIC31xx series of audio codec is a low-power, highly integrated
+ * high performance codec which provides a stereo DAC, a mono ADC,
+ * and mono/stereo Class-D speaker driver.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
+
+#include "tlv320aic31xx.h"
+
+static const struct reg_default aic31xx_reg_defaults[] = {
+       { AIC31XX_CLKMUX, 0x00 },
+       { AIC31XX_PLLPR, 0x11 },
+       { AIC31XX_PLLJ, 0x04 },
+       { AIC31XX_PLLDMSB, 0x00 },
+       { AIC31XX_PLLDLSB, 0x00 },
+       { AIC31XX_NDAC, 0x01 },
+       { AIC31XX_MDAC, 0x01 },
+       { AIC31XX_DOSRMSB, 0x00 },
+       { AIC31XX_DOSRLSB, 0x80 },
+       { AIC31XX_NADC, 0x01 },
+       { AIC31XX_MADC, 0x01 },
+       { AIC31XX_AOSR, 0x80 },
+       { AIC31XX_IFACE1, 0x00 },
+       { AIC31XX_DATA_OFFSET, 0x00 },
+       { AIC31XX_IFACE2, 0x00 },
+       { AIC31XX_BCLKN, 0x01 },
+       { AIC31XX_DACSETUP, 0x14 },
+       { AIC31XX_DACMUTE, 0x0c },
+       { AIC31XX_LDACVOL, 0x00 },
+       { AIC31XX_RDACVOL, 0x00 },
+       { AIC31XX_ADCSETUP, 0x00 },
+       { AIC31XX_ADCFGA, 0x80 },
+       { AIC31XX_ADCVOL, 0x00 },
+       { AIC31XX_HPDRIVER, 0x04 },
+       { AIC31XX_SPKAMP, 0x06 },
+       { AIC31XX_DACMIXERROUTE, 0x00 },
+       { AIC31XX_LANALOGHPL, 0x7f },
+       { AIC31XX_RANALOGHPR, 0x7f },
+       { AIC31XX_LANALOGSPL, 0x7f },
+       { AIC31XX_RANALOGSPR, 0x7f },
+       { AIC31XX_HPLGAIN, 0x02 },
+       { AIC31XX_HPRGAIN, 0x02 },
+       { AIC31XX_SPLGAIN, 0x00 },
+       { AIC31XX_SPRGAIN, 0x00 },
+       { AIC31XX_MICBIAS, 0x00 },
+       { AIC31XX_MICPGA, 0x80 },
+       { AIC31XX_MICPGAPI, 0x00 },
+       { AIC31XX_MICPGAMI, 0x00 },
+};
+
+static bool aic31xx_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case AIC31XX_PAGECTL: /* regmap implementation requires this */
+       case AIC31XX_RESET: /* always clears after write */
+       case AIC31XX_OT_FLAG:
+       case AIC31XX_ADCFLAG:
+       case AIC31XX_DACFLAG1:
+       case AIC31XX_DACFLAG2:
+       case AIC31XX_OFFLAG: /* Sticky interrupt flags */
+       case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */
+       case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */
+       case AIC31XX_INTRDACFLAG2:
+       case AIC31XX_INTRADCFLAG2:
+               return true;
+       }
+       return false;
+}
+
+static bool aic31xx_writeable(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case AIC31XX_OT_FLAG:
+       case AIC31XX_ADCFLAG:
+       case AIC31XX_DACFLAG1:
+       case AIC31XX_DACFLAG2:
+       case AIC31XX_OFFLAG: /* Sticky interrupt flags */
+       case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */
+       case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */
+       case AIC31XX_INTRDACFLAG2:
+       case AIC31XX_INTRADCFLAG2:
+               return false;
+       }
+       return true;
+}
+
+static const struct regmap_range_cfg aic31xx_ranges[] = {
+       {
+               .range_min = 0,
+               .range_max = 12 * 128,
+               .selector_reg = AIC31XX_PAGECTL,
+               .selector_mask = 0xff,
+               .selector_shift = 0,
+               .window_start = 0,
+               .window_len = 128,
+       },
+};
+
+static const struct regmap_config aic31xx_i2c_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .writeable_reg = aic31xx_writeable,
+       .volatile_reg = aic31xx_volatile,
+       .reg_defaults = aic31xx_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(aic31xx_reg_defaults),
+       .cache_type = REGCACHE_RBTREE,
+       .ranges = aic31xx_ranges,
+       .num_ranges = ARRAY_SIZE(aic31xx_ranges),
+       .max_register = 12 * 128,
+};
+
+#define AIC31XX_NUM_SUPPLIES   6
+static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = {
+       "HPVDD",
+       "SPRVDD",
+       "SPLVDD",
+       "AVDD",
+       "IOVDD",
+       "DVDD",
+};
+
+struct aic31xx_disable_nb {
+       struct notifier_block nb;
+       struct aic31xx_priv *aic31xx;
+};
+
+struct aic31xx_priv {
+       struct snd_soc_codec *codec;
+       u8 i2c_regs_status;
+       struct device *dev;
+       struct regmap *regmap;
+       struct aic31xx_pdata pdata;
+       struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
+       struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
+       unsigned int sysclk;
+       int rate_div_line;
+};
+
+struct aic31xx_rate_divs {
+       u32 mclk;
+       u32 rate;
+       u8 p_val;
+       u8 pll_j;
+       u16 pll_d;
+       u16 dosr;
+       u8 ndac;
+       u8 mdac;
+       u8 aosr;
+       u8 nadc;
+       u8 madc;
+};
+
+/* ADC dividers can be disabled by cofiguring them to 0 */
+static const struct aic31xx_rate_divs aic31xx_divs[] = {
+       /* mclk      rate  pll: p  j     d     dosr ndac mdac  aors nadc madc */
+       /* 8k rate */
+       {12000000,   8000,      1, 8, 1920,     128,  48,  2,   128,  48,  2},
+       {24000000,   8000,      2, 8, 1920,     128,  48,  2,   128,  48,  2},
+       {25000000,   8000,      2, 7, 8643,     128,  48,  2,   128,  48,  2},
+       /* 11.025k rate */
+       {12000000,  11025,      1, 7, 5264,     128,  32,  2,   128,  32,  2},
+       {24000000,  11025,      2, 7, 5264,     128,  32,  2,   128,  32,  2},
+       {25000000,  11025,      2, 7, 2253,     128,  32,  2,   128,  32,  2},
+       /* 16k rate */
+       {12000000,  16000,      1, 8, 1920,     128,  24,  2,   128,  24,  2},
+       {24000000,  16000,      2, 8, 1920,     128,  24,  2,   128,  24,  2},
+       {25000000,  16000,      2, 7, 8643,     128,  24,  2,   128,  24,  2},
+       /* 22.05k rate */
+       {12000000,  22050,      1, 7, 5264,     128,  16,  2,   128,  16,  2},
+       {24000000,  22050,      2, 7, 5264,     128,  16,  2,   128,  16,  2},
+       {25000000,  22050,      2, 7, 2253,     128,  16,  2,   128,  16,  2},
+       /* 32k rate */
+       {12000000,  32000,      1, 8, 1920,     128,  12,  2,   128,  12,  2},
+       {24000000,  32000,      2, 8, 1920,     128,  12,  2,   128,  12,  2},
+       {25000000,  32000,      2, 7, 8643,     128,  12,  2,   128,  12,  2},
+       /* 44.1k rate */
+       {12000000,  44100,      1, 7, 5264,     128,   8,  2,   128,   8,  2},
+       {24000000,  44100,      2, 7, 5264,     128,   8,  2,   128,   8,  2},
+       {25000000,  44100,      2, 7, 2253,     128,   8,  2,   128,   8,  2},
+       /* 48k rate */
+       {12000000,  48000,      1, 8, 1920,     128,   8,  2,   128,   8,  2},
+       {24000000,  48000,      2, 8, 1920,     128,   8,  2,   128,   8,  2},
+       {25000000,  48000,      2, 7, 8643,     128,   8,  2,   128,   8,  2},
+       /* 88.2k rate */
+       {12000000,  88200,      1, 7, 5264,      64,   8,  2,    64,   8,  2},
+       {24000000,  88200,      2, 7, 5264,      64,   8,  2,    64,   8,  2},
+       {25000000,  88200,      2, 7, 2253,      64,   8,  2,    64,   8,  2},
+       /* 96k rate */
+       {12000000,  96000,      1, 8, 1920,      64,   8,  2,    64,   8,  2},
+       {24000000,  96000,      2, 8, 1920,      64,   8,  2,    64,   8,  2},
+       {25000000,  96000,      2, 7, 8643,      64,   8,  2,    64,   8,  2},
+       /* 176.4k rate */
+       {12000000, 176400,      1, 7, 5264,      32,   8,  2,    32,   8,  2},
+       {24000000, 176400,      2, 7, 5264,      32,   8,  2,    32,   8,  2},
+       {25000000, 176400,      2, 7, 2253,      32,   8,  2,    32,   8,  2},
+       /* 192k rate */
+       {12000000, 192000,      1, 8, 1920,      32,   8,  2,    32,   8,  2},
+       {24000000, 192000,      2, 8, 1920,      32,   8,  2,    32,   8,  2},
+       {25000000, 192000,      2, 7, 8643,      32,   8,  2,    32,   8,  2},
+};
+
+static const char * const ldac_in_text[] = {
+       "Off", "Left Data", "Right Data", "Mono"
+};
+
+static const char * const rdac_in_text[] = {
+       "Off", "Right Data", "Left Data", "Mono"
+};
+
+static SOC_ENUM_SINGLE_DECL(ldac_in_enum, AIC31XX_DACSETUP, 4, ldac_in_text);
+
+static SOC_ENUM_SINGLE_DECL(rdac_in_enum, AIC31XX_DACSETUP, 2, rdac_in_text);
+
+static const char * const mic_select_text[] = {
+       "Off", "FFR 10 Ohm", "FFR 20 Ohm", "FFR 40 Ohm"
+};
+
+static const
+SOC_ENUM_SINGLE_DECL(mic1lp_p_enum, AIC31XX_MICPGAPI, 6, mic_select_text);
+static const
+SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4, mic_select_text);
+static const
+SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, mic_select_text);
+
+static const
+SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text);
+static const
+SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, mic_select_text);
+
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
+static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0);
+static const DECLARE_TLV_DB_SCALE(adc_cgain_tlv, -2000, 50, 0);
+static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, 0, 50, 0);
+static const DECLARE_TLV_DB_SCALE(hp_drv_tlv, 0, 100, 0);
+static const DECLARE_TLV_DB_SCALE(class_D_drv_tlv, 600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -6350, 50, 0);
+static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0);
+
+/*
+ * controls to be exported to the user space
+ */
+static const struct snd_kcontrol_new aic31xx_snd_controls[] = {
+       SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL,
+                          AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv),
+
+       SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1,
+                      adc_fgain_tlv),
+
+       SOC_SINGLE("ADC Capture Switch", AIC31XX_ADCFGA, 7, 1, 1),
+       SOC_DOUBLE_R_S_TLV("ADC Capture Volume", AIC31XX_ADCVOL, AIC31XX_ADCVOL,
+                          0, -24, 40, 6, 0, adc_cgain_tlv),
+
+       SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0,
+                      119, 0, mic_pga_tlv),
+
+       SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN,
+                    AIC31XX_HPRGAIN, 2, 1, 0),
+       SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN,
+                        AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv),
+
+       SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL,
+                        AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv),
+};
+
+static const struct snd_kcontrol_new aic311x_snd_controls[] = {
+       SOC_DOUBLE_R("Speaker Driver Playback Switch", AIC31XX_SPLGAIN,
+                    AIC31XX_SPRGAIN, 2, 1, 0),
+       SOC_DOUBLE_R_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN,
+                        AIC31XX_SPRGAIN, 3, 3, 0, class_D_drv_tlv),
+
+       SOC_DOUBLE_R_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL,
+                        AIC31XX_RANALOGSPR, 0, 0x7F, 1, sp_vol_tlv),
+};
+
+static const struct snd_kcontrol_new aic310x_snd_controls[] = {
+       SOC_SINGLE("Speaker Driver Playback Switch", AIC31XX_SPLGAIN,
+                  2, 1, 0),
+       SOC_SINGLE_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN,
+                      3, 3, 0, class_D_drv_tlv),
+
+       SOC_SINGLE_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL,
+                      0, 0x7F, 1, sp_vol_tlv),
+};
+
+static const struct snd_kcontrol_new ldac_in_control =
+       SOC_DAPM_ENUM("DAC Left Input", ldac_in_enum);
+
+static const struct snd_kcontrol_new rdac_in_control =
+       SOC_DAPM_ENUM("DAC Right Input", rdac_in_enum);
+
+static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
+                            unsigned int mask, unsigned int wbits, int sleep,
+                            int count)
+{
+       unsigned int bits;
+       int counter = count;
+       int ret = regmap_read(aic31xx->regmap, reg, &bits);
+       while ((bits & mask) != wbits && counter && !ret) {
+               usleep_range(sleep, sleep * 2);
+               ret = regmap_read(aic31xx->regmap, reg, &bits);
+               counter--;
+       }
+       if ((bits & mask) != wbits) {
+               dev_err(aic31xx->dev,
+                       "%s: Failed! 0x%x was 0x%x expected 0x%x (%d, 0x%x, %d us)\n",
+                       __func__, reg, bits, wbits, ret, mask,
+                       (count - counter) * sleep);
+               ret = -1;
+       }
+       return ret;
+}
+
+#define WIDGET_BIT(reg, shift) (((shift) << 8) | (reg))
+
+static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
+                                   struct snd_kcontrol *kcontrol, int event)
+{
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(w->codec);
+       unsigned int reg = AIC31XX_DACFLAG1;
+       unsigned int mask;
+
+       switch (WIDGET_BIT(w->reg, w->shift)) {
+       case WIDGET_BIT(AIC31XX_DACSETUP, 7):
+               mask = AIC31XX_LDACPWRSTATUS_MASK;
+               break;
+       case WIDGET_BIT(AIC31XX_DACSETUP, 6):
+               mask = AIC31XX_RDACPWRSTATUS_MASK;
+               break;
+       case WIDGET_BIT(AIC31XX_HPDRIVER, 7):
+               mask = AIC31XX_HPLDRVPWRSTATUS_MASK;
+               break;
+       case WIDGET_BIT(AIC31XX_HPDRIVER, 6):
+               mask = AIC31XX_HPRDRVPWRSTATUS_MASK;
+               break;
+       case WIDGET_BIT(AIC31XX_SPKAMP, 7):
+               mask = AIC31XX_SPLDRVPWRSTATUS_MASK;
+               break;
+       case WIDGET_BIT(AIC31XX_SPKAMP, 6):
+               mask = AIC31XX_SPRDRVPWRSTATUS_MASK;
+               break;
+       case WIDGET_BIT(AIC31XX_ADCSETUP, 7):
+               mask = AIC31XX_ADCPWRSTATUS_MASK;
+               reg = AIC31XX_ADCFLAG;
+               break;
+       default:
+               dev_err(w->codec->dev, "Unknown widget '%s' calling %s/n",
+                       w->name, __func__);
+               return -EINVAL;
+       }
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100);
+       case SND_SOC_DAPM_POST_PMD:
+               return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
+       default:
+               dev_dbg(w->codec->dev,
+                       "Unhandled dapm widget event %d from %s\n",
+                       event, w->name);
+       }
+       return 0;
+}
+
+static const struct snd_kcontrol_new left_output_switches[] = {
+       SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0),
+       SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0),
+       SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0),
+};
+
+static const struct snd_kcontrol_new right_output_switches[] = {
+       SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0),
+       SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0),
+};
+
+static const struct snd_kcontrol_new p_term_mic1lp =
+       SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum);
+
+static const struct snd_kcontrol_new p_term_mic1rp =
+       SOC_DAPM_ENUM("MIC1RP P-Terminal", mic1rp_p_enum);
+
+static const struct snd_kcontrol_new p_term_mic1lm =
+       SOC_DAPM_ENUM("MIC1LM P-Terminal", mic1lm_p_enum);
+
+static const struct snd_kcontrol_new m_term_mic1lm =
+       SOC_DAPM_ENUM("MIC1LM M-Terminal", mic1lm_m_enum);
+
+static const struct snd_kcontrol_new aic31xx_dapm_hpl_switch =
+       SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGHPL, 7, 1, 0);
+
+static const struct snd_kcontrol_new aic31xx_dapm_hpr_switch =
+       SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGHPR, 7, 1, 0);
+
+static const struct snd_kcontrol_new aic31xx_dapm_spl_switch =
+       SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGSPL, 7, 1, 0);
+
+static const struct snd_kcontrol_new aic31xx_dapm_spr_switch =
+       SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGSPR, 7, 1, 0);
+
+static int mic_bias_event(struct snd_soc_dapm_widget *w,
+                         struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               /* change mic bias voltage to user defined */
+               snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+                                   AIC31XX_MICBIAS_MASK,
+                                   aic31xx->pdata.micbias_vg <<
+                                   AIC31XX_MICBIAS_SHIFT);
+               dev_dbg(codec->dev, "%s: turned on\n", __func__);
+               break;
+       case SND_SOC_DAPM_PRE_PMD:
+               /* turn mic bias off */
+               snd_soc_update_bits(codec, AIC31XX_MICBIAS,
+                                   AIC31XX_MICBIAS_MASK, 0);
+               dev_dbg(codec->dev, "%s: turned off\n", __func__);
+               break;
+       }
+       return 0;
+}
+
+static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = {
+       SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
+
+       SND_SOC_DAPM_MUX("DAC Left Input",
+                        SND_SOC_NOPM, 0, 0, &ldac_in_control),
+       SND_SOC_DAPM_MUX("DAC Right Input",
+                        SND_SOC_NOPM, 0, 0, &rdac_in_control),
+       /* DACs */
+       SND_SOC_DAPM_DAC_E("DAC Left", "Left Playback",
+                          AIC31XX_DACSETUP, 7, 0, aic31xx_dapm_power_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+       SND_SOC_DAPM_DAC_E("DAC Right", "Right Playback",
+                          AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+       /* Output Mixers */
+       SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0,
+                          left_output_switches,
+                          ARRAY_SIZE(left_output_switches)),
+       SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0,
+                          right_output_switches,
+                          ARRAY_SIZE(right_output_switches)),
+
+       SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0,
+                           &aic31xx_dapm_hpl_switch),
+       SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0,
+                           &aic31xx_dapm_hpr_switch),
+
+       /* Output drivers */
+       SND_SOC_DAPM_OUT_DRV_E("HPL Driver", AIC31XX_HPDRIVER, 7, 0,
+                              NULL, 0, aic31xx_dapm_power_event,
+                              SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+       SND_SOC_DAPM_OUT_DRV_E("HPR Driver", AIC31XX_HPDRIVER, 6, 0,
+                              NULL, 0, aic31xx_dapm_power_event,
+                              SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+
+       /* ADC */
+       SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0,
+                          aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+                          SND_SOC_DAPM_POST_PMD),
+
+       /* Input Selection to MIC_PGA */
+       SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0,
+                        &p_term_mic1lp),
+       SND_SOC_DAPM_MUX("MIC1RP P-Terminal", SND_SOC_NOPM, 0, 0,
+                        &p_term_mic1rp),
+       SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0,
+                        &p_term_mic1lm),
+
+       SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0,
+                        &m_term_mic1lm),
+       /* Enabling & Disabling MIC Gain Ctl */
+       SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA,
+                        7, 1, NULL, 0),
+
+       /* Mic Bias */
+       SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event,
+                           SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+       /* Outputs */
+       SND_SOC_DAPM_OUTPUT("HPL"),
+       SND_SOC_DAPM_OUTPUT("HPR"),
+
+       /* Inputs */
+       SND_SOC_DAPM_INPUT("MIC1LP"),
+       SND_SOC_DAPM_INPUT("MIC1RP"),
+       SND_SOC_DAPM_INPUT("MIC1LM"),
+};
+
+static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = {
+       /* AIC3111 and AIC3110 have stereo class-D amplifier */
+       SND_SOC_DAPM_OUT_DRV_E("SPL ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0,
+                              aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+                              SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_OUT_DRV_E("SPR ClassD", AIC31XX_SPKAMP, 6, 0, NULL, 0,
+                              aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+                              SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_SWITCH("Speaker Left", SND_SOC_NOPM, 0, 0,
+                           &aic31xx_dapm_spl_switch),
+       SND_SOC_DAPM_SWITCH("Speaker Right", SND_SOC_NOPM, 0, 0,
+                           &aic31xx_dapm_spr_switch),
+       SND_SOC_DAPM_OUTPUT("SPL"),
+       SND_SOC_DAPM_OUTPUT("SPR"),
+};
+
+/* AIC3100 and AIC3120 have only mono class-D amplifier */
+static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = {
+       SND_SOC_DAPM_OUT_DRV_E("SPK ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0,
+                              aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU |
+                              SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_SWITCH("Speaker", SND_SOC_NOPM, 0, 0,
+                           &aic31xx_dapm_spl_switch),
+       SND_SOC_DAPM_OUTPUT("SPK"),
+};
+
+static const struct snd_soc_dapm_route
+aic31xx_audio_map[] = {
+       /* DAC Input Routing */
+       {"DAC Left Input", "Left Data", "DAC IN"},
+       {"DAC Left Input", "Right Data", "DAC IN"},
+       {"DAC Left Input", "Mono", "DAC IN"},
+       {"DAC Right Input", "Left Data", "DAC IN"},
+       {"DAC Right Input", "Right Data", "DAC IN"},
+       {"DAC Right Input", "Mono", "DAC IN"},
+       {"DAC Left", NULL, "DAC Left Input"},
+       {"DAC Right", NULL, "DAC Right Input"},
+
+       /* Mic input */
+       {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"},
+       {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"},
+       {"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"},
+       {"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"},
+       {"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"},
+       {"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"},
+       {"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"},
+       {"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"},
+       {"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"},
+
+       {"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"},
+       {"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"},
+       {"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"},
+
+       {"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"},
+       {"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"},
+       {"MIC_GAIN_CTL", NULL, "MIC1LM P-Terminal"},
+       {"MIC_GAIN_CTL", NULL, "MIC1LM M-Terminal"},
+
+       {"ADC", NULL, "MIC_GAIN_CTL"},
+
+       /* Left Output */
+       {"Output Left", "From Left DAC", "DAC Left"},
+       {"Output Left", "From MIC1LP", "MIC1LP"},
+       {"Output Left", "From MIC1RP", "MIC1RP"},
+
+       /* Right Output */
+       {"Output Right", "From Right DAC", "DAC Right"},
+       {"Output Right", "From MIC1RP", "MIC1RP"},
+
+       /* HPL path */
+       {"HP Left", "Switch", "Output Left"},
+       {"HPL Driver", NULL, "HP Left"},
+       {"HPL", NULL, "HPL Driver"},
+
+       /* HPR path */
+       {"HP Right", "Switch", "Output Right"},
+       {"HPR Driver", NULL, "HP Right"},
+       {"HPR", NULL, "HPR Driver"},
+};
+
+static const struct snd_soc_dapm_route
+aic311x_audio_map[] = {
+       /* SP L path */
+       {"Speaker Left", "Switch", "Output Left"},
+       {"SPL ClassD", NULL, "Speaker Left"},
+       {"SPL", NULL, "SPL ClassD"},
+
+       /* SP R path */
+       {"Speaker Right", "Switch", "Output Right"},
+       {"SPR ClassD", NULL, "Speaker Right"},
+       {"SPR", NULL, "SPR ClassD"},
+};
+
+static const struct snd_soc_dapm_route
+aic310x_audio_map[] = {
+       /* SP L path */
+       {"Speaker", "Switch", "Output Left"},
+       {"SPK ClassD", NULL, "Speaker"},
+       {"SPK", NULL, "SPK ClassD"},
+};
+
+static int aic31xx_add_controls(struct snd_soc_codec *codec)
+{
+       int ret = 0;
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+
+       if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT)
+               ret = snd_soc_add_codec_controls(
+                       codec, aic311x_snd_controls,
+                       ARRAY_SIZE(aic311x_snd_controls));
+       else
+               ret = snd_soc_add_codec_controls(
+                       codec, aic310x_snd_controls,
+                       ARRAY_SIZE(aic310x_snd_controls));
+
+       return ret;
+}
+
+static int aic31xx_add_widgets(struct snd_soc_codec *codec)
+{
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int ret = 0;
+
+       if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) {
+               ret = snd_soc_dapm_new_controls(
+                       dapm, aic311x_dapm_widgets,
+                       ARRAY_SIZE(aic311x_dapm_widgets));
+               if (ret)
+                       return ret;
+
+               ret = snd_soc_dapm_add_routes(dapm, aic311x_audio_map,
+                                             ARRAY_SIZE(aic311x_audio_map));
+               if (ret)
+                       return ret;
+       } else {
+               ret = snd_soc_dapm_new_controls(
+                       dapm, aic310x_dapm_widgets,
+                       ARRAY_SIZE(aic310x_dapm_widgets));
+               if (ret)
+                       return ret;
+
+               ret = snd_soc_dapm_add_routes(dapm, aic310x_audio_map,
+                                             ARRAY_SIZE(aic310x_audio_map));
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int aic31xx_setup_pll(struct snd_soc_codec *codec,
+                            struct snd_pcm_hw_params *params)
+{
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int bclk_n = 0;
+       int i;
+
+       /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
+       snd_soc_update_bits(codec, AIC31XX_CLKMUX,
+                           AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL);
+       snd_soc_update_bits(codec, AIC31XX_IFACE2,
+                           AIC31XX_BDIVCLK_MASK, AIC31XX_DAC2BCLK);
+
+       for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
+               if (aic31xx_divs[i].rate == params_rate(params) &&
+                   aic31xx_divs[i].mclk == aic31xx->sysclk)
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(aic31xx_divs)) {
+               dev_err(codec->dev, "%s: Sampling rate %u not supported\n",
+                       __func__, params_rate(params));
+               return -EINVAL;
+       }
+
+       /* PLL configuration */
+       snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
+                           (aic31xx_divs[i].p_val << 4) | 0x01);
+       snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
+
+       snd_soc_write(codec, AIC31XX_PLLDMSB,
+                     aic31xx_divs[i].pll_d >> 8);
+       snd_soc_write(codec, AIC31XX_PLLDLSB,
+                     aic31xx_divs[i].pll_d & 0xff);
+
+       /* DAC dividers configuration */
+       snd_soc_update_bits(codec, AIC31XX_NDAC, AIC31XX_PLL_MASK,
+                           aic31xx_divs[i].ndac);
+       snd_soc_update_bits(codec, AIC31XX_MDAC, AIC31XX_PLL_MASK,
+                           aic31xx_divs[i].mdac);
+
+       snd_soc_write(codec, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8);
+       snd_soc_write(codec, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff);
+
+       /* ADC dividers configuration. Write reset value 1 if not used. */
+       snd_soc_update_bits(codec, AIC31XX_NADC, AIC31XX_PLL_MASK,
+                           aic31xx_divs[i].nadc ? aic31xx_divs[i].nadc : 1);
+       snd_soc_update_bits(codec, AIC31XX_MADC, AIC31XX_PLL_MASK,
+                           aic31xx_divs[i].madc ? aic31xx_divs[i].madc : 1);
+
+       snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr);
+
+       /* Bit clock divider configuration. */
+       bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac)
+               / snd_soc_params_to_frame_size(params);
+       if (bclk_n == 0) {
+               dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n",
+                       __func__);
+               return -EINVAL;
+       }
+
+       snd_soc_update_bits(codec, AIC31XX_BCLKN,
+                           AIC31XX_PLL_MASK, bclk_n);
+
+       aic31xx->rate_div_line = i;
+
+       dev_dbg(codec->dev,
+               "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n",
+               aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d,
+               aic31xx_divs[i].p_val, aic31xx_divs[i].dosr,
+               aic31xx_divs[i].ndac, aic31xx_divs[i].mdac,
+               aic31xx_divs[i].aosr, aic31xx_divs[i].nadc,
+               aic31xx_divs[i].madc, bclk_n);
+
+       return 0;
+}
+
+static int aic31xx_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params,
+                            struct snd_soc_dai *dai)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       u8 data = 0;
+
+       dev_dbg(codec->dev, "## %s: format %d width %d rate %d\n",
+               __func__, params_format(params), params_width(params),
+               params_rate(params));
+
+       switch (params_width(params)) {
+       case 16:
+               break;
+       case 20:
+               data = (AIC31XX_WORD_LEN_20BITS <<
+                       AIC31XX_IFACE1_DATALEN_SHIFT);
+               break;
+       case 24:
+               data = (AIC31XX_WORD_LEN_24BITS <<
+                       AIC31XX_IFACE1_DATALEN_SHIFT);
+               break;
+       case 32:
+               data = (AIC31XX_WORD_LEN_32BITS <<
+                       AIC31XX_IFACE1_DATALEN_SHIFT);
+               break;
+       default:
+               dev_err(codec->dev, "%s: Unsupported format %d\n",
+                       __func__, params_format(params));
+               return -EINVAL;
+       }
+
+       snd_soc_update_bits(codec, AIC31XX_IFACE1,
+                           AIC31XX_IFACE1_DATALEN_MASK,
+                           data);
+
+       return aic31xx_setup_pll(codec, params);
+}
+
+static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+
+       if (mute) {
+               snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+                                   AIC31XX_DACMUTE_MASK,
+                                   AIC31XX_DACMUTE_MASK);
+       } else {
+               snd_soc_update_bits(codec, AIC31XX_DACMUTE,
+                                   AIC31XX_DACMUTE_MASK, 0x0);
+       }
+
+       return 0;
+}
+
+static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                              unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u8 iface_reg1 = 0;
+       u8 iface_reg3 = 0;
+       u8 dsp_a_val = 0;
+
+       dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
+
+       /* set master/slave audio interface */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER;
+               break;
+       default:
+               dev_alert(codec->dev, "Invalid DAI master/slave interface\n");
+               return -EINVAL;
+       }
+
+       /* interface format */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               dsp_a_val = 0x1;
+       case SND_SOC_DAIFMT_DSP_B:
+               /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       iface_reg3 |= AIC31XX_BCLKINV_MASK;
+                       break;
+               case SND_SOC_DAIFMT_IB_NF:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               iface_reg1 |= (AIC31XX_DSP_MODE <<
+                              AIC31XX_IFACE1_DATATYPE_SHIFT);
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               iface_reg1 |= (AIC31XX_RIGHT_JUSTIFIED_MODE <<
+                              AIC31XX_IFACE1_DATATYPE_SHIFT);
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               iface_reg1 |= (AIC31XX_LEFT_JUSTIFIED_MODE <<
+                              AIC31XX_IFACE1_DATATYPE_SHIFT);
+               break;
+       default:
+               dev_err(codec->dev, "Invalid DAI interface format\n");
+               return -EINVAL;
+       }
+
+       snd_soc_update_bits(codec, AIC31XX_IFACE1,
+                           AIC31XX_IFACE1_DATATYPE_MASK |
+                           AIC31XX_IFACE1_MASTER_MASK,
+                           iface_reg1);
+       snd_soc_update_bits(codec, AIC31XX_DATA_OFFSET,
+                           AIC31XX_DATA_OFFSET_MASK,
+                           dsp_a_val);
+       snd_soc_update_bits(codec, AIC31XX_IFACE2,
+                           AIC31XX_BCLKINV_MASK,
+                           iface_reg3);
+
+       return 0;
+}
+
+static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+                                 int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int i;
+
+       dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
+               __func__, clk_id, freq, dir);
+
+       for (i = 0; aic31xx_divs[i].mclk != freq; i++) {
+               if (i == ARRAY_SIZE(aic31xx_divs)) {
+                       dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n",
+                               __func__, freq);
+                       return -EINVAL;
+               }
+       }
+
+       /* set clock on MCLK, BCLK, or GPIO1 as PLL input */
+       snd_soc_update_bits(codec, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
+                           clk_id << AIC31XX_PLL_CLKIN_SHIFT);
+
+       aic31xx->sysclk = freq;
+       return 0;
+}
+
+static int aic31xx_regulator_event(struct notifier_block *nb,
+                                  unsigned long event, void *data)
+{
+       struct aic31xx_disable_nb *disable_nb =
+               container_of(nb, struct aic31xx_disable_nb, nb);
+       struct aic31xx_priv *aic31xx = disable_nb->aic31xx;
+
+       if (event & REGULATOR_EVENT_DISABLE) {
+               /*
+                * Put codec to reset and as at least one of the
+                * supplies was disabled.
+                */
+               if (gpio_is_valid(aic31xx->pdata.gpio_reset))
+                       gpio_set_value(aic31xx->pdata.gpio_reset, 0);
+
+               regcache_mark_dirty(aic31xx->regmap);
+               dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__);
+       }
+
+       return 0;
+}
+
+static void aic31xx_clk_on(struct snd_soc_codec *codec)
+{
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       u8 mask = AIC31XX_PM_MASK;
+       u8 on = AIC31XX_PM_MASK;
+
+       dev_dbg(codec->dev, "codec clock -> on (rate %d)\n",
+               aic31xx_divs[aic31xx->rate_div_line].rate);
+       snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, on);
+       mdelay(10);
+       snd_soc_update_bits(codec, AIC31XX_NDAC, mask, on);
+       snd_soc_update_bits(codec, AIC31XX_MDAC, mask, on);
+       if (aic31xx_divs[aic31xx->rate_div_line].nadc)
+               snd_soc_update_bits(codec, AIC31XX_NADC, mask, on);
+       if (aic31xx_divs[aic31xx->rate_div_line].madc)
+               snd_soc_update_bits(codec, AIC31XX_MADC, mask, on);
+       snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, on);
+}
+
+static void aic31xx_clk_off(struct snd_soc_codec *codec)
+{
+       u8 mask = AIC31XX_PM_MASK;
+       u8 off = 0;
+
+       dev_dbg(codec->dev, "codec clock -> off\n");
+       snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, off);
+       snd_soc_update_bits(codec, AIC31XX_MADC, mask, off);
+       snd_soc_update_bits(codec, AIC31XX_NADC, mask, off);
+       snd_soc_update_bits(codec, AIC31XX_MDAC, mask, off);
+       snd_soc_update_bits(codec, AIC31XX_NDAC, mask, off);
+       snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, off);
+}
+
+static int aic31xx_power_on(struct snd_soc_codec *codec)
+{
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int ret = 0;
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies),
+                                   aic31xx->supplies);
+       if (ret)
+               return ret;
+
+       if (gpio_is_valid(aic31xx->pdata.gpio_reset)) {
+               gpio_set_value(aic31xx->pdata.gpio_reset, 1);
+               udelay(100);
+       }
+       regcache_cache_only(aic31xx->regmap, false);
+       ret = regcache_sync(aic31xx->regmap);
+       if (ret != 0) {
+               dev_err(codec->dev,
+                       "Failed to restore cache: %d\n", ret);
+               regcache_cache_only(aic31xx->regmap, true);
+               regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
+                                      aic31xx->supplies);
+               return ret;
+       }
+       return 0;
+}
+
+static int aic31xx_power_off(struct snd_soc_codec *codec)
+{
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int ret = 0;
+
+       regcache_cache_only(aic31xx->regmap, true);
+       ret = regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies),
+                                    aic31xx->supplies);
+
+       return ret;
+}
+
+static int aic31xx_set_bias_level(struct snd_soc_codec *codec,
+                                 enum snd_soc_bias_level level)
+{
+       dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
+               codec->dapm.bias_level, level);
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+                       aic31xx_clk_on(codec);
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               switch (codec->dapm.bias_level) {
+               case SND_SOC_BIAS_OFF:
+                       aic31xx_power_on(codec);
+                       break;
+               case SND_SOC_BIAS_PREPARE:
+                       aic31xx_clk_off(codec);
+                       break;
+               default:
+                       BUG();
+               }
+               break;
+       case SND_SOC_BIAS_OFF:
+               if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+                       aic31xx_power_off(codec);
+               break;
+       }
+       codec->dapm.bias_level = level;
+
+       return 0;
+}
+
+static int aic31xx_suspend(struct snd_soc_codec *codec)
+{
+       aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static int aic31xx_resume(struct snd_soc_codec *codec)
+{
+       aic31xx_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       return 0;
+}
+
+static int aic31xx_codec_probe(struct snd_soc_codec *codec)
+{
+       int ret = 0;
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int i;
+
+       dev_dbg(aic31xx->dev, "## %s\n", __func__);
+
+       aic31xx = snd_soc_codec_get_drvdata(codec);
+
+       aic31xx->codec = codec;
+
+       for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
+               aic31xx->disable_nb[i].nb.notifier_call =
+                       aic31xx_regulator_event;
+               aic31xx->disable_nb[i].aic31xx = aic31xx;
+               ret = regulator_register_notifier(aic31xx->supplies[i].consumer,
+                                                 &aic31xx->disable_nb[i].nb);
+               if (ret) {
+                       dev_err(codec->dev,
+                               "Failed to request regulator notifier: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       regcache_cache_only(aic31xx->regmap, true);
+       regcache_mark_dirty(aic31xx->regmap);
+
+       ret = aic31xx_add_controls(codec);
+       if (ret)
+               return ret;
+
+       ret = aic31xx_add_widgets(codec);
+
+       return ret;
+}
+
+static int aic31xx_codec_remove(struct snd_soc_codec *codec)
+{
+       struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int i;
+       /* power down chip */
+       aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
+               regulator_unregister_notifier(aic31xx->supplies[i].consumer,
+                                             &aic31xx->disable_nb[i].nb);
+
+       return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_driver_aic31xx = {
+       .probe                  = aic31xx_codec_probe,
+       .remove                 = aic31xx_codec_remove,
+       .suspend                = aic31xx_suspend,
+       .resume                 = aic31xx_resume,
+       .set_bias_level         = aic31xx_set_bias_level,
+       .controls               = aic31xx_snd_controls,
+       .num_controls           = ARRAY_SIZE(aic31xx_snd_controls),
+       .dapm_widgets           = aic31xx_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(aic31xx_dapm_widgets),
+       .dapm_routes            = aic31xx_audio_map,
+       .num_dapm_routes        = ARRAY_SIZE(aic31xx_audio_map),
+};
+
+static struct snd_soc_dai_ops aic31xx_dai_ops = {
+       .hw_params      = aic31xx_hw_params,
+       .set_sysclk     = aic31xx_set_dai_sysclk,
+       .set_fmt        = aic31xx_set_dai_fmt,
+       .digital_mute   = aic31xx_dac_mute,
+};
+
+static struct snd_soc_dai_driver aic31xx_dai_driver[] = {
+       {
+               .name = "tlv320aic31xx-hifi",
+               .playback = {
+                       .stream_name     = "Playback",
+                       .channels_min    = 1,
+                       .channels_max    = 2,
+                       .rates           = AIC31XX_RATES,
+                       .formats         = AIC31XX_FORMATS,
+               },
+               .capture = {
+                       .stream_name     = "Capture",
+                       .channels_min    = 1,
+                       .channels_max    = 2,
+                       .rates           = AIC31XX_RATES,
+                       .formats         = AIC31XX_FORMATS,
+               },
+               .ops = &aic31xx_dai_ops,
+               .symmetric_rates = 1,
+       }
+};
+
+#if defined(CONFIG_OF)
+static const struct of_device_id tlv320aic31xx_of_match[] = {
+       { .compatible = "ti,tlv320aic310x" },
+       { .compatible = "ti,tlv320aic311x" },
+       { .compatible = "ti,tlv320aic3100" },
+       { .compatible = "ti,tlv320aic3110" },
+       { .compatible = "ti,tlv320aic3120" },
+       { .compatible = "ti,tlv320aic3111" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match);
+
+static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
+{
+       struct device_node *np = aic31xx->dev->of_node;
+       unsigned int value = MICBIAS_2_0V;
+       int ret;
+
+       of_property_read_u32(np, "ai31xx-micbias-vg", &value);
+       switch (value) {
+       case MICBIAS_2_0V:
+       case MICBIAS_2_5V:
+       case MICBIAS_AVDDV:
+               aic31xx->pdata.micbias_vg = value;
+               break;
+       default:
+               dev_err(aic31xx->dev,
+                       "Bad ai31xx-micbias-vg value %d DT\n",
+                       value);
+               aic31xx->pdata.micbias_vg = MICBIAS_2_0V;
+       }
+
+       ret = of_get_named_gpio(np, "gpio-reset", 0);
+       if (ret > 0)
+               aic31xx->pdata.gpio_reset = ret;
+}
+#else /* CONFIG_OF */
+static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx)
+{
+}
+#endif /* CONFIG_OF */
+
+static void aic31xx_device_init(struct aic31xx_priv *aic31xx)
+{
+       int ret, i;
+
+       dev_set_drvdata(aic31xx->dev, aic31xx);
+
+       if (dev_get_platdata(aic31xx->dev))
+               memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev),
+                      sizeof(aic31xx->pdata));
+       else if (aic31xx->dev->of_node)
+               aic31xx_pdata_from_of(aic31xx);
+
+       if (aic31xx->pdata.gpio_reset) {
+               ret = devm_gpio_request_one(aic31xx->dev,
+                                           aic31xx->pdata.gpio_reset,
+                                           GPIOF_OUT_INIT_HIGH,
+                                           "aic31xx-reset-pin");
+               if (ret < 0) {
+                       dev_err(aic31xx->dev, "not able to acquire gpio\n");
+                       return;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++)
+               aic31xx->supplies[i].supply = aic31xx_supply_names[i];
+
+       ret = devm_regulator_bulk_get(aic31xx->dev,
+                                     ARRAY_SIZE(aic31xx->supplies),
+                                     aic31xx->supplies);
+       if (ret != 0)
+               dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret);
+
+}
+
+static int aic31xx_i2c_probe(struct i2c_client *i2c,
+                            const struct i2c_device_id *id)
+{
+       struct aic31xx_priv *aic31xx;
+       int ret;
+       const struct regmap_config *regmap_config;
+
+       dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__,
+               id->name, (int) id->driver_data);
+
+       regmap_config = &aic31xx_i2c_regmap;
+
+       aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL);
+       if (aic31xx == NULL)
+               return -ENOMEM;
+
+       aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config);
+       if (IS_ERR(aic31xx->regmap)) {
+               ret = PTR_ERR(aic31xx->regmap);
+               dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               return ret;
+       }
+       aic31xx->dev = &i2c->dev;
+
+       aic31xx->pdata.codec_type = id->driver_data;
+
+       aic31xx_device_init(aic31xx);
+
+       return snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx,
+                                    aic31xx_dai_driver,
+                                    ARRAY_SIZE(aic31xx_dai_driver));
+}
+
+static int aic31xx_i2c_remove(struct i2c_client *i2c)
+{
+       snd_soc_unregister_codec(&i2c->dev);
+       return 0;
+}
+
+static const struct i2c_device_id aic31xx_i2c_id[] = {
+       { "tlv320aic310x", AIC3100 },
+       { "tlv320aic311x", AIC3110 },
+       { "tlv320aic3100", AIC3100 },
+       { "tlv320aic3110", AIC3110 },
+       { "tlv320aic3120", AIC3120 },
+       { "tlv320aic3111", AIC3111 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id);
+
+static struct i2c_driver aic31xx_i2c_driver = {
+       .driver = {
+               .name   = "tlv320aic31xx-codec",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(tlv320aic31xx_of_match),
+       },
+       .probe          = aic31xx_i2c_probe,
+       .remove         = aic31xx_i2c_remove,
+       .id_table       = aic31xx_i2c_id,
+};
+
+module_i2c_driver(aic31xx_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC TLV320AIC3111 codec driver");
+MODULE_AUTHOR("Jyri Sarha");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h
new file mode 100644 (file)
index 0000000..52ed57c
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * ALSA SoC TLV320AIC31XX codec driver
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#ifndef _TLV320AIC31XX_H
+#define _TLV320AIC31XX_H
+
+#define AIC31XX_RATES  SNDRV_PCM_RATE_8000_192000
+
+#define AIC31XX_FORMATS        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
+                        | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+
+#define AIC31XX_STEREO_CLASS_D_BIT     0x1
+#define AIC31XX_MINIDSP_BIT            0x2
+
+enum aic31xx_type {
+       AIC3100 = 0,
+       AIC3110 = AIC31XX_STEREO_CLASS_D_BIT,
+       AIC3120 = AIC31XX_MINIDSP_BIT,
+       AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT),
+};
+
+struct aic31xx_pdata {
+       enum aic31xx_type codec_type;
+       unsigned int gpio_reset;
+       int micbias_vg;
+};
+
+/* Page Control Register */
+#define AIC31XX_PAGECTL                                0x00
+
+/* Page 0 Registers */
+/* Software reset register */
+#define AIC31XX_RESET                          0x01
+/* OT FLAG register */
+#define AIC31XX_OT_FLAG                                0x03
+/* Clock clock Gen muxing, Multiplexers*/
+#define AIC31XX_CLKMUX                         0x04
+/* PLL P and R-VAL register */
+#define AIC31XX_PLLPR                          0x05
+/* PLL J-VAL register */
+#define AIC31XX_PLLJ                           0x06
+/* PLL D-VAL MSB register */
+#define AIC31XX_PLLDMSB                                0x07
+/* PLL D-VAL LSB register */
+#define AIC31XX_PLLDLSB                                0x08
+/* DAC NDAC_VAL register*/
+#define AIC31XX_NDAC                           0x0B
+/* DAC MDAC_VAL register */
+#define AIC31XX_MDAC                           0x0C
+/* DAC OSR setting register 1, MSB value */
+#define AIC31XX_DOSRMSB                                0x0D
+/* DAC OSR setting register 2, LSB value */
+#define AIC31XX_DOSRLSB                                0x0E
+#define AIC31XX_MINI_DSP_INPOL                 0x10
+/* Clock setting register 8, PLL */
+#define AIC31XX_NADC                           0x12
+/* Clock setting register 9, PLL */
+#define AIC31XX_MADC                           0x13
+/* ADC Oversampling (AOSR) Register */
+#define AIC31XX_AOSR                           0x14
+/* Clock setting register 9, Multiplexers */
+#define AIC31XX_CLKOUTMUX                      0x19
+/* Clock setting register 10, CLOCKOUT M divider value */
+#define AIC31XX_CLKOUTMVAL                     0x1A
+/* Audio Interface Setting Register 1 */
+#define AIC31XX_IFACE1                         0x1B
+/* Audio Data Slot Offset Programming */
+#define AIC31XX_DATA_OFFSET                    0x1C
+/* Audio Interface Setting Register 2 */
+#define AIC31XX_IFACE2                         0x1D
+/* Clock setting register 11, BCLK N Divider */
+#define AIC31XX_BCLKN                          0x1E
+/* Audio Interface Setting Register 3, Secondary Audio Interface */
+#define AIC31XX_IFACESEC1                      0x1F
+/* Audio Interface Setting Register 4 */
+#define AIC31XX_IFACESEC2                      0x20
+/* Audio Interface Setting Register 5 */
+#define AIC31XX_IFACESEC3                      0x21
+/* I2C Bus Condition */
+#define AIC31XX_I2C                            0x22
+/* ADC FLAG */
+#define AIC31XX_ADCFLAG                                0x24
+/* DAC Flag Registers */
+#define AIC31XX_DACFLAG1                       0x25
+#define AIC31XX_DACFLAG2                       0x26
+/* Sticky Interrupt flag (overflow) */
+#define AIC31XX_OFFLAG                         0x27
+/* Sticy DAC Interrupt flags */
+#define AIC31XX_INTRDACFLAG                    0x2C
+/* Sticy ADC Interrupt flags */
+#define AIC31XX_INTRADCFLAG                    0x2D
+/* DAC Interrupt flags 2 */
+#define AIC31XX_INTRDACFLAG2                   0x2E
+/* ADC Interrupt flags 2 */
+#define AIC31XX_INTRADCFLAG2                   0x2F
+/* INT1 interrupt control */
+#define AIC31XX_INT1CTRL                       0x30
+/* INT2 interrupt control */
+#define AIC31XX_INT2CTRL                       0x31
+/* GPIO1 control */
+#define AIC31XX_GPIO1                          0x33
+
+#define AIC31XX_DACPRB                         0x3C
+/* ADC Instruction Set Register */
+#define AIC31XX_ADCPRB                         0x3D
+/* DAC channel setup register */
+#define AIC31XX_DACSETUP                       0x3F
+/* DAC Mute and volume control register */
+#define AIC31XX_DACMUTE                                0x40
+/* Left DAC channel digital volume control */
+#define AIC31XX_LDACVOL                                0x41
+/* Right DAC channel digital volume control */
+#define AIC31XX_RDACVOL                                0x42
+/* Headset detection */
+#define AIC31XX_HSDETECT                       0x43
+/* ADC Digital Mic */
+#define AIC31XX_ADCSETUP                       0x51
+/* ADC Digital Volume Control Fine Adjust */
+#define AIC31XX_ADCFGA                         0x52
+/* ADC Digital Volume Control Coarse Adjust */
+#define AIC31XX_ADCVOL                         0x53
+
+
+/* Page 1 Registers */
+/* Headphone drivers */
+#define AIC31XX_HPDRIVER                       0x9F
+/* Class-D Speakear Amplifier */
+#define AIC31XX_SPKAMP                         0xA0
+/* HP Output Drivers POP Removal Settings */
+#define AIC31XX_HPPOP                          0xA1
+/* Output Driver PGA Ramp-Down Period Control */
+#define AIC31XX_SPPGARAMP                      0xA2
+/* DAC_L and DAC_R Output Mixer Routing */
+#define AIC31XX_DACMIXERROUTE                  0xA3
+/* Left Analog Vol to HPL */
+#define AIC31XX_LANALOGHPL                     0xA4
+/* Right Analog Vol to HPR */
+#define AIC31XX_RANALOGHPR                     0xA5
+/* Left Analog Vol to SPL */
+#define AIC31XX_LANALOGSPL                     0xA6
+/* Right Analog Vol to SPR */
+#define AIC31XX_RANALOGSPR                     0xA7
+/* HPL Driver */
+#define AIC31XX_HPLGAIN                                0xA8
+/* HPR Driver */
+#define AIC31XX_HPRGAIN                                0xA9
+/* SPL Driver */
+#define AIC31XX_SPLGAIN                                0xAA
+/* SPR Driver */
+#define AIC31XX_SPRGAIN                                0xAB
+/* HP Driver Control */
+#define AIC31XX_HPCONTROL                      0xAC
+/* MIC Bias Control */
+#define AIC31XX_MICBIAS                                0xAE
+/* MIC PGA*/
+#define AIC31XX_MICPGA                         0xAF
+/* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */
+#define AIC31XX_MICPGAPI                       0xB0
+/* ADC Input Selection for M-Terminal */
+#define AIC31XX_MICPGAMI                       0xB1
+/* Input CM Settings */
+#define AIC31XX_MICPGACM                       0xB2
+
+/* Bits, masks and shifts */
+
+/* AIC31XX_CLKMUX */
+#define AIC31XX_PLL_CLKIN_MASK                 0x0c
+#define AIC31XX_PLL_CLKIN_SHIFT                        2
+#define AIC31XX_PLL_CLKIN_MCLK                 0
+#define AIC31XX_CODEC_CLKIN_MASK               0x03
+#define AIC31XX_CODEC_CLKIN_SHIFT              0
+#define AIC31XX_CODEC_CLKIN_PLL                        3
+#define AIC31XX_CODEC_CLKIN_BCLK               1
+
+/* AIC31XX_PLLPR, AIC31XX_NDAC, AIC31XX_MDAC, AIC31XX_NADC, AIC31XX_MADC,
+   AIC31XX_BCLKN */
+#define AIC31XX_PLL_MASK               0x7f
+#define AIC31XX_PM_MASK                        0x80
+
+/* AIC31XX_IFACE1 */
+#define AIC31XX_WORD_LEN_16BITS                0x00
+#define AIC31XX_WORD_LEN_20BITS                0x01
+#define AIC31XX_WORD_LEN_24BITS                0x02
+#define AIC31XX_WORD_LEN_32BITS                0x03
+#define AIC31XX_IFACE1_DATALEN_MASK    0x30
+#define AIC31XX_IFACE1_DATALEN_SHIFT   (4)
+#define AIC31XX_IFACE1_DATATYPE_MASK   0xC0
+#define AIC31XX_IFACE1_DATATYPE_SHIFT  (6)
+#define AIC31XX_I2S_MODE               0x00
+#define AIC31XX_DSP_MODE               0x01
+#define AIC31XX_RIGHT_JUSTIFIED_MODE   0x02
+#define AIC31XX_LEFT_JUSTIFIED_MODE    0x03
+#define AIC31XX_IFACE1_MASTER_MASK     0x0C
+#define AIC31XX_BCLK_MASTER            0x08
+#define AIC31XX_WCLK_MASTER            0x04
+
+/* AIC31XX_DATA_OFFSET */
+#define AIC31XX_DATA_OFFSET_MASK       0xFF
+
+/* AIC31XX_IFACE2 */
+#define AIC31XX_BCLKINV_MASK           0x08
+#define AIC31XX_BDIVCLK_MASK           0x03
+#define AIC31XX_DAC2BCLK               0x00
+#define AIC31XX_DACMOD2BCLK            0x01
+#define AIC31XX_ADC2BCLK               0x02
+#define AIC31XX_ADCMOD2BCLK            0x03
+
+/* AIC31XX_ADCFLAG */
+#define AIC31XX_ADCPWRSTATUS_MASK              0x40
+
+/* AIC31XX_DACFLAG1 */
+#define AIC31XX_LDACPWRSTATUS_MASK             0x80
+#define AIC31XX_RDACPWRSTATUS_MASK             0x08
+#define AIC31XX_HPLDRVPWRSTATUS_MASK           0x20
+#define AIC31XX_HPRDRVPWRSTATUS_MASK           0x02
+#define AIC31XX_SPLDRVPWRSTATUS_MASK           0x10
+#define AIC31XX_SPRDRVPWRSTATUS_MASK           0x01
+
+/* AIC31XX_INTRDACFLAG */
+#define AIC31XX_HPSCDETECT_MASK                        0x80
+#define AIC31XX_BUTTONPRESS_MASK               0x20
+#define AIC31XX_HSPLUG_MASK                    0x10
+#define AIC31XX_LDRCTHRES_MASK                 0x08
+#define AIC31XX_RDRCTHRES_MASK                 0x04
+#define AIC31XX_DACSINT_MASK                   0x02
+#define AIC31XX_DACAINT_MASK                   0x01
+
+/* AIC31XX_INT1CTRL */
+#define AIC31XX_HSPLUGDET_MASK                 0x80
+#define AIC31XX_BUTTONPRESSDET_MASK            0x40
+#define AIC31XX_DRCTHRES_MASK                  0x20
+#define AIC31XX_AGCNOISE_MASK                  0x10
+#define AIC31XX_OC_MASK                                0x08
+#define AIC31XX_ENGINE_MASK                    0x04
+
+/* AIC31XX_DACSETUP */
+#define AIC31XX_SOFTSTEP_MASK                  0x03
+
+/* AIC31XX_DACMUTE */
+#define AIC31XX_DACMUTE_MASK                   0x0C
+
+/* AIC31XX_MICBIAS */
+#define AIC31XX_MICBIAS_MASK                   0x03
+#define AIC31XX_MICBIAS_SHIFT                  0
+
+#endif /* _TLV320AIC31XX_H */
index c6bd7e75352d2c5298e28df490f1444dc027bc10..1d9b117345a3ae6fc8182f73733603a34f6a20d7 100644 (file)
@@ -614,8 +614,6 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
        struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
        u32 tmp_reg;
 
-       snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-
        if (gpio_is_valid(aic32x4->rstn_gpio)) {
                ndelay(10);
                gpio_set_value(aic32x4->rstn_gpio, 1);
index 470fbfb4b3861314b6ecc74dfd95d5c2cd8b0d89..b1835103e9b4002ab44429d40bb16da8372f65aa 100644 (file)
@@ -1344,12 +1344,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
        INIT_LIST_HEAD(&aic3x->list);
        aic3x->codec = codec;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
                aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
                aic3x->disable_nb[i].aic3x = aic3x;
index 793516146670420c3d7cadfdd7745371a26de5d9..6bfc8a17331b05c887a80199f05fa4fb38baac31 100644 (file)
@@ -122,7 +122,6 @@ struct tlv320dac33_priv {
        unsigned int uthr;
 
        enum dac33_state state;
-       enum snd_soc_control_type control_type;
        void *control_data;
 };
 
index c94d4c1e3dacc1d7a51f2c6708848d56af6ecf9e..edf27acc1d77da6ba457cef5e8a403867e753fb2 100644 (file)
@@ -203,8 +203,7 @@ static int uda134x_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 snd_soc_codec *codec = dai->codec;
        struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
        u8 hw_params;
 
index 4dadaa8ad46c1f3edd8440c6479b0ce578841246..e62e70781ec21fe72bac4137c518f1bf01794e88 100644 (file)
@@ -566,8 +566,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
 static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_codec *codec = dai->codec;
        u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
 
        /* shut down WSPLL power if running from this clock */
index 8ae50274ea8f12f275938e2cdab2c836db1f687e..83a2c872925c4bbd9a844ea36f8b5127fd72fd41 100644 (file)
@@ -786,8 +786,6 @@ static int wm2000_probe(struct snd_soc_codec *codec)
 {
        struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
 
-       snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_REGMAP);
-
        /* This will trigger a transition to standby mode by default */
        wm2000_anc_set_mode(wm2000);
 
index 1e0a083d83459c9a501081cc0b2351f8c098f372..2e721e06671bd26c7dc65c7f7a546567d3c6d54c 100644 (file)
@@ -1554,15 +1554,8 @@ static int wm2200_probe(struct snd_soc_codec *codec)
        int ret;
 
        wm2200->codec = codec;
-       codec->control_data = wm2200->regmap;
        codec->dapm.bias_level = SND_SOC_BIAS_OFF;
 
-       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;
-       }
-
        ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
        if (ret != 0)
                return ret;
index d3fa65fd9e85a84b466217824c48e10a1cbe7ed7..eca983fad8918e2599b5c990eada31b2147ddc17 100644 (file)
@@ -2343,13 +2343,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
        int ret, i;
 
        wm5100->codec = codec;
-       codec->control_data = wm5100->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;
-       }
 
        for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
                snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
index 34109050ceeded82cc4e223f467aba8171b4f74c..dcf1d12cfef8f7bd5cb835d995eef1cb71e1ad93 100644 (file)
@@ -1760,9 +1760,7 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
        struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = priv->core.arizona->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+       ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap);
        if (ret != 0)
                return ret;
 
index d7bf8848174af59049c84a1e3149aa027d01b574..df5a38dd8328db5922a4db96758b50d81e6255ee 100644 (file)
@@ -1587,10 +1587,9 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
        struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = priv->core.arizona->regmap;
        priv->core.arizona->dapm = &codec->dapm;
 
-       ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+       ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap);
        if (ret != 0)
                return ret;
 
index a183dcf3d5c12343884be365e0f50c90248135b8..757256bf7672ef9a44d156d895ca0537018ab852 100644 (file)
@@ -1505,9 +1505,7 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
        if (ret != 0)
                return ret;
 
-       codec->control_data = wm8350->regmap;
-
-       snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+       snd_soc_codec_set_cache_io(codec, wm8350->regmap);
 
        /* Put the codec into reset if it wasn't already */
        wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
index 6d684d934f4de1e2b2c43dfc18d5659ada570cf1..146564feaea04156d8d0d2fe5608390047b4cad0 100644 (file)
@@ -1316,10 +1316,9 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec)
 
        snd_soc_codec_set_drvdata(codec, priv);
        priv->wm8400 = wm8400;
-       codec->control_data = wm8400->regmap;
        priv->codec = codec;
 
-       snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+       snd_soc_codec_set_cache_io(codec, wm8400->regmap);
 
        ret = devm_regulator_bulk_get(wm8400->dev,
                                 ARRAY_SIZE(power), &power[0]);
index 7df7d45727559e98501eef2500b3cc610ee8a4b0..1c1e328feeb862f84efbfca08b924c1313c69d4f 100644 (file)
@@ -589,20 +589,12 @@ static int wm8510_resume(struct snd_soc_codec *codec)
 
 static int wm8510_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        wm8510_reset(codec);
 
        /* power on device */
        wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-       return ret;
+       return 0;
 }
 
 /* power down chip */
index 5dfd571b1a03bbf7677221e5fd4b73056fab6a53..601ee8178af1c0adb32a224daa3dbbc5ad40d1cf 100644 (file)
@@ -392,18 +392,11 @@ static int wm8523_resume(struct snd_soc_codec *codec)
 static int wm8523_probe(struct snd_soc_codec *codec)
 {
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-       int ret;
 
        wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
        wm8523->rate_constraint.count =
                ARRAY_SIZE(wm8523->rate_constraint_list);
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        /* Change some default settings - latch VU and enable ZC */
        snd_soc_update_bits(codec, WM8523_DAC_GAINR,
                            WM8523_DACR_VU, WM8523_DACR_VU);
index 318989acbbe5fbb97878856ccab46330422f6bdf..af7ed8b5d4e187e5b85dc6f3d47b9f7711ca86b2 100644 (file)
@@ -504,8 +504,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_codec *codec = dai->codec;
        struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
        u16 paifa = 0;
        u16 paifb = 0;
@@ -869,12 +868,6 @@ static int wm8580_probe(struct snd_soc_codec *codec)
        struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
        int ret = 0;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
                                    wm8580->supplies);
        if (ret != 0) {
index 6efcc40a7cb3c3ef82499283a2abcd29a0c55dad..b0fbcb377bafa5cffcc2d7cd78f7f131641cd089 100644 (file)
@@ -367,12 +367,6 @@ static int wm8711_probe(struct snd_soc_codec *codec)
 {
        int ret;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8711_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
index cd89033e84c08a1d290cb012cee545273b35badd..bac7fc28fe71b34c0afc27f553cc01efebd6cf8d 100644 (file)
@@ -228,19 +228,10 @@ static int wm8728_resume(struct snd_soc_codec *codec)
 
 static int wm8728_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
-                      ret);
-               return ret;
-       }
-
        /* power on device */
        wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-       return ret;
+       return 0;
 }
 
 static int wm8728_remove(struct snd_soc_codec *codec)
index d9655f981df1e006bcf465862bce1333a6661f48..d74f43975b90fb3e90a5b7b36b0239e4f6e52aeb 100644 (file)
@@ -583,13 +583,6 @@ static int wm8731_probe(struct snd_soc_codec *codec)
        struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
        int ret = 0, i;
 
-       codec->control_data = wm8731->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
                wm8731->supplies[i].supply = wm8731_supply_names[i];
 
index ecc4e8725d5be67577ef59646a8664849091b8e7..b27f26cdc04932dfb5d62224f9abd20de921f7cb 100644 (file)
@@ -570,12 +570,6 @@ static int wm8737_probe(struct snd_soc_codec *codec)
        struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
                                    wm8737->supplies);
        if (ret != 0) {
index dd02ebf880156995690cf8a8c098f392689d98ab..b33542a046073504a5ee5d16af4ca4a6698b5e86 100644 (file)
@@ -429,12 +429,6 @@ static int wm8741_probe(struct snd_soc_codec *codec)
                goto err_get;
        }
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               goto err_enable;
-       }
-
        ret = wm8741_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
index 78616a638a55ad4a76f11559f08c6dc4bdb708f6..33990b63d21428a8f8281ff98b1c071f907b211e 100644 (file)
@@ -702,12 +702,6 @@ static int wm8750_probe(struct snd_soc_codec *codec)
 {
        int ret;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8750_reset(codec);
        if (ret < 0) {
                printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
index 6a6855d8b8ea8e68cd7de3c07490815b1dc875a6..cbb8d55052a44a56bcfc22c00d1b64beeeb47da9 100644 (file)
@@ -1470,13 +1470,6 @@ static int wm8753_probe(struct snd_soc_codec *codec)
 
        INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
 
-       codec->control_data = wm8753->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8753_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
index 5bce2101348514aa6508dc9dac7f895d176ae0d9..c61aeb38efb8a191cd142a7b54f65e348e07d4fb 100644 (file)
@@ -580,12 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec)
        wm8770 = snd_soc_codec_get_drvdata(codec);
        wm8770->codec = codec;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
                                    wm8770->supplies);
        if (ret) {
index ef824672523206a1a3f5d593647a20ae5487b941..70952ceb278b8699a11600c011bf8bcf35e99699 100644 (file)
@@ -430,12 +430,6 @@ static int wm8776_probe(struct snd_soc_codec *codec)
 {
        int ret = 0;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8776_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
index 72d12bbe1a56444c947344fd57ee7d8a8b0dba15..ee76f0fb429967c4f563450a111d3ce651540fd0 100644 (file)
@@ -546,14 +546,6 @@ static int wm8804_probe(struct snd_soc_codec *codec)
 
        wm8804 = snd_soc_codec_get_drvdata(codec);
 
-       codec->control_data = wm8804->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
-               return ret;
-       }
-
        for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
                wm8804->supplies[i].supply = wm8804_supply_names[i];
 
index 43c2201cb90131ebdb66e2f10326f4c904700011..d09fdce57f5a85d8b35c195feb68db70d069edc6 100644 (file)
@@ -1178,13 +1178,7 @@ static int wm8900_resume(struct snd_soc_codec *codec)
 
 static int wm8900_probe(struct snd_soc_codec *codec)
 {
-       int ret = 0, reg;
-
-       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;
-       }
+       int reg;
 
        reg = snd_soc_read(codec, WM8900_REG_ID);
        if (reg != 0x8900) {
index b82b70a3b3d35a82c12452b1692340af00bc3782..b0084a127d18c6214636ed96ef40f3ae8b4b56ae 100644 (file)
@@ -1897,21 +1897,13 @@ static void wm8903_free_gpio(struct wm8903_priv *wm8903)
 static int wm8903_probe(struct snd_soc_codec *codec)
 {
        struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
-       int ret;
 
        wm8903->codec = codec;
-       codec->control_data = wm8903->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;
-       }
 
        /* power on device */
        wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-       return ret;
+       return 0;
 }
 
 /* power down chip */
index 27299cda0e990db1469eb648bf7353efa644b911..49c35c36935e45ed478191ac063c8816fd618a27 100644 (file)
@@ -2048,9 +2048,6 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
 static int wm8904_probe(struct snd_soc_codec *codec)
 {
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
-       int ret;
-
-       codec->control_data = wm8904->regmap;
 
        switch (wm8904->devtype) {
        case WM8904:
@@ -2064,12 +2061,6 @@ static int wm8904_probe(struct snd_soc_codec *codec)
                return -EINVAL;
        }
 
-       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;
-       }
-
        wm8904_handle_pdata(codec);
 
        wm8904_add_widgets(codec);
index 87f032d0d19f91cedeebba7f82f9f4660dfd1e24..fc6eec9ad66b16f01c20fb486e5efd8ee9ce16ae 100644 (file)
@@ -712,12 +712,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
        int ret;
        u16 reg;
 
-       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;
-       }
-
        ret = wm8940_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
index d4dcaecc8a5fd4b7b62365223ea1d1bcb2a9d070..fecd4e4f4c5731c6d9cbeefaa782bbef632e1daa 100644 (file)
@@ -895,14 +895,6 @@ static int wm8955_probe(struct snd_soc_codec *codec)
        struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
        int ret, i;
 
-       codec->control_data = wm8955->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
                wm8955->supplies[i].supply = wm8955_supply_names[i];
 
index f156010e52bc1ae5f206e1ddcf1b3a62aa1c1f2d..d04e9cad445c391046f0d586005668e62d1e997b 100644 (file)
@@ -976,12 +976,6 @@ static int wm8960_probe(struct snd_soc_codec *codec)
                        wm8960->set_bias_level = wm8960_set_bias_level_capless;
        }
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8960_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
index ce8fa6e01cb446de8a8a41f2283fb9e536a0a690..9c88f04442b3777c0e5a8dad0dda0f4e301ef4b8 100644 (file)
@@ -836,15 +836,8 @@ static struct snd_soc_dai_driver wm8961_dai = {
 static int wm8961_probe(struct snd_soc_codec *codec)
 {
        struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int ret = 0;
        u16 reg;
 
-       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;
-       }
-
        /* Enable class W */
        reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
        reg |= WM8961_CP_DYN_PWR_MASK;
index 62af9dc59fc5866d8e66bea8dad7525ac69a1ded..5522d2566c6742d5ee19f91b4358b30f51276b62 100644 (file)
@@ -3424,13 +3424,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
        bool dmicclk, dmicdat;
 
        wm8962->codec = codec;
-       codec->control_data = wm8962->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;
-       }
 
        wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
        wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1;
index 67aba78a7ca5d8de561d2a3c70a0f5a6e4307f7d..09b7b42002210b717e9ded871d4932fc1003a744 100644 (file)
@@ -648,12 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec)
        int ret = 0;
        u16 reg;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
        wm8971_workq = create_workqueue("wm8971");
        if (wm8971_workq == NULL)
index 6e16c430646149dad83a9c9c39022f53f8f9b9a8..0627c56fa44e5441050984797d7117c85a9d75df 100644 (file)
@@ -593,12 +593,6 @@ static int wm8974_probe(struct snd_soc_codec *codec)
 {
        int ret = 0;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8974_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
index a9e2f465c331e1e92e8429f75eafcdf53a83bd8e..28ef46c91f62fa6883bd567f7f18a27dec40883e 100644 (file)
@@ -975,19 +975,13 @@ static const int update_reg[] = {
 static int wm8978_probe(struct snd_soc_codec *codec)
 {
        struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
-       int ret = 0, i;
+       int i;
 
        /*
         * Set default system clock to PLL, it is more precise, this is also the
         * default hardware setting
         */
        wm8978->sysclk = WM8978_PLL;
-       codec->control_data = wm8978->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
 
        /*
         * Set the update bit in all registers, that have one. This way all
index 58f0551eed2d9f50df910dd8f703f39308fa7fca..2b9bfa53efbfeea53d4d8033f10b0d50e4074f38 100644 (file)
@@ -995,12 +995,6 @@ static int wm8983_probe(struct snd_soc_codec *codec)
        int ret;
        int i;
 
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
-               return ret;
-       }
-
        ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
index d786f2b39764a92d49b937884db97b6c408546a0..5473dc969585de3852feb6cbbdca7d09b4ace49f 100644 (file)
@@ -995,13 +995,6 @@ static int wm8985_probe(struct snd_soc_codec *codec)
        int ret;
 
        wm8985 = snd_soc_codec_get_drvdata(codec);
-       codec->control_data = wm8985->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
-               return ret;
-       }
 
        for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++)
                wm8985->supplies[i].supply = wm8985_supply_names[i];
index 0277a76c6bef780cde535e110b881d9ea666b3c3..3a1ae4f5164df1272a517906ed873fc7ff7b2cd0 100644 (file)
@@ -810,16 +810,8 @@ static int wm8988_resume(struct snd_soc_codec *codec)
 
 static int wm8988_probe(struct snd_soc_codec *codec)
 {
-       struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
        int ret = 0;
 
-       codec->control_data = wm8988->regmap;
-       ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        ret = wm8988_reset(codec);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to issue reset\n");
index 33f53ab1e7b051261cfb185efa9a8fbad41ceee1..c413c19914534c4fe34e55778a474691743e156f 100644 (file)
@@ -1289,14 +1289,6 @@ static int wm8990_resume(struct snd_soc_codec *codec)
  */
 static int wm8990_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
-       if (ret < 0) {
-               printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
-               return ret;
-       }
-
        wm8990_reset(codec);
 
        /* charge output caps */
index 32d219570ccaeb57302d8fb4d63d26ec8a1b871f..844cc4a60d667ef8f67dd7b35f29b3834c07b938 100644 (file)
@@ -1248,14 +1248,6 @@ static int wm8991_remove(struct snd_soc_codec *codec)
 
 static int wm8991_probe(struct snd_soc_codec *codec)
 {
-       int ret;
-
-       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;
-       }
-
        wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        return 0;
index 7b0630a076fa3b2574bfdf7b385f89056250197e..f825dc04ebe12cd4e41c19369fa254048189327f 100644 (file)
@@ -1493,13 +1493,6 @@ static int wm8993_probe(struct snd_soc_codec *codec)
        wm8993->hubs_data.dcs_codes_r = -2;
        wm8993->hubs_data.series_startup = 1;
 
-       codec->control_data = wm8993->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;
-       }
-
        /* Latch volume update bits and default ZC on */
        snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
                            WM8993_DAC_VU, WM8993_DAC_VU);
index 79854cb7feb6cbd42d749efc2634ac7adc826c8e..6303537f54c6d0dde224f7f1c2ee028a7c5c930b 100644 (file)
@@ -3998,9 +3998,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        int ret, i;
 
        wm8994->hubs.codec = codec;
-       codec->control_data = control->regmap;
 
-       snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
+       snd_soc_codec_set_cache_io(codec, control->regmap);
 
        mutex_init(&wm8994->accdet_lock);
        INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
index ddb197dc1d5349022f1a5c77c777cd7b2e5c99b3..d3152cf5bd5607490f34b7fe3fdb49915343e4da 100644 (file)
@@ -2042,13 +2042,6 @@ static int wm8995_probe(struct snd_soc_codec *codec)
        wm8995 = snd_soc_codec_get_drvdata(codec);
        wm8995->codec = codec;
 
-       codec->control_data = wm8995->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;
-       }
-
        for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
                wm8995->supplies[i].supply = wm8995_supply_names[i];
 
index c8244af7d56a32142f4e01e8a71f83a6c32494b3..c6cbb3b8ace96a8d462159d975ae5525b5ac7ed4 100644 (file)
@@ -2633,14 +2633,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
        init_completion(&wm8996->dcs_done);
        init_completion(&wm8996->fll_lock);
 
-       codec->control_data = wm8996->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);
-               goto err;
-       }
-
        if (wm8996->pdata.num_retune_mobile_cfgs)
                wm8996_retune_mobile_pdata(codec);
        else
@@ -2679,13 +2671,11 @@ static int wm8996_probe(struct snd_soc_codec *codec)
                } else {
                        dev_err(codec->dev, "Failed to request IRQ: %d\n",
                                ret);
+                       return ret;
                }
        }
 
        return 0;
-
-err:
-       return ret;
 }
 
 static int wm8996_remove(struct snd_soc_codec *codec)
index e10f44d7fdb78381a9c459d1d9bce5cbfa61b44d..004186b6bd48131932ac8fceca088548b9df9eb5 100644 (file)
@@ -1053,9 +1053,7 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
        struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       codec->control_data = priv->core.arizona->regmap;
-
-       ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+       ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap);
        if (ret != 0)
                return ret;
 
index 721cee71d5fc16bce510ebaf4cd72fc7f1a944dd..d18eff31fbbc618243a9b0db38e603e7af92bb30 100644 (file)
@@ -1260,15 +1260,6 @@ static struct snd_soc_dai_driver wm9081_dai = {
 static int wm9081_probe(struct snd_soc_codec *codec)
 {
        struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-       int ret;
-
-       codec->control_data = wm9081->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;
-       }
 
        /* Enable zero cross by default */
        snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
@@ -1283,7 +1274,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
                                     ARRAY_SIZE(wm9081_eq_controls));
        }
 
-       return ret;
+       return 0;
 }
 
 static int wm9081_remove(struct snd_soc_codec *codec)
index a07fe1618eec439d3ba001573331f4046b4e2095..87934171f0637da2c2a307893a641a43b0193e0b 100644 (file)
@@ -522,16 +522,6 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 
 static int wm9090_probe(struct snd_soc_codec *codec)
 {
-       struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev);
-       int ret;
-
-       codec->control_data = wm9090->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;
-       }
-
        /* Configure some defaults; they will be written out when we
         * bring the bias up.
         */
index 621e9a997d4c015bebeeb7d1a39a751941815dc0..cab98a580053bd9978e2ba8317583654fe09cf74 100644 (file)
@@ -123,35 +123,29 @@ static const struct snd_soc_dapm_route audio_map[] = {
 /* Logic for a aic3x as connected on a davinci-evm */
 static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 {
+       struct snd_soc_card *card = rtd->card;
        struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
        struct device_node *np = codec->card->dev->of_node;
        int ret;
 
        /* Add davinci-evm specific widgets */
-       snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
+       snd_soc_dapm_new_controls(&card->dapm, aic3x_dapm_widgets,
                                  ARRAY_SIZE(aic3x_dapm_widgets));
 
        if (np) {
-               ret = snd_soc_of_parse_audio_routing(codec->card,
-                                                       "ti,audio-routing");
+               ret = snd_soc_of_parse_audio_routing(card, "ti,audio-routing");
                if (ret)
                        return ret;
        } else {
                /* Set up davinci-evm specific audio path audio_map */
-               snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+               snd_soc_dapm_add_routes(&card->dapm, audio_map,
+                                       ARRAY_SIZE(audio_map));
        }
 
        /* not connected */
-       snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
-       snd_soc_dapm_disable_pin(dapm, "HPLCOM");
-       snd_soc_dapm_disable_pin(dapm, "HPRCOM");
-
-       /* always connected */
-       snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
-       snd_soc_dapm_enable_pin(dapm, "Line Out");
-       snd_soc_dapm_enable_pin(dapm, "Mic Jack");
-       snd_soc_dapm_enable_pin(dapm, "Line In");
+       snd_soc_dapm_nc_pin(&codec->dapm, "MONO_LOUT");
+       snd_soc_dapm_nc_pin(&codec->dapm, "HPLCOM");
+       snd_soc_dapm_nc_pin(&codec->dapm, "HPRCOM");
 
        return 0;
 }
index b0ae0677f023edd24e226efc1f056d907a85734e..a01ae97c90aae4aba50ccf21184adb1a519f7dcc 100644 (file)
@@ -1026,6 +1026,7 @@ nodata:
 static int davinci_mcasp_probe(struct platform_device *pdev)
 {
        struct davinci_pcm_dma_params *dma_params;
+       struct snd_dmaengine_dai_dma_data *dma_data;
        struct resource *mem, *ioarea, *res, *dat;
        struct davinci_mcasp_pdata *pdata;
        struct davinci_mcasp *mcasp;
@@ -1095,6 +1096,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                mcasp->dat_port = true;
 
        dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
+       dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
        dma_params->asp_chan_q = pdata->asp_chan_q;
        dma_params->ram_chan_q = pdata->ram_chan_q;
        dma_params->sram_pool = pdata->sram_pool;
@@ -1105,7 +1107,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                dma_params->dma_addr = mem->start + pdata->tx_dma_offset;
 
        /* Unconditional dmaengine stuff */
-       mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_params->dma_addr;
+       dma_data->addr = dma_params->dma_addr;
 
        res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
        if (res)
@@ -1113,7 +1115,14 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
        else
                dma_params->channel = pdata->tx_dma_channel;
 
+       /* dmaengine filter data for DT and non-DT boot */
+       if (pdev->dev.of_node)
+               dma_data->filter_data = "tx";
+       else
+               dma_data->filter_data = &dma_params->channel;
+
        dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
+       dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
        dma_params->asp_chan_q = pdata->asp_chan_q;
        dma_params->ram_chan_q = pdata->ram_chan_q;
        dma_params->sram_pool = pdata->sram_pool;
@@ -1124,7 +1133,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                dma_params->dma_addr = mem->start + pdata->rx_dma_offset;
 
        /* Unconditional dmaengine stuff */
-       mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_params->dma_addr;
+       dma_data->addr = dma_params->dma_addr;
 
        if (mcasp->version < MCASP_VERSION_3) {
                mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
@@ -1140,9 +1149,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
        else
                dma_params->channel = pdata->rx_dma_channel;
 
-       /* Unconditional dmaengine stuff */
-       mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx";
-       mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx";
+       /* dmaengine filter data for DT and non-DT boot */
+       if (pdev->dev.of_node)
+               dma_data->filter_data = "rx";
+       else
+               dma_data->filter_data = &dma_params->channel;
 
        dev_set_drvdata(&pdev->dev, mcasp);
 
diff --git a/sound/soc/davinci/edma-pcm.c b/sound/soc/davinci/edma-pcm.c
new file mode 100644 (file)
index 0000000..d38afb1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * edma-pcm.c - eDMA PCM driver using dmaengine for AM3xxx, AM4xxx
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * Based on: sound/soc/tegra/tegra_pcm.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+#include <linux/edma.h>
+
+static const struct snd_pcm_hardware edma_pcm_hardware = {
+       .info                   = SNDRV_PCM_INFO_MMAP |
+                                 SNDRV_PCM_INFO_MMAP_VALID |
+                                 SNDRV_PCM_INFO_BATCH |
+                                 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
+                                 SNDRV_PCM_INFO_INTERLEAVED,
+       .buffer_bytes_max       = 128 * 1024,
+       .period_bytes_min       = 32,
+       .period_bytes_max       = 64 * 1024,
+       .periods_min            = 2,
+       .periods_max            = 19, /* Limit by edma dmaengine driver */
+};
+
+static const struct snd_dmaengine_pcm_config edma_dmaengine_pcm_config = {
+       .pcm_hardware = &edma_pcm_hardware,
+       .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+       .compat_filter_fn = edma_filter_fn,
+       .prealloc_buffer_size = 128 * 1024,
+};
+
+int edma_pcm_platform_register(struct device *dev)
+{
+       return devm_snd_dmaengine_pcm_register(dev, &edma_dmaengine_pcm_config,
+                                       SND_DMAENGINE_PCM_FLAG_COMPAT);
+}
+EXPORT_SYMBOL_GPL(edma_pcm_platform_register);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("eDMA PCM ASoC platform driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/edma-pcm.h b/sound/soc/davinci/edma-pcm.h
new file mode 100644 (file)
index 0000000..894c378
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * edma-pcm.h - eDMA PCM driver using dmaengine for AM3xxx, AM4xxx
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * Based on: sound/soc/tegra/tegra_pcm.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef __EDMA_PCM_H__
+#define __EDMA_PCM_H__
+
+int edma_pcm_platform_register(struct device *dev);
+
+#endif /* __EDMA_PCM_H__ */
index 78ed4a42ad217e904a40591afb500019ec3a017b..49f8437665dea5d326833a4aff3ad506c6c02d56 100644 (file)
@@ -1,11 +1,20 @@
 config SND_KIRKWOOD_SOC
        tristate "SoC Audio for the Marvell Kirkwood and Dove chips"
-       depends on ARCH_KIRKWOOD || ARCH_DOVE || COMPILE_TEST
+       depends on ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST
        help
          Say Y or M if you want to add support for codecs attached to
          the Kirkwood I2S interface. You will also need to select the
          audio interfaces to support below.
 
+config SND_KIRKWOOD_SOC_ARMADA370_DB
+       tristate "SoC Audio support for Armada 370 DB"
+       depends on SND_KIRKWOOD_SOC && (ARCH_MVEBU || COMPILE_TEST) && I2C
+       select SND_SOC_CS42L51
+       select SND_SOC_SPDIF
+       help
+         Say Y if you want to add support for SoC audio on
+         the Armada 370 Development Board.
+
 config SND_KIRKWOOD_SOC_OPENRD
        tristate "SoC Audio support for Kirkwood Openrd Client"
        depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE || COMPILE_TEST)
index 9e781385cb88be80d8b4eb3da2b2090ca92f3a15..7c1d8fe09e6b6a6d465729904a0bbe7773d05fdb 100644 (file)
@@ -4,6 +4,8 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
 
 snd-soc-openrd-objs := kirkwood-openrd.o
 snd-soc-t5325-objs := kirkwood-t5325.o
+snd-soc-armada-370-db-objs := armada-370-db.o
 
+obj-$(CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB) += snd-soc-armada-370-db.o
 obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
 obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c
new file mode 100644 (file)
index 0000000..c443338
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <linux/of.h>
+#include <linux/platform_data/asoc-kirkwood.h>
+#include "../codecs/cs42l51.h"
+
+static int a370db_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;
+       unsigned int freq;
+
+       switch (params_rate(params)) {
+       default:
+       case 44100:
+               freq = 11289600;
+               break;
+       case 48000:
+               freq = 12288000;
+               break;
+       case 96000:
+               freq = 24576000;
+               break;
+       }
+
+       return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
+}
+
+static struct snd_soc_ops a370db_ops = {
+       .hw_params = a370db_hw_params,
+};
+
+static const struct snd_soc_dapm_widget a370db_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Out Jack", NULL),
+       SND_SOC_DAPM_LINE("In Jack", NULL),
+};
+
+static const struct snd_soc_dapm_route a370db_route[] = {
+       { "Out Jack",   NULL,   "HPL" },
+       { "Out Jack",   NULL,   "HPR" },
+       { "AIN1L",      NULL,   "In Jack" },
+       { "AIN1L",      NULL,   "In Jack" },
+};
+
+static struct snd_soc_dai_link a370db_dai[] = {
+{
+       .name = "CS42L51",
+       .stream_name = "analog",
+       .cpu_dai_name = "i2s",
+       .codec_dai_name = "cs42l51-hifi",
+       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
+       .ops = &a370db_ops,
+},
+{
+       .name = "S/PDIF out",
+       .stream_name = "spdif-out",
+       .cpu_dai_name = "spdif",
+       .codec_dai_name = "dit-hifi",
+       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
+},
+{
+       .name = "S/PDIF in",
+       .stream_name = "spdif-in",
+       .cpu_dai_name = "spdif",
+       .codec_dai_name = "dir-hifi",
+       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
+},
+};
+
+static struct snd_soc_card a370db = {
+       .name = "a370db",
+       .owner = THIS_MODULE,
+       .dai_link = a370db_dai,
+       .num_links = ARRAY_SIZE(a370db_dai),
+       .dapm_widgets = a370db_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(a370db_dapm_widgets),
+       .dapm_routes = a370db_route,
+       .num_dapm_routes = ARRAY_SIZE(a370db_route),
+};
+
+static int a370db_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &a370db;
+
+       card->dev = &pdev->dev;
+
+       a370db_dai[0].cpu_of_node =
+               of_parse_phandle(pdev->dev.of_node,
+                                "marvell,audio-controller", 0);
+       a370db_dai[0].platform_of_node = a370db_dai[0].cpu_of_node;
+
+       a370db_dai[0].codec_of_node =
+               of_parse_phandle(pdev->dev.of_node,
+                                "marvell,audio-codec", 0);
+
+       a370db_dai[1].cpu_of_node = a370db_dai[0].cpu_of_node;
+       a370db_dai[1].platform_of_node = a370db_dai[0].cpu_of_node;
+
+       a370db_dai[1].codec_of_node =
+               of_parse_phandle(pdev->dev.of_node,
+                                "marvell,audio-codec", 1);
+
+       a370db_dai[2].cpu_of_node = a370db_dai[0].cpu_of_node;
+       a370db_dai[2].platform_of_node = a370db_dai[0].cpu_of_node;
+
+       a370db_dai[2].codec_of_node =
+               of_parse_phandle(pdev->dev.of_node,
+                                "marvell,audio-codec", 2);
+
+       return devm_snd_soc_register_card(card->dev, card);
+}
+
+static const struct of_device_id a370db_dt_ids[] = {
+       { .compatible = "marvell,a370db-audio" },
+       { },
+};
+
+static struct platform_driver a370db_driver = {
+       .driver         = {
+               .name   = "a370db-audio",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(a370db_dt_ids),
+       },
+       .probe          = a370db_probe,
+};
+
+module_platform_driver(a370db_driver);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("ALSA SoC a370db audio client");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:a370db-audio");
index 3920a5e8125f886e15caa6607fed9e84a32950cd..9f842222e79802e2628a826ac536a506a069d8c0 100644 (file)
@@ -633,6 +633,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
 static struct of_device_id mvebu_audio_of_match[] = {
        { .compatible = "marvell,kirkwood-audio" },
        { .compatible = "marvell,dove-audio" },
+       { .compatible = "marvell,armada370-audio" },
        { }
 };
 MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
index f141435b0b4ad7f19a8e0b5069e016cfdebb121d..56a5219c0a00587fc412caf76927adf4d11799a5 100644 (file)
@@ -325,7 +325,7 @@ static void cx81801_close(struct tty_struct *tty)
 
        snd_soc_dapm_sync_unlocked(dapm);
 
-       snd_soc_dapm_mutex_unlock(codec);
+       snd_soc_dapm_mutex_unlock(dapm);
 }
 
 /* Line discipline .hangup() */
index 41ab6678b65d17035ededcae69f59ffe1a3aa19f..259e048681c0fd4bdfc1d4e67c3b3b804fe73504 100644 (file)
@@ -41,9 +41,8 @@ static int magician_hp_switch;
 static int magician_spk_switch = 1;
 static int magician_in_sel = MAGICIAN_MIC;
 
-static void magician_ext_control(struct snd_soc_codec *codec)
+static void magician_ext_control(struct snd_soc_dapm_context *dapm)
 {
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
 
        snd_soc_dapm_mutex_lock(dapm);
 
@@ -75,10 +74,9 @@ static void magician_ext_control(struct snd_soc_codec *codec)
 static int magician_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
 
        /* check the jack status at stream startup */
-       magician_ext_control(codec);
+       magician_ext_control(&rtd->card->dapm);
 
        return 0;
 }
@@ -277,13 +275,13 @@ static int magician_get_hp(struct snd_kcontrol *kcontrol,
 static int magician_set_hp(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);
 
        if (magician_hp_switch == ucontrol->value.integer.value[0])
                return 0;
 
        magician_hp_switch = ucontrol->value.integer.value[0];
-       magician_ext_control(codec);
+       magician_ext_control(&card->dapm);
        return 1;
 }
 
@@ -297,13 +295,13 @@ static int magician_get_spk(struct snd_kcontrol *kcontrol,
 static int magician_set_spk(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);
 
        if (magician_spk_switch == ucontrol->value.integer.value[0])
                return 0;
 
        magician_spk_switch = ucontrol->value.integer.value[0];
-       magician_ext_control(codec);
+       magician_ext_control(&card->dapm);
        return 1;
 }
 
@@ -400,7 +398,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int err;
 
        /* NC codec pins */
        snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
@@ -410,19 +407,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
        snd_soc_dapm_nc_pin(dapm, "VINL");
        snd_soc_dapm_nc_pin(dapm, "VINR");
 
-       /* Add magician specific controls */
-       err = snd_soc_add_codec_controls(codec, uda1380_magician_controls,
-                               ARRAY_SIZE(uda1380_magician_controls));
-       if (err < 0)
-               return err;
-
-       /* Add magician specific widgets */
-       snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
-                                 ARRAY_SIZE(uda1380_dapm_widgets));
-
-       /* Set up magician specific audio path interconnects */
-       snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
        return 0;
 }
 
@@ -456,6 +440,12 @@ static struct snd_soc_card snd_soc_card_magician = {
        .dai_link = magician_dai,
        .num_links = ARRAY_SIZE(magician_dai),
 
+       .controls = uda1380_magician_controls,
+       .num_controls = ARRAY_SIZE(uda1380_magician_controls),
+       .dapm_widgets = uda1380_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets),
+       .dapm_routes = audio_map,
+       .num_dapm_routes = ARRAY_SIZE(audio_map),
 };
 
 static struct platform_device *magician_snd_device;
index cead1658d10a497c14bc84ede0f2888c6a950f6e..4a956d1cb26960a23bb77eea839908d608b56677 100644 (file)
@@ -44,9 +44,8 @@
 static int tosa_jack_func;
 static int tosa_spk_func;
 
-static void tosa_ext_control(struct snd_soc_codec *codec)
+static void tosa_ext_control(struct snd_soc_dapm_context *dapm)
 {
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
 
        snd_soc_dapm_mutex_lock(dapm);
 
@@ -82,10 +81,9 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
 static int tosa_startup(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
 
        /* check the jack status at stream startup */
-       tosa_ext_control(codec);
+       tosa_ext_control(&rtd->card->dapm);
 
        return 0;
 }
@@ -104,13 +102,13 @@ static int tosa_get_jack(struct snd_kcontrol *kcontrol,
 static int tosa_set_jack(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);
 
        if (tosa_jack_func == ucontrol->value.integer.value[0])
                return 0;
 
        tosa_jack_func = ucontrol->value.integer.value[0];
-       tosa_ext_control(codec);
+       tosa_ext_control(&card->dapm);
        return 1;
 }
 
@@ -124,13 +122,13 @@ static int tosa_get_spk(struct snd_kcontrol *kcontrol,
 static int tosa_set_spk(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);
 
        if (tosa_spk_func == ucontrol->value.integer.value[0])
                return 0;
 
        tosa_spk_func = ucontrol->value.integer.value[0];
-       tosa_ext_control(codec);
+       tosa_ext_control(&card->dapm);
        return 1;
 }
 
@@ -191,24 +189,10 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int err;
 
        snd_soc_dapm_nc_pin(dapm, "OUT3");
        snd_soc_dapm_nc_pin(dapm, "MONOOUT");
 
-       /* add tosa specific controls */
-       err = snd_soc_add_codec_controls(codec, tosa_controls,
-                               ARRAY_SIZE(tosa_controls));
-       if (err < 0)
-               return err;
-
-       /* add tosa specific widgets */
-       snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
-                                 ARRAY_SIZE(tosa_dapm_widgets));
-
-       /* set up tosa specific audio path audio_map */
-       snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
        return 0;
 }
 
@@ -239,6 +223,13 @@ static struct snd_soc_card tosa = {
        .owner = THIS_MODULE,
        .dai_link = tosa_dai,
        .num_links = ARRAY_SIZE(tosa_dai),
+
+       .controls = tosa_controls,
+       .num_controls = ARRAY_SIZE(tosa_controls),
+       .dapm_widgets = tosa_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(tosa_dapm_widgets),
+       .dapm_routes = audio_map,
+       .num_dapm_routes = ARRAY_SIZE(audio_map),
 };
 
 static int tosa_probe(struct platform_device *pdev)
index 945e8abdc10fbf9579a1f89bd9a6a0610980256f..0b21d1dc80c1be2844fcf8e9024007b1d879159d 100644 (file)
@@ -104,8 +104,8 @@ static int output_type_get(struct snd_kcontrol *kcontrol,
 static int output_type_put(struct snd_kcontrol *kcontrol,
                           struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = kcontrol->private_data;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct snd_soc_card *card = kcontrol->private_data;
+       struct snd_soc_dapm_context *dapm = &card->dapm;
        unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
        char *differential = "Audio Out Differential";
        char *stereo = "Audio Out Stereo";
@@ -137,13 +137,7 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       /* Add s6105 specific widgets */
-       snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
-                                 ARRAY_SIZE(aic3x_dapm_widgets));
-
-       /* Set up s6105 specific audio path audio_map */
-       snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+       struct snd_soc_card *card = rtd->card;
 
        /* not present */
        snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
@@ -157,17 +151,10 @@ static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
        snd_soc_dapm_nc_pin(dapm, "RLOUT");
        snd_soc_dapm_nc_pin(dapm, "HPRCOM");
 
-       /* always connected */
-       snd_soc_dapm_enable_pin(dapm, "Audio In");
-
        /* must correspond to audio_out_mux.private_value initializer */
-       snd_soc_dapm_disable_pin(dapm, "Audio Out Differential");
-       snd_soc_dapm_sync(dapm);
-       snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo");
-
-       snd_soc_dapm_sync(dapm);
+       snd_soc_dapm_disable_pin(&card->dapm, "Audio Out Differential");
 
-       snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
+       snd_ctl_add(card->snd_card, snd_ctl_new1(&audio_out_mux, card));
 
        return 0;
 }
@@ -190,6 +177,11 @@ static struct snd_soc_card snd_soc_card_s6105 = {
        .owner = THIS_MODULE,
        .dai_link = &s6105_dai,
        .num_links = 1,
+
+       .dapm_widgets = aic3x_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
+       .dapm_routes = audio_map,
+       .num_dapm_routes = ARRAY_SIZE(audio_map),
 };
 
 static struct s6000_snd_platform_data s6105_snd_data __initdata = {
index 1967f44e7cd4d18fd078a71c52c3f0faf472b95f..710a079a7377db8f9cf55422648242496fd97d07 100644 (file)
@@ -1711,9 +1711,9 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               fsi->clk_master = 1;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
+               fsi->clk_master = 1; /* codec is slave, cpu is master */
                break;
        default:
                return -EINVAL;
index 6a1b45df8101d8f4db9714f48af22a81dea1be6d..d836e8a9fdce38fc559a0a7d91c2dc0d2e13eb43 100644 (file)
@@ -510,10 +510,10 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
-               rdai->clk_master = 1;
+               rdai->clk_master = 0;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               rdai->clk_master = 0;
+               rdai->clk_master = 1; /* codec is slave, cpu is master */
                break;
        default:
                return -EINVAL;
index 359c2849b364b3c78ec0824d864dadb3125b4294..b322cf294d0659ec60b4b1bd70b0f63f3bbdf77e 100644 (file)
@@ -1137,6 +1137,16 @@ static int soc_probe_codec(struct snd_soc_card *card,
 
        codec->dapm.idle_bias_off = driver->idle_bias_off;
 
+       if (!codec->write && dev_get_regmap(codec->dev, NULL)) {
+               /* Set the default I/O up try regmap */
+               ret = snd_soc_codec_set_cache_io(codec, NULL);
+               if (ret < 0) {
+                       dev_err(codec->dev,
+                               "Failed to set cache I/O: %d\n", ret);
+                       goto err_probe;
+               }
+       }
+
        if (driver->probe) {
                ret = driver->probe(codec);
                if (ret < 0) {
@@ -1150,10 +1160,6 @@ static int soc_probe_codec(struct snd_soc_card *card,
                        codec->name);
        }
 
-       /* If the driver didn't set I/O up try regmap */
-       if (!codec->write && dev_get_regmap(codec->dev, NULL))
-               snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
-
        if (driver->controls)
                snd_soc_add_codec_controls(codec, driver->controls,
                                     driver->num_controls);
index aa886cca3ecf94a8ecf2c360312cd3dc3bcb4184..260efc8466fc352cf70d08663799c7fde0758a2e 100644 (file)
 static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
                    unsigned int value)
 {
-       int ret;
-
-       if (!snd_soc_codec_volatile_register(codec, reg) &&
-           reg < codec->driver->reg_cache_size &&
-           !codec->cache_bypass) {
-               ret = snd_soc_cache_write(codec, reg, value);
-               if (ret < 0)
-                       return -1;
-       }
-
-       if (codec->cache_only) {
-               codec->cache_sync = 1;
-               return 0;
-       }
-
        return regmap_write(codec->control_data, reg, value);
 }
 
@@ -46,32 +31,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
        int ret;
        unsigned int val;
 
-       if (reg >= codec->driver->reg_cache_size ||
-           snd_soc_codec_volatile_register(codec, reg) ||
-           codec->cache_bypass) {
-               if (codec->cache_only)
-                       return -1;
-
-               ret = regmap_read(codec->control_data, reg, &val);
-               if (ret == 0)
-                       return val;
-               else
-                       return -1;
-       }
-
-       ret = snd_soc_cache_read(codec, reg, &val);
-       if (ret < 0)
+       ret = regmap_read(codec->control_data, reg, &val);
+       if (ret == 0)
+               return val;
+       else
                return -1;
-       return val;
 }
 
 /**
  * snd_soc_codec_set_cache_io: Set up standard I/O functions.
  *
  * @codec: CODEC to configure.
- * @addr_bits: Number of bits of register address data.
- * @data_bits: Number of bits of data per register.
- * @control: Control bus used.
+ * @map: Register map to write to
  *
  * Register formats are frequently shared between many I2C and SPI
  * devices.  In order to promote code reuse the ASoC core provides
@@ -85,60 +56,36 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
  * volatile registers.
  */
 int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
-                              int addr_bits, int data_bits,
-                              enum snd_soc_control_type control)
+                              struct regmap *regmap)
 {
-       struct regmap_config config;
        int ret;
 
-       memset(&config, 0, sizeof(config));
-       codec->write = hw_write;
-       codec->read = hw_read;
-
-       config.reg_bits = addr_bits;
-       config.val_bits = data_bits;
+       /* Device has made its own regmap arrangements */
+       if (!regmap)
+               codec->control_data = dev_get_regmap(codec->dev, NULL);
+       else
+               codec->control_data = regmap;
 
-       switch (control) {
-#if IS_ENABLED(CONFIG_REGMAP_I2C)
-       case SND_SOC_I2C:
-               codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
-                                                     &config);
-               break;
-#endif
+       if (IS_ERR(codec->control_data))
+               return PTR_ERR(codec->control_data);
 
-#if IS_ENABLED(CONFIG_REGMAP_SPI)
-       case SND_SOC_SPI:
-               codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
-                                                     &config);
-               break;
-#endif
-
-       case SND_SOC_REGMAP:
-               /* Device has made its own regmap arrangements */
-               codec->using_regmap = true;
-               if (!codec->control_data)
-                       codec->control_data = dev_get_regmap(codec->dev, NULL);
+       codec->write = hw_write;
+       codec->read = hw_read;
 
-               if (codec->control_data) {
-                       ret = regmap_get_val_bytes(codec->control_data);
-                       /* Errors are legitimate for non-integer byte
-                        * multiples */
-                       if (ret > 0)
-                               codec->val_bytes = ret;
-               }
-               break;
+       ret = regmap_get_val_bytes(codec->control_data);
+       /* Errors are legitimate for non-integer byte
+        * multiples */
+       if (ret > 0)
+               codec->val_bytes = ret;
 
-       default:
-               return -EINVAL;
-       }
+       codec->using_regmap = true;
 
-       return PTR_ERR_OR_ZERO(codec->control_data);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
 #else
 int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
-                              int addr_bits, int data_bits,
-                              enum snd_soc_control_type control)
+                              struct regmap *regmap)
 {
        return -ENOTSUPP;
 }
index 23d43dac91da2c0d9c6ad8bbf792036483da3fab..b903f822d1b2069062cae422d4a3a5f96f3ca342 100644 (file)
@@ -250,7 +250,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
                report = 0;
 
        if (gpio->jack_status_check)
-               report = gpio->jack_status_check();
+               report = gpio->jack_status_check(gpio->data);
 
        snd_soc_jack_report(jack, report, gpio->report);
 }
@@ -342,7 +342,8 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
                gpio_export(gpios[i].gpio, false);
 
                /* Update initial jack status */
-               snd_soc_jack_gpio_detect(&gpios[i]);
+               schedule_delayed_work(&gpios[i].work,
+                                     msecs_to_jiffies(gpios[i].debounce_time));
        }
 
        return 0;
index 330eaf007d899adb8122b9f1a0d25b0b15f15c6c..2cedf09f6d9613c7b34bb22888806fde598052c6 100644 (file)
@@ -2050,7 +2050,6 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card)
 
                paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list);
                if (paths < 0) {
-                       dpcm_path_put(&list);
                        dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
                                        fe->dai_link->name,  "playback");
                        mutex_unlock(&card->mutex);
@@ -2080,7 +2079,6 @@ capture:
 
                paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list);
                if (paths < 0) {
-                       dpcm_path_put(&list);
                        dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
                                        fe->dai_link->name,  "capture");
                        mutex_unlock(&card->mutex);
@@ -2145,7 +2143,6 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
        fe->dpcm[stream].runtime = fe_substream->runtime;
 
        if (dpcm_path_get(fe, stream, &list) <= 0) {
-               dpcm_path_put(&list);
                dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
                        fe->dai_link->name, stream ? "capture" : "playback");
        }
index cf5e1cfe818d9b6a8c4f980e4d5c9f23dacbe2c6..0a59e2383ef357ba4d4d83f57a5df9e448a4373c 100644 (file)
@@ -306,7 +306,7 @@ static const struct regmap_config tegra20_ac97_regmap_config = {
        .readable_reg = tegra20_ac97_wr_rd_reg,
        .volatile_reg = tegra20_ac97_volatile_reg,
        .precious_reg = tegra20_ac97_precious_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static int tegra20_ac97_platform_probe(struct platform_device *pdev)
index e72392927bd2ba3b7ca192e4ff75dde96b2488bd..a634f13b3ffc51456ea174c885196fe3dd26f3f2 100644 (file)
@@ -128,7 +128,7 @@ static const struct regmap_config tegra20_das_regmap_config = {
        .max_register = LAST_REG(DAC_INPUT_DATA_CLK_SEL),
        .writeable_reg = tegra20_das_wr_rd_reg,
        .readable_reg = tegra20_das_wr_rd_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static int tegra20_das_probe(struct platform_device *pdev)
index 42c1f6bfaf2e5bb2a4f2df89269be672b26e377c..79a9932ffe6ed49b2a99ba4b66c5b205b9877da4 100644 (file)
@@ -333,7 +333,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = {
        .readable_reg = tegra20_i2s_wr_rd_reg,
        .volatile_reg = tegra20_i2s_volatile_reg,
        .precious_reg = tegra20_i2s_precious_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static int tegra20_i2s_platform_probe(struct platform_device *pdev)
index 8c7c1028e5797dbc9b23ec88b58a4cd840db1c5c..a0ce92400faf9e69331b2fdbf33d854c1b6f469c 100644 (file)
@@ -259,7 +259,7 @@ static const struct regmap_config tegra20_spdif_regmap_config = {
        .readable_reg = tegra20_spdif_wr_rd_reg,
        .volatile_reg = tegra20_spdif_volatile_reg,
        .precious_reg = tegra20_spdif_precious_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static int tegra20_spdif_platform_probe(struct platform_device *pdev)
index d6f4c9940e0c64fee63b1e447ba11b40a5cfc2d1..0db68f49f4d9ba02c05ff71379ade1dd8e98d17c 100644 (file)
@@ -471,7 +471,7 @@ static const struct regmap_config tegra30_ahub_apbif_regmap_config = {
        .readable_reg = tegra30_ahub_apbif_wr_rd_reg,
        .volatile_reg = tegra30_ahub_apbif_volatile_reg,
        .precious_reg = tegra30_ahub_apbif_precious_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static bool tegra30_ahub_ahub_wr_rd_reg(struct device *dev, unsigned int reg)
@@ -490,7 +490,7 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
        .max_register = LAST_REG(AUDIO_RX),
        .writeable_reg = tegra30_ahub_ahub_wr_rd_reg,
        .readable_reg = tegra30_ahub_ahub_wr_rd_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static struct tegra30_ahub_soc_data soc_data_tegra30 = {
index 49ad9366add86b008823f6091315d74d78f13aeb..f146c41dd3ecddb5b2d0f471eaa08e1b447235e7 100644 (file)
@@ -357,7 +357,7 @@ static const struct regmap_config tegra30_i2s_regmap_config = {
        .writeable_reg = tegra30_i2s_wr_rd_reg,
        .readable_reg = tegra30_i2s_wr_rd_reg,
        .volatile_reg = tegra30_i2s_volatile_reg,
-       .cache_type = REGCACHE_RBTREE,
+       .cache_type = REGCACHE_FLAT,
 };
 
 static const struct tegra30_i2s_soc_data tegra30_i2s_config = {
index 004cd74734b62b941cf64db1634d2774f70f6e3c..ee577ea03ba50f05a4b14379ddcd17a3f73593c0 100644 (file)
@@ -12,7 +12,7 @@ YACC = bison
 
 all : bpf_jit_disasm bpf_dbg bpf_asm
 
-bpf_jit_disasm : CFLAGS = -Wall -O2
+bpf_jit_disasm : CFLAGS = -Wall -O2 -DPACKAGE='bpf_jit_disasm'
 bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl
 bpf_jit_disasm : bpf_jit_disasm.o
 
index 6aa6fb6f7bd938b7ed7ccc2e7c07511b03a6cee6..f954c26de231d2860cf1b70a5ccb6597629137b8 100644 (file)
@@ -825,7 +825,6 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscal
        P_SIGNUM(PIPE);
        P_SIGNUM(ALRM);
        P_SIGNUM(TERM);
-       P_SIGNUM(STKFLT);
        P_SIGNUM(CHLD);
        P_SIGNUM(CONT);
        P_SIGNUM(STOP);
@@ -841,6 +840,15 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscal
        P_SIGNUM(IO);
        P_SIGNUM(PWR);
        P_SIGNUM(SYS);
+#ifdef SIGEMT
+       P_SIGNUM(EMT);
+#endif
+#ifdef SIGSTKFLT
+       P_SIGNUM(STKFLT);
+#endif
+#ifdef SIGSWI
+       P_SIGNUM(SWI);
+#endif
        default: break;
        }
 
index c872991e0f655ba581443f0f413d81a5b910842f..620a1983b76b9921157c78f9ad3888851db1eb11 100644 (file)
@@ -1213,7 +1213,7 @@ static void ip__resolve_ams(struct machine *machine, struct thread *thread,
                 */
                thread__find_addr_location(thread, machine, m, MAP__FUNCTION,
                                ip, &al);
-               if (al.sym)
+               if (al.map)
                        goto found;
        }
 found:
index 3e9f336740fa8699b2bdd16669e05cd8f8f6dede..516d19fb999bcfaddb6511e0292ea341a0e74aa6 100644 (file)
@@ -151,15 +151,15 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
 
                gelf_getshdr(sec, shp);
                str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
-               if (!strcmp(name, str)) {
+               if (str && !strcmp(name, str)) {
                        if (idx)
                                *idx = cnt;
-                       break;
+                       return sec;
                }
                ++cnt;
        }
 
-       return sec;
+       return NULL;
 }
 
 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
index d66418237d21522df42e33a316b808c1e5962ffd..aa290c0de6f56d9e3f142d46124ee5d0688dd68d 100644 (file)
@@ -201,6 +201,7 @@ int main(int argc, char **argv)
 
        msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666);
        if (msgque.msq_id == -1) {
+               err = -errno;
                printf("Can't create queue\n");
                goto err_out;
        }